00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "buildproductionlinecommand.h"
00023
00024 #include "../vehicle.h"
00025 #include "../mapfield.h"
00026 #include "../gamemap.h"
00027 #include "../viewcalculation.h"
00028 #include "../spfst.h"
00029 #include "../mapdisplayinterface.h"
00030 #include "action-registry.h"
00031 #include "../itemrepository.h"
00032 #include "../containercontrols.h"
00033 #include "consumeresource.h"
00034 #include "servicecommand.h"
00035 #include "convertcontainer.h"
00036
00037 bool BuildProductionLineCommand :: avail ( const ContainerBase* factory )
00038 {
00039 if ( !factory )
00040 return false;
00041
00042 return factory->baseType->hasFunction( ContainerBaseType::InternalVehicleProduction )
00043 && !factory->baseType->hasFunction( ContainerBaseType::NoProductionCustomization ) ;
00044 }
00045
00046
00047 vector<const VehicleType*> BuildProductionLineCommand :: productionLinesBuyable()
00048 {
00049
00050 vector<const VehicleType*> list;
00051
00052 ContainerBase* container = getContainer();
00053
00054 if ( !avail( container ))
00055 return list;
00056
00057 Resources r = container->getResource( Resources(maxint, maxint, maxint), 1 );
00058
00059 for ( int i = 0; i < vehicleTypeRepository.getNum(); ++i ) {
00060 VehicleType* veh = getMap()->getvehicletype_bypos ( i );
00061 if ( veh ) {
00062 bool found = find( container->getProduction().begin(), container->getProduction().end(), veh ) != container->getProduction().end();
00063 if ( container->baseType->vehicleFit ( veh ) && !found )
00064 if ( container->vehicleUnloadable(veh) || container->baseType->hasFunction( ContainerBaseType::ProduceNonLeavableUnits ))
00065 if ( veh->techDependency.available ( container->getMap()->getCurrentPlayer().research ))
00066 if ( container->baseType->vehicleCategoriesProduceable & (1 << veh->movemalustyp))
00067 list.push_back( veh );
00068 }
00069 }
00070 return list;
00071 }
00072
00073 Resources BuildProductionLineCommand :: resourcesNeeded( const ContainerBaseType* factory, const VehicleType* veh )
00074 {
00075 return factory->productionEfficiency * veh->productionCost * productionLineConstructionCostFactor ;
00076 }
00077
00078
00079
00080 BuildProductionLineCommand :: BuildProductionLineCommand ( ContainerBase* container )
00081 : ContainerCommand ( container ), vehicleTypeId(-1)
00082 {
00083
00084 }
00085
00086
00087
00088 void BuildProductionLineCommand::setProduction( const VehicleType* vehicleType )
00089 {
00090 if ( vehicleType ) {
00091 vehicleTypeId = vehicleType->id;
00092 setState( SetUp );
00093 }
00094 }
00095
00096
00097 ActionResult BuildProductionLineCommand::go ( const Context& context )
00098 {
00099 if ( getState() != SetUp )
00100 return ActionResult(22000);
00101
00102 if ( !avail( getContainer() ))
00103 return ActionResult(22800);
00104
00105 const VehicleType* vt = NULL;
00106 vector<const VehicleType*> types = productionLinesBuyable();
00107 for ( vector<const VehicleType*>::iterator i = types.begin(); i != types.end(); ++i )
00108 if ( (*i)->id == vehicleTypeId )
00109 vt = *i;
00110
00111 if ( !vt )
00112 return ActionResult(22900);
00113
00114
00115 Resources needed = resourcesNeeded( getContainer()->baseType, vt );
00116 Resources avail = getContainer()->getResource( needed, true );
00117 if ( avail < needed )
00118 return ActionResult(22901);
00119
00120 auto_ptr<ConsumeResource> cr ( new ConsumeResource( getContainer(), needed ));
00121 ActionResult res = cr->execute(context);
00122
00123 if ( !res.successful() ) {
00124 setState( Failed );
00125 return res;
00126 }
00127
00128 getContainer()->addProductionLine( vt );
00129
00130 cr.release();
00131 setState( Finished );
00132
00133 return res;
00134 }
00135
00136 ActionResult BuildProductionLineCommand::undoAction( const Context& context )
00137 {
00138 VehicleType* vt = vehicleTypeRepository.getObject_byID( vehicleTypeId );
00139 if ( !vt )
00140 return ActionResult(22902);
00141
00142 getContainer()->deleteProductionLine( vt );
00143
00144 return ContainerCommand::undoAction( context );
00145 }
00146
00147
00148 static const int BuildProductionLineCommandVersion = 1;
00149
00150 void BuildProductionLineCommand :: readData ( tnstream& stream )
00151 {
00152 ContainerCommand::readData( stream );
00153 int version = stream.readInt();
00154 if ( version > BuildProductionLineCommandVersion )
00155 throw tinvalidversion ( "BuildProductionLineCommand", BuildProductionLineCommandVersion, version );
00156 vehicleTypeId = stream.readInt();
00157 }
00158
00159 void BuildProductionLineCommand :: writeData ( tnstream& stream ) const
00160 {
00161 ContainerCommand::writeData( stream );
00162 stream.writeInt( BuildProductionLineCommandVersion );
00163 stream.writeInt( vehicleTypeId );
00164 }
00165
00166
00167 ASCString BuildProductionLineCommand :: getCommandString() const
00168 {
00169 ASCString c;
00170 c.format("buildProductionLine ( map, %d, %d )", getContainerID(), vehicleTypeId );
00171 return c;
00172
00173 }
00174
00175 GameActionID BuildProductionLineCommand::getID() const
00176 {
00177 return ActionRegistry::BuildProductionLineCommand;
00178 }
00179
00180 ASCString BuildProductionLineCommand::getDescription() const
00181 {
00182 ASCString s = "Add production line for type ";
00183
00184 VehicleType* vt = vehicleTypeRepository.getObject_byID( vehicleTypeId );
00185 if ( !vt )
00186 s += ASCString::toString(vehicleTypeId);
00187 else
00188 s += vt->getName();
00189
00190 if ( getContainer(true) ) {
00191 s += " to " + getContainer()->getName();
00192 }
00193
00194 return s;
00195 }
00196
00197 namespace
00198 {
00199 const bool r1 = registerAction<BuildProductionLineCommand> ( ActionRegistry::BuildProductionLineCommand );
00200 }
00201