00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <pgtooltiphelp.h>
00011
00012 #include "../gamemap.h"
00013 #include "../containercontrols.h"
00014 #include "../cannedmessages.h"
00015 #include "../gameoptions.h"
00016 #include "../dialog.h"
00017 #include "../sg.h"
00018
00019 #include "vehicleproductionselection.h"
00020
00021 #include "../actions/buildproductionlinecommand.h"
00022 #include "../actions/removeproductionlinecommand.h"
00023
00024 VehicleProduction_SelectionItemFactory::VehicleProduction_SelectionItemFactory( Resources plantResources, const ContainerBase* productionplant, const ConstructUnitCommand::Producables& produceableUnits )
00025 : VehicleTypeSelectionItemFactory( plantResources, convertAndCreateArrays( produceableUnits, &items ), productionplant->getMap()->getCurrentPlayer() ),
00026 fillResources(true),
00027 fillAmmo(true),
00028 plant(productionplant),
00029 produceables( produceableUnits)
00030 {
00031 }
00032
00033
00034 const VehicleProduction_SelectionItemFactory::Container& VehicleProduction_SelectionItemFactory::convertAndCreateArrays( const ConstructUnitCommand::Producables& from, Container** items )
00035 {
00036 *items = new Container();
00037 return convertArrays( from, **items );
00038 }
00039
00040 const VehicleProduction_SelectionItemFactory::Container& VehicleProduction_SelectionItemFactory::convertArrays( const ConstructUnitCommand::Producables& from, Container& items )
00041 {
00042 items.clear();
00043 for( ConstructUnitCommand::Producables::const_iterator i = from.begin(); i != from.end(); ++i )
00044 if ( !(i->prerequisites.getValue() & ( ConstructUnitCommand::Lack::Research | ConstructUnitCommand::Lack::Unloadability )))
00045 items.push_back ( i->type );
00046 return items;
00047 }
00048
00049
00050 void VehicleProduction_SelectionItemFactory::vehicleTypeSelected( const VehicleType* type, bool mouse )
00051 {
00052 sigVehicleTypeSelected( type, mouse );
00053 }
00054
00055 void VehicleProduction_SelectionItemFactory::itemMarked( const SelectionWidget* widget, bool mouse )
00056 {
00057 if ( !widget )
00058 return;
00059
00060 const VehicleTypeBaseWidget* fw = dynamic_cast<const VehicleTypeBaseWidget*>(widget);
00061 assert( fw );
00062 sigVehicleTypeMarked( fw->getVehicletype() );
00063 }
00064
00065
00066 bool VehicleProduction_SelectionItemFactory::getAmmoFilling()
00067 {
00068 if ( plant->baseType->hasFunction(ContainerBaseType::AmmoProduction))
00069 return fillAmmo;
00070 else
00071 return false;
00072 }
00073
00074 bool VehicleProduction_SelectionItemFactory::setAmmoFilling( bool value )
00075 {
00076 fillAmmo = value;
00077 reloadAllItems();
00078 return true;
00079 }
00080
00081 bool VehicleProduction_SelectionItemFactory::getResourceFilling()
00082 {
00083 return fillResources;
00084 }
00085
00086 bool VehicleProduction_SelectionItemFactory::setResourceFilling( bool value )
00087 {
00088 fillResources = value;
00089 reloadAllItems();
00090 return true;
00091 }
00092
00093 void VehicleProduction_SelectionItemFactory::updateProducables()
00094 {
00095 convertArrays( produceables, *items );
00096 }
00097
00098
00099 Resources VehicleProduction_SelectionItemFactory::getCost( const VehicleType* type )
00100 {
00101 for ( ConstructUnitCommand::Producables::const_iterator i = produceables.begin(); i != produceables.end(); ++i ) {
00102 if ( i->type == type ) {
00103 Resources cost = i->cost;
00104 if ( fillResources )
00105 cost += Resources( 0, type->getStorageCapacity(plant->getMap()->_resourcemode).material, type->getStorageCapacity(plant->getMap()->_resourcemode).fuel );
00106
00107 if ( fillAmmo )
00108 for ( int w = 0; w < type->weapons.count; ++w )
00109 if ( type->weapons.weapon[w].requiresAmmo() ) {
00110 int wt = type->weapons.weapon[w].getScalarWeaponType();
00111 cost += Resources( ammoProductionCost[wt][0], ammoProductionCost[wt][1], ammoProductionCost[wt][2] ) * type->weapons.weapon[w].count;
00112 }
00113 return cost;
00114 }
00115 }
00116 return Resources(0,0,0);
00117 };
00118
00119
00120 AddProductionLine_SelectionItemFactory::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)
00121 {
00122
00123 };
00124
00125 void AddProductionLine_SelectionItemFactory::vehicleTypeSelected( const VehicleType* type, bool mouse )
00126 {
00127 auto_ptr<BuildProductionLineCommand> bplc ( new BuildProductionLineCommand(plant ));
00128 bplc->setProduction( type );
00129 ActionResult res = bplc->execute ( createContext( plant->getMap() ));
00130 if ( res.successful() )
00131 bplc.release();
00132 else
00133 displayActionError( res );
00134 }
00135
00136 Resources AddProductionLine_SelectionItemFactory::getCost( const VehicleType* type )
00137 {
00138 return BuildProductionLineCommand::resourcesNeeded( plant->baseType, type );
00139 };
00140
00141
00142 void VehicleProduction_SelectionWindow::vtMarked( const VehicleType* vt )
00143 {
00144 vtSelected( vt, true );
00145 }
00146
00147 void VehicleProduction_SelectionWindow::vtSelected( const VehicleType* vt, bool mouse )
00148 {
00149 selected = vt;
00150
00151 if ( !mouse )
00152 produce();
00153 };
00154
00155 bool VehicleProduction_SelectionWindow::produce()
00156 {
00157 if ( selected ) {
00158 finallySelected = selected;
00159 quitModalLoop(0);
00160 return true;
00161 } else
00162 return false;
00163 }
00164
00165
00166 bool VehicleProduction_SelectionWindow::closeWindow()
00167 {
00168 selected = NULL;
00169 return ASC_PG_Dialog::closeWindow();
00170 }
00171
00172 bool VehicleProduction_SelectionWindow::quitSignalled()
00173 {
00174 selected = NULL;
00175 QuitModal();
00176 return true;
00177 };
00178
00179 void VehicleProduction_SelectionWindow::reLoadAndUpdate()
00180 {
00181 reloadProducebles();
00182 factory->setAvailableResource(my_plant->getResource(Resources(maxint,maxint,maxint)));
00183 factory->updateProducables();
00184 isw->reLoad( true );
00185 }
00186
00187 bool VehicleProduction_SelectionWindow::eventKeyDown(const SDL_KeyboardEvent* key)
00188 {
00189 int mod = SDL_GetModState() & ~(KMOD_NUM | KMOD_CAPS | KMOD_MODE);
00190 if ( mod )
00191 return false;
00192
00193 switch ( key->keysym.sym ) {
00194 case SDLK_ESCAPE:
00195 closeWindow();
00196 return true;
00197
00198 case SDLK_PLUS:
00199 addProductionLine();
00200 QuitModal();
00201 return true;
00202
00203 case SDLK_MINUS:
00204 removeProductionLine();
00205 QuitModal();
00206 return true;
00207 default:;
00208 }
00209
00210 return false;
00211 }
00212
00213
00214 VehicleProduction_SelectionWindow::VehicleProduction_SelectionWindow( PG_Widget *parent, const PG_Rect &r, ContainerBase* plant, const ConstructUnitCommand::Producables& produceableUnits, bool internally )
00215 : ASC_PG_Dialog( parent, r, "Choose Vehicle Type" ), selected(NULL), finallySelected(NULL), isw(NULL), factory(NULL), my_plant( plant ), produceables( produceableUnits )
00216 {
00217 factory = new VehicleProduction_SelectionItemFactory( plant->getResource(Resources(maxint,maxint,maxint), true), plant, produceableUnits );
00218 if ( internally ) {
00219 factory->setAmmoFilling( CGameOptions::Instance()->unitProduction.fillAmmo );
00220 factory->setResourceFilling ( CGameOptions::Instance()->unitProduction.fillResources );
00221 } else {
00222 factory->setAmmoFilling( false );
00223 factory->setResourceFilling ( false );
00224 }
00225
00226 factory->sigVehicleTypeSelected.connect ( SigC::slot( *this, &VehicleProduction_SelectionWindow::vtSelected ));
00227 factory->sigVehicleTypeMarked.connect ( SigC::slot( *this, &VehicleProduction_SelectionWindow::vtMarked ));
00228
00229 isw = new ItemSelectorWidget( this, PG_Rect(10, GetTitlebarHeight(), r.Width() - 20, r.Height() - GetTitlebarHeight() - 40), factory );
00230 isw->sigQuitModal.connect( SigC::slot( *this, &VehicleProduction_SelectionWindow::quitSignalled));
00231
00232 int y = GetTitlebarHeight() + isw->Height();
00233 if ( internally ) {
00234 PG_CheckButton* fillRes = new PG_CheckButton( this, PG_Rect( 10, y + 2, r.Width() / 2 - 50, 20), "Fill with Resources" );
00235 if ( factory->getResourceFilling() )
00236 fillRes->SetPressed();
00237 fillRes->sigClick.connect( SigC::slot( *factory, &VehicleProduction_SelectionItemFactory::setResourceFilling ));
00238 if ( plant->baseType->hasFunction(ContainerBaseType::AmmoProduction)) {
00239 PG_CheckButton* fillAmmo = new PG_CheckButton( this, PG_Rect( 10, y + 20, r.Width() / 2 - 50, 20), "Fill with Ammo" );
00240 if ( factory->getAmmoFilling() )
00241 fillAmmo->SetPressed();
00242 fillAmmo->sigClick.connect( SigC::slot( *factory, &VehicleProduction_SelectionItemFactory::setAmmoFilling ));
00243 } else
00244 factory->setAmmoFilling( false );
00245
00246 } else {
00247 factory->setAmmoFilling( false );
00248 factory->setResourceFilling ( false );
00249 }
00250
00251 factory->reloadAllItems.connect( SigC::slot( *this, &VehicleProduction_SelectionWindow::reLoadAndUpdate ));
00252
00253 PG_Rect rr ( r.Width() / 2 + 10, y + 2, (r.Width() - 20) - (r.Width() / 2 + 10) , 35);
00254 PG_Button* b = new PG_Button( this, PG_Rect( rr.x + rr.h + 5, rr.y, rr.w - 40, rr.h ) , "Produce" );
00255 b->sigClick.connect( SigC::slot( *this,&VehicleProduction_SelectionWindow::produce ));
00256
00257 if ( !plant->baseType->hasFunction(ContainerBaseType::NoProductionCustomization) && internally ) {
00258 PG_Button* b2 = new PG_Button( this, PG_Rect( rr.x, rr.y, rr.h, rr.h ), "+" );
00259 b2->sigClick.connect( SigC::slot( *this, &VehicleProduction_SelectionWindow::addProductionLine ));
00260 new PG_ToolTipHelp( b2, "Add production line");
00261
00262 PG_Button* b3 = new PG_Button( this, PG_Rect( rr.x - rr.h - 5, rr.y, rr.h, rr.h ), "-" );
00263 b3->sigClick.connect( SigC::slot( *this, &VehicleProduction_SelectionWindow::removeProductionLine ));
00264 new PG_ToolTipHelp( b3, "Remove production line");
00265 }
00266 };
00267
00268
00269 bool VehicleProduction_SelectionWindow::addProductionLine()
00270 {
00271 BuildProductionLineCommand bplc( my_plant );
00272 {
00273 ItemSelectorWindow isw( NULL, PG_Rect( 100, 150, 400, 400 ), "choose production line", new AddProductionLine_SelectionItemFactory( my_plant, bplc.productionLinesBuyable() ));
00274 isw.Show();
00275 isw.RunModal();
00276 }
00277 reLoadAndUpdate();
00278 return true;
00279 }
00280
00281 bool VehicleProduction_SelectionWindow::removeProductionLine()
00282 {
00283 if ( selected && choice_dlg("do you really want to remove this production line ?","~y~es","~n~o") == 1) {
00284 auto_ptr<RemoveProductionLineCommand> rplc ( new RemoveProductionLineCommand( my_plant ));
00285 rplc->setRemoval( selected );
00286 ActionResult res = rplc->execute( createContext( my_plant->getMap() ));
00287 if ( res.successful())
00288 rplc.release();
00289 else
00290 displayActionError(res);
00291 reLoadAndUpdate();
00292 }
00293 return true;
00294 }
00295
00296
00297 bool VehicleProduction_SelectionWindow::fillWithAmmo()
00298 {
00299 return factory->getAmmoFilling();
00300 }
00301
00302 bool VehicleProduction_SelectionWindow::fillWithResources()
00303 {
00304 return factory->getResourceFilling();
00305 }
00306