00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "recycleunitcommand.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 "destructcontainer.h"
00036
00037 bool RecycleUnitCommand :: avail ( const ContainerBase* carrier, const Vehicle* unit )
00038 {
00039 if ( !carrier || !unit )
00040 return false;
00041
00042 if ( !carrier->findUnit( unit->networkid, false ) )
00043 return false;
00044
00045 if ( !carrier->isBuilding() )
00046 return false;
00047
00048 return true;
00049 }
00050
00051
00052 Resources RecycleUnitCommand::getOutput( const ContainerBase* carrier, const Vehicle* unit )
00053 {
00054 if ( !avail( carrier, unit ))
00055 return Resources();
00056
00057 int output;
00058 if ( carrier->baseType->hasFunction( ContainerBaseType::RecycleUnits ) )
00059 output = recyclingoutput;
00060 else
00061 output = destructoutput;
00062
00063 Resources res;
00064
00065 for ( ContainerBase::Cargo::const_iterator i = unit->getCargo().begin(); i != unit->getCargo().end(); i++)
00066 if ( *i )
00067 res += getOutput ( carrier, *i );
00068
00069 res.material += unit->typ->productionCost.material * (100 - unit->damage/2 ) * output / (100*100);
00070 return res;
00071
00072 }
00073
00074
00075 RecycleUnitCommand :: RecycleUnitCommand ( ContainerBase* container )
00076 : ContainerCommand ( container ), unitID(-1)
00077 {
00078
00079 }
00080
00081
00082
00083
00084
00085 ActionResult RecycleUnitCommand::go ( const Context& context )
00086 {
00087 if ( getState() != SetUp )
00088 return ActionResult(22000);
00089
00090 Vehicle* unit = getMap()->getUnit( unitID );
00091 if ( !unit )
00092 return ActionResult( 22100 );
00093
00094 if ( !avail( getContainer(), unit ))
00095 return ActionResult( 22101 );
00096
00097 auto_ptr<ServiceCommand> service ( new ServiceCommand( getContainer()));
00098
00099 const ServiceTargetSearcher::Targets& targets = service->getDestinations();
00100 if ( find( targets.begin(), targets.end(), unit ) != targets.end() ) {
00101 service->setDestination( unit );
00102
00103 service->getTransferHandler( ).emptyDest();
00104 service->saveTransfers();
00105 ActionResult res = service->execute( context );
00106 if ( res.successful() )
00107 service.release();
00108 else
00109 return res;
00110 }
00111
00112 Resources resource = getOutput ( getContainer(), unit );
00113
00114 resource = getContainer()->putResource( resource, true, 1, context.actingPlayer->getPosition() );
00115
00116 ActionResult res = (new ConsumeResource(getContainer(), -resource))->execute(context);
00117
00118 if ( res.successful() )
00119 res = (new DestructContainer( unit))->execute( context );
00120
00121 if ( res.successful() )
00122 setState( Finished );
00123 else
00124 setState( Failed );
00125
00126 return res;
00127 }
00128
00129
00130
00131 static const int RecycleUnitCommandVersion = 1;
00132
00133 void RecycleUnitCommand :: readData ( tnstream& stream )
00134 {
00135 ContainerCommand::readData( stream );
00136 int version = stream.readInt();
00137 if ( version > RecycleUnitCommandVersion )
00138 throw tinvalidversion ( "RecycleUnitCommand", RecycleUnitCommandVersion, version );
00139 unitID = stream.readInt();
00140 }
00141
00142 void RecycleUnitCommand :: writeData ( tnstream& stream ) const
00143 {
00144 ContainerCommand::writeData( stream );
00145 stream.writeInt( RecycleUnitCommandVersion );
00146 stream.writeInt( unitID );
00147 }
00148
00149 void RecycleUnitCommand :: setUnit( Vehicle* unit )
00150 {
00151 unitID = unit->networkid;
00152 setState( SetUp );
00153 }
00154
00155
00156 ASCString RecycleUnitCommand :: getCommandString() const
00157 {
00158 ASCString c;
00159 c.format("recycleUnit ( map, %d, %d )", getContainerID(), unitID );
00160 return c;
00161
00162 }
00163
00164 GameActionID RecycleUnitCommand::getID() const
00165 {
00166 return ActionRegistry::RecycleUnitCommand;
00167 }
00168
00169 ASCString RecycleUnitCommand::getDescription() const
00170 {
00171 ASCString s = "Recycle ";
00172
00173 if ( getMap()->getUnit( unitID ))
00174 s += getMap()->getUnit( unitID )->getName();
00175
00176 if ( getContainer(true) ) {
00177 s += " by " + getContainer()->getName();
00178 }
00179 return s;
00180 }
00181
00182 namespace
00183 {
00184 const bool r1 = registerAction<RecycleUnitCommand> ( ActionRegistry::RecycleUnitCommand );
00185 }
00186