00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <pgimage.h>
00019 #include <pgtooltiphelp.h>
00020 #include "cargodialog.h"
00021 #include "cargowidget.h"
00022 #include "vehicletypeselector.h"
00023
00024 #include "../containerbase.h"
00025 #include "../paradialog.h"
00026 #include "../util/messaginghub.h"
00027 #include "../iconrepository.h"
00028 #include "../vehicle.h"
00029 #include "../gamemap.h"
00030 #include "../containercontrols.h"
00031
00032 #include "../asc-mainscreen.h"
00033 #include "../guiiconhandler.h"
00034 #include "../guifunctions.h"
00035 #include "../guifunctions-interface.h"
00036 #include "../cannedmessages.h"
00037 #include "../dashboard.h"
00038 #include "../dialog.h"
00039 #include "../containerbase-functions.h"
00040 #include "../resourcenet.h"
00041
00042 #include "../containerbase-functions.h"
00043 #include "../gameoptions.h"
00044
00045 #include "../actions/moveunitcommand.h"
00046 #include "../actions/cargomovecommand.h"
00047 #include "../actions/servicecommand.h"
00048 #include "../actions/recycleunitcommand.h"
00049 #include "../actions/repairunitcommand.h"
00050 #include "../actions/trainunitcommand.h"
00051 #include "../actions/repairbuildingcommand.h"
00052 #include "../actions/transfercontrolcommand.h"
00053 #include "../actions/setresourceprocessingratecommand.h"
00054
00055 #include "selectionwindow.h"
00056 #include "ammotransferdialog.h"
00057 #include "unitinfodialog.h"
00058 #include "vehicleproductionselection.h"
00059 #include "../sg.h"
00060 #include "../spfst.h"
00061
00062 const VehicleType* selectVehicletype( ContainerBase* plant, const vector<VehicleType*>& items );
00063
00064
00065 class CargoDialog;
00066
00067 class SubWindow: public SigC::Object
00068 {
00069 protected:
00070 CargoDialog* cargoDialog;
00071 PG_Widget* widget;
00072
00073 SubWindow() : cargoDialog(NULL), widget(NULL) {};
00074 ContainerBase* container();
00075 public:
00076 virtual bool available( CargoDialog* cd ) = 0;
00077 virtual ASCString getASCTXTname() = 0;
00078 virtual ASCString getFullName() = 0;
00079 virtual void registerSubwindow( CargoDialog* cd );
00080 virtual void registerChilds( CargoDialog* cd );
00081 virtual void update() = 0;
00082 virtual ~SubWindow() {} ;
00083 };
00084
00085
00086 class SubWinButton : public PG_Button
00087 {
00088
00089 static int calcWidth() {
00090 if ( buttonwidth == -1 ) {
00091 buttonwidth = IconRepository::getIcon("cargo-buttonpressed.png").w();
00092 }
00093 return buttonwidth;
00094 }
00095
00096 static int calcHeight() {
00097 if ( buttonheight == -1 ) {
00098 buttonheight = IconRepository::getIcon("cargo-buttonpressed.png").h();
00099 }
00100 return buttonheight;
00101 }
00102
00103 public:
00104 static int buttonwidth;
00105 static int buttonheight;
00106
00107
00108 SubWinButton( PG_Widget *parent, const SPoint& pos, SubWindow* subWindow ) : PG_Button( parent, PG_Rect( pos.x, pos.y, calcWidth(), calcHeight() ), "", -1, "SubWinButton") {
00109 SetBackground( PRESSED, IconRepository::getIcon("cargo-buttonpressed.png").getBaseSurface() );
00110 SetBackground( HIGHLITED, IconRepository::getIcon("cargo-buttonhighlighted.png").getBaseSurface() );
00111 SetBackground( UNPRESSED, IconRepository::getIcon("cargo-buttonunpressed.png").getBaseSurface() );
00112 SetBorderSize(0,0,0);
00113 ASCString filename = ASCString("cargo-") + subWindow->getASCTXTname();
00114 SetIcon( IconRepository::getIcon( filename + ".png" ).getBaseSurface(),
00115 IconRepository::getIcon( filename + "-pressed.png" ).getBaseSurface(),
00116 IconRepository::getIcon( filename + ".png" ).getBaseSurface() );
00117 SetToggle( true );
00118 new PG_ToolTipHelp ( this, subWindow->getFullName() );
00119 };
00120 };
00121
00122 int SubWinButton::buttonwidth = -1;
00123 int SubWinButton::buttonheight = -1;
00124
00125
00126
00127 namespace CargoGuiFunctions
00128 {
00129
00130 class MovementDestination : public GuiFunctions::Movement
00131 {
00132 PG_Widget& parent;
00133 public:
00134 MovementDestination( PG_Widget& masterParent ) : parent( masterParent) {};
00135
00136 void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00137 GuiFunctions::Movement::execute( pos, subject, num );
00138 if ( !NewGuiHost::pendingCommand )
00139 parent.QuitModal();
00140 }
00141 };
00142
00143 class CancelMovement : public GuiFunctions::Cancel
00144 {
00145 PG_Widget& parent;
00146 public:
00147 CancelMovement ( PG_Widget& masterParent ) : parent( masterParent) {};
00148
00149 bool available( const MapCoordinate& pos, ContainerBase* subject, int num )
00150 {
00151 if ( !NewGuiHost::pendingCommand )
00152 parent.QuitModal();
00153
00154 return true;
00155 }
00156
00157 void execute( const MapCoordinate& pos, ContainerBase* subject, int num ) {
00158 GuiFunctions::Cancel::execute( pos, subject, num );
00159 parent.QuitModal();
00160 }
00161 };
00162
00163
00164 class CloseDialog : public GuiFunction
00165 {
00166 CargoDialog& parent;
00167 public:
00168 CloseDialog( CargoDialog& masterParent ) : parent( masterParent) {};
00169 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00170 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00171 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00172 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00173 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00174 };
00175
00176
00177 class Movement : public GuiFunction
00178 {
00179 CargoDialog& parent;
00180 public:
00181 Movement( CargoDialog& masterParent ) : parent( masterParent) {};
00182 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00183 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00184 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00185 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00186 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00187 };
00188
00189
00190 class UnitProduction : public GuiFunction, public SigC::Object
00191 {
00192 CargoDialog& parent;
00193 ConstructUnitCommand::Producables producables;
00194 ConstructUnitCommand* constructUnitCommand;
00195 void productionLinesChanged();
00196 public:
00197 UnitProduction( CargoDialog& masterParent ) : parent( masterParent), constructUnitCommand(NULL) {};
00198 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00199 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00200 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00201 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00202 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00203 };
00204
00205 class UnitTraining : public GuiFunction
00206 {
00207 CargoDialog& parent;
00208 public:
00209 UnitTraining( CargoDialog& masterParent ) : parent( masterParent) {};
00210 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00211 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00212 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00213 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00214 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00215 };
00216
00217 class RefuelUnitCommand : public GuiFunction
00218 {
00219 CargoDialog& parent;
00220 public:
00221 RefuelUnitCommand( CargoDialog& masterParent ) : parent( masterParent) {};
00222 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00223 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00224 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00225 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00226 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00227 };
00228 class RefuelUnitDialogCommand : public GuiFunction
00229 {
00230 CargoDialog& parent;
00231 public:
00232 RefuelUnitDialogCommand( CargoDialog& masterParent ) : parent( masterParent) {};
00233 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00234 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00235 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00236 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00237 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00238 };
00239
00240 class RepairUnit : public GuiFunction
00241 {
00242 CargoDialog& parent;
00243 public:
00244 RepairUnit( CargoDialog& masterParent ) : parent( masterParent) {};
00245 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00246 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00247 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00248 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00249 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00250 };
00251
00252 class MoveUnitUp : public GuiFunction
00253 {
00254 CargoDialog& parent;
00255 public:
00256 MoveUnitUp ( CargoDialog& masterParent ) : parent( masterParent) {};
00257 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00258 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00259 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00260 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00261 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00262 };
00263
00264 class MoveUnitIntoInnerContainer : public GuiFunction
00265 {
00266 CargoDialog& parent;
00267 public:
00268 MoveUnitIntoInnerContainer ( CargoDialog& masterParent ) : parent( masterParent) {};
00269 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00270 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00271 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00272 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00273 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00274 };
00275
00276
00277 class OpenContainer: public GuiFunction
00278 {
00279 CargoDialog& parent;
00280 public:
00281 OpenContainer( CargoDialog& masterParent ) : parent( masterParent) {};
00282 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00283 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00284 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00285 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00286 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00287 };
00288
00289 class RecycleUnitCommandButton : public GuiFunction
00290 {
00291 ASCString getCommandName( const ContainerBase* carrier );
00292 CargoDialog& parent;
00293 public:
00294 RecycleUnitCommandButton( CargoDialog& masterParent ) : parent( masterParent) {};
00295 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00296 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00297 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00298 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00299 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00300 };
00301
00302
00303 class UnitInfo : public GuiFunction
00304 {
00305 CargoDialog& parent;
00306 public:
00307 UnitInfo( CargoDialog& masterParent ) : parent( masterParent) {};
00308 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00309 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00310 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00311 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00312 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00313 };
00314
00315 class TransferUnitControl : public GuiFunction
00316 {
00317 CargoDialog& parent;
00318 public:
00319 TransferUnitControl( CargoDialog& masterParent ) : parent( masterParent) {};
00320 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00321 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00322 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00323 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00324 };
00325
00326
00327
00328 };
00329
00330
00331 class BuildingControlWindow;
00332 class CargoInfoWindow;
00333
00334 class CargoDialog : public Panel
00335 {
00336
00337 GuiIconHandler guiIconHandler;
00338
00339 ContainerBase* container;
00340 bool setupOK;
00341 Surface infoImage;
00342
00343 typedef vector<SubWindow*> Activesubwindows;
00344 Activesubwindows activesubwindows;
00345
00346 typedef deallocating_vector<SubWindow*> Subwindows;
00347 Subwindows subwindows;
00348
00349 vector<SubWinButton*> subWinButtons;
00350
00351 CargoWidget* cargoWidget;
00352 SubWindow* researchWindow;
00353 SubWindow* matterWindow;
00354 BuildingControlWindow* buildingControlWindow;
00355
00356 bool shutdownImmediately;
00357
00358 void containerDestroyed() {
00359 shutdownImmediately = true;
00360 }
00361
00362 CargoInfoWindow* ciw;
00363
00364 bool eventKeyDown(const SDL_KeyboardEvent* key) {
00365 int mod = SDL_GetModState() & ~(KMOD_NUM | KMOD_CAPS | KMOD_MODE);
00366
00367 if ( !mod ) {
00368 if ( key->keysym.sym == SDLK_ESCAPE ) {
00369 QuitModal();
00370 return true;
00371 }
00372 }
00373
00374 if ( (mod & KMOD_SHIFT) && (mod & KMOD_CTRL)) {
00375 switch ( key->keysym.unicode ) {
00376 case 26:
00377 getContainer()->getMap()->actions.redo( createContext( getContainer()->getMap() ) );
00378 cargoChanged();
00379 return true;
00380 }
00381 }
00382
00383 if ( (mod & KMOD_CTRL) && !(mod & KMOD_SHIFT)) {
00384 switch ( key->keysym.unicode ) {
00385 case 26:
00386 getContainer()->getMap()->actions.undo( createContext( getContainer()->getMap() ) );
00387 if ( shutdownImmediately ) {
00388 QuitModal();
00389 return true;
00390 }
00391
00392 cargoChanged();
00393 for ( Activesubwindows::iterator i = activesubwindows.begin(); i != activesubwindows.end(); ++i )
00394 (*i)->update();
00395 return true;
00396 }
00397 }
00398
00399 return false;
00400 };
00401
00402
00403
00404 void registerSpecialDisplay( const ASCString& name ) {
00405 SpecialDisplayWidget* sdw = dynamic_cast<SpecialDisplayWidget*>( FindChild( name, true ) );
00406 if ( sdw )
00407 sdw->display.connect( SigC::slot( *this, &CargoDialog::painter ));
00408 };
00409
00410 void registerSpecialInput( const ASCString& name ) {
00411 SpecialInputWidget* siw = dynamic_cast<SpecialInputWidget*>( FindChild( name, true ) );
00412 if ( siw )
00413 siw->sigMouseButtonDown.connect( SigC::slot( *this, &CargoDialog::onClick ));
00414 };
00415
00416 bool onClick ( PG_MessageObject* obj, const SDL_MouseButtonEvent* event ) {
00417 PG_Widget* w = dynamic_cast<PG_Widget*>(obj);
00418 if ( w ) {
00419
00420 return true;
00421 }
00422 return false;
00423 };
00424
00425 void onUnitClick ( Vehicle* veh,SPoint pos, bool first ) {
00426
00427 if ( mainScreenWidget&& mainScreenWidget->getGuiHost() && (!first || CGameOptions::Instance()->mouse.singleClickAction) ) {
00428 SPoint iconPos = pos;
00429 if ( veh ) {
00430 iconPos.x -= smallGuiIconSizeX/2;
00431 iconPos.y -= smallGuiIconSizeY/2;
00432 } else {
00433 iconPos.x += 2;
00434 iconPos.y += 2;
00435 }
00436
00437 mainScreenWidget->getGuiHost()->showSmallIcons( this, iconPos, false );
00438 }
00439
00440 };
00441
00442 void clearSmallIcons( ) {
00443 if ( mainScreenWidget && mainScreenWidget->getGuiHost() )
00444 mainScreenWidget->getGuiHost()->clearSmallIcons();
00445 }
00446
00447
00448
00449 void painter ( const PG_Rect &src, const ASCString& name, const PG_Rect &dst) {
00450 Surface screen = Surface::Wrap( PG_Application::GetScreen() );
00451
00452 if ( name == "unitpad_unitsymbol" ) {
00453 Vehicle* v = dynamic_cast<Vehicle*>(container);
00454 if ( v )
00455 v->paint( screen, SPoint( dst.x, dst.y ), 0);
00456 }
00457
00458 if ( name == "SelectedImage" ) {
00459 if ( getMarkedUnit() )
00460 getMarkedUnit()->typ->paint( screen, SPoint( dst.x, dst.y ), getMarkedUnit()->getOwningPlayer().getPlayerColor() );
00461 }
00462
00463 };
00464
00465 bool activate_i( int pane ) {
00466 if ( pane >= 0 && pane < activesubwindows.size() ) {
00467 activate( activesubwindows[pane]->getASCTXTname() );
00468 activesubwindows[pane]->update();
00469 }
00470 return true;
00471 }
00472
00473 void activate( const ASCString& pane ) {
00474 BulkGraphicUpdates bgu( this );
00475 for ( int i = 0; i < activesubwindows.size(); ++i )
00476 if ( activesubwindows[i]->getASCTXTname() != pane )
00477 hide( activesubwindows[i]->getASCTXTname() );
00478
00479 for ( int i = 0; i < activesubwindows.size(); ++i )
00480 if ( activesubwindows[i]->getASCTXTname() == pane )
00481 show( activesubwindows[i]->getASCTXTname() );
00482
00483 for ( int i = 0; i< subWinButtons.size(); ++i )
00484 subWinButtons[i]->SetPressed( activesubwindows[i]->getASCTXTname() == pane );
00485 };
00486
00487
00488 void registerGuiFunctions( GuiIconHandler& handler ) {
00489 handler.registerUserFunction( new CargoGuiFunctions::Movement( *this ) );
00490 handler.registerUserFunction( new CargoGuiFunctions::RefuelUnitCommand( *this ) );
00491 handler.registerUserFunction( new CargoGuiFunctions::RefuelUnitDialogCommand( *this ) );
00492 handler.registerUserFunction( new CargoGuiFunctions::RepairUnit( *this ) );
00493 handler.registerUserFunction( new CargoGuiFunctions::UnitProduction( *this ));
00494 handler.registerUserFunction( new CargoGuiFunctions::UnitTraining( *this ));
00495 handler.registerUserFunction( new CargoGuiFunctions::MoveUnitUp( *this ));
00496 handler.registerUserFunction( new CargoGuiFunctions::MoveUnitIntoInnerContainer( *this ));
00497 handler.registerUserFunction( new CargoGuiFunctions::OpenContainer( *this ));
00498 handler.registerUserFunction( new CargoGuiFunctions::RecycleUnitCommandButton( *this ));
00499 handler.registerUserFunction( new CargoGuiFunctions::UnitInfo( *this ));
00500 handler.registerUserFunction( new CargoGuiFunctions::TransferUnitControl( *this ));
00501 handler.registerUserFunction( new CargoGuiFunctions::CloseDialog( *this ));
00502 }
00503
00504 void checkStoringPosition( Vehicle* unit ) {
00505 if ( mainScreenWidget&& mainScreenWidget->getGuiHost() ) {
00506 mainScreenWidget->getGuiHost()->eval( container->getPosition(), unit );
00507 }
00508
00509 if ( mainScreenWidget && mainScreenWidget->getUnitInfoPanel() )
00510 mainScreenWidget->getUnitInfoPanel()->showUnitData( unit, NULL, NULL, true );
00511 }
00512
00513 void updateLoadMeter() {
00514 if ( container->baseType->maxLoadableWeight > 0 )
00515 setBargraphValue ( "LoadingMeter", float( container->cargoWeight()) / container->baseType->maxLoadableWeight );
00516 }
00517
00518 void dragUnitToInnerContainer( Vehicle* draggedUnit, Vehicle* targetUnit ) {
00519 if ( !draggedUnit )
00520 return;
00521
00522 if ( draggedUnit != targetUnit ) {
00523 if ( targetUnit && CargoMoveCommand::moveInAvail(draggedUnit, targetUnit) ) {
00524 auto_ptr<CargoMoveCommand> cargomove ( new CargoMoveCommand( draggedUnit ));
00525 cargomove->setMode( CargoMoveCommand::moveInwards );
00526 cargomove->setTargetCarrier( targetUnit );
00527 ActionResult res = cargomove->execute ( createContext( getContainer()->getMap() ));
00528 if ( res.successful() )
00529 cargomove.release();
00530 } else {
00531 if ( container->getCarrier() && !targetUnit ) {
00532 auto_ptr<CargoMoveCommand> cargomove ( new CargoMoveCommand( draggedUnit ));
00533 cargomove->setMode( CargoMoveCommand::moveOutwards );
00534 ActionResult res = cargomove->execute ( createContext( getContainer()->getMap() ));
00535 if ( res.successful() )
00536 cargomove.release();
00537 } else {
00538
00539 }
00540 }
00541 }
00542 cargoChanged();
00543 }
00544
00545 bool dragUnitToInnerContainerAvail( Vehicle* draggedUnit, Vehicle* targetUnit ) {
00546 return CargoMoveCommand::moveInAvail( draggedUnit, targetUnit );
00547 }
00548
00549 void dragInProcess() {
00550 if ( mainScreenWidget && mainScreenWidget->getGuiHost() )
00551 mainScreenWidget->getGuiHost()->clearSmallIcons();
00552 }
00553
00554 void dragAborted() {
00555
00556 cargoChanged();
00557 }
00558
00559 public:
00560 int getResourceValue ( int resourcetype, int y, int scope ) {
00561 int player = container->getMap()->actplayer;
00562 if ( container->getMap()->getCurrentPlayer().stat == Player::supervisor )
00563 player = container->getOwner();
00564
00565 switch ( y ) {
00566 case 0: {
00567 GetResource gr ( container->getMap() );
00568 return gr.getresource ( container->getPosition().x, container->getPosition().y, resourcetype, maxint, 1, player, scope );
00569 }
00570 case 1: {
00571 GetResourceCapacity grc ( container->getMap() );
00572 return grc.getresource ( container->getPosition().x, container->getPosition().y, resourcetype, maxint, 1, player, scope );
00573 }
00574 case 2: {
00575 GetResourcePlus grp ( container->getMap() );
00576 return grp.getresource ( container->getPosition().x, container->getPosition().y, resourcetype, player, scope );
00577 }
00578 case 3: {
00579 GetResourceUsage gru( container->getMap() );
00580 return gru.getresource ( container->getPosition().x, container->getPosition().y, resourcetype, player, scope );
00581 }
00582 }
00583 return -1;
00584 }
00585
00586
00587 public:
00588
00589 CargoDialog (PG_Widget *parent, ContainerBase* cb );
00590
00591 void addAvailableSubwin( SubWindow* w ) {
00592 activesubwindows.push_back( w );
00593 };
00594
00595 void updateResourceDisplay() {
00596 setLabelText( "energyavail", container->getResource(maxint, 0, true ) );
00597 setLabelText( "materialavail", container->getResource(maxint, 1, true ) );
00598 setLabelText( "fuelavail", container->getResource(maxint, 2, true ) );
00599 setLabelText( "numericaldamage", container->damage );
00600 }
00601
00602
00603 Vehicle* getMarkedUnit() {
00604 if ( cargoWidget )
00605 return cargoWidget->getMarkedUnit();
00606 else
00607 return NULL;
00608 }
00609
00610 void cargoChanged() {
00611
00612 if ( cargoWidget ) {
00613 cargoWidget->redrawAll();
00614 if ( mainScreenWidget && mainScreenWidget->getUnitInfoPanel() )
00615 mainScreenWidget->getUnitInfoPanel()->showUnitData( cargoWidget->getMarkedUnit(), NULL, NULL, true );
00616
00617 checkStoringPosition( cargoWidget->getMarkedUnit() );
00618 }
00619 sigCargoChanged();
00620 updateResourceDisplay();
00621 showAmmo();
00622 updateLoadMeter();
00623 }
00624
00625 int RunModal() {
00626 if ( setupOK )
00627 return Panel::RunModal();
00628 return 0;
00629 }
00630
00631 bool ProcessEvent ( const SDL_Event * event,bool bModal = false ) {
00632
00633
00634 if ( mainScreenWidget && mainScreenWidget->getUnitInfoPanel() )
00635 if ( mainScreenWidget->getUnitInfoPanel()->ProcessEvent( event, bModal ))
00636 return true;
00637
00638 if ( mainScreenWidget && mainScreenWidget->getGuiHost() )
00639 if ( mainScreenWidget->getGuiHost()->ProcessEvent( event, bModal ))
00640 return true;
00641
00642 if ( Panel::ProcessEvent( event, bModal ))
00643 return true;
00644
00645 return false;
00646 }
00647
00648 void showAmmo() {
00649 setLabelText( "cmmun", container->getAmmo( cwcruisemissile, maxint, true ));
00650 setLabelText( "minemun", container->getAmmo( cwminen, maxint, true ));
00651 setLabelText( "bombmun", container->getAmmo( cwbombn, maxint, true ));
00652 setLabelText( "lmmun", container->getAmmo( cwlargemissilen, maxint, true ));
00653 setLabelText( "smmun", container->getAmmo( cwsmallmissilen, maxint, true ));
00654 setLabelText( "mgmun", container->getAmmo( cwmachinegunn, maxint, true ));
00655 setLabelText( "canmun", container->getAmmo( cwcannonn, maxint, true ));
00656 setLabelText( "torpmun", container->getAmmo( cwtorpedon, maxint, true ));
00657 }
00658
00659 void userHandler( const ASCString& label, PropertyReadingContainer& pc, PG_Widget* parent, WidgetParameters widgetParams );
00660
00661 ContainerBase* getContainer() {
00662 return container;
00663 };
00664
00665 GameMap* getMap() {
00666 if ( container ) return container->getMap();
00667 else return NULL;
00668 };
00669
00670 SigC::Signal0<void> sigCargoChanged;
00671
00672 void setUnitInfoWidgets( const ContainerBase* container, const ASCString& prefix ) {
00673 if ( container ) {
00674 ASCString s;
00675 s.format( "%d / %d", container->cargoWeight(), container->baseType->maxLoadableWeight );
00676 setLabelText( prefix + "CargoUsage", s );
00677
00678 int slots = 0;
00679 for ( ContainerBase::Cargo::const_iterator i = container->getCargo().begin(); i != container->getCargo().end(); ++i )
00680 if( *i )
00681 ++slots;
00682
00683 if ( container->baseType->maxLoadableUnits )
00684 setBargraphValue ( prefix + "LoadingMeter3", float( slots ) / float(container->baseType->maxLoadableUnits) );
00685 else
00686 setBargraphValue ( prefix + "LoadingMeter3", 0 );
00687
00688 s.format( "%d / %d", slots, container->baseType->maxLoadableUnits );
00689 setLabelText( prefix + "SlotSummary", s );
00690
00691 setLabelText( prefix + "UsedCargoSlots", slots );
00692 setLabelText( prefix + "CargoSlotCount", container->baseType->maxLoadableUnits );
00693 if ( container->baseType->maxLoadableUnits )
00694 setLabelText( prefix + "MaxLoadableWeight", container->baseType->maxLoadableWeight );
00695 else
00696 setLabelText( prefix + "MaxLoadableWeight", "-" );
00697
00698 setLabelText( prefix + "UserName", container->name );
00699 setLabelText( prefix + "UnitTypeName", container->baseType->name );
00700 setLabelText( prefix + "UnitTypeDescription", container->baseType->description );
00701
00702 } else {
00703 setLabelText( prefix + "CargoUsage", "" );
00704 setBargraphValue ( prefix + "LoadingMeter3", 0 );
00705 setLabelText( prefix + "UsedCargoSlots", "" );
00706 setLabelText( prefix + "CargoSlotCount", "" );
00707 setLabelText( prefix + "MaxLoadableWeight", "" );
00708
00709 setLabelText( prefix + "UserName", "" );
00710 setLabelText( prefix + "UnitTypeName", "" );
00711 setLabelText( prefix + "UnitTypeDescription", "" );
00712
00713 }
00714 }
00715
00716 void updateVariables( ) {
00717 PG_Widget* widget = this;
00718
00719 {
00720 setLabelText( "MaxSolarPower", container->maxplus.energy );
00721
00722 static const char* weathernames[] = {"terrain_weather_dry.png",
00723 "terrain_weather_lightrain.png",
00724 "terrain_weather_heavyrain.png",
00725 "terrain_weather_lightsnow.png",
00726 "terrain_weather_heavysnow.png",
00727 "terrain_weather_ice.png"
00728 };
00729
00730
00731 SolarPowerplant solarPowerPlant ( container );
00732 Resources plus = solarPowerPlant.getPlus();
00733 setLabelText( "CurrentSolarPower", plus.energy );
00734 setImage( "Weather", weathernames[ container->getMap()->getField( container->getPosition() )->getWeather() ], widget );
00735 }
00736
00737
00738 {
00739 WindPowerplant windPowerPlant ( container );
00740 Resources plus = windPowerPlant.getPlus();
00741 setLabelText( "CurrentWindPower", plus.energy, widget );
00742
00743 #ifdef WEATHERGENERATOR
00744 if ( container->getMap()->weatherSystem )
00745 setLabelText( "WindSpeed", container->getMap()->weatherSystem->getCurrentWindSpeed(), widget );
00746 #else
00747 setLabelText( "WindSpeed", container->getMap()->weather.windSpeed, widget );
00748 #endif
00749 }
00750
00751
00752 {
00753
00754 class MoveMalusType
00755 {
00756 public:
00757 enum { deflt,
00758 light_tracked_vehicle,
00759 medium_tracked_vehicle,
00760 heavy_tracked_vehicle,
00761 light_wheeled_vehicle,
00762 medium_wheeled_vehicle,
00763 heavy_wheeled_vehicle,
00764 trooper,
00765 rail_vehicle,
00766 medium_aircraft,
00767 medium_ship,
00768 structure,
00769 light_aircraft,
00770 heavy_aircraft,
00771 light_ship,
00772 heavy_ship,
00773 helicopter,
00774 hoovercraft
00775 };
00776 };
00777
00778 setUnitInfoWidgets( container, "" );
00779
00780
00781 setUnitInfoWidgets( getMarkedUnit(), "Selected" );
00782
00783 PG_Widget* typeImage = FindChild( "TypeImage", true );
00784 PG_ToolTipHelp* typeImageTooltip= NULL;
00785 if ( typeImage )
00786 typeImageTooltip = PG_ToolTipHelp::GetToolTip( typeImage );
00787
00788 if ( getMarkedUnit() ) {
00789 setLabelText( "CurrentCargo", getMarkedUnit()->weight(), widget );
00790 setImage( "TypeImage", moveMaliTypeIcons[getMarkedUnit()->typ->movemalustyp], widget );
00791 show( "TypeImage" );
00792 if ( typeImageTooltip )
00793 typeImageTooltip->SetText( cmovemalitypes[getMarkedUnit()->typ->movemalustyp ] );
00794
00795 if ( getMarkedUnit()->baseType->infoImageSmallFilename.length() > 0 ) {
00796 setImage( "Selected3DImageSmall", getMarkedUnit()->baseType->infoImageSmallFilename, widget );
00797 show( "Selected3DImageSmall" );
00798 } else
00799 hide( "Selected3DImageSmall" );
00800
00801 } else {
00802 setLabelText( "CurrentCargo", "-" , widget );
00803 hide( "TypeImage" );
00804 hide( "Selected3DImageSmall" );
00805 }
00806
00807 PG_Widget* w = FindChild( "SelectedImage", true );
00808 if ( w )
00809 w->Update();
00810
00811 if ( container->baseType->maxLoadableWeight > 0 )
00812 setBargraphValue ( "LoadingMeter2", float( container->cargoWeight()) / container->baseType->maxLoadableWeight, widget );
00813
00814 setLabelText("CargoWeight", container->cargoWeight() );
00815
00816 if ( container->baseType->maxLoadableWeight >= 1000000 ) {
00817 setLabelText ( "FreeWeight", "unlimited", widget );
00818 setLabelText ( "MaxWeight", "unlimited", widget );
00819 } else {
00820 setLabelText ( "FreeWeight", container->baseType->maxLoadableWeight - container->cargoWeight(), widget );
00821 setLabelText ( "MaxWeight", container->baseType->maxLoadableWeight, widget );
00822 }
00823
00824 setLabelText ( "FreeSlots", container->baseType->maxLoadableUnits - container->vehiclesLoaded(), widget );
00825 setLabelText ( "MaxSlots", container->baseType->maxLoadableUnits , widget );
00826 setLabelText ( "MaxUnitSize", container->baseType->maxLoadableUnitSize, widget );
00827 }
00828
00829
00830 {
00831 Building* bld = dynamic_cast<Building*>( container );
00832 if ( bld ) {
00833 if ( RepairBuildingCommand::avail( bld )) {
00834 RepairBuildingCommand rbc( bld );
00835 RepairBuildingCommand::RepairData repairData = rbc.getCost();
00836 setLabelText( "RepairCostLabel", "Cost for repairing " + ASCString::toString( repairData.damageDelta ) + "%", widget );
00837
00838 setLabelText( "EnergyCost", repairData.cost.energy, widget );
00839 setLabelText( "MaterialCost", repairData.cost.material, widget );
00840 setLabelText( "FuelCost", repairData.cost.fuel, widget );
00841
00842 } else {
00843 setLabelText( "RepairCostLabel", "No repair possible", widget );
00844
00845 setLabelText( "EnergyCost", "-", widget );
00846 setLabelText( "MaterialCost", "-", widget );
00847 setLabelText( "FuelCost", "-", widget );
00848 }
00849 }
00850 setLabelText( "Jamming", container->baseType->jamming , widget );
00851 setLabelText( "View", container->baseType->view, widget );
00852 setLabelText( "Armor", container->getArmor(), widget );
00853 }
00854
00855 }
00856
00857
00858 ~CargoDialog() {
00859 if ( setupOK )
00860 NewGuiHost::popIconHandler();
00861
00862 }
00863
00864 };
00865
00866
00867
00868
00869
00870 void cargoDialog( ContainerBase* cb )
00871 {
00872 CargoDialog cd ( NULL, cb );
00873 cd.Show();
00874 cd.RunModal();
00875 }
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893 void SubWindow::registerSubwindow( CargoDialog* cd )
00894 {
00895 cargoDialog = cd;
00896 cd->addAvailableSubwin( this );
00897 }
00898
00899 void SubWindow::registerChilds( CargoDialog* cd )
00900 {
00901 widget = cd->FindChild( getASCTXTname(), true);
00902 if ( !widget )
00903 warningMessage( "Could not find widget with name " + getASCTXTname() );
00904 }
00905
00906
00907 ContainerBase* SubWindow::container()
00908 {
00909 return cargoDialog->getContainer();
00910 }
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921 class SolarPowerWindow : public SubWindow
00922 {
00923
00924 public:
00925 bool available( CargoDialog* cd ) {
00926 if ( !cd->getMap()->getCurrentPlayer().diplomacy.isAllied( cd->getContainer() ))
00927 return false;
00928
00929 return cd->getContainer()->baseType->hasFunction( ContainerBaseType::SolarPowerPlant );
00930 };
00931
00932 ASCString getASCTXTname() {
00933 return "solarpower";
00934 };
00935
00936 ASCString getFullName() {
00937 return "Solar Power Generation";
00938 };
00939
00940 void update() {
00941 cargoDialog->updateVariables();
00942 }
00943 };
00944
00945 class WindPowerWindow : public SubWindow
00946 {
00947 public:
00948 bool available( CargoDialog* cd ) {
00949 if ( !cd->getMap()->getCurrentPlayer().diplomacy.isAllied( cd->getContainer() ))
00950 return false;
00951
00952 return cd->getContainer()->baseType->hasFunction( ContainerBaseType::WindPowerPlant );
00953 };
00954
00955 ASCString getASCTXTname() {
00956 return "windpower";
00957 };
00958
00959 ASCString getFullName() {
00960 return "Wind Power Generation";
00961 };
00962
00963
00964 void update() {
00965 cargoDialog->updateVariables();
00966 }
00967 };
00968
00969 class NetControlWindow : public SubWindow
00970 {
00971
00972 private:
00973
00974 bool click( PG_Button* b, int x, int y ) {
00975 return true;
00976 }
00977
00978 PG_Button* findButton( int x, int y ) {
00979 char c = 'a' + x;
00980 ASCString buttonName = "Button" + ASCString::toString(y) + c;
00981 return dynamic_cast<PG_Button*>( widget->FindChild( buttonName, true ) );
00982 }
00983
00984 public:
00985 bool available( CargoDialog* cd ) {
00986 if ( !cd->getMap()->getCurrentPlayer().diplomacy.isAllied( cd->getContainer() ))
00987 return false;
00988
00989 return dynamic_cast<Building*>(cd->getContainer()) != NULL;
00990 };
00991
00992 ASCString getASCTXTname() {
00993 return "netcontrol";
00994 };
00995
00996 ASCString getFullName() {
00997 return "Resource Network Control";
00998 };
00999
01000
01001 void registerChilds( CargoDialog* cd ) {
01002 SubWindow::registerChilds( cd );
01003
01004 if ( widget ) {
01005 for ( int x = 0; x < 3; ++x ) {
01006 for ( int y = 0; y < 4; ++y ) {
01007 PG_Button* b = findButton( x, y );
01008 if ( b ) {
01009 b->sigClick.connect( SigC::bind( SigC::bind( SigC::slot( *this, &NetControlWindow::click ), x), y));
01010 if ( y >= 2)
01011 b->SetToggle( true );
01012 }
01013
01014 }
01015 }
01016
01017 }
01018 }
01019
01020 void update() {
01021 cargoDialog->updateVariables();
01022 }
01023 };
01024
01025
01026 class CargoInfoWindow : public SubWindow
01027 {
01028 public:
01029 bool available( CargoDialog* cd ) {
01030 return true;
01031 };
01032
01033 ASCString getASCTXTname() {
01034 return "cargoinfo";
01035 };
01036
01037 ASCString getFullName() {
01038 return "Cargo Info";
01039 };
01040
01041 void registerSubwindow( CargoDialog* cd ) {
01042 SubWindow::registerSubwindow( cd );
01043 cargoDialog->sigCargoChanged.connect( SigC::slot( *this, &CargoInfoWindow::update ));
01044 };
01045
01046
01047 void registerChilds( CargoDialog* cd ) {
01048 SubWindow::registerChilds( cd );
01049
01050 }
01051
01052 void update() {
01053 cargoDialog->updateVariables();
01054 }
01055 };
01056
01057
01058 class BuildingControlWindow : public SubWindow
01059 {
01060 public:
01061 SigC::Signal0<void> damageChanged;
01062
01063
01064 void registerChilds( CargoDialog* cd ) {
01065 SubWindow::registerChilds( cd );
01066
01067 if ( widget ) {
01068 PG_Button* b = dynamic_cast<PG_Button*>( widget->FindChild( "RepairButton", true ) );
01069 if ( b )
01070 b->sigClick.connect( SigC::slot( *this, &BuildingControlWindow::repair ));
01071 }
01072 }
01073
01074 bool repair() {
01075 Building* bld = dynamic_cast<Building*>(container() );
01076 if ( !RepairBuildingCommand::avail( bld ))
01077 return false;
01078
01079 auto_ptr<RepairBuildingCommand> rbc ( new RepairBuildingCommand( bld ));
01080 ActionResult res = rbc->execute( createContext( container()->getMap() ));
01081 if ( res.successful() )
01082 rbc.release();
01083 else
01084 displayActionError( res );
01085
01086 cargoDialog->updateResourceDisplay();
01087
01088 damageChanged();
01089 update();
01090
01091 if ( widget )
01092 widget->Update();
01093
01094 return true;
01095 }
01096
01097
01098 bool available( CargoDialog* cd ) {
01099 if ( !cd->getMap()->getCurrentPlayer().diplomacy.isAllied( cd->getContainer() ))
01100 return false;
01101
01102 Building* bld = dynamic_cast<Building*>(cd->getContainer());
01103 if ( !bld )
01104 return false;
01105
01106 return true;
01107
01108
01109 };
01110
01111 ASCString getASCTXTname() {
01112 return "damagecontrol";
01113 };
01114
01115 ASCString getFullName() {
01116 return "Building Control";
01117 };
01118
01119
01120 void update() {
01121 cargoDialog->updateVariables();
01122
01123 damageChanged();
01124 }
01125 };
01126
01127
01128 class ResourceInfoWindow : public SubWindow
01129 {
01130
01131
01132 public:
01133 bool available( CargoDialog* cd ) {
01134 if ( !cd->getMap()->getCurrentPlayer().diplomacy.isAllied( cd->getContainer() ) && cd->getMap()->getCurrentPlayer().stat != Player::supervisor )
01135 return false;
01136
01137 return dynamic_cast<Building*>( cd->getContainer() ) != NULL;
01138 };
01139
01140 ASCString getASCTXTname() {
01141 return "resourceinfo";
01142 };
01143
01144 ASCString getFullName() {
01145 return "Resource Network Information";
01146 };
01147
01148
01149 void update() {
01150
01151 ContainerBase* activeContainer= container();
01152
01153 int value[3][3][4];
01154 int mx = 0;
01155
01156 for ( int c = 0; c < 3; c++ )
01157 for ( int x = 0; x < 3; x++ )
01158 for ( int y = 0; y < 4; y++ ) {
01159 value[c][x][y] = cargoDialog->getResourceValue ( x, y, c );
01160 if ( y != 1 )
01161 if ( value[c][x][y] > mx )
01162 mx = value[c][x][y];
01163 }
01164
01165
01166
01167 for ( int c = 0; c < 3; c++ )
01168 for ( int x = 0; x < 3; x++ )
01169 for ( int y = 0; y < 4; y++ ) {
01170 char xx = 'A' + (c * 3 + x);
01171 char yy = '1' + y;
01172 ASCString label = "Res";
01173 label += xx;
01174 label += yy;
01175 if ( (y != 1 || value[c][x][y] < mx*10 || value[c][x][y] < 1000000000 ) && ( !activeContainer->getMap()->isResourceGlobal(x) || y!=0 ||c ==2))
01176 cargoDialog->setLabelText( label, value[c][x][y] );
01177 else
01178 cargoDialog->setLabelText( label, "-" );
01179 }
01180
01181 }
01182
01183 };
01184
01185
01186 class GraphWidget : public PG_Widget
01187 {
01188 map<int,int> verticalLines;
01189 vector<int> curves;
01190 typedef vector< pair<int,int> > Bars;
01191 Bars bars;
01192 protected:
01193 int xrange;
01194 int yrange;
01195 virtual int getPoint( int curve, int x ) {
01196 return 0;
01197 };
01198 virtual int getBarHeight( int bar ) {
01199 return 0;
01200 };
01201 virtual void click( int x, int button ) {};
01202
01203 bool eventMouseMotion (const SDL_MouseMotionEvent *motion) {
01204 PG_Point p = ScreenToClient ( motion->x, motion->y );
01205 if ( motion->type == SDL_MOUSEMOTION && (motion->state == SDL_BUTTON(1)))
01206 click ( p.x, 1 );
01207
01208 if ( motion->type == SDL_MOUSEMOTION && (motion->state == SDL_BUTTON(3)))
01209 click( p.x, 3 );
01210
01211 return true;
01212 }
01213
01214 bool eventMouseButtonDown (const SDL_MouseButtonEvent *button) {
01215 PG_Point p = ScreenToClient ( button->x, button->y );
01216 if ( button->type == SDL_MOUSEBUTTONDOWN && (button->button == SDL_BUTTON_LEFT))
01217 click ( p.x, 1 );
01218
01219 if ( button->type == SDL_MOUSEBUTTONDOWN && (button->button == SDL_BUTTON_RIGHT))
01220 click ( p.x, 3 );
01221
01222 return true;
01223 }
01224
01225 int mapColor( int col ) {
01226 PG_Color color = col;
01227 return color.MapRGBA( PG_Application::GetScreen()->format, 255-GetTransparency());
01228 }
01229
01230 public:
01231 GraphWidget( PG_Widget *parent, const PG_Rect& rect ) : PG_Widget( parent, rect ), xrange(1), yrange(1) {};
01232 void setRange( int x, int y ) {
01233 xrange = max( x, 1);
01234 yrange = max( y, 1);
01235 }
01236
01237 int addCurve( int color ) {
01238 curves.push_back( color );
01239 return curves.size();
01240 }
01241
01242 int addBar( int pos, int color ) {
01243 bars.push_back ( make_pair( pos, color ));
01244 return bars.size();
01245 }
01246
01247
01248 void addVerticalLine ( int x, int color ) {
01249 verticalLines[x] = color;
01250 }
01251
01252 void clearVerticalLines() {
01253 verticalLines.clear();
01254 }
01255
01256 void eventBlit (SDL_Surface *surface, const PG_Rect &src, const PG_Rect &dst) {
01257 Surface s = Surface::Wrap( PG_Application::GetScreen() );
01258
01259 for ( int c = 0; c < curves.size(); ++c ) {
01260 int realcol = mapColor( curves[c] );
01261
01262 for ( int x = 0; x < Width(); ++x ) {
01263 int y = getPoint( c, x * xrange / Width() ) * Height() / yrange;
01264 if ( y < 0 )
01265 y = 0;
01266 if ( y >= Height() )
01267 y = Height() -1 ;
01268 PG_Point pos = ClientToScreen( x, Height() - y );
01269 s.SetPixel( pos.x, pos.y, realcol );
01270 }
01271 }
01272
01273 for ( map<int,int>::iterator v = verticalLines.begin(); v != verticalLines.end(); ++v ) {
01274 int realcol = mapColor( v->second );
01275
01276 int x = v->first * Width() / xrange;
01277 for ( int y = 0; y < Height(); ++y ) {
01278 PG_Point pos = ClientToScreen( x, y );
01279 s.SetPixel( pos.x, pos.y, realcol );
01280 }
01281 }
01282 int barNum = 0;
01283 for ( Bars::iterator b = bars.begin(); b != bars.end(); ++b ) {
01284 int x = b->first * Width() / (xrange+1);
01285 int x2 = (b->first + 1) * Width() / xrange - 1;
01286 if ( x2 <= x )
01287 x2 = x + 1;
01288
01289 int y = getBarHeight( barNum ) * Height() / yrange;
01290 if ( y < 0 )
01291 y = 0;
01292 if ( y >= Height() )
01293 y = Height() -1 ;
01294
01295 PG_Point pos = ClientToScreen( x, Height() - y );
01296 paintFilledRectangle<4>( s, SPoint( pos.x, pos.y), x2-x, y, ColorMerger_ColoredOverwrite<4>( mapColor( b->second ) ) );
01297
01298 ++barNum;
01299 }
01300 };
01301 };
01302
01303 class ResearchGraph : public GraphWidget
01304 {
01305 ContainerBase* cont;
01306 protected:
01307 int getPoint( int curve, int x ) {
01308 Resources cost = returnResourcenUseForResearch( cont, x );
01309 return cost.energy;
01310 }
01311
01312
01313 void addSecondaryLab( ContainerBase* lab ) {
01314 if ( lab->baseType->nominalresearchpoints && lab->baseType->hasFunction( ContainerBaseType::Research ) ) {
01315 int rel = lab->researchpoints * cont->baseType->nominalresearchpoints / lab->baseType->nominalresearchpoints;
01316 addVerticalLine( rel, 0xd9d9d9 );
01317 }
01318 }
01319
01320 void recalc() {
01321 clearVerticalLines();
01322
01323 Player& player = cont->getMap()->player[ cont->getOwner() ];
01324 for ( Player::BuildingList::iterator i = player.buildingList.begin(); i != player.buildingList.end(); ++i )
01325 addSecondaryLab( *i );
01326
01327 for ( Player::VehicleList::iterator i = player.vehicleList.begin(); i != player.vehicleList.end(); ++i )
01328 addSecondaryLab( *i );
01329
01330 addVerticalLine( cont->researchpoints, 0xd5d200 );
01331 }
01332
01333 bool setResearch ( ContainerBase* lab, int x ) {
01334 if ( cont->baseType->nominalresearchpoints ) {
01335 int res;
01336
01337 if ( returnResourcenUseForResearch ( lab, lab->maxresearchpoints ) == Resources(0,0,0))
01338 res = lab->maxresearchpoints;
01339 else
01340 res = x * xrange / Width() * lab->baseType->nominalresearchpoints / cont->baseType->nominalresearchpoints;
01341
01342 if ( res > lab->maxresearchpoints )
01343 res = lab->maxresearchpoints;
01344 int old = lab->researchpoints;
01345 lab->researchpoints = res;
01346 return res != old;
01347 } else
01348 return false;
01349 }
01350
01351
01352 void click( int x, int button ) {
01353 setResearch( x, button == 3 );
01354 }
01355
01356 void setResearch( int x, bool global = false ) {
01357 if ( global ) {
01358 Player& player = cont->getMap()->player[ cont->getOwner() ];
01359 for ( Player::BuildingList::iterator i = player.buildingList.begin(); i != player.buildingList.end(); ++i )
01360 setResearch( *i, x );
01361
01362 for ( Player::VehicleList::iterator i = player.vehicleList.begin(); i != player.vehicleList.end(); ++i )
01363 setResearch( *i, x );
01364 }
01365
01366 if ( setResearch( cont, x ) || global ) {
01367 sigChange();
01368 recalc();
01369 Update();
01370 }
01371 }
01372
01373 public:
01374 ResearchGraph( PG_Widget *parent, const PG_Rect& rect, ContainerBase* container ) : GraphWidget( parent, rect ), cont( container ) {
01375 setRange( cont->maxresearchpoints+1, returnResourcenUseForResearch( cont, cont->maxresearchpoints ).energy );
01376 addCurve( 0x00ff00 );
01377 recalc();
01378 }
01379
01380 SigC::Signal0<void> sigChange;
01381
01382 };
01383
01384
01385 class ResearchWindow : public SubWindow
01386 {
01387 public:
01388 bool available( CargoDialog* cd ) {
01389 if ( !cd->getMap()->getCurrentPlayer().diplomacy.isAllied( cd->getContainer() ))
01390 return false;
01391
01392 return cd->getContainer()->baseType->hasFunction( ContainerBaseType::Research );
01393 };
01394
01395 ASCString getASCTXTname() {
01396 return "research";
01397 };
01398
01399 ASCString getFullName() {
01400 return "Research Lab";
01401 };
01402
01403
01404 void update() {
01405 ContainerBase* activeContainer= container();
01406
01407
01408 Player& player = activeContainer->getMap()->player[ activeContainer->getOwner() ];
01409
01410 cargoDialog->setLabelText( "ResPerTurnLocal", activeContainer->researchpoints * player.research.getMultiplier(), widget );
01411 cargoDialog->setLabelText( "ResPerTurnGlobal", player.research.getResearchPerTurn(), widget );
01412
01413 Resources cost = returnResourcenUseForResearch( activeContainer );
01414 for ( int r = 0; r < 3; ++r)
01415 cargoDialog->setLabelText( "CostLocal" + ASCString::toString(r), cost.resource(r), widget );
01416
01417 Resources globalCost;
01418 for ( Player::BuildingList::iterator i = player.buildingList.begin(); i != player.buildingList.end(); ++i )
01419 globalCost += returnResourcenUseForResearch( *i );
01420
01421 for ( Player::VehicleList::iterator i = player.vehicleList.begin(); i != player.vehicleList.end(); ++i )
01422 globalCost += returnResourcenUseForResearch( *i );
01423
01424 for ( int r = 0; r < 3; ++r)
01425 cargoDialog->setLabelText( "CostGlobal" + ASCString::toString(r), globalCost.resource(r), widget );
01426
01427 int availIn = player.research.currentTechAvailableIn();
01428 if ( availIn >= 0 )
01429 cargoDialog->setLabelText( "AvailGlobal", availIn, widget );
01430 else
01431 cargoDialog->setLabelText( "AvailGlobal", "-", widget );
01432
01433 if ( player.research.activetechnology )
01434 cargoDialog->setLabelText( "CurrentTech", player.research.activetechnology->name, widget );
01435 else
01436 cargoDialog->setLabelText( "CurrentTech", "-", widget );
01437 }
01438 };
01439
01440
01441
01442 class MatterAndMiningBaseWindow : public SubWindow
01443 {
01444 PG_Slider* slider;
01445 bool first;
01446
01447 protected:
01448 virtual bool invertSlider() {
01449 return false;
01450 };
01451 private:
01452
01453 bool scrollPos( long pos ) {
01454 if ( invertSlider() )
01455 pos = 100 - pos;
01456
01457 setnewpower( pos );
01458 update();
01459 return true;
01460 };
01461
01462
01463 bool scrollTrack( long pos ) {
01464
01465 if ( invertSlider() )
01466 pos = 100 - pos;
01467
01468 showResourceTable( getOutput( pos ));
01469
01470 return true;
01471 };
01472
01473 void setnewpower ( ContainerBase* c, int power ) {
01474 if ( hasFunction( c ) ) {
01475 auto_ptr<SetResourceProcessingRateCommand> srprc ( new SetResourceProcessingRateCommand( c, power ));
01476
01477 ActionResult res = srprc->execute( createContext( c->getMap() ));
01478 if ( res.successful() )
01479 srprc.release();
01480 else
01481 displayActionError( res );
01482 }
01483 }
01484
01485 void setnewpower ( int pwr ) {
01486 if ( pwr < 0 )
01487 pwr = 0;
01488
01489 if ( pwr > 100 )
01490 pwr = 100;
01491
01492 bool allbuildings = false;
01493
01494 Player& player = container()->getMap()->player[ container()->getOwner() ];
01495
01496 if ( allbuildings ) {
01497 for ( Player::BuildingList::iterator bi = player.buildingList.begin(); bi != player.buildingList.end(); bi++ )
01498 setnewpower( *bi, pwr );
01499 for ( Player::VehicleList::iterator bi = player.vehicleList.begin(); bi != player.vehicleList.end(); bi++ )
01500 setnewpower( *bi, pwr );
01501 } else {
01502 setnewpower( container(), pwr );
01503 }
01504 }
01505
01506 virtual bool hasFunction( const ContainerBase* container ) = 0;
01507
01508 bool available( CargoDialog* cd ) {
01509 if ( !cd->getMap()->getCurrentPlayer().diplomacy.isAllied( cd->getContainer() ))
01510 return false;
01511
01512 return hasFunction( cd->getContainer() );
01513 };
01514
01515 virtual Resources getOutput() = 0;
01516 virtual Resources getOutput( int rate ) = 0;
01517
01518 private:
01519 void showResourceTable( const Resources& res ) {
01520 for ( int r = 0; r < 3; ++r ) {
01521 ASCString s = Resources::name(r);
01522 int amount = res.resource(r);
01523 if ( container()->maxplus.resource(r) < 0 ) {
01524 s += "In";
01525 amount = -amount;
01526 } else {
01527 s += "Out";
01528 }
01529 if ( container()->maxplus.resource(r) != 0 )
01530 cargoDialog->setLabelText( s, amount, widget );
01531 }
01532 }
01533
01534 public:
01535 MatterAndMiningBaseWindow () : slider(NULL), first(true) {};
01536
01537
01538 void update() {
01539 cargoDialog->updateVariables();
01540
01541 if ( widget )
01542 slider = dynamic_cast<PG_Slider*>( widget->FindChild( "PowerSlider", true ));
01543
01544 if ( first && slider ) {
01545 first = false;
01546 slider->SetRange( 0, 100 );
01547 slider->sigScrollPos.connect( SigC::slot( *this, &MatterAndMiningBaseWindow::scrollPos ));
01548 slider->sigScrollTrack.connect( SigC::slot( *this, &MatterAndMiningBaseWindow::scrollTrack ));
01549 }
01550
01551 for ( int r = 0; r < 3; ++r )
01552 if ( container()->maxplus.resource(r) ) {
01553 slider->SetPosition( 100 * container()->plus.resource(r) / container()->maxplus.resource(r) );
01554 break;
01555 }
01556
01557 showResourceTable( getOutput() );
01558 }
01559 };
01560
01561 class MatterConversionWindow : public MatterAndMiningBaseWindow
01562 {
01563 protected:
01564 bool hasFunction( const ContainerBase* container ) {
01565 return container->baseType->hasFunction( ContainerBaseType::MatterConverter );
01566 };
01567
01568 Resources getOutput() {
01569 return container()->plus;
01570 }
01571
01572 Resources getOutput( int rate ) {
01573 Resources r;
01574 for ( int i = 0; i < Resources::count; ++i )
01575 r.resource(i) = rate * container()->maxplus.resource(i) / 100;
01576 return r;
01577 }
01578
01579
01580 public:
01581
01582 ASCString getASCTXTname() {
01583 return "conventionalpower";
01584 };
01585
01586 ASCString getFullName() {
01587 return "Power Generation";
01588 };
01589
01590 };
01591
01592
01593
01594 class MiningGraph : public GraphWidget
01595 {
01596 ContainerBase* cont;
01597 GetMiningInfo::MiningInfo mininginfo;
01598 protected:
01599
01600 int getBarHeight( int bar ) {
01601 int r = (bar % 4) - 1;
01602 switch ( bar % 4 ) {
01603 case 0:
01604 case 1:
01605 return 100;
01606 case 2:
01607 case 3:
01608 return 100 * mininginfo.avail[bar/4].resource(r) / mininginfo.max[bar/4].resource(r);
01609 };
01610 return 0;
01611 };
01612
01613
01614 public:
01615 MiningGraph( PG_Widget *parent, const PG_Rect& rect, ContainerBase* container ) : GraphWidget( parent, rect ), cont( container ) {
01616 setRange( (maxminingrange+1)*3+1, 110 );
01617
01618 GetMiningInfo gmi ( container );
01619 mininginfo = gmi.getMiningInfo();
01620
01621 int neutralColor = 0x666666;
01622
01623 for ( int i = 0; i <= min( mininginfo.nextMiningDistance + 1, maxminingrange); ++i ) {
01624 addBar( i * 3, neutralColor );
01625 addBar( i * 3+1, neutralColor );
01626 addBar( i * 3, Resources::materialColor );
01627 addBar( i * 3+1, Resources::fuelColor );
01628 }
01629
01630 }
01631 };
01632
01633
01634 class MiningWindow : public MatterAndMiningBaseWindow
01635 {
01636 protected:
01637 bool hasFunction( const ContainerBase* container ) {
01638 return container->baseType->hasFunction( ContainerBaseType::MiningStation );
01639 };
01640
01641 bool invertSlider() {
01642 return false;
01643 };
01644
01645 Resources getOutput() {
01646 Resources r;
01647 MiningStation miningStation ( container(), true );
01648
01649 for ( int i = 0; i <3; ++i ) {
01650 Resources plus = miningStation.getPlus();
01651 if ( plus.resource(i) > 0 )
01652 r.resource(i) = plus.resource(i);
01653
01654 Resources usage = miningStation.getUsage();
01655 if ( usage.resource(i) > 0 )
01656 r.resource(i) = -usage.resource(i);
01657 }
01658 return r;
01659 }
01660
01661 Resources getOutput( int rate ) {
01662 ContainerBase* c = container();
01663 Resources temp = c->plus;
01664
01665 for ( int r = 0; r < Resources::count; r++ )
01666 c->plus.resource(r) = c->maxplus.resource(r) * rate/100;
01667
01668
01669 Resources r;
01670 MiningStation miningStation ( container(), true );
01671
01672 for ( int i = 0; i <3; ++i ) {
01673 Resources plus = miningStation.getPlus();
01674 if ( plus.resource(i) > 0 )
01675 r.resource(i) = plus.resource(i);
01676
01677 Resources usage = miningStation.getUsage();
01678 if ( usage.resource(i) > 0 )
01679 r.resource(i) = -usage.resource(i);
01680 }
01681
01682 c->plus = temp;
01683
01684 return r;
01685 }
01686
01687 public:
01688
01689 ASCString getASCTXTname() {
01690 return "mining";
01691 };
01692
01693 ASCString getFullName() {
01694 return "Mining Facility";
01695 };
01696
01697
01698 void update() {
01699 MatterAndMiningBaseWindow::update();
01700 }
01701 };
01702
01703
01704
01705 class DamageBarWidget : public PG_ThemeWidget
01706 {
01707 private:
01708 ContainerBase* container;
01709 public:
01710 DamageBarWidget (PG_Widget *parent, const PG_Rect &rect, ContainerBase* container ) : PG_ThemeWidget( parent, rect, false ) {
01711 this->container = container;
01712 };
01713
01714
01715 void repaint() {
01716 Update();
01717 }
01718
01719 void eventBlit (SDL_Surface *surface, const PG_Rect &src, const PG_Rect &dst) {
01720 DI_Color color( container->damage * 255 / 100, (100-container->damage) * 255/100, 0 );
01721
01722 PG_Rect r = dst;
01723 r.w = (100 - container->damage ) * dst.w / 100;
01724
01725 Resources cost;
01726 int w2 = (100 - container->damage + container->repairableDamage() ) * dst.w / 100;
01727
01728 Uint32 c = color.MapRGBA( PG_Application::GetScreen()->format, 255-GetTransparency());
01729 if ( w > 0 ) {
01730 SDL_FillRect(PG_Application::GetScreen(), &r, c );
01731 }
01732
01733 if ( w2 > 0 ) {
01734 int h = dst.h / 4;
01735 Surface s = Surface::Wrap( PG_Application::GetScreen() );
01736 ColorMerger_Set<4> cm ( c );
01737 drawLine<4> ( s, cm, SPoint(dst.x, dst.y + h), SPoint( dst.x + w2, dst.y + h));
01738 drawLine<4> ( s, cm, SPoint(dst.x, dst.y + h+1), SPoint( dst.x + w2, dst.y + h+1));
01739 drawLine<4> ( s, cm, SPoint(dst.x, dst.y + dst.h - h-1), SPoint( dst.x + w2, dst.y + dst.h - h-1));
01740 drawLine<4> ( s, cm, SPoint(dst.x, dst.y + dst.h - h), SPoint( dst.x + w2, dst.y + dst.h - h));
01741 drawLine<4> ( s, cm, SPoint( dst.x + w2, dst.y), SPoint( dst.x + w2, dst.y + dst.h));
01742 drawLine<4> ( s, cm, SPoint( dst.x-1 + w2, dst.y), SPoint( dst.x-1 + w2, dst.y + dst.h));
01743 }
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754 }
01755
01756 };
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771 CargoDialog ::CargoDialog (PG_Widget *parent, ContainerBase* cb )
01772 : Panel( parent, PG_Rect::null, "cargodialog", false ), container(cb), setupOK(false), cargoWidget(NULL), researchWindow( NULL ), matterWindow(NULL)
01773 {
01774 shutdownImmediately = false;
01775
01776 sigClose.connect( SigC::slot( *this, &CargoDialog::QuitModal ));
01777
01778 registerGuiFunctions( guiIconHandler );
01779
01780 cb->destroyed.connect( SigC::slot( *this, &CargoDialog::containerDestroyed ));
01781
01782 ciw = new CargoInfoWindow;
01783 subwindows.push_back( ciw );
01784 subwindows.push_back( new SolarPowerWindow );
01785 subwindows.push_back( new WindPowerWindow );
01786 subwindows.push_back( new MiningWindow );
01787 subwindows.push_back( new ResourceInfoWindow );
01788
01789
01790 buildingControlWindow = new BuildingControlWindow;
01791 subwindows.push_back( buildingControlWindow );
01792
01793 researchWindow = new ResearchWindow;
01794 subwindows.push_back( researchWindow );
01795
01796 matterWindow = new MatterConversionWindow;
01797 subwindows.push_back ( matterWindow );
01798
01799 for ( Subwindows::iterator i = subwindows.begin(); i != subwindows.end(); ++i )
01800 if ( (*i)->available( this ))
01801 (*i)->registerSubwindow( this );
01802
01803
01804
01805
01806
01807
01808
01809 try {
01810 if ( !setup() )
01811 return;
01812
01813
01814
01815 if ( my_xpos + Width() > PG_Application::GetScreenWidth() - 100 )
01816 MoveWidget( 0, 0, false);
01817
01818
01819 } catch ( ParsingError err ) {
01820 errorMessage( err.getMessage() );
01821 return;
01822 } catch ( ... ) {
01823 errorMessage( "unknown exception" );
01824 return;
01825 }
01826
01827 registerSpecialDisplay( "unitpad_unitsymbol" );
01828 registerSpecialDisplay( "SelectedImage" );
01829
01830
01831 for ( Subwindows::iterator i = subwindows.begin(); i != subwindows.end(); ++i ) {
01832 if ( (*i)->available( this ))
01833 (*i)->registerChilds( this );
01834 hide( (*i)->getASCTXTname() );
01835 }
01836
01837
01838
01839 if ( !cb->baseType->infoImageFilename.empty() && exist( cb->baseType->infoImageFilename )) {
01840 PG_Image* img = dynamic_cast<PG_Image*>(FindChild( "ContainerImage", true ));
01841 if ( img ) {
01842 tnfilestream stream ( cb->baseType->infoImageFilename, tnstream::reading );
01843 infoImage.readImageFile( stream );
01844 img->SetDrawMode( PG_Draw::STRETCH );
01845 img->SetImage( infoImage.getBaseSurface(), false );
01846 img->SizeWidget( img->GetParent()->w, img->GetParent()->h );
01847 }
01848 } else {
01849 PG_Image* img = dynamic_cast<PG_Image*>(FindChild( "ContainerImage", true ));
01850 Vehicle* v = dynamic_cast<Vehicle*>(cb);
01851 if ( img && v )
01852 img->SetImage( infoImage.getBaseSurface(), false );
01853
01854 }
01855
01856 if ( container->baseType->infoImageSmallFilename.length() > 0 )
01857 setImage( "Container3DImageSmall", container->baseType->infoImageSmallFilename );
01858
01859
01860
01861 setLabelText( "UnitName", cb->getName() );
01862 if ( cb->getName() != cb->baseType->name )
01863 setLabelText( "UnitClass", cb->baseType->name );
01864
01865 NewGuiHost::pushIconHandler( &guiIconHandler );
01866
01867 activate_i(0);
01868 cargoChanged();
01869 Show();
01870 setupOK = true;
01871
01872 };
01873
01874
01875 void CargoDialog::userHandler( const ASCString& label, PropertyReadingContainer& pc, PG_Widget* parent, WidgetParameters widgetParams )
01876 {
01877 if ( label == "ButtonPanel" ) {
01878 int x = 0;
01879 int y = 0;
01880 for ( int i = 0; i < activesubwindows.size(); ++i ) {
01881 SubWinButton* button = new SubWinButton( parent, SPoint( x, y ), activesubwindows[i] );
01882 button->sigClick.connect( SigC::bind( SigC::slot( *this, &CargoDialog::activate_i ), i));
01883 if ( x + 2*SubWinButton::buttonwidth < parent->Width() )
01884 x += SubWinButton::buttonwidth;
01885 else {
01886 x = 0;
01887 y += SubWinButton::buttonheight;
01888 }
01889 subWinButtons.push_back( button );
01890 }
01891 }
01892
01893 if ( label == "ResourceTable" ) {
01894 int gap = 2;
01895 int cellwidth = (parent->Width() - 8 * gap) / 9;
01896 int cellHeight = (parent->Height() - 3 * gap ) / 4;
01897 for ( int x = 0; x < 9; ++x )
01898 for ( int y = 0; y < 4; ++y ) {
01899 PG_Rect r ( x * parent->Width() / 9, y * parent->Height() / 4, cellwidth, cellHeight );
01900 PG_Label* l = new PG_Label ( parent, r, PG_NULLSTR );
01901 widgetParams.assign( l );
01902 ASCString label = "Res";
01903 char xx = 'A' + x;
01904 char yy = '1' + y;
01905 label += xx;
01906 label += yy;
01907 l->SetName( label );
01908 }
01909 }
01910
01911 if ( label == "ResearchGraph" ) {
01912 ResearchGraph* graph = new ResearchGraph( parent, PG_Rect( 0, 0, parent->Width(), parent->Height() ), container );
01913 graph->sigChange.connect( SigC::slot( *researchWindow, &SubWindow::update ));
01914 }
01915
01916 if ( label == "MiningGraph" ) {
01917 MiningGraph* mg = new MiningGraph( parent, PG_Rect( 0, 0, parent->Width(), parent->Height() ), container );
01918 new PG_ToolTipHelp( mg, "Horizontal: distance from building ; vertical: amount of resources(M/F)");
01919
01920 }
01921
01922 if ( label == "DamageBar" ) {
01923 DamageBarWidget* dbw = new DamageBarWidget( parent, PG_Rect( 0, 0, parent->Width(), parent->Height() ), container );
01924 buildingControlWindow->damageChanged.connect( SigC::slot( *dbw, &DamageBarWidget::repaint ));
01925 }
01926
01927 if ( label == "ScrollArea" ) {
01928 PG_Widget* unitScrollArea = parent;
01929 if ( unitScrollArea ) {
01930 cargoWidget = new CargoWidget( unitScrollArea, PG_Rect( 1, 1, unitScrollArea->Width() -2 , unitScrollArea->Height() -2 ), container, false );
01931 cargoWidget->enableDragNDrop( true );
01932 cargoWidget->sigDragDone.connect( SigC::slot( *this, &CargoDialog::dragUnitToInnerContainer ));
01933 cargoWidget->sigDragAvail.connect( SigC::slot( *this, &CargoDialog::dragUnitToInnerContainerAvail ));
01934 cargoWidget->sigDragInProcess.connect( SigC::slot( *this, &CargoDialog::dragInProcess ));
01935 cargoWidget->sigDragAborted.connect( SigC::slot( *this, &CargoDialog::dragAborted ));
01936
01937 vector<StoringPosition*> storingPositionVector;
01938
01939 int x = 0;
01940 int y = 0;
01941
01942 int posNum = container->baseType->maxLoadableUnits;
01943 if ( container->getCargo().size() > posNum )
01944 posNum = container->getCargo().size();
01945
01946 int unitColumnCount = 0;
01947 for ( int i = 0; i < posNum; ++i ) {
01948 pc.openBracket( "UnitSlot" );
01949
01950 int unitposx, unitposy;
01951 pc.addInteger( "unitposx", unitposx );
01952 pc.addInteger( "unitposy", unitposy );
01953
01954 StoringPosition* sp = new StoringPosition( cargoWidget, PG_Point( x, y), PG_Point(unitposx, unitposy), cargoWidget->getHighLightingManager(), container->getCargo(), i, container->baseType->maxLoadableUnits >= container->getCargo().size(), cargoWidget );
01955 storingPositionVector.push_back( sp );
01956 x += sp->Width();
01957 if ( x + sp->Width() >= parent->Width() - 20 ) {
01958 if ( !unitColumnCount )
01959 unitColumnCount = i + 1;
01960 x = 0;
01961 y += sp->Height();
01962 }
01963
01964
01965 widgetParams.runTextIO( pc );
01966 parsePanelASCTXT( pc, sp, widgetParams );
01967 pc.closeBracket();
01968
01969 }
01970
01971 cargoWidget->registerStoringPositions( storingPositionVector, unitColumnCount );
01972 cargoWidget->sigScrollTrack.connect( SigC::slot( *this, &CargoDialog::clearSmallIcons ));
01973
01974 cargoWidget->unitMarked.connect( SigC::slot( *this, &CargoDialog::checkStoringPosition ));
01975
01976 if ( ciw )
01977 cargoWidget->unitMarked.connect( SigC::hide<Vehicle*>( SigC::slot( *ciw, &CargoInfoWindow::update )));
01978
01979 if ( mainScreenWidget && mainScreenWidget->getGuiHost() )
01980 cargoWidget->unitMarked.connect( SigC::hide<Vehicle*>( SigC::slot( *this, &CargoDialog::clearSmallIcons )));
01981
01982 cargoWidget->unitClicked.connect ( SigC::slot( *this, &CargoDialog::onUnitClick ));
01983
01984 container->cargoChanged.connect( SigC::slot( *cargoWidget, &CargoWidget::redrawAll ));
01985 }
01986 }
01987 if ( label == "UnitTypeList" || label == "UnitTypeListHorizontal" ) {
01988 int y = 0;
01989 int x = 0;
01990 parent->SetTransparency(255);
01991 for ( int i = 0; i < cmovemalitypenum; ++i ) {
01992 if ( container->baseType->vehicleCategoriesStorable & (1<<i)) {
01993 PG_Image* img = new PG_Image( parent, PG_Point(x, y),IconRepository::getIcon(moveMaliTypeIcons[i] ).getBaseSurface(), false);
01994 new PG_ToolTipHelp( img, cmovemalitypes[i] );
01995 if ( label == "UnitTypeList" )
01996 y += img->Height();
01997
01998 if ( label == "UnitTypeListHorizontal" )
01999 x += img->Width();
02000 }
02001 }
02002
02003 }
02004
02005 };
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021 namespace CargoGuiFunctions
02022 {
02023
02024
02025 bool Movement::checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
02026 {
02027 return ( key->keysym.sym == SDLK_SPACE );
02028 };
02029
02030 Surface& Movement::getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
02031 {
02032 return IconRepository::getIcon("movement.png");
02033 };
02034 ASCString Movement::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
02035 {
02036 return "move unit";
02037 };
02038
02039 bool Movement::available( const MapCoordinate& pos, ContainerBase* subject, int num )
02040 {
02041 Vehicle* unit = dynamic_cast<Vehicle*>(subject);
02042 if ( unit && unit->getOwner() == unit->getMap()->actplayer )
02043 return unit->canMove();
02044 return false;
02045 }
02046
02047 void Movement::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
02048 {
02049 if ( !mainScreenWidget )
02050 return;
02051
02052 Vehicle* unit = dynamic_cast<Vehicle*>(subject);
02053 if ( !unit )
02054 return;
02055
02056 int mode = 0;
02057 if ( isKeyPressed( SDLK_LSHIFT ) || isKeyPressed( SDLK_RSHIFT ))
02058 mode |= MoveUnitCommand::DisableHeightChange | MoveUnitCommand::LimitVerticalDirection;
02059
02060
02061 MoveUnitCommand* move = new MoveUnitCommand( unit );
02062
02063 ActionResult res = move->searchFields (-1, mode);
02064 if ( !res.successful() ) {
02065 dispmessage2 ( res.getCode(), NULL );
02066 delete move;
02067 return;
02068 }
02069
02070 for ( set<MapCoordinate3D>::const_iterator i = move->getReachableFields().begin(); i != move->getReachableFields().end(); ++i )
02071 unit->getMap()->getField( *i)->a.temp = 1;
02072
02073 for ( set<MapCoordinate3D>::const_iterator i = move->getReachableFieldsIndirect().begin(); i != move->getReachableFieldsIndirect().end(); ++i )
02074 unit->getMap()->getField( *i)->a.temp2 = 2;
02075
02076 repaintMap();
02077 NewGuiHost::pendingCommand = move;
02078
02079 GuiIconHandler guiIconHandler;
02080 guiIconHandler.registerUserFunction( new MovementDestination( *mainScreenWidget ) );
02081 guiIconHandler.registerUserFunction( new CancelMovement( *mainScreenWidget ) );
02082
02083 NewGuiHost::pushIconHandler( &guiIconHandler );
02084
02085 parent.Hide();
02086
02087 mainScreenWidget->Update();
02088 mainScreenWidget->RunModal();
02089 parent.getMap()->cleartemps(7);
02090
02091 NewGuiHost::popIconHandler();
02092 parent.cargoChanged();
02093 parent.Show();
02094
02095 }
02096
02097
02099
02100
02101 bool UnitProduction::available( const MapCoordinate& pos, ContainerBase* subject, int num )
02102 {
02103 if ( parent.getContainer()->getOwner() == parent.getContainer()->getMap()->actplayer )
02104 return ConstructUnitCommand::internalConstructionAvail( parent.getContainer() );
02105
02106 return false;
02107 }
02108
02109
02110 bool UnitProduction::checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
02111 {
02112 return ( key->keysym.sym == 'p' );
02113 };
02114
02115 Surface& UnitProduction::getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
02116 {
02117 return IconRepository::getIcon("unitproduction.png");
02118 };
02119 ASCString UnitProduction::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
02120 {
02121 return "produce unit";
02122 };
02123
02124 void UnitProduction::productionLinesChanged()
02125 {
02126 if (constructUnitCommand ) {
02127 producables.clear();
02128 ConstructUnitCommand::Producables temp = constructUnitCommand->getProduceableVehicles();
02129 producables.insert( producables.end(), temp.begin(), temp.end () );
02130 }
02131 }
02132
02133 void UnitProduction::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
02134 {
02135 bool refillAmmo;
02136 bool refillResources;
02137
02138 auto_ptr<ConstructUnitCommand> production ( new ConstructUnitCommand( parent.getContainer() ));
02139 constructUnitCommand = production.get();
02140
02141 const VehicleType* v;
02142 {
02143 production->setMode( ConstructUnitCommand::internal );
02144 producables = production->getProduceableVehicles();
02145 VehicleProduction_SelectionWindow fsw( NULL, PG_Rect( 10, 10, 450, 550 ), parent.getContainer(), producables, true );
02146 fsw.reloadProducebles.connect( SigC::slot( *this, &UnitProduction::productionLinesChanged ));
02147 fsw.SetTransparency(0);
02148 fsw.Show();
02149 fsw.RunModal();
02150 v = fsw.getVehicletype();
02151 refillAmmo = fsw.fillWithAmmo();
02152 refillResources = fsw.fillWithResources();
02153 }
02154 if ( v ) {
02155
02156 for ( ConstructUnitCommand::Producables::const_iterator i = producables.begin(); i != producables.end(); ++i )
02157 if ( i->type == v ) {
02158 if ( i->prerequisites.getValue() & ( ConstructUnitCommand::Lack::Energy | ConstructUnitCommand::Lack::Material | ConstructUnitCommand::Lack::Fuel )) {
02159 warningMessage("Not enough resources to build unit");
02160 return;
02161 }
02162
02163 if ( i->prerequisites.getValue() & ( ConstructUnitCommand::Lack::Movement )) {
02164 warningMessage("Not enough movement to build unit");
02165 return;
02166 }
02167
02168 if ( i->prerequisites.getValue() & ( ConstructUnitCommand::Lack::Research )) {
02169 warningMessage("This unit has not been researched yet");
02170 return;
02171 }
02172 }
02173
02174 production->setVehicleType( v );
02175 ActionResult res = production->execute ( createContext( parent.getContainer()->getMap() ) );
02176
02177 if ( !res.successful() )
02178 throw res;
02179
02180 production.release();
02181
02182 Vehicle* newUnit = constructUnitCommand->getProducedUnit();
02183 if ( !newUnit )
02184 throw ActionResult( 21804 );
02185
02186
02187 if ( refillAmmo || refillResources ) {
02188 auto_ptr<ServiceCommand> ser ( new ServiceCommand( parent.getContainer() ));
02189 ser->setDestination( newUnit );
02190 TransferHandler& trans = ser->getTransferHandler();
02191 if ( refillAmmo )
02192 trans.fillDestAmmo();
02193
02194 if ( refillResources )
02195 trans.fillDestResource();
02196
02197 ser->saveTransfers();
02198 ActionResult res = ser->execute( createContext( newUnit->getMap() ));
02199 if ( res.successful() )
02200 ser.release();
02201 else
02202 displayActionError(res);
02203
02204 }
02205 if ( CGameOptions::Instance()->unitProduction.fillAmmo != refillAmmo ) {
02206 CGameOptions::Instance()->unitProduction.fillAmmo = refillAmmo;
02207 CGameOptions::Instance()->setChanged();
02208 }
02209 if ( CGameOptions::Instance()->unitProduction.fillResources != refillResources ) {
02210 CGameOptions::Instance()->unitProduction.fillResources = refillResources;
02211 CGameOptions::Instance()->setChanged();
02212 }
02213
02214 }
02215 parent.cargoChanged();
02216 constructUnitCommand = NULL;
02217 }
02218
02219
02221
02222
02223 bool UnitTraining::available( const MapCoordinate& pos, ContainerBase* subject, int num )
02224 {
02225 if ( !subject )
02226 return false;
02227
02228 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02229 if ( !veh )
02230 return false;
02231
02232 GameMap* map = parent.getContainer()->getMap();
02233 if ( map->actplayer == veh->getOwner() || map->actplayer == parent.getContainer()->getOwner() )
02234 if ( map->player[map->actplayer].diplomacy.isAllied( veh->getOwner() ))
02235 return TrainUnitCommand::avail( parent.getContainer(), veh);
02236
02237 return false;
02238 }
02239
02240
02241 bool UnitTraining::checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
02242 {
02243 return ( key->keysym.sym == 't' );
02244 };
02245
02246 Surface& UnitTraining::getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
02247 {
02248 return IconRepository::getIcon("training.png");
02249 };
02250
02251 ASCString UnitTraining::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
02252 {
02253 return "train unit";
02254 };
02255
02256
02257 void UnitTraining::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
02258 {
02259 if ( !subject )
02260 return;
02261
02262 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02263 if ( !veh )
02264 return;
02265
02266 auto_ptr<TrainUnitCommand> tuc ( new TrainUnitCommand( parent.getContainer() ));
02267 tuc->setUnit( veh );
02268 ActionResult res = tuc->execute( createContext( veh->getMap()));
02269 if ( res.successful() ) {
02270 tuc.release();
02271 parent.cargoChanged();
02272 } else
02273 displayActionError( res );
02274 }
02275
02276
02279
02280
02281 bool RefuelUnitCommand::available( const MapCoordinate& pos, ContainerBase* subject, int num )
02282 {
02283 if ( !subject )
02284 return false;
02285
02286 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02287 if ( !veh )
02288 return false;
02289
02290 ServiceCommand sc( parent.getContainer() );
02291 const ServiceTargetSearcher::Targets& dest = sc.getDestinations();
02292
02293 return find( dest.begin(), dest.end(), subject ) != dest.end();
02294 }
02295
02296
02297 bool RefuelUnitCommand::checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
02298 {
02299 return ( key->keysym.sym == 'f' );
02300 };
02301
02302 Surface& RefuelUnitCommand::getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
02303 {
02304 return IconRepository::getIcon("refuel.png");
02305 };
02306
02307 ASCString RefuelUnitCommand::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
02308 {
02309 return "refuel unit";
02310 };
02311
02312
02313 void RefuelUnitCommand::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
02314 {
02315 if ( !subject )
02316 return;
02317
02318 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02319 if ( !veh )
02320 return;
02321
02322 auto_ptr<ServiceCommand> ser ( new ServiceCommand( parent.getContainer() ));
02323 ser->setDestination( subject );
02324 ser->getTransferHandler().fillDest();
02325 ser->saveTransfers();
02326 ActionResult res = ser->execute( createContext( subject->getMap() ));
02327 if ( res.successful() )
02328 ser.release();
02329 else
02330 displayActionError(res);
02331 parent.cargoChanged();
02332 }
02334
02335 bool RepairUnit::available( const MapCoordinate& pos, ContainerBase* subject, int num )
02336 {
02337 if ( !subject )
02338 return false;
02339
02340 if ( !RepairUnitCommand::availInternally( parent.getContainer() ) )
02341 return false;
02342
02343 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02344 if ( !veh )
02345 return false;
02346
02347
02348 return veh->damage > 0;
02349 }
02350
02351
02352 bool RepairUnit::checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
02353 {
02354 return ( key->keysym.sym == 'r' );
02355 };
02356
02357 Surface& RepairUnit::getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
02358 {
02359 return IconRepository::getIcon("repair.png");
02360 };
02361
02362 ASCString RepairUnit::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
02363 {
02364 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02365 if ( veh && parent.getContainer() ) {
02366 Resources r;
02367 parent.getContainer()->getMaxRepair ( veh, 0, r);
02368 return "~r~epair unit (cost: " + r.toString() + ")";
02369 }
02370
02371 return "repair unit";
02372 };
02373
02374
02375 void RepairUnit::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
02376 {
02377 if ( !subject )
02378 return;
02379
02380 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02381 if ( !veh )
02382 return;
02383
02384 auto_ptr<RepairUnitCommand> rp ( new RepairUnitCommand( parent.getContainer() ));
02385
02386 if ( !rp->validTarget( veh ) )
02387 return;
02388
02389 rp->setTarget( veh );
02390 ActionResult res = rp->execute( createContext ( veh->getMap() ));
02391 if ( res.successful() )
02392 rp.release();
02393
02394 parent.cargoChanged();
02395 }
02396
02398
02399 bool MoveUnitUp::available( const MapCoordinate& pos, ContainerBase* subject, int num )
02400 {
02401 if ( !subject )
02402 return false;
02403
02404 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02405 if ( !veh )
02406 return false;
02407
02408 return CargoMoveCommand::moveOutAvail( veh );
02409 }
02410
02411
02412 bool MoveUnitUp::checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
02413 {
02414 return ( key->keysym.sym == 'o' );
02415 };
02416
02417 Surface& MoveUnitUp::getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
02418 {
02419 return IconRepository::getIcon("moveunitup.png");
02420 };
02421
02422 ASCString MoveUnitUp::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
02423 {
02424 return "move unit to ~o~uter transport";
02425 };
02426
02427
02428 void MoveUnitUp::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
02429 {
02430 if ( !subject )
02431 return;
02432
02433
02434 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02435 if ( !veh )
02436 return;
02437
02438 auto_ptr<CargoMoveCommand> cargomove ( new CargoMoveCommand( veh ));
02439 cargomove->setMode( CargoMoveCommand::moveOutwards );
02440 ActionResult res = cargomove->execute ( createContext( veh->getMap() ));
02441 if ( res.successful() )
02442 cargomove.release();
02443
02444 parent.cargoChanged();
02445 }
02446
02448
02449
02450 bool CloseDialog::available( const MapCoordinate& pos, ContainerBase* subject, int num )
02451 {
02452 return true;
02453 }
02454
02455
02456 bool CloseDialog::checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
02457 {
02458 return ( key->keysym.sym == 'x' );
02459 };
02460
02461 Surface& CloseDialog::getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
02462 {
02463 return IconRepository::getIcon("closecargodialog.png");
02464 };
02465
02466 ASCString CloseDialog::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
02467 {
02468 return "close dialog";
02469 };
02470
02471
02472 void CloseDialog::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
02473 {
02474 parent.QuitModal();
02475 }
02476
02478
02479
02480 bool UnitInfo::available( const MapCoordinate& pos, ContainerBase* subject, int num )
02481 {
02482 if ( !subject )
02483 return false;
02484
02485 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02486 return veh;
02487 }
02488
02489
02490 bool UnitInfo::checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
02491 {
02492 return ( key->keysym.sym == 'i' );
02493 };
02494
02495 Surface& UnitInfo::getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
02496 {
02497 return IconRepository::getIcon("unitinfo.png");
02498 };
02499
02500 ASCString UnitInfo::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
02501 {
02502 return "show unit ~i~nformation";
02503 };
02504
02505
02506 void UnitInfo::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
02507 {
02508 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02509 if ( veh )
02510 unitInfoDialog( veh->typ );
02511 }
02512
02514
02515
02516 bool TransferUnitControl::available( const MapCoordinate& pos, ContainerBase* subject, int num )
02517 {
02518 if ( !subject )
02519 return false;
02520
02521 if ( subject->getOwner() != subject->getMap()->actplayer )
02522 return false;
02523
02524 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02525 if ( !veh )
02526 return false;
02527
02528 return TransferControlCommand::avail( subject );
02529
02530 }
02531
02532
02533 Surface& TransferUnitControl::getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
02534 {
02535 return IconRepository::getIcon("transferunitcontrol.png");
02536 };
02537
02538 ASCString TransferUnitControl::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
02539 {
02540 return "transfer unit control";
02541 };
02542
02543
02544 void TransferUnitControl::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
02545 {
02546 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02547 if ( veh ) {
02548
02549 auto_ptr<TransferControlCommand> tcc ( new TransferControlCommand( subject ));
02550 TransferControlCommand::Receivers rec = tcc->getReceivers();
02551
02552 vector<ASCString> entries;
02553 for ( TransferControlCommand::Receivers::iterator i = rec.begin(); i != rec.end(); ++i )
02554 entries.push_back ( (*i)->getName() );
02555
02556 if ( !entries.size() ) {
02557 infoMessage("you don't have any allies!");
02558 return;
02559 }
02560
02561 int result = chooseString ( "Choose player", entries );
02562 if ( result >= 0 ) {
02563 tcc->setReceiver( rec[result] );
02564 ActionResult res = tcc->execute( createContext( subject->getMap() ));
02565 if ( res.successful() ) {
02566 tcc.release();
02567 parent.cargoChanged();
02568 } else
02569 displayActionError( res );
02570 }
02571
02572
02573 }
02574 }
02575
02577
02578
02579
02580 bool MoveUnitIntoInnerContainer::available( const MapCoordinate& pos, ContainerBase* subject, int num )
02581 {
02582 if ( !subject )
02583 return false;
02584
02585 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02586 if ( !veh )
02587 return false;
02588
02589 CargoMoveCommand cmc( veh );
02590 return cmc.getTargetCarriers().size() > 0 ;
02591 }
02592
02593
02594 bool MoveUnitIntoInnerContainer::checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
02595 {
02596 return ( key->keysym.sym == 'u' );
02597 };
02598
02599 Surface& MoveUnitIntoInnerContainer::getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
02600 {
02601 return IconRepository::getIcon("container-in.png");
02602 };
02603
02604 ASCString MoveUnitIntoInnerContainer::getName( const MapCoordinate& pos, ContainerBase* subject, int num )
02605 {
02606 return "move ~u~nit into neighboring transport";
02607 };
02608
02609
02610
02611 class VehicleWidget: public VehicleBaseWidget
02612 {
02613 private:
02614 Vehicle* veh;
02615 public:
02616 VehicleWidget( PG_Widget* parent, const PG_Point& pos, int width, Vehicle* unit )
02617 : VehicleBaseWidget( parent, pos, width, unit, unit->getMap()->getPlayer(unit) ) {
02618 veh = unit;
02619 };
02620
02621 Vehicle* getUnit() const {
02622 return veh;
02623 };
02624 };
02625
02626 class VehicleSelectionFactory: public SelectionItemFactory, public SigC::Object
02627 {
02628 public:
02629 typedef vector<Vehicle*> Container;
02630 protected:
02631 Container::iterator it;
02632 Container& items;
02633
02634 public:
02635 VehicleSelectionFactory( Container& units ) : items ( units ), selected(NULL) {};
02636 void restart() {
02637 it = items.begin();
02638 };
02639
02640 SelectionWidget* spawnNextItem( PG_Widget* parent, const PG_Point& pos ) {
02641 if ( it != items.end() ) {
02642 Vehicle* v = *(it++);
02643 return new VehicleWidget( parent, pos, parent->Width() - 15, v );
02644 } else
02645 return NULL;
02646 };
02647
02648 void itemSelected( const SelectionWidget* widget, bool mouse ) {
02649 if ( !widget )
02650 return;
02651
02652 const VehicleWidget* vw = dynamic_cast<const VehicleWidget*>(widget);
02653 assert( vw );
02654 selected = vw->getUnit();
02655 }
02656
02657 Vehicle* selected;
02658 };
02659
02660
02661 Vehicle* selectVehicle( vector<Vehicle*> targets )
02662 {
02663 Vehicle* target = NULL;
02664 VehicleSelectionFactory* vsf = new VehicleSelectionFactory( targets );
02665 ItemSelectorWindow isw ( NULL, PG_Rect( 50, 50, 300, 400), "Please choose target unit", vsf );
02666 isw.Show();
02667 isw.RunModal();
02668 target = vsf->selected;
02669 return target;
02670 }
02671
02672
02673
02674
02675 void MoveUnitIntoInnerContainer::execute( const MapCoordinate& pos, ContainerBase* subject, int num )
02676 {
02677 if ( !subject )
02678 return;
02679
02680
02681 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02682 if ( !veh )
02683 return;
02684
02685 auto_ptr<CargoMoveCommand> cargomove ( new CargoMoveCommand( veh ));
02686 cargomove->setMode( CargoMoveCommand::moveInwards );
02687
02688 vector<Vehicle*> targets = cargomove->getTargetCarriers();
02689
02690 choiceDialog("You can also use Drag'n'Drop to move units in the Cargo Dialog\nMouse button: " + CGameOptions::Mouse::getButtonName( CGameOptions::Instance()->mouse.dragndropbutton ), "OK", "", "dragndropinfo");
02691
02692 Vehicle* target = selectVehicle( targets );
02693 if ( target ) {
02694 cargomove->setTargetCarrier( target );
02695 ActionResult res = cargomove->execute ( createContext( veh->getMap() ));
02696 if ( res.successful() )
02697 cargomove.release();
02698 }
02699 parent.cargoChanged();
02700 }
02701
02702
02703
02705
02706 bool RefuelUnitDialogCommand :: available( const MapCoordinate& pos, ContainerBase* subject, int num )
02707 {
02708 if ( !subject )
02709 return false;
02710
02711 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02712 if ( !veh )
02713 return false;
02714
02715 ServiceCommand sc( parent.getContainer() );
02716 const ServiceTargetSearcher::Targets& dest = sc.getDestinations();
02717
02718 return find( dest.begin(), dest.end(), subject ) != dest.end();
02719 };
02720
02721 void RefuelUnitDialogCommand :: execute( const MapCoordinate& pos, ContainerBase* subject, int num )
02722 {
02723 if ( !subject )
02724 return;
02725
02726 auto_ptr<ServiceCommand> ser ( new ServiceCommand( parent.getContainer() ));
02727 ser->setDestination( subject );
02728 ammoTransferWindow( parent.getContainer(), subject, ser.get() );
02729 parent.cargoChanged();
02730 if ( ser->getState() == Command::Finished )
02731 ser.release();
02732 }
02733
02734 Surface& RefuelUnitDialogCommand :: getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
02735 {
02736 return IconRepository::getIcon("refuel-dialog.png");
02737 };
02738
02739 bool RefuelUnitDialogCommand :: checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
02740 {
02741 return ( key->keysym.unicode == 'd' );
02742 };
02743
02744 ASCString RefuelUnitDialogCommand :: getName( const MapCoordinate& pos, ContainerBase* subject, int num )
02745 {
02746 return "Refuel Dialog";
02747 };
02748
02750
02751 bool OpenContainer :: available( const MapCoordinate& pos, ContainerBase* subject, int num )
02752 {
02753 if ( !subject )
02754 return false;
02755
02756 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02757 if ( !veh )
02758 return false;
02759
02760 Player& player = veh->getMap()->player[veh->getOwner()];
02761 if ( veh->typ->maxLoadableUnits && player.diplomacy.isAllied( veh->getMap()->actplayer) )
02762 return true;
02763
02764 return false;
02765 };
02766
02767 void OpenContainer :: execute( const MapCoordinate& pos, ContainerBase* subject, int num )
02768 {
02769 if ( !subject )
02770 return;
02771
02772 cargoDialog( subject );
02773 parent.cargoChanged();
02774 }
02775
02776 Surface& OpenContainer :: getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
02777 {
02778 return IconRepository::getIcon("container.png");
02779 };
02780
02781 bool OpenContainer :: checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
02782 {
02783 return ( key->keysym.unicode == 'l' );
02784 };
02785
02786 ASCString OpenContainer :: getName( const MapCoordinate& pos, ContainerBase* subject, int num )
02787 {
02788 return "open transport ";
02789 };
02790
02791
02792
02793
02795
02796
02797 bool RecycleUnitCommandButton :: available( const MapCoordinate& pos, ContainerBase* subject, int num )
02798 {
02799 if ( !subject )
02800 return false;
02801
02802 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02803 if ( !veh )
02804 return false;
02805
02806 if ( !RecycleUnitCommand::avail( parent.getContainer(), veh))
02807 return false;
02808
02809 Player& player = veh->getMap()->player[veh->getOwner()];
02810 if ( player.diplomacy.isAllied( veh->getMap()->actplayer) )
02811 return true;
02812 else
02813 return false;
02814 };
02815
02816 ASCString RecycleUnitCommandButton :: getCommandName( const ContainerBase* carrier )
02817 {
02818 if ( carrier->baseType->hasFunction( ContainerBaseType::RecycleUnits ))
02819 return "recycle";
02820 else
02821 return "salvage";
02822 }
02823
02824
02825 void RecycleUnitCommandButton :: execute( const MapCoordinate& pos, ContainerBase* subject, int num )
02826 {
02827 if ( !subject )
02828 return;
02829
02830 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02831 if ( !veh )
02832 return;
02833
02834 ASCString msg = "do you really want to " + getCommandName( parent.getContainer() ) + " this unit ?";
02835
02836 if (choice_dlg( msg ,"~y~es","~n~o") == 1) {
02837 auto_ptr<RecycleUnitCommand> command ( new RecycleUnitCommand( parent.getContainer() ));
02838 command->setUnit( veh );
02839 ActionResult res = command->execute( createContext( parent.getContainer()->getMap() ));
02840 if ( res.successful() )
02841 command.release();
02842 else
02843 displayActionError( res );
02844 parent.cargoChanged();
02845 }
02846 }
02847
02848
02849 Surface& RecycleUnitCommandButton :: getImage( const MapCoordinate& pos, ContainerBase* subject, int num )
02850 {
02851 return IconRepository::getIcon("recycle.png");
02852 };
02853
02854 bool RecycleUnitCommandButton :: checkForKey( const SDL_KeyboardEvent* key, int modifier, int num )
02855 {
02856 return false;
02857 };
02858
02859 ASCString RecycleUnitCommandButton :: getName( const MapCoordinate& pos, ContainerBase* subject, int num )
02860 {
02861 if ( !subject )
02862 return "";
02863
02864 Vehicle* veh = dynamic_cast<Vehicle*>(subject);
02865 if ( !veh )
02866 return "";
02867
02868 ASCString s = getCommandName( parent.getContainer() ) + " unit - ";
02869
02870 Resources res = RecycleUnitCommand::getOutput( parent.getContainer(), veh );
02871
02872 bool cost = false;
02873 for ( int r = 0; r < 3; ++r ) {
02874 if ( res.resource(r) < 0 ) {
02875 if ( !cost ) {
02876 s += "Cost: ";
02877 cost = true;
02878 }
02879 s += ASCString::toString( -res.resource( r ));
02880 s += " ";
02881 s += Resources::name( r );
02882 }
02883 }
02884
02885 bool gain = false;
02886 for ( int r = 0; r < 3; ++r ) {
02887 if ( res.resource(r) > 0 ) {
02888 if ( !gain ) {
02889 s += "Gain: ";
02890 cost = true;
02891 }
02892 s += ASCString::toString( res.resource( r ));
02893 s += " ";
02894 s += Resources::name( r );
02895 }
02896 }
02897
02898 return s;
02899
02900 };
02901
02902 }
02903