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