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 "../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 "../unitctrl.h"
00037 #include "../cannedmessages.h"
00038 #include "../replay.h"
00039 #include "../dashboard.h"
00040 #include "../dialog.h"
00041 #include "../containerbase-functions.h"
00042 #include "../resourcenet.h"
00043
00044 #include "../containerbase-functions.h"
00045 #include "../gameoptions.h"
00046
00047 #include "selectionwindow.h"
00048 #include "ammotransferdialog.h"
00049 #include "unitinfodialog.h"
00050
00051
00052
00053 const Vehicletype* selectVehicletype( ContainerBase* plant, const vector<Vehicletype*>& items );
00054
00055
00056
00057 class CargoDialog;
00058
00059 class SubWindow: public SigC::Object
00060 {
00061 protected:
00062 CargoDialog* cargoDialog;
00063 PG_Widget* widget;
00064
00065 SubWindow() : cargoDialog(NULL), widget(NULL) {};
00066 ContainerBase* container();
00067 public:
00068 virtual bool available( CargoDialog* cd ) = 0;
00069 virtual ASCString getASCTXTname() = 0;
00070 virtual ASCString getFullName() = 0;
00071 virtual void registerSubwindow( CargoDialog* cd );
00072 virtual void registerChilds( CargoDialog* cd );
00073 virtual void update() = 0;
00074 virtual ~SubWindow() {} ;
00075 };
00076
00077
00078 class SubWinButton : public PG_Button
00079 {
00080 public:
00081 static const int buttonwidth = 47;
00082 static const int buttonheight = 28;
00083
00084 SubWinButton( PG_Widget *parent, const SPoint& pos, SubWindow* subWindow ) : PG_Button( parent, PG_Rect( pos.x, pos.y, buttonwidth, buttonheight ), "", -1, "SubWinButton")
00085 {
00086 SetBackground( PRESSED, IconRepository::getIcon("cargo-buttonpressed.png").getBaseSurface() );
00087 SetBackground( HIGHLITED, IconRepository::getIcon("cargo-buttonhighlighted.png").getBaseSurface() );
00088 SetBackground( UNPRESSED, IconRepository::getIcon("cargo-buttonunpressed.png").getBaseSurface() );
00089 SetBorderSize(0,0,0);
00090 ASCString filename = ASCString("cargo-") + subWindow->getASCTXTname();
00091 SetIcon( IconRepository::getIcon( filename + ".png" ).getBaseSurface(),
00092 IconRepository::getIcon( filename + "-pressed.png" ).getBaseSurface(),
00093 IconRepository::getIcon( filename + ".png" ).getBaseSurface() );
00094 SetToggle( true );
00095 new PG_ToolTipHelp ( this, subWindow->getFullName() );
00096 };
00097 };
00098
00099
00100 namespace CargoGuiFunctions {
00101
00102 class MovementDestination : public GuiFunctions::Movement {
00103 PG_Widget& parent;
00104 public:
00105 MovementDestination( PG_Widget& masterParent ) : parent( masterParent) {};
00106
00107 void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00108 {
00109 GuiFunctions::Movement::execute( pos, subject, num );
00110 if ( !pendingVehicleActions.move )
00111 parent.QuitModal();
00112 }
00113 };
00114
00115 class CancelMovement : public GuiFunctions::Cancel {
00116 PG_Widget& parent;
00117 public:
00118 CancelMovement ( PG_Widget& masterParent ) : parent( masterParent) {};
00119
00120 void execute( const MapCoordinate& pos, ContainerBase* subject, int num )
00121 {
00122 GuiFunctions::Cancel::execute( pos, subject, num );
00123 parent.QuitModal();
00124 }
00125 };
00126
00127
00128 class CloseDialog : public GuiFunction
00129 {
00130 CargoDialog& parent;
00131 public:
00132 CloseDialog( CargoDialog& masterParent ) : parent( masterParent) {};
00133 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00134 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00135 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00136 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00137 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00138 };
00139
00140
00141 class Movement : public GuiFunction
00142 {
00143 CargoDialog& parent;
00144 public:
00145 Movement( CargoDialog& masterParent ) : parent( masterParent) {};
00146 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00147 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00148 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00149 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00150 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00151 };
00152
00153
00154 class UnitProduction : public GuiFunction
00155 {
00156 CargoDialog& parent;
00157 public:
00158 UnitProduction( CargoDialog& masterParent ) : parent( masterParent) {};
00159 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00160 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00161 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00162 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00163 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00164 };
00165
00166 class UnitTraining : public GuiFunction
00167 {
00168 CargoDialog& parent;
00169 public:
00170 UnitTraining( CargoDialog& masterParent ) : parent( masterParent) {};
00171 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00172 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00173 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00174 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00175 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00176 };
00177
00178 class RefuelUnit : public GuiFunction
00179 {
00180 CargoDialog& parent;
00181 public:
00182 RefuelUnit( CargoDialog& masterParent ) : parent( masterParent) {};
00183 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00184 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00185 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00186 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00187 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00188 };
00189
00190 class RefuelUnitDialog : public GuiFunction
00191 {
00192 CargoDialog& parent;
00193 public:
00194 RefuelUnitDialog( CargoDialog& masterParent ) : parent( masterParent) {};
00195 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00196 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00197 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00198 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00199 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00200 };
00201
00202 class RepairUnit : public GuiFunction
00203 {
00204 CargoDialog& parent;
00205 public:
00206 RepairUnit( CargoDialog& masterParent ) : parent( masterParent) {};
00207 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00208 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00209 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00210 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00211 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00212 };
00213
00214 class MoveUnitUp : public GuiFunction
00215 {
00216 CargoDialog& parent;
00217 public:
00218 MoveUnitUp ( CargoDialog& masterParent ) : parent( masterParent) {};
00219 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00220 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00221 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00222 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00223 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00224 };
00225
00226 class MoveUnitIntoInnerContainer : public GuiFunction
00227 {
00228 CargoDialog& parent;
00229 public:
00230 MoveUnitIntoInnerContainer ( CargoDialog& masterParent ) : parent( masterParent) {};
00231 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00232 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00233 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00234 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00235 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00236 };
00237
00238
00239 class OpenContainer: public GuiFunction
00240 {
00241 CargoDialog& parent;
00242 public:
00243 OpenContainer( CargoDialog& masterParent ) : parent( masterParent) {};
00244 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00245 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00246 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00247 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00248 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00249 };
00250
00251 class RecycleUnit : public GuiFunction
00252 {
00253 CargoDialog& parent;
00254 public:
00255 RecycleUnit( CargoDialog& masterParent ) : parent( masterParent) {};
00256 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00257 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00258 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00259 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00260 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00261 };
00262
00263 class UnitInfo : public GuiFunction
00264 {
00265 CargoDialog& parent;
00266 public:
00267 UnitInfo( CargoDialog& masterParent ) : parent( masterParent) {};
00268 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00269 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00270 bool checkForKey( const SDL_KeyboardEvent* key, int modifier, int num );
00271 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00272 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00273 };
00274
00275 class TransferUnitControl : public GuiFunction
00276 {
00277 CargoDialog& parent;
00278 public:
00279 TransferUnitControl( CargoDialog& masterParent ) : parent( masterParent) {};
00280 bool available( const MapCoordinate& pos, ContainerBase* subject, int num );
00281 void execute( const MapCoordinate& pos, ContainerBase* subject, int num );
00282 Surface& getImage( const MapCoordinate& pos, ContainerBase* subject, int num );
00283 ASCString getName( const MapCoordinate& pos, ContainerBase* subject, int num );
00284 };
00285
00286
00287
00288 };
00289
00290
00291 class BuildingControlWindow;
00292 class CargoInfoWindow;
00293
00294 class CargoDialog : public Panel
00295 {
00296
00297 ContainerControls containerControls;
00298
00299 GuiIconHandler guiIconHandler;
00300
00301 ContainerBase* container;
00302 bool setupOK;
00303 Surface infoImage;
00304
00305 typedef vector<SubWindow*> Activesubwindows;
00306 Activesubwindows activesubwindows;
00307
00308 typedef deallocating_vector<SubWindow*> Subwindows;
00309 Subwindows subwindows;
00310
00311 vector<SubWinButton*> subWinButtons;
00312
00313 CargoWidget* cargoWidget;
00314 SubWindow* researchWindow;
00315 SubWindow* matterWindow;
00316 BuildingControlWindow* buildingControlWindow;
00317
00318 CargoInfoWindow* ciw;
00319
00320 bool eventKeyDown(const SDL_KeyboardEvent* key)
00321 {
00322 if ( key->keysym.sym == SDLK_ESCAPE ) {
00323 QuitModal();
00324 return true;
00325 }
00326 return false;
00327 };
00328
00329
00330
00331 void registerSpecialDisplay( const ASCString& name )
00332 {
00333 SpecialDisplayWidget* sdw = dynamic_cast<SpecialDisplayWidget*>( FindChild( name, true ) );
00334 if ( sdw )
00335 sdw->display.connect( SigC::slot( *this, &CargoDialog::painter ));
00336 };
00337
00338 void registerSpecialInput( const ASCString& name )
00339 {
00340 SpecialInputWidget* siw = dynamic_cast<SpecialInputWidget*>( FindChild( name, true ) );
00341 if ( siw )
00342 siw->sigMouseButtonDown.connect( SigC::slot( *this, &CargoDialog::onClick ));
00343 };
00344
00345 bool onClick ( PG_MessageObject* obj, const SDL_MouseButtonEvent* event )
00346 {
00347 PG_Widget* w = dynamic_cast<PG_Widget*>(obj);
00348 if ( w ) {
00349
00350 return true;
00351 }
00352 return false;
00353 };
00354
00355 void onUnitClick ( Vehicle* veh,SPoint pos, bool first )
00356 {
00357
00358 if ( mainScreenWidget&& mainScreenWidget->getGuiHost() && (!first || CGameOptions::Instance()->mouse.singleClickAction) ) {
00359 SPoint iconPos = pos;
00360 if ( veh ) {
00361 iconPos.x -= smallGuiIconSizeX/2;
00362 iconPos.y -= smallGuiIconSizeY/2;
00363 } else {
00364 iconPos.x += 2;
00365 iconPos.y += 2;
00366 }
00367
00368 mainScreenWidget->getGuiHost()->showSmallIcons( this, iconPos, false );
00369 }
00370
00371 };
00372
00373 void clearSmallIcons( )
00374 {
00375 if ( mainScreenWidget && mainScreenWidget->getGuiHost() )
00376 mainScreenWidget->getGuiHost()->clearSmallIcons();
00377 }
00378
00379
00380
00381 void painter ( const PG_Rect &src, const ASCString& name, const PG_Rect &dst)
00382 {
00383 Surface screen = Surface::Wrap( PG_Application::GetScreen() );
00384
00385 if ( name == "unitpad_unitsymbol" ) {
00386 Vehicle* v = dynamic_cast<Vehicle*>(container);
00387 if ( v )
00388 v->paint( screen, SPoint( dst.x, dst.y ));
00389 }
00390 };
00391
00392 bool activate_i( int pane )
00393 {
00394 if ( pane >= 0 && pane < activesubwindows.size() ) {
00395 activate( activesubwindows[pane]->getASCTXTname() );
00396 activesubwindows[pane]->update();
00397 }
00398 return true;
00399 }
00400
00401 void activate( const ASCString& pane )
00402 {
00403 BulkGraphicUpdates bgu( this );
00404 for ( int i = 0; i < activesubwindows.size(); ++i )
00405 if ( activesubwindows[i]->getASCTXTname() != pane )
00406 hide( activesubwindows[i]->getASCTXTname() );
00407
00408 for ( int i = 0; i < activesubwindows.size(); ++i )
00409 if ( activesubwindows[i]->getASCTXTname() == pane )
00410 show( activesubwindows[i]->getASCTXTname() );
00411
00412 for ( int i = 0; i< subWinButtons.size(); ++i )
00413 subWinButtons[i]->SetPressed( activesubwindows[i]->getASCTXTname() == pane );
00414 };
00415
00416
00417 void registerGuiFunctions( GuiIconHandler& handler )
00418 {
00419 registerCargoGuiFunctions( handler );
00420 handler.registerUserFunction( new CargoGuiFunctions::Movement( *this ) );
00421 handler.registerUserFunction( new CargoGuiFunctions::RefuelUnit( *this ) );
00422 handler.registerUserFunction( new CargoGuiFunctions::RefuelUnitDialog( *this ) );
00423 handler.registerUserFunction( new CargoGuiFunctions::RepairUnit( *this ) );
00424 handler.registerUserFunction( new CargoGuiFunctions::UnitProduction( *this ));
00425 handler.registerUserFunction( new CargoGuiFunctions::UnitTraining( *this ));
00426 handler.registerUserFunction( new CargoGuiFunctions::MoveUnitUp( *this ));
00427 handler.registerUserFunction( new CargoGuiFunctions::MoveUnitIntoInnerContainer( *this ));
00428 handler.registerUserFunction( new CargoGuiFunctions::OpenContainer( *this ));
00429 handler.registerUserFunction( new CargoGuiFunctions::RecycleUnit( *this ));
00430 handler.registerUserFunction( new CargoGuiFunctions::UnitInfo( *this ));
00431 handler.registerUserFunction( new CargoGuiFunctions::TransferUnitControl( *this ));
00432 handler.registerUserFunction( new CargoGuiFunctions::CloseDialog( *this ));
00433 }
00434
00435 void checkStoringPosition( Vehicle* unit )
00436 {
00437 if ( mainScreenWidget&& mainScreenWidget->getGuiHost() ) {
00438 mainScreenWidget->getGuiHost()->eval( container->getPosition(), unit );
00439 }
00440
00441 if ( mainScreenWidget && mainScreenWidget->getUnitInfoPanel() )
00442 mainScreenWidget->getUnitInfoPanel()->showUnitData( unit, NULL, NULL, true );
00443 }
00444
00445 void updateLoadMeter()
00446 {
00447 if ( container->baseType->maxLoadableWeight > 0 )
00448 setBargraphValue ( "LoadingMeter", float( container->cargoWeight()) / container->baseType->maxLoadableWeight );
00449 }
00450
00451 void dragUnitToInnerContainer( Vehicle* draggedUnit, Vehicle* targetUnit )
00452 {
00453 if ( !draggedUnit )
00454 return;
00455
00456 if ( draggedUnit != targetUnit ) {
00457 if ( targetUnit ) {
00458 containerControls.moveUnitDown( draggedUnit, targetUnit );
00459 } else {
00460 if ( container->getCarrier() )
00461 containerControls.moveUnitUp( draggedUnit );
00462 else {
00463
00464 }
00465 }
00466 }
00467 cargoChanged();
00468 }
00469
00470 bool dragUnitToInnerContainerAvail( Vehicle* draggedUnit, Vehicle* targetUnit )
00471 {
00472 return containerControls.moveUnitDownAvail( draggedUnit, targetUnit );
00473 }
00474
00475 void dragInProcess()
00476 {
00477 if ( mainScreenWidget && mainScreenWidget->getGuiHost() )
00478 mainScreenWidget->getGuiHost()->clearSmallIcons();
00479 }
00480
00481 void dragAborted()
00482 {
00483
00484 cargoChanged();
00485 }
00486
00487
00488 public:
00489
00490 CargoDialog (PG_Widget *parent, ContainerBase* cb );
00491
00492 void addAvailableSubwin( SubWindow* w )
00493 {
00494 activesubwindows.push_back( w );
00495 };
00496
00497 void updateResourceDisplay()
00498 {
00499 setLabelText( "energyavail", container->getResource(maxint, 0, true ) );
00500 setLabelText( "materialavail", container->getResource(maxint, 1, true ) );
00501 setLabelText( "fuelavail", container->getResource(maxint, 2, true ) );
00502 setLabelText( "numericaldamage", container->damage );
00503 }
00504
00505
00506 Vehicle* getMarkedUnit()
00507 {
00508 if ( cargoWidget )
00509 return cargoWidget->getMarkedUnit();
00510 else
00511 return NULL;
00512 }
00513
00514 void cargoChanged()
00515 {
00516
00517 if ( cargoWidget ) {
00518 cargoWidget->redrawAll();
00519 if ( mainScreenWidget && mainScreenWidget->getUnitInfoPanel() )
00520 mainScreenWidget->getUnitInfoPanel()->showUnitData( cargoWidget->getMarkedUnit(), NULL, NULL, true );
00521
00522 checkStoringPosition( cargoWidget->getMarkedUnit() );
00523 }
00524 sigCargoChanged();
00525 updateResourceDisplay();
00526 showAmmo();
00527 updateLoadMeter();
00528 }
00529
00530 int RunModal()
00531 {
00532 if ( setupOK )
00533 return Panel::RunModal();
00534 return 0;
00535 }
00536
00537 bool ProcessEvent ( const SDL_Event * event,bool bModal = false )
00538 {
00539
00540
00541 if ( mainScreenWidget && mainScreenWidget->getUnitInfoPanel() )
00542 if ( mainScreenWidget->getUnitInfoPanel()->ProcessEvent( event, bModal ))
00543 return true;
00544
00545 if ( mainScreenWidget && mainScreenWidget->getGuiHost() )
00546 if ( mainScreenWidget->getGuiHost()->ProcessEvent( event, bModal ))
00547 return true;
00548
00549 if ( Panel::ProcessEvent( event, bModal ))
00550 return true;
00551
00552 return false;
00553 }
00554
00555 void showAmmo()
00556 {
00557 setLabelText( "cmmun", container->getAmmo( cwcruisemissile, maxint, true ));
00558 setLabelText( "minemun", container->getAmmo( cwminen, maxint, true ));
00559 setLabelText( "bombmun", container->getAmmo( cwbombn, maxint, true ));
00560 setLabelText( "lmmun", container->getAmmo( cwlargemissilen, maxint, true ));
00561 setLabelText( "smmun", container->getAmmo( cwsmallmissilen, maxint, true ));
00562 setLabelText( "mgmun", container->getAmmo( cwmachinegunn, maxint, true ));
00563 setLabelText( "canmun", container->getAmmo( cwcannonn, maxint, true ));
00564 setLabelText( "torpmun", container->getAmmo( cwtorpedon, maxint, true ));
00565 }
00566
00567 void userHandler( const ASCString& label, PropertyReadingContainer& pc, PG_Widget* parent, WidgetParameters widgetParams );
00568
00569 ContainerBase* getContainer() { return container; };
00570
00571 GameMap* getMap() { if ( container ) return container->getMap(); else return NULL; };
00572
00573 ContainerControls& getControls() { return containerControls; };
00574
00575 SigC::Signal0<void> sigCargoChanged;
00576
00577
00578 ~CargoDialog()
00579 {
00580 if ( setupOK )
00581 NewGuiHost::popIconHandler();
00582
00583 }
00584
00585 };
00586
00587
00588
00589
00590
00591 void cargoDialog( ContainerBase* cb )
00592 {
00593 CargoDialog cd ( NULL, cb );
00594 cd.Show();
00595 cd.RunModal();
00596 }
00597
00598
00599
00600
00601
00602 class VehicleProduction_SelectionItemFactory: public VehicleTypeSelectionItemFactory {
00603 bool fillResources;
00604 bool fillAmmo;
00605 const ContainerBase* plant;
00606
00607
00608 Container* produceables;
00609
00610 Container& filterVehicleTypes( const Container& vehicles, const ContainerBase* productionplant )
00611 {
00612 produceables = new Container();
00613 for ( Container::const_iterator i = vehicles.begin(); i != vehicles.end(); ++i ) {
00614 if ( productionplant->getMap()->getgameparameter( cgp_produceOnlyResearchedStuffInternally )) {
00615 ContainerConstControls cc ( productionplant );
00616 if ( !(cc.unitProductionPrerequisites( *i ) & ~(1+2+4)))
00617 produceables->push_back( *i );
00618 } else
00619 produceables->push_back( *i );
00620 }
00621
00622 return *produceables;
00623 }
00624
00625 protected:
00626 void vehicleTypeSelected( const Vehicletype* type, bool mouse )
00627 {
00628 sigVehicleTypeSelected( type, mouse );
00629 }
00630
00631 void itemMarked( const SelectionWidget* widget, bool mouse )
00632 {
00633 if ( !widget )
00634 return;
00635
00636 const VehicleTypeBaseWidget* fw = dynamic_cast<const VehicleTypeBaseWidget*>(widget);
00637 assert( fw );
00638 sigVehicleTypeMarked( fw->getVehicletype() );
00639 }
00640
00641 const Container& getOriginalItems() {
00642 delete produceables;
00643 filterVehicleTypes( plant->getProduction(), plant );
00644 return *produceables;
00645 };
00646
00647 public:
00648 VehicleProduction_SelectionItemFactory( Resources plantResources, const ContainerBase* productionplant )
00649 : VehicleTypeSelectionItemFactory( plantResources, filterVehicleTypes( productionplant->getProduction(), productionplant), productionplant->getMap()->getCurrentPlayer() ),
00650 fillResources(true),
00651 fillAmmo(true),
00652 plant(productionplant)
00653 {
00654 };
00655
00656
00657 bool getAmmoFilling()
00658 {
00659 if ( plant->baseType->hasFunction(ContainerBaseType::AmmoProduction))
00660 return fillAmmo;
00661 else
00662 return false;
00663 }
00664
00665 bool setAmmoFilling( bool value )
00666 {
00667 fillAmmo = value;
00668 reloadAllItems();
00669 return true;
00670 }
00671
00672 bool getResourceFilling()
00673 {
00674 return fillResources;
00675 }
00676
00677 bool setResourceFilling( bool value )
00678 {
00679 fillResources = value;
00680 reloadAllItems();
00681 return true;
00682 }
00683
00684
00685 Resources getCost( const Vehicletype* type )
00686 {
00687 Resources cost = plant->getProductionCost( type );
00688 if ( fillResources )
00689 cost += Resources( 0, type->getStorageCapacity(plant->getMap()->_resourcemode).material, type->getStorageCapacity(plant->getMap()->_resourcemode).fuel );
00690
00691 if ( fillAmmo )
00692 for ( int w = 0; w < type->weapons.count; ++w )
00693 if ( type->weapons.weapon[w].requiresAmmo() ) {
00694 int wt = type->weapons.weapon[w].getScalarWeaponType();
00695 cost += Resources( cwaffenproduktionskosten[wt][0], cwaffenproduktionskosten[wt][1], cwaffenproduktionskosten[wt][2] ) * type->weapons.weapon[w].count;
00696 }
00697 return cost;
00698 };
00699
00700 SigC::Signal2<void,const Vehicletype*, bool > sigVehicleTypeSelected;
00701 SigC::Signal1<void,const Vehicletype* > sigVehicleTypeMarked;
00702
00703 ~VehicleProduction_SelectionItemFactory()
00704 {
00705 delete produceables;
00706 }
00707
00708 };
00709
00710
00711 class AddProductionLine_SelectionItemFactory: public VehicleTypeSelectionItemFactory {
00712 ContainerBase* plant;
00713 public:
00714 AddProductionLine_SelectionItemFactory( ContainerBase* my_plant, const Container& types ) : VehicleTypeSelectionItemFactory( my_plant->getResource(Resources(maxint,maxint,maxint), true), types, my_plant->getMap()->getCurrentPlayer() ), plant(my_plant)
00715 {
00716
00717 };
00718
00719 void vehicleTypeSelected( const Vehicletype* type, bool mouse )
00720 {
00721 ContainerControls cc( plant );
00722 int res = cc.buildProductionLine( type );
00723 if ( res < 0 )
00724 errorMessage( getmessage ( -res ));
00725 }
00726
00727 Resources getCost( const Vehicletype* type )
00728 {
00729 ContainerControls cc ( plant );
00730 return cc.buildProductionLineResourcesNeeded( type );
00731 };
00732 };
00733
00734
00735 class VehicleProduction_SelectionWindow : public ASC_PG_Dialog {
00736 const Vehicletype* selected;
00737 const Vehicletype* finallySelected;
00738 ItemSelectorWidget* isw;
00739 VehicleProduction_SelectionItemFactory* factory;
00740 ContainerBase* my_plant;
00741 protected:
00742 void vtMarked( const Vehicletype* vt )
00743 {
00744 vtSelected( vt, true );
00745 }
00746
00747 void vtSelected( const Vehicletype* vt, bool mouse )
00748 {
00749 selected = vt;
00750
00751 if ( !mouse )
00752 produce();
00753 };
00754
00755 bool produce()
00756 {
00757 if ( selected ) {
00758 finallySelected = selected;
00759 quitModalLoop(0);
00760 return true;
00761 } else
00762 return false;
00763 }
00764
00765
00766 bool closeWindow()
00767 {
00768 selected = NULL;
00769 return ASC_PG_Dialog::closeWindow();
00770 }
00771
00772 bool quitSignalled()
00773 {
00774 selected = NULL;
00775 QuitModal();
00776 return true;
00777 };
00778
00779 void reLoadAndUpdate()
00780 {
00781 factory->setAvailableResource(my_plant->getResource(Resources(maxint,maxint,maxint)));
00782 isw->reLoad( true );
00783 }
00784
00785 bool eventKeyDown(const SDL_KeyboardEvent* key)
00786 {
00787 int mod = SDL_GetModState() & ~(KMOD_NUM | KMOD_CAPS | KMOD_MODE);
00788 if ( mod )
00789 return false;
00790
00791 if ( key->keysym.sym == SDLK_ESCAPE ) {
00792 closeWindow();
00793 return true;
00794 }
00795
00796 return false;
00797 }
00798
00799
00800 public:
00801 VehicleProduction_SelectionWindow( PG_Widget *parent, const PG_Rect &r, ContainerBase* plant ) : ASC_PG_Dialog( parent, r, "Choose Vehicle Type" ), selected(NULL), finallySelected(NULL), isw(NULL), factory(NULL), my_plant( plant )
00802 {
00803 factory = new VehicleProduction_SelectionItemFactory( plant->getResource(Resources(maxint,maxint,maxint), true), plant );
00804
00805 factory->setResourceFilling ( CGameOptions::Instance()->unitProduction.fillResources );
00806
00807
00808 factory->sigVehicleTypeSelected.connect ( SigC::slot( *this, &VehicleProduction_SelectionWindow::vtSelected ));
00809 factory->sigVehicleTypeMarked.connect ( SigC::slot( *this, &VehicleProduction_SelectionWindow::vtMarked ));
00810
00811 isw = new ItemSelectorWidget( this, PG_Rect(10, GetTitlebarHeight(), r.Width() - 20, r.Height() - GetTitlebarHeight() - 40), factory );
00812 isw->sigQuitModal.connect( SigC::slot( *this, &VehicleProduction_SelectionWindow::quitSignalled));
00813
00814 factory->reloadAllItems.connect( SigC::slot( *this, &VehicleProduction_SelectionWindow::reLoadAndUpdate ));
00815
00816
00817 int y = GetTitlebarHeight() + isw->Height();
00818 PG_CheckButton* fillRes = new PG_CheckButton( this, PG_Rect( 10, y + 2, r.Width() / 2 - 50, 20), "Fill with Resources" );
00819
00820
00821 if ( factory->getResourceFilling() )
00822 fillRes->SetPressed();
00823 fillRes->sigClick.connect( SigC::slot( *factory, &VehicleProduction_SelectionItemFactory::setResourceFilling ));
00824
00825 if ( plant->baseType->hasFunction(ContainerBaseType::AmmoProduction)) {
00826 factory->setAmmoFilling( CGameOptions::Instance()->unitProduction.fillAmmo );
00827 PG_CheckButton* fillAmmo = new PG_CheckButton( this, PG_Rect( 10, y + 20, r.Width() / 2 - 50, 20), "Fill with Ammo" );
00828 if ( factory->getAmmoFilling() )
00829 fillAmmo->SetPressed();
00830 fillAmmo->sigClick.connect( SigC::slot( *factory, &VehicleProduction_SelectionItemFactory::setAmmoFilling ));
00831 } else
00832 factory->setAmmoFilling( false );
00833
00834 PG_Rect rr ( r.Width() / 2 + 10, y + 2, (r.Width() - 20) - (r.Width() / 2 + 10) , 35);
00835 PG_Button* b = new PG_Button( this, PG_Rect( rr.x + rr.h + 5, rr.y, rr.w - 40, rr.h ) , "Produce" );
00836 b->sigClick.connect( SigC::slot( *this,&VehicleProduction_SelectionWindow::produce ));
00837
00838 if ( !plant->baseType->hasFunction(ContainerBaseType::NoProductionCustomization)) {
00839 PG_Button* b2 = new PG_Button( this, PG_Rect( rr.x, rr.y, rr.h, rr.h ), "+" );
00840 b2->sigClick.connect( SigC::slot( *this, &VehicleProduction_SelectionWindow::addProductionLine ));
00841 new PG_ToolTipHelp( b2, "Add production line");
00842
00843 PG_Button* b3 = new PG_Button( this, PG_Rect( rr.x - rr.h - 5, rr.y, rr.h, rr.h ), "-" );
00844 b3->sigClick.connect( SigC::slot( *this, &VehicleProduction_SelectionWindow::removeProductionLine ));
00845 new PG_ToolTipHelp( b3, "Remove production line");
00846 }
00847
00848
00849 SetTransparency(0);
00850 };
00851
00852 bool addProductionLine()
00853 {
00854 ContainerControls cc ( my_plant );
00855 {
00856 ItemSelectorWindow isw( NULL, PG_Rect( 100, 150, 400, 400 ), "choose production line", new AddProductionLine_SelectionItemFactory( my_plant, cc.productionLinesBuyable() ));
00857 isw.Show();
00858 isw.RunModal();
00859 }
00860 reLoadAndUpdate();
00861 return true;
00862 }
00863
00864 bool removeProductionLine()
00865 {
00866 if ( selected && choice_dlg("do you really want to remove this production line ?","~y~es","~n~o") == 1) {
00867 ContainerControls cc ( my_plant );
00868 cc.removeProductionLine( selected );
00869 reLoadAndUpdate();
00870 }
00871 return true;
00872 }
00873
00874
00875 bool fillWithAmmo()
00876 {
00877 return factory->getAmmoFilling();
00878 }
00879
00880 bool fillWithResources()
00881 {
00882 return factory->getResourceFilling();
00883 }
00884
00885
00886 const Vehicletype* getVehicletype() { return finallySelected; };
00887 };
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903 void SubWindow::registerSubwindow( CargoDialog* cd )
00904 {
00905 cargoDialog = cd;
00906 cd->addAvailableSubwin( this );
00907 }
00908
00909 void SubWindow::registerChilds( CargoDialog* cd )
00910 {
00911 widget = cd->FindChild( getASCTXTname(), true);
00912 if ( !widget )
00913 warning( "Could not find widget with name " + getASCTXTname() );
00914 }
00915
00916
00917 ContainerBase* SubWindow::container()
00918 {
00919 return cargoDialog->getContainer();
00920 }
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931 class SolarPowerWindow : public SubWindow {
00932
00933 public:
00934 bool available( CargoDialog* cd )
00935 {
00936 if ( !cd->getMap()->getCurrentPlayer().diplomacy.isAllied( cd->getContainer() ))
00937 return false;
00938
00939 return cd->getContainer()->baseType->hasFunction( ContainerBaseType::SolarPowerPlant );
00940 };
00941
00942 ASCString getASCTXTname()
00943 {
00944 return "solarpower";
00945 };
00946
00947 ASCString getFullName()
00948 {
00949 return "Solar Power Generation";
00950 };
00951
00952 void update()
00953 {
00954 cargoDialog->setLabelText( "MaxPower", container()->maxplus.energy, widget );
00955
00956 static const char* weathernames[] = {"terrain_weather_dry.png",
00957 "terrain_weather_lightrain.png",
00958 "terrain_weather_heavyrain.png",
00959 "terrain_weather_lightsnow.png",
00960 "terrain_weather_heavysnow.png",
00961 "terrain_weather_ice.png" };
00962
00963
00964 SolarPowerplant solarPowerPlant ( container() );
00965 Resources plus = solarPowerPlant.getPlus();
00966 cargoDialog->setLabelText( "CurrentPower", plus.energy, widget );
00967 cargoDialog->setImage( "Weather", weathernames[ container()->getMap()->getField( container()->getPosition() )->getweather() ], widget );
00968 }
00969 };
00970
00971 class WindPowerWindow : public SubWindow {
00972 public:
00973 bool available( CargoDialog* cd )
00974 {
00975 if ( !cd->getMap()->getCurrentPlayer().diplomacy.isAllied( cd->getContainer() ))
00976 return false;
00977
00978 return cd->getContainer()->baseType->hasFunction( ContainerBaseType::WindPowerPlant );
00979 };
00980
00981 ASCString getASCTXTname()
00982 {
00983 return "windpower";
00984 };
00985
00986 ASCString getFullName()
00987 {
00988 return "Wind Power Generation";
00989 };
00990
00991
00992 void update()
00993 {
00994 cargoDialog->setLabelText( "MaxPower", container()->maxplus.energy, widget );
00995
00996 WindPowerplant windPowerPlant ( container() );
00997 Resources plus = windPowerPlant.getPlus();
00998 cargoDialog->setLabelText( "CurrentPower", plus.energy, widget );
00999
01000 #ifdef WEATHERGENERATOR
01001 if ( container()->getMap()->weatherSystem )
01002 cargoDialog->setLabelText( "Weather", container()->getMap()->weatherSystem->getCurrentWindSpeed(), widget );
01003 #else
01004 cargoDialog->setLabelText( "Weather", container()->getMap()->weather.windSpeed, widget );
01005 #endif
01006 }
01007 };
01008
01009 class NetControlWindow : public SubWindow {
01010
01011 private:
01012
01013 bool click( PG_Button* b, int x, int y )
01014 {
01015 return true;
01016 }
01017
01018 PG_Button* findButton( int x, int y )
01019 {
01020 char c = 'a' + x;
01021 ASCString buttonName = "Button" + ASCString::toString(y) + c;
01022 return dynamic_cast<PG_Button*>( widget->FindChild( buttonName, true ) );
01023 }
01024
01025 public:
01026 bool available( CargoDialog* cd )
01027 {
01028 if ( !cd->getMap()->getCurrentPlayer().diplomacy.isAllied( cd->getContainer() ))
01029 return false;
01030
01031 return dynamic_cast<Building*>(cd->getContainer()) != NULL;
01032 };
01033
01034 ASCString getASCTXTname()
01035 {
01036 return "netcontrol";
01037 };
01038
01039 ASCString getFullName()
01040 {
01041 return "Resource Network Control";
01042 };
01043
01044
01045 void registerChilds( CargoDialog* cd )
01046 {
01047 SubWindow::registerChilds( cd );
01048
01049 if ( widget ) {
01050 for ( int x = 0; x < 3; ++x ) {
01051 for ( int y = 0; y < 4; ++y ) {
01052 PG_Button* b = findButton( x, y );
01053 if ( b ) {
01054 b->sigClick.connect( SigC::bind( SigC::bind( SigC::slot( *this, &NetControlWindow::click ), x), y));
01055 if( y >= 2)
01056 b->