00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "sigc++/retype.h"
00024
00025 #include "dashboard.h"
00026 #include "graphics/blitter.h"
00027 #include "graphics/drawing.h"
00028 #include "gamemap.h"
00029 #include "iconrepository.h"
00030 #include "spfst.h"
00031 #include "pgimage.h"
00032 #include "textfiletags.h"
00033 #include "mapdisplay.h"
00034 #include "dialogs/unitinfodialog.h"
00035 #include "dialogs/vehicletypeselector.h"
00036 #include "gameoptions.h"
00037 #include "graphics/ColorTransform_PlayerColor.h"
00038
00039 #include "sg.h"
00040
00041 class WeaponInfoLine;
00042
00043 class WeaponInfoPanel : public Panel {
00044 int weaponCount;
00045 static ASCString name;
00046
00047 vector<WeaponInfoLine*> weaponInfoLines;
00048
00049 protected:
00050 bool onClick ( PG_MessageObject* obj, const SDL_MouseButtonEvent* event );
00051 void painter ( const PG_Rect &src, const ASCString& name, const PG_Rect &dst);
00052
00053 bool eventMouseMotion(const SDL_MouseMotionEvent* motion);
00054
00055 public:
00056 WeaponInfoPanel (PG_Widget *parent, const Vehicle* veh, const Vehicletype* vt ) ;
00057 void showWeapon( const SingleWeapon* weap = NULL );
00058
00059
00060 bool eventMouseButtonUp (const SDL_MouseButtonEvent *button);
00061
00062 static const ASCString& WIP_Name();
00063
00064 };
00065
00066
00067
00068 class ExperienceOverview : public PG_Widget {
00069 static const int columns = 4;
00070 protected:
00071 bool eventMouseButtonUp (const SDL_MouseButtonEvent *button)
00072 {
00073 QuitModal();
00074 return true;
00075 };
00076
00077 static PG_Rect getSize( const PG_Point& pos )
00078 {
00079 const Surface& s = IconRepository::getIcon("experience0.png");
00080 return PG_Rect( pos.x, pos.y, columns * s.w(), (maxunitexperience + columns-1)/columns * s.h() );
00081 }
00082
00083 public:
00084 ExperienceOverview( const PG_Point& pos, int exp = -1 ) : PG_Widget( NULL, getSize(pos), true )
00085 {
00086
00087 }
00088
00089
00090 int RunModal()
00091 {
00092 SetCapture();
00093 return PG_Widget::RunModal();
00094 }
00095
00096 void eventDraw (SDL_Surface *surface, const PG_Rect &rect)
00097 {
00098 const Surface& s = IconRepository::getIcon("experience0.png");
00099 int width = s.w();
00100 int height = s.h();
00101
00102 Surface s2 = Surface::Wrap( surface );
00103 for ( int i = 0; i <= maxunitexperience; ++i )
00104 s2.Blit( IconRepository::getIcon("experience" + ASCString::toString(i) + ".png"), SPoint( i % columns * width , i/columns*height) );
00105 }
00106 };
00107
00108 DashboardPanel::DashboardPanel ( PG_Widget *parent, const PG_Rect &r, const ASCString& panelName_, bool loadTheme = true )
00109 :LayoutablePanel ( parent, r, panelName_, loadTheme ), veh(NULL), bld(NULL)
00110 {
00111 updateFieldInfo.connect ( SigC::slot( *this, &DashboardPanel::eval ));
00112 registerSpecialDisplay( "windarrow" );
00113
00114 registerSpecialDisplay( "unitexp" );
00115 registerSpecialDisplay( "unit_level" );
00116 registerSpecialDisplay( "unit_pic" );
00117 for ( int i = 0; i < 10; ++i)
00118 registerSpecialDisplay( "symbol_weapon" + ASCString::toString(i) );
00119 registerSpecialDisplay( "showplayercolor0" );
00120 registerSpecialDisplay( "showplayercolor1" );
00121 registerSpecialDisplay( "field_weather" );
00122
00123 ContainerBase::anyContainerDestroyed.connect( SigC::slot( *this, &DashboardPanel::containerDeleted ));
00124
00125 GameMap::sigMapDeletion.connect( SigC::slot( *this, &DashboardPanel::reset ));
00126
00127 PG_Widget* w = parent->FindChild( "unitexp", true );
00128 if ( w )
00129 w->sigMouseButtonDown.connect( SigC::slot( *this, &DashboardPanel::viewExperienceOverview ));
00130 };
00131
00132 bool DashboardPanel::viewExperienceOverview()
00133 {
00134 PG_Widget* w = GetParent()->FindChild( "unitexp", true );
00135 if ( w ) {
00136 ExperienceOverview eo(PG_Point( w->my_xpos, w->my_ypos ));
00137 eo.Show();
00138 eo.RunModal();
00139 return true;
00140 } else
00141 return false;
00142 }
00143
00144
00145 void DashboardPanel::containerDeleted( ContainerBase* c )
00146 {
00147 if ( c == veh )
00148 veh = NULL;
00149
00150 if ( c == bld )
00151 bld = NULL;
00152 }
00153
00154
00155 bool DashboardPanel::containerRenamed( PG_LineEdit* lineEdit )
00156 {
00157 if ( veh ) {
00158 if ( veh->getMap()->actplayer == veh->getOwner() )
00159 veh->name = lineEdit->GetText();
00160 else
00161 lineEdit->SetText( veh->name );
00162 }
00163
00164 if ( bld ) {
00165 if ( bld->getMap()->actplayer == bld->getOwner() )
00166 bld->name = lineEdit->GetText();
00167 else
00168 lineEdit->SetText( bld->name );
00169 }
00170
00171 return true;
00172 }
00173
00174 void DashboardPanel::reset(GameMap& map)
00175 {
00176 if ( veh && veh->getMap() == &map )
00177 veh = NULL;
00178
00179 if ( bld && bld->getMap() == &map )
00180 bld = NULL;
00181 }
00182
00183
00184
00185 void DashboardPanel::registerSpecialDisplay( const ASCString& name )
00186 {
00187 SpecialDisplayWidget* sdw = dynamic_cast<SpecialDisplayWidget*>( FindChild( name, true ) );
00188 if ( sdw )
00189 sdw->display.connect( SigC::slot( *this, &DashboardPanel::painter ));
00190 }
00191
00192
00193 void DashboardPanel::painter ( const PG_Rect &src, const ASCString& name, const PG_Rect &dst)
00194 {
00195 if ( !actmap )
00196 return;
00197
00198 Surface screen = Surface::Wrap( PG_Application::GetScreen() );
00199
00200 if ( name == "windarrow" ) {
00201 if ( actmap && actmap->weather.windSpeed > 0 ) {
00202 MegaBlitter<4,colorDepth,ColorTransform_None, ColorMerger_AlphaOverwrite, SourcePixelSelector_DirectRotation> blitter;
00203 blitter.setAngle( (6 - actmap->weather.windDirection) * (360 /6));
00204 blitter.blit ( IconRepository::getIcon("wind-arrow.png"), screen, SPoint(dst.x, dst.y) );
00205 }
00206 return;
00207 }
00208
00209 if( name == "showplayercolor0" || name == "showplayercolor1" ) {
00210 MegaBlitter<4,4,ColorTransform_PlayerTrueCol,ColorMerger_PlainOverwrite> blitter;
00211 blitter.setColor( actmap->player[actmap->actplayer].getColor() );
00212
00213 blitter.blit( IconRepository::getIcon("show_playercolor.png"), screen, SPoint(dst.x, dst.y));
00214 return;
00215 }
00216
00217
00218 if ( name == "field_weather" ) {
00219 MapCoordinate mc = actmap->getCursor();
00220 if ( actmap && mc.valid() && fieldvisiblenow( actmap->getField(mc), actmap->getPlayerView() ) ) {
00221 MegaBlitter<4,colorDepth,ColorTransform_None, ColorMerger_AlphaOverwrite> blitter;
00222
00223 static const char* weathernames[] = {"terrain_weather_dry.png",
00224 "terrain_weather_lightrain.png",
00225 "terrain_weather_heavyrain.png",
00226 "terrain_weather_lightsnow.png",
00227 "terrain_weather_heavysnow.png",
00228 "terrain_weather_ice.png" };
00229
00230 blitter.blit ( IconRepository::getIcon(weathernames[actmap->getField(mc)->getweather()]), screen, SPoint(dst.x, dst.y) );
00231 }
00232 return;
00233 }
00234
00235
00236
00237
00238
00239 if ( veh && !fieldvisiblenow( veh->getMap()->getField( veh->getPosition() ), veh->getMap()->getPlayerView() ))
00240 return;
00241
00242
00243
00244 if ( name == "unitexp" ) {
00245 int experience = 0;
00246 if ( veh )
00247 experience = veh->experience;
00248
00249 screen.Blit( IconRepository::getIcon("experience" + ASCString::toString(experience) + ".png"), SPoint(dst.x, dst.y) );
00250 }
00251
00252 if ( name == "unit_level" ) {
00253 int height1 = 0;
00254 int height2 = 0;
00255 int player = actmap->actplayer;
00256 if ( veh ) {
00257 height1 = veh->height;
00258 height2 = veh->typ->height;
00259 player = veh->getOwner();
00260 }
00261
00262 for ( int i = 0; i < 8; ++i ) {
00263 if ( height1 & (1 << i )) {
00264 MegaBlitter<4,4,ColorTransform_PlayerTrueCol,ColorMerger_PlainOverwrite> blitter;
00265 blitter.setColor( actmap->player[player].getColor() );
00266
00267 blitter.blit( IconRepository::getIcon("height-b" + ASCString::toString(i) + ".png"), screen, SPoint(dst.x, dst.y + (7-i) * 13));
00268 } else
00269 if ( height2 & (1 << i ))
00270 screen.Blit( IconRepository::getIcon("height-a" + ASCString::toString(i) + ".png"), SPoint(dst.x, dst.y + (7-i) * 13 ) );
00271
00272 }
00273 }
00274
00275 if ( name == "unit_pic" ) {
00276 if ( veh )
00277 veh->typ->paint( screen, SPoint( dst.x, dst.y ), veh->getOwningPlayer().getPlayerColor() );
00278 }
00279
00280 if ( veh ) {
00281 int pos = 0;
00282 for ( int i = 0; i < veh->typ->weapons.count; ++i) {
00283 if ( !veh->typ->weapons.weapon[i].service() && pos < 10 ) {
00284 if ( name == "symbol_weapon" + ASCString::toString(pos) )
00285 screen.Blit( IconRepository::getIcon(SingleWeapon::getIconFileName( veh->typ->weapons.weapon[i].getScalarWeaponType()) + "-small.png"), SPoint(dst.x, dst.y));
00286
00287 ++pos;
00288 }
00289 }
00290 }
00291
00292 }
00293
00294
00295 void DashboardPanel::eval()
00296 {
00297 if ( !actmap || actmap->actplayer < 0 )
00298 return;
00299
00300
00301 MapCoordinate mc = actmap->player[actmap->actplayer].cursorPos;
00302 tfield* fld = actmap->getField(mc);
00303
00304 Vehicle* veh = fld? fld->vehicle : NULL;
00305
00306 BulkGraphicUpdates bgu( this );
00307
00308 setBargraphValue( "winddisplay", float(actmap->weather.windSpeed ) / 255 );
00309
00310 setLabelText( "windspeed", actmap->weather.windSpeed );
00311
00312 if ( mc.valid() && fieldvisiblenow( fld, actmap->getPlayerView() )) {
00313 setLabelText( "terrain_harbour", fld->bdt.test(cbharbour) ? "YES" : "NO" );
00314 setLabelText( "terrain_pipe", fld->bdt.test(cbpipeline) || fld->building ? "YES" : "NO" );
00315
00316 setLabelText( "terrain_defencebonus", fld->getdefensebonus() );
00317 setLabelText( "terrain_attackbonus", fld->getattackbonus() );
00318 setLabelText( "terrain_jam", fld->getjamming() );
00319 setLabelText( "terrain_name", fld->typ->terraintype->name );
00320
00321 int unitspeed;
00322 if ( veh )
00323 unitspeed = getmaxwindspeedforunit ( veh );
00324 else
00325 unitspeed = maxint;
00326
00327 int windspeed = actmap->weather.windSpeed*maxwindspeed ;
00328 if ( unitspeed < 255*256 ) {
00329 if ( windspeed > unitspeed*9/10 )
00330 setBarGraphColor( "winddisplay", 0xff0000 );
00331 else
00332 if ( windspeed > unitspeed*66/100 )
00333 setBarGraphColor( "winddisplay", 0xffff00 );
00334 else
00335 setBarGraphColor( "winddisplay", 0x00ff00 );
00336 } else
00337 setBarGraphColor( "winddisplay", 0x00ff00 );
00338
00339 } else {
00340 setLabelText( "terrain_harbour", "" );
00341 setLabelText( "terrain_pipe", "" );
00342
00343 setLabelText( "terrain_defencebonus", "" );
00344 setLabelText( "terrain_attackbonus", "" );
00345 setLabelText( "terrain_jam", "" );
00346 setLabelText( "terrain_name", "" );
00347 setBarGraphColor( "winddisplay", 0x00ff00 );
00348 }
00349
00350 if ( mc.valid() && fld ) {
00351 if ( veh && fieldvisiblenow( fld, actmap->getPlayerView() ) ) {
00352 showUnitData( veh, NULL, fld );
00353 } else {
00354
00355 Building* bld = fld->building;
00356 if ( bld && fieldvisiblenow( fld, actmap->getPlayerView() ) )
00357 showUnitData( NULL, bld, fld );
00358 else
00359 showUnitData( NULL, NULL, fld );
00360 }
00361 }
00362
00363
00364
00365 }
00366 void DashboardPanel::showUnitData( Vehicle* veh, Building* bld, tfield* fld, bool redraw )
00367 {
00368 int weaponsDisplayed = 0;
00369 this->veh = veh;
00370 this->bld = bld;
00371
00372 bool bulk = PG_Application::GetBulkMode();
00373 if ( redraw )
00374 PG_Application::SetBulkMode(true);
00375
00376
00377 if ( veh ) {
00378 setLabelText( "unittypename", veh->typ->name );
00379 if ( veh->name.empty() )
00380 setLabelText( "unitname", veh->typ->description );
00381 else
00382 setLabelText( "unitname", veh->name );
00383 setBargraphValue( "unitdamage", float(100-veh->damage) / 100 );
00384 setLabelText( "unitstatus", 100-veh->damage );
00385
00386 setBargraphValue( "unitfuel", veh->getStorageCapacity().fuel ? float( veh->getTank().fuel) / veh->getStorageCapacity().fuel : 0 );
00387 setLabelText( "unitfuelstatus", veh->getTank().fuel );
00388 setBargraphValue( "unitmaterial", veh->getStorageCapacity().material ? float( veh->getTank().material) / veh->getStorageCapacity().material : 0 );
00389 setLabelText( "unitmaterialstatus", veh->getTank().material );
00390 setBargraphValue( "unitenergy", veh->getStorageCapacity().energy ? float( veh->getTank().energy) / veh->getStorageCapacity().energy : 0 );
00391 setLabelText( "unitenergystatus", veh->getTank().energy );
00392
00393 int endurance = UnitHooveringLogic::getEndurance( veh );
00394 if ( endurance >= 0 )
00395 setLabelText( "unitEndurance", endurance );
00396 else
00397 setLabelText( "unitEndurance", "-" );
00398
00399
00400 ASCString moveString = ASCString::toString( veh->getMovement() / 10 );
00401 if ( veh->getMovement() % 10 )
00402 moveString += "." + ASCString::toString(veh->getMovement()%10);
00403
00404 setLabelText( "movepoints", moveString );
00405
00406 if ( veh->typ->fuelConsumption )
00407 setLabelText( "fuelrange", veh->getTank().fuel / veh->typ->fuelConsumption );
00408 else
00409 setLabelText( "fuelrange", "-" );
00410
00411 setLabelText( "armor", veh->typ->armor );
00412
00413 int &pos = weaponsDisplayed;
00414 for ( int i = 0; i < veh->typ->weapons.count; ++i) {
00415 if ( !veh->typ->weapons.weapon[i].service() && pos < 10 ) {
00416 ASCString ps = ASCString::toString(pos);
00417 setLabelText( "punch_weapon" + ps, veh->typ->weapons.weapon[i].maxstrength );
00418 if ( veh->typ->hasFunction( ContainerBaseType::NoReactionfire ) || !veh->typ->weapons.weapon[i].shootable() || veh->typ->weapons.weapon[i].getScalarWeaponType() == cwminen )
00419 setLabelText( "RF_weapon" + ps, "-" );
00420 else
00421 setLabelText( "RF_weapon" + ps, veh->typ->weapons.weapon[i].reactionFireShots );
00422 setLabelText( "status_ammo" + ps, veh->ammo[i] );
00423 setBargraphValue( "bar_ammo" + ps, veh->typ->weapons.weapon[i].count ? float(veh->ammo[i]) / veh->typ->weapons.weapon[i].count : 0 );
00424 ++pos;
00425 }
00426 }
00427 } else {
00428 if ( bld ) {
00429 setLabelText( "unittypename", bld->typ->name );
00430 setLabelText( "unitname", bld->name );
00431 setBargraphValue( "unitdamage", float(100-bld->damage) / 100 );
00432 setLabelText( "unitstatus", 100-bld->damage );
00433 setLabelText( "armor", bld->getArmor() );
00434
00435 if ( 0 ) {
00436 setLabelText( "unitfuelstatus", bld->getAvailableResource(maxint,2) );
00437 setLabelText( "unitmaterialstatus", bld->getAvailableResource(maxint,1) );
00438 setLabelText( "unitenergystatus", bld->getAvailableResource(maxint,0) );
00439 } else {
00440 setLabelText( "unitfuelstatus", "" );
00441 setLabelText( "unitmaterialstatus", "" );
00442 setLabelText( "unitenergystatus", "" );
00443 }
00444
00445
00446 } else {
00447 setLabelText( "armor", "" );
00448 setLabelText( "unittypename", "" );
00449 setLabelText( "unitname", "" );
00450 bool objectFound = false;
00451 if ( fld && fld->objects.size() ) {
00452 for ( tfield::ObjectContainer::iterator i = fld->objects.begin(); i != fld->objects.end(); ++i )
00453 if ( i->typ->armor > 0 ) {
00454 setBargraphValue( "unitdamage", float(100-i->damage) / 100 );
00455 objectFound = true;
00456 break;
00457 }
00458 }
00459 if ( !objectFound )
00460 setBargraphValue( "unitdamage", 0 );
00461 setLabelText( "unitstatus", "" );
00462
00463 setLabelText( "unitfuelstatus", "" );
00464 setLabelText( "unitmaterialstatus", "" );
00465 setLabelText( "unitenergystatus", "" );
00466
00467 }
00468
00469 setBargraphValue( "unitfuel", 0 );
00470 setBargraphValue( "unitmaterial", 0 );
00471 setBargraphValue( "unitenergy", 0 );
00472 setLabelText( "unitEndurance", "" );
00473
00474 setLabelText( "fuelrange", "-" );
00475 setLabelText( "movepoints", "" );
00476 }
00477 for ( int i = weaponsDisplayed; i < 10; ++i ) {
00478 ASCString ps = ASCString::toString(i);
00479 setLabelText( "punch_weapon" + ps, "" );
00480 setLabelText( "RF_weapon" + ps, "" );
00481 setLabelText( "status_ammo" + ps, "" );
00482 setBargraphValue( "bar_ammo" + ps, 0 );
00483 }
00484
00485 if ( redraw ) {
00486 if ( !bulk )
00487 PG_Application::SetBulkMode(false);
00488 Redraw(true);
00489 }
00490 }
00491
00492
00493
00494 WindInfoPanel::WindInfoPanel (PG_Widget *parent, const PG_Rect &r ) : DashboardPanel( parent, r, "WindInfo" )
00495 {
00496 }
00497
00498
00499
00500
00501 UnitInfoPanel::UnitInfoPanel (PG_Widget *parent, const PG_Rect &r ) : DashboardPanel( parent, r, "UnitInfo" )
00502 {
00503 SpecialInputWidget* siw = dynamic_cast<SpecialInputWidget*>( FindChild( "weapinfo", true ) );
00504 if ( siw ) {
00505 siw->sigMouseButtonDown.connect( SigC::slot( *this, &UnitInfoPanel::onClick ));
00506 siw->sigMouseButtonUp.connect( SigC::slot( *this, &UnitInfoPanel::onClick ));
00507 }
00508
00509 PG_LineEdit* l = dynamic_cast<PG_LineEdit*>( parent->FindChild( "unitname", true ) );
00510 if ( l ) {
00511 l->sigEditEnd.connect( SigC::slot( *this, &UnitInfoPanel::containerRenamed ));
00512 l->sigEditUpdate.connect( SigC::slot( *this, &UnitInfoPanel::containerRenamed ));
00513 }
00514
00515 VehicleTypeSelectionItemFactory::showVehicleInfo.connect( SigC::slot( *this, &UnitInfoPanel::showUnitInfo ));
00516 }
00517
00518 void UnitInfoPanel::showUnitInfo( const Vehicletype* vt )
00519 {
00520
00521 }
00522
00523
00524 bool UnitInfoPanel::onClick ( PG_MessageObject* obj, const SDL_MouseButtonEvent* event )
00525 {
00526
00527 static const bool modalWeaponInfo = true;
00528
00529 SpecialInputWidget* siw = dynamic_cast<SpecialInputWidget*>(obj);
00530 if ( siw ) {
00531 if ( event->button == SDL_BUTTON_RIGHT ) {
00532 if ( event->type == SDL_MOUSEBUTTONDOWN ) {
00533
00534 tfield* fld = actmap->getField( actmap->player[actmap->actplayer].cursorPos );
00535 const Vehicle* vehicle = veh;
00536 const Vehicletype* vt = veh ? veh->typ : NULL;
00537 if ( !veh && fld && fld->vehicle ) {
00538 vt = fld->vehicle->typ;
00539 vehicle = fld->vehicle;
00540 }
00541 if ( vt || veh ) {
00542
00543 WeaponInfoPanel* wip = new WeaponInfoPanel( NULL, vehicle, vt );
00544 wip->Show();
00545 wip->BringToFront();
00546 if ( modalWeaponInfo ) {
00547 wip->SetCapture();
00548 wip->RunModal();
00549 delete wip;
00550 }
00551
00552 }
00553 return true;
00554 }
00555 if ( event->type == SDL_MOUSEBUTTONUP && !modalWeaponInfo ) {
00556 bool result = false;
00557 PG_Widget* wip;
00558 do {
00559 wip = PG_Application::GetWidgetByName( WeaponInfoPanel::WIP_Name() );
00560 if ( wip ) {
00561 delete wip;
00562 result = true;
00563 }
00564 } while ( wip );
00565 return result;
00566 }
00567 }
00568 }
00569 return false;
00570 }
00571
00572 class WeaponInfoLine: public PG_Image {
00573 const SingleWeapon* weapon;
00574 const Vehicletype* veh;
00575 WeaponInfoPanel* wip;
00576 static WeaponInfoLine* displayed;
00577 public:
00578 WeaponInfoLine( WeaponInfoPanel* parent, const PG_Point& p, SDL_Surface* image, const SingleWeapon* weap, const Vehicletype* vehicle )
00579 : PG_Image( parent, p, image, false ), weapon(weap), veh ( vehicle ), wip(parent)
00580 {
00581 };
00582
00583 void painter ( const PG_Rect &src, const ASCString& name, const PG_Rect &dst)
00584 {
00585 Surface screen = Surface::Wrap( PG_Application::GetScreen() );
00586 if ( name == "weapon_symbol1" )
00587 screen.Blit( IconRepository::getIcon(SingleWeapon::getIconFileName( weapon->getScalarWeaponType()) + "-small.png"), SPoint(dst.x, dst.y));
00588
00589 if ( name == "weapon_targets" || name == "weapon_shootfrom" ) {
00590 int height;
00591 if (name == "weapon_targets")
00592 height = weapon->targ;
00593 else {
00594 height = weapon->sourceheight;
00595 if ( veh )
00596 height &= veh->height;
00597 }
00598
00599 for ( int i = 0; i < 8; ++i )
00600 if ( height & (1 << i )) {
00601 Surface& tick = IconRepository::getIcon("weapon_ok.png");
00602 screen.Blit( tick, SPoint(dst.x + i * tick.w(), dst.y ) );
00603 }
00604 }
00605
00606 };
00607
00608 void registerSpecialDisplay( const ASCString& name )
00609 {
00610 SpecialDisplayWidget* sdw = dynamic_cast<SpecialDisplayWidget*>( FindChild( name, true ) );
00611 if ( sdw )
00612 sdw->display.connect( SigC::slot( *this, &WeaponInfoLine::painter ));
00613 };
00614
00615 void eventMouseEnter()
00616 {
00617 wip->showWeapon( weapon );
00618 displayed = this;
00619 };
00620
00621 void eventMouseLeave()
00622 {
00623 if ( displayed == this )
00624 wip->showWeapon();
00625 };
00626
00627 bool activate()
00628 {
00629 if ( displayed != this ) {
00630 wip->showWeapon( weapon);
00631 displayed = this;
00632 return true;
00633 } else
00634 return false;
00635 }
00636 };
00637
00638 WeaponInfoLine* WeaponInfoLine::displayed = NULL;
00639
00640
00641
00642 WeaponInfoPanel::WeaponInfoPanel (PG_Widget *parent, const Vehicle* veh, const Vehicletype* vt ) : Panel( parent, PG_Rect::null, "WeaponInfo" ), weaponCount(0)
00643 {
00644 SetName(name);
00645
00646 vector<const SingleWeapon*> displayedWeapons;
00647 vector<int> displayedWeaponNum;
00648
00649 for ( int j = 0; j < vt->weapons.count ; j++)
00650 if ( vt->weapons.weapon[j].getScalarWeaponType() >= 0 ) {
00651 ++weaponCount;
00652 displayedWeapons.push_back( &vt->weapons.weapon[j] );
00653 displayedWeaponNum.push_back(j);
00654 }
00655
00656
00657 Surface& head = IconRepository::getIcon("weapon_large_top.png");
00658 Surface& line = IconRepository::getIcon("weapon_large_line.png");
00659 Surface& foot = IconRepository::getIcon("weapon_large_bottom.png");
00660 int height = head.h() + foot.h() + weaponCount * line.h() + GetTitlebarHeight();
00661
00662 SizeWidget( head.w(), height, false );
00663
00664 int lineStartY = GetTitlebarHeight() + head.h() - 1;
00665
00666 PG_Widget* footWidget = FindChild( "bottom", true );
00667 assert( footWidget != NULL );
00668 footWidget->MoveWidget(0, lineStartY + line.h() * weaponCount, false );
00669
00670 for ( int i = 0; i < weaponCount; ++i ) {
00671 WidgetParameters widgetParams = getDefaultWidgetParams();
00672 WeaponInfoLine* lineWidget = new WeaponInfoLine ( this, PG_Point( 0, lineStartY + i * line.h() ), line.getBaseSurface(), displayedWeapons[i], vt );
00673
00674 PropertyReadingContainer pc ( "panel", textPropertyGroup );
00675
00676 pc.openBracket("LineWidget");
00677 parsePanelASCTXT( pc, lineWidget, widgetParams );
00678 pc.closeBracket();
00679
00680
00681 assignWeaponInfo( this, lineWidget, *displayedWeapons[i] );
00682 lineWidget->registerSpecialDisplay( "weapon_shootfrom" );
00683 lineWidget->registerSpecialDisplay( "weapon_targets" );
00684 if ( veh )
00685 setLabelText( "weapon_currentammo", veh->ammo[displayedWeaponNum[i]], lineWidget );
00686
00687 weaponInfoLines.push_back( lineWidget );
00688 }
00689 setLabelText( "weapon_shootaftermove", vt->wait ? "no" : "yes" );
00690 setLabelText( "weapon_moveaftershoot", vt->hasFunction( ContainerBaseType::MoveAfterAttack ) ? "yes" : "no" );
00691
00692
00693
00694
00695
00696 }
00697
00698
00699 void WeaponInfoPanel::showWeapon( const SingleWeapon* weap )
00700 {
00701 PG_Application::SetBulkMode(true);
00702 int effic[13];
00703 for ( int k = 0; k < 13; k++ )
00704 if ( weap )
00705 effic[k] = weap->efficiency[k];
00706 else
00707 effic[k] = -1;
00708
00709 if ( weap ) {
00710 int mindelta = 1000;
00711 int maxdelta = -1000;
00712 for ( int h1 = 0; h1 < 8; h1++ )
00713 for ( int h2 = 0; h2 < 8; h2++ )
00714 if ( weap->sourceheight & ( 1 << h1 ) )
00715 if ( weap->targ & ( 1 << h2 )) {
00716 int delta = getheightdelta ( h1, h2);
00717 if ( delta > maxdelta )
00718 maxdelta = delta;
00719 if ( delta < mindelta )
00720 mindelta = delta;
00721 }
00722 for ( int a = -6; a < mindelta; a++ )
00723 effic[6+a] = -1;
00724 for ( int b = maxdelta+1; b < 7; b++ )
00725 effic[6+b] = -1;
00726 }
00727
00728 for ( int i = -6; i <= 6; ++i ) {
00729 if ( effic[6+i] >= 0 )
00730 setLabelText( "weapon_distance_" + ASCString::toString(i), i );
00731 else
00732 setLabelText( "weapon_distance_" + ASCString::toString(i), "" );
00733
00734 if ( weap && effic[6+i] >= 0 )
00735 setLabelText( "weapon_efficiency_" + ASCString::toString(i), weap->efficiency[6+i] );
00736 else
00737 setLabelText( "weapon_efficiency_" + ASCString::toString(i), "" );
00738 }
00739
00740
00741 static const int colors[6] = { 0x969595, 0xdfdfdf, 0xfac914, 0x5383e6, 0xff5e5e, 0x08ce37 };
00742
00743 for ( int i = 0; i< cmovemalitypenum; ++i)
00744 if ( weap ) {
00745 int col;
00746 if ( weap->targetingAccuracy[i] < 10 )
00747 col = colors[0] ;
00748 else
00749 if ( weap->targetingAccuracy[i] < 30 )
00750 col = colors[1] ;
00751 else
00752 if ( weap->targetingAccuracy[i] < 80 )
00753 col = colors[3] ;
00754 else
00755 if ( weap->targetingAccuracy[i] < 120 )
00756 col = colors[2];
00757 else
00758 col = colors[4];
00759 setLabelColor( ASCString("weapon_efficiency_") + unitCategoryTags[i], col );
00760 setLabelText( ASCString("weapon_efficiency_") + unitCategoryTags[i], weap->targetingAccuracy[i] );
00761 } else
00762 setLabelText( ASCString("weapon_efficiency_") + unitCategoryTags[i], "" );
00763
00764 if ( weap )
00765 setLabelText( "weapon_text2", weap->getName() );
00766 else
00767 setLabelText( "weapon_text2", "" );
00768
00769 if ( weap ) {
00770 setImage( "weapon_symbol2", IconRepository::getIcon(SingleWeapon::getIconFileName( weap->getScalarWeaponType()) + "-small.png") );
00771 show( "weapon_symbol2" );
00772 } else
00773 hide( "weapon_symbol2" );
00774
00775 PG_Application::SetBulkMode(false);
00776 Update();
00777 }
00778
00779 bool WeaponInfoPanel::eventMouseButtonUp (const SDL_MouseButtonEvent *button)
00780 {
00781 if ( Panel::eventMouseButtonUp( button ))
00782 return true;
00783
00784 if ( button->button == SDL_BUTTON_RIGHT ) {
00785 QuitModal();
00786 return true;
00787 } else
00788 return false;
00789 }
00790
00791
00792 bool WeaponInfoPanel::eventMouseMotion(const SDL_MouseMotionEvent* motion)
00793 {
00794 for ( int i = 0; i < weaponInfoLines.size();++i )
00795 if ( weaponInfoLines[i]->IsMouseInside() )
00796 return weaponInfoLines[i]->activate();
00797 return false;
00798 };
00799
00800
00801 ASCString WeaponInfoPanel::name = "WeaponInfoPanel";
00802 const ASCString& WeaponInfoPanel::WIP_Name()
00803 {
00804 return name;
00805 }
00806
00807
00808 MapInfoPanel::MapInfoPanel (PG_Widget *parent, const PG_Rect &r, MapDisplayPG* mapDisplay ) : DashboardPanel( parent, r, "MapInfo" ), zoomSlider(NULL), changeActive(false)
00809 {
00810 assert( mapDisplay );
00811 this->mapDisplay = mapDisplay;
00812
00813 zoomSlider = dynamic_cast<PG_Slider*>( FindChild( "zoomscroller", true ) );
00814 if ( zoomSlider ) {
00815 zoomSlider->SetRange(0,75);
00816 zoomSlider->sigSlide.connect( SigC::slot( *this, &MapInfoPanel::scrollTrack ));
00817 mapDisplay->newZoom.connect( SigC::slot( *this, &MapInfoPanel::zoomChanged ));
00818 zoomSlider->SetPosition( 100 - mapDisplay->getZoom() );
00819 }
00820
00821 const int labelnum = 4;
00822 const char* label[labelnum] = { "pipes", "container", "resources", "visibilityvalue"};
00823 for ( int i = 0; i < labelnum; ++i ) {
00824 PG_CheckButton* cb = dynamic_cast<PG_CheckButton*>( FindChild( label[i], true ) );
00825 if ( mapDisplay->layerActive( label[i] )
00826 )
00827 layerChanged( true, label[i]);
00828 if ( cb )
00829 cb->sigClick.connect( SigC::bind( SigC::slot( *this, &MapInfoPanel::checkBox ), label[i] ));
00830 }
00831
00832 mapDisplay->layerChanged.connect( SigC::slot( *this, &MapInfoPanel::layerChanged ));
00833
00834 PG_Button* b = dynamic_cast<PG_Button*>( FindChild( "weaprange", true ) );
00835 if ( b )
00836 b->sigClick.connect( SigC::slot( *this, &MapInfoPanel::showWeaponRange ));
00837
00838 PG_Button* b2 = dynamic_cast<PG_Button*>( FindChild( "moverange", true ) );
00839 if ( b2 )
00840 b2->sigClick.connect( SigC::slot( *this, &MapInfoPanel::showMovementRange ));
00841
00842 }
00843
00844 void MapInfoPanel::layerChanged( bool state, const ASCString& label )
00845 {
00846 PG_CheckButton* cb = dynamic_cast<PG_CheckButton*>( FindChild( label, true ) );
00847 if ( cb && ! changeActive )
00848 if ( state )
00849 cb->SetPressed();
00850 else
00851 cb->SetUnpressed();
00852 }
00853
00854 bool MapInfoPanel::showWeaponRange()
00855 {
00856 execuseraction( ua_viewunitweaponrange );
00857 return true;
00858 }
00859
00860 bool MapInfoPanel::showMovementRange()
00861 {
00862 execuseraction( ua_viewunitmovementrange );
00863 return true;
00864 }
00865
00866
00867 void MapInfoPanel::zoomChanged( int zoom )
00868 {
00869 if ( !changeActive )
00870 if ( zoomSlider )
00871 zoomSlider->SetPosition( 100 - zoom );
00872 }
00873
00874 bool MapInfoPanel::scrollTrack( long pos )
00875 {
00876 changeActive = true;
00877 mapDisplay->setNewZoom( 100 - pos );
00878 repaintMap();
00879 changeActive = false;
00880 return true;
00881 }
00882
00883 bool MapInfoPanel::checkBox( bool state, const char* name )
00884 {
00885 changeActive = true;
00886 mapDisplay->activateMapLayer( name, state );
00887 repaintMap();
00888 changeActive = false;
00889 return true;
00890 }
00891
00892