00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "trainunitcommand.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 "consumeammo.h"
00034 #include "changeunitproperty.h"
00035
00036 bool TrainUnitCommand :: avail ( const ContainerBase* carrier, const Vehicle* unit )
00037 {
00038 if ( !carrier || !unit )
00039 return false;
00040
00041 if ( carrier->getMap()->getgameparameter( cgp_bi3_training ) )
00042 return false;
00043
00044 if ( !carrier->findUnit( unit->networkid, false ) )
00045 return false;
00046
00047 if ( unit->getCarrier() != carrier )
00048 return false;
00049
00050 if( unit->experience >= min( unit->getMap()->getgameparameter( cgp_maxtrainingexperience ), maxunitexperience))
00051 return false;
00052
00053 if ( unit->attacked )
00054 return false;
00055
00056
00057 if ( !carrier->baseType->hasFunction(ContainerBaseType::TrainingCenter) )
00058 return false;
00059
00060 int num = 0;
00061 int numsh = 0;
00062 for (int i = 0; i < unit->typ->weapons.count; i++ )
00063 if ( unit->typ->weapons.weapon[i].shootable() && (unit->typ->weapons.weapon[i].count > 0 )) {
00064 if ( unit->ammo[i] )
00065 numsh++;
00066 else
00067 num++;
00068 }
00069
00070 if ( num == 0 && numsh > 0 )
00071 return true;
00072 else
00073 return false;
00074 }
00075
00076
00077
00078 TrainUnitCommand :: TrainUnitCommand ( ContainerBase* container )
00079 : ContainerCommand ( container ), unitID(-1)
00080 {
00081
00082 }
00083
00084
00085
00086
00087
00088 ActionResult TrainUnitCommand::go ( const Context& context )
00089 {
00090 if ( getState() != SetUp )
00091 return ActionResult(22000);
00092
00093 Vehicle* unit = getMap()->getUnit( unitID );
00094 if ( !unit )
00095 return ActionResult( 22100 );
00096
00097 if ( !avail( getContainer(), unit ))
00098 return ActionResult( 22101 );
00099
00100 int newexp = unit->experience + getMap()->getgameparameter( cgp_trainingIncrement );
00101 int maxexp = min( unit->getMap()->getgameparameter( cgp_maxtrainingexperience ), maxunitexperience);
00102 if ( newexp > maxexp )
00103 newexp = maxexp;
00104
00105 auto_ptr<ChangeUnitProperty> train ( new ChangeUnitProperty( unit, ChangeUnitProperty::Experience, newexp ));
00106 ActionResult res = train->execute( context );
00107 if ( res.successful() )
00108 train.release();
00109
00110 auto_ptr<ChangeUnitProperty> train2 ( new ChangeUnitProperty( unit, ChangeUnitProperty::AttackedFlag, 1 ));
00111 res = train2->execute( context );
00112 if ( res.successful() )
00113 train2.release();
00114
00115 auto_ptr<ChangeUnitProperty> move ( new ChangeUnitProperty( unit, ChangeUnitProperty::Movement, 0 ));
00116 res = move->execute( context );
00117 if ( res.successful() )
00118 move.release();
00119
00120
00121 for (int i = 0; i < unit->typ->weapons.count; i++ ) {
00122 if ( unit->typ->weapons.weapon[i].shootable() && (unit->typ->weapons.weapon[i].count > 0 )) {
00123 auto_ptr<ConsumeAmmo> consumer ( new ConsumeAmmo( unit, unit->typ->weapons.weapon[i].getScalarWeaponType(), i, 1 ));
00124 res = consumer->execute( context );
00125 if ( res.successful() )
00126 consumer.release();
00127 else
00128 break;
00129 }
00130 }
00131
00132
00133 if ( res.successful() )
00134 setState( Finished );
00135 else
00136 setState( Failed );
00137
00138 return res;
00139 }
00140
00141
00142
00143 static const int TrainUnitCommandVersion = 1;
00144
00145 void TrainUnitCommand :: readData ( tnstream& stream )
00146 {
00147 ContainerCommand::readData( stream );
00148 int version = stream.readInt();
00149 if ( version > TrainUnitCommandVersion )
00150 throw tinvalidversion ( "TrainUnitCommand", TrainUnitCommandVersion, version );
00151 unitID = stream.readInt();
00152 }
00153
00154 void TrainUnitCommand :: writeData ( tnstream& stream ) const
00155 {
00156 ContainerCommand::writeData( stream );
00157 stream.writeInt( TrainUnitCommandVersion );
00158 stream.writeInt( unitID );
00159 }
00160
00161 void TrainUnitCommand :: setUnit( Vehicle* unit )
00162 {
00163 unitID = unit->networkid;
00164 setState( SetUp );
00165 }
00166
00167
00168 ASCString TrainUnitCommand :: getCommandString() const
00169 {
00170 ASCString c;
00171 c.format("trainUnit ( map, %d, %d )", getContainerID(), unitID );
00172 return c;
00173
00174 }
00175
00176 GameActionID TrainUnitCommand::getID() const
00177 {
00178 return ActionRegistry::TrainUnitCommand;
00179 }
00180
00181 ASCString TrainUnitCommand::getDescription() const
00182 {
00183 ASCString s = "Train ";
00184
00185 if ( getMap()->getUnit( unitID ))
00186 s += getMap()->getUnit( unitID )->getName();
00187 else
00188 s += "unit id " + ASCString::toString(unitID);
00189
00190 return s;
00191 }
00192
00193 namespace
00194 {
00195 const bool r1 = registerAction<TrainUnitCommand> ( ActionRegistry::TrainUnitCommand );
00196 }
00197