00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "servicecommand.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 "servicing.h"
00035 #include "changeunitmovement.h"
00036 #include "consumeammo.h"
00037
00038
00039 bool ServiceCommand :: availExternally ( ContainerBase* eht )
00040 {
00041 ServiceTargetSearcher sts( eht, ServiceTargetSearcher::checkAmmo + ServiceTargetSearcher::checkResources );
00042 return sts.externallyAvailable();
00043 }
00044
00045 bool ServiceCommand :: avail ( ContainerBase* source, ContainerBase* target )
00046 {
00047 if ( target->getCarrier() == source ) {
00048 ServiceCommand sc( source );
00049 const ServiceTargetSearcher::Targets& dest = sc.getDestinations();
00050
00051 return find( dest.begin(), dest.end(), target ) != dest.end();
00052
00053 } else {
00054 ServiceTargetSearcher sts( source, ServiceTargetSearcher::checkAmmo + ServiceTargetSearcher::checkResources );
00055 if ( !sts.externallyAvailable())
00056 return false;
00057
00058 return find( sts.getTargets().begin(), sts.getTargets().end(), target ) != sts.getTargets().end();
00059 }
00060 }
00061
00062
00063 ServiceCommand :: ServiceCommand ( ContainerBase* container )
00064 : ContainerCommand ( container ), targetSearcher(NULL), transferHandler(NULL),destinationSpecified(false), destinationContainerID(0)
00065 {
00066
00067 }
00068
00069 const ServiceTargetSearcher::Targets& ServiceCommand::getDestinations()
00070 {
00071 delete targetSearcher;
00072 targetSearcher = new ServiceTargetSearcher( getContainer(), ServiceTargetSearcher::checkAmmo + ServiceTargetSearcher::checkResources );
00073 targetSearcher->startSearch();
00074 return targetSearcher->getTargets();
00075 }
00076
00077 void ServiceCommand::setDestination( ContainerBase* destination )
00078 {
00079 destinationSpecified = true;
00080 destinationContainerID = destination->getIdentification();
00081 }
00082
00083
00084 ContainerBase* ServiceCommand::getDestination()
00085 {
00086 if ( !destinationSpecified )
00087 return NULL;
00088
00089 return getMap()->getContainer( destinationContainerID );
00090 }
00091
00092
00093 TransferHandler& ServiceCommand::getTransferHandler()
00094 {
00095 delete transferHandler;
00096 transferHandler = NULL;
00097 if ( !getDestination() )
00098 throw ActionResult( 22002 );
00099
00100 transferHandler = new TransferHandler( getContainer(), getDestination() );
00101
00102 orgValues.clear();
00103 TransferHandler::Transfers& transfers = transferHandler->getTransfers();
00104 for ( TransferHandler::Transfers::iterator i = transfers.begin(); i != transfers.end(); ++i )
00105 orgValues[ (*i)->getID()] = (*i)->getAmount( (*i)->getDstContainer() );
00106
00107 return *transferHandler;
00108 }
00109
00110 void ServiceCommand::saveTransfers()
00111 {
00112 values.clear();
00113 if ( transferHandler ) {
00114 TransferHandler::Transfers& transfers = transferHandler->getTransfers();
00115 for ( TransferHandler::Transfers::iterator i = transfers.begin(); i != transfers.end(); ++i )
00116 values[ (*i)->getID()] = (*i)->getAmount( (*i)->getDstContainer() );
00117
00118 setState( SetUp );
00119 }
00120 }
00121
00122
00123 ActionResult ServiceCommand::go ( const Context& context )
00124 {
00125 if ( getState() != SetUp )
00126 return ActionResult(22000);
00127
00128
00129 TransferHandler& handler = getTransferHandler();
00130
00131 for ( Values::iterator i = values.begin(); i != values.end(); ++i ) {
00132 TransferHandler::Transfers& transfers = handler.getTransfers();
00133 for ( TransferHandler::Transfers::iterator t = transfers.begin(); t != transfers.end(); ++t )
00134 if ( (*t)->getID() == i->first ) {
00135 if ( !(*t)->setDestAmount( i->second ) )
00136 return ActionResult( 22001, (*t)->getName() );
00137 (*t)->commit( context );
00138 }
00139 }
00140
00141 setState( Finished );
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 ActionResult res(0);
00156 return res;
00157 }
00158
00159
00160 static const int ServiceCommandVersion = 2;
00161
00162 void ServiceCommand :: readData ( tnstream& stream )
00163 {
00164 ContainerCommand::readData( stream );
00165 int version = stream.readInt();
00166 if ( version > ServiceCommandVersion )
00167 throw tinvalidversion ( "ServiceCommand", ServiceCommandVersion, version );
00168
00169 destinationSpecified = stream.readInt();
00170 destinationContainerID = stream.readInt();
00171
00172 int size = stream.readInt();
00173 for ( int i = 0; i < size; ++i ) {
00174 int key = stream.readInt();
00175 int value = stream.readInt();
00176 values[key] = value;
00177 }
00178
00179 orgValues.clear();
00180 if ( version >= 2 ) {
00181 int size = stream.readInt();
00182 for ( int i = 0; i < size; ++i ) {
00183 int key = stream.readInt();
00184 int value = stream.readInt();
00185 orgValues[key] = value;
00186 }
00187 }
00188 }
00189
00190 void ServiceCommand :: writeData ( tnstream& stream ) const
00191 {
00192 ContainerCommand::writeData( stream );
00193 stream.writeInt( ServiceCommandVersion );
00194
00195 stream.writeInt( destinationSpecified );
00196 stream.writeInt( destinationContainerID );
00197
00198 stream.writeInt( values.size() );
00199 for ( Values::const_iterator i = values.begin(); i != values.end(); ++i ) {
00200 stream.writeInt( i->first );
00201 stream.writeInt( i->second );
00202 }
00203
00204 stream.writeInt( orgValues.size() );
00205 for ( Values::const_iterator i = orgValues.begin(); i != orgValues.end(); ++i ) {
00206 stream.writeInt( i->first );
00207 stream.writeInt( i->second );
00208 }
00209
00210 }
00211
00212
00213 ASCString ServiceCommand :: getCommandString() const
00214 {
00215 ASCString c;
00216 for ( Values::const_iterator i = values.begin(); i != values.end(); ++i ) {
00217 if ( orgValues.find(i->first)==orgValues.end() || i->second != orgValues.find(i->first)->second) {
00218 ASCString s;
00219 s.format("serviceCommand ( map, %d, %d, %d, %d)", getContainerID(), destinationContainerID, i->first, i->second );
00220
00221 if ( c.length() )
00222 c += "\n";
00223
00224 c += s;
00225 }
00226 }
00227 return c;
00228 }
00229
00230 GameActionID ServiceCommand::getID() const
00231 {
00232 return ActionRegistry::ServiceCommand;
00233 }
00234
00235 ASCString ServiceCommand::getDescription() const
00236 {
00237 ASCString s = "Service ";
00238
00239 if ( getContainer(true) ) {
00240 s += " by " + getContainer()->getName();
00241 }
00242 return s;
00243 }
00244
00245 ActionResult ServiceCommand::checkExecutionPrecondition() const
00246 {
00247 if ( getMap()->getCurrentPlayer().diplomacy.isAllied( getContainer() ))
00248 return ActionResult(0);
00249 else
00250 return ActionResult(101);
00251 }
00252
00253
00254 ServiceCommand::~ServiceCommand()
00255 {
00256 delete targetSearcher;
00257 delete transferHandler;
00258 }
00259
00260 namespace
00261 {
00262 const bool r1 = registerAction<ServiceCommand> ( ActionRegistry::ServiceCommand );
00263 }
00264