00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "spawnunit.h"
00023 #include "viewregistration.h"
00024 #include "unitfieldregistration.h"
00025 #include "action-registry.h"
00026
00027 #include "../vehicle.h"
00028 #include "../gamemap.h"
00029 #include "../viewcalculation.h"
00030
00031 SpawnUnit::SpawnUnit( GameMap* gamemap, const MapCoordinate3D& position, int vehicleTypeID, int owner )
00032 : GameAction( gamemap ), pos(position), networkid(-1), carrierID(0), carrier( false ), mapNetworkIdCounterBefore(0), mapNetworkIdCounterAfter(0)
00033 {
00034 this->vehicleTypeID = vehicleTypeID;
00035 this->owner = owner;
00036
00037 }
00038
00039 SpawnUnit::SpawnUnit( GameMap* gamemap, const ContainerBase* carrier, int vehicleTypeID )
00040 : GameAction( gamemap ), pos( carrier->getPosition() ), networkid(-1), carrierID( carrier->getIdentification() ), carrier(true), mapNetworkIdCounterBefore(0), mapNetworkIdCounterAfter(0)
00041 {
00042 this->vehicleTypeID = vehicleTypeID;
00043 this->owner = carrier->getOwner();
00044 }
00045
00046
00047 ContainerBase* SpawnUnit::getCarrier( bool dontThrow )
00048 {
00049 ContainerBase* veh = getMap()->getContainer( carrierID );
00050 if ( !veh && !dontThrow )
00051 throw ActionResult(21001, "ID is " + ASCString::toString(carrierID) );
00052 else
00053 return veh;
00054 }
00055
00056
00057 ASCString SpawnUnit::getDescription() const
00058 {
00059 const VehicleType* veh = getMap()->getvehicletype_byid( vehicleTypeID );
00060 ASCString res ;
00061 if ( veh )
00062 res = "Spawn Unit of type " + veh->getName();
00063 else
00064 res = "Spawn Object " ;
00065 res += " at " + pos.toString();
00066 return res;
00067 }
00068
00069
00070 static const int spawnUnitStreamVersion = 2;
00071
00072 void SpawnUnit::readData ( tnstream& stream )
00073 {
00074 int version = stream.readInt();
00075 if ( version < 1 || version > spawnUnitStreamVersion )
00076 throw tinvalidversion ( "SpawnUnit", spawnUnitStreamVersion, version );
00077
00078 vehicleTypeID = stream.readInt();
00079 pos.read( stream );
00080 owner = stream.readInt();
00081 networkid = stream.readInt();
00082 carrierID = stream.readInt();
00083 carrier = stream.readInt();
00084
00085 if ( version >= 2 ) {
00086 mapNetworkIdCounterAfter = stream.readInt();
00087 mapNetworkIdCounterBefore = stream.readInt();
00088 }
00089 };
00090
00091
00092 void SpawnUnit::writeData ( tnstream& stream ) const
00093 {
00094 stream.writeInt( spawnUnitStreamVersion );
00095 stream.writeInt( vehicleTypeID );
00096 pos.write( stream );
00097 stream.writeInt( owner );
00098 stream.writeInt( networkid );
00099 stream.writeInt( carrierID );
00100 stream.writeInt( carrier );
00101 stream.writeInt( mapNetworkIdCounterAfter );
00102 stream.writeInt( mapNetworkIdCounterBefore );
00103 };
00104
00105
00106 GameActionID SpawnUnit::getID() const
00107 {
00108 return ActionRegistry::SpawnUnit;
00109 }
00110
00111 ActionResult SpawnUnit::runAction( const Context& context )
00112 {
00113 MapField* fld = getMap()->getField(pos);
00114 if ( !fld )
00115 return ActionResult( 21002, pos );
00116
00117 const VehicleType* vehicleType = getMap()->getvehicletype_byid( vehicleTypeID );
00118 if ( !vehicleType )
00119 return ActionResult( 21801, "Vehicle id is " + ASCString::toString(vehicleTypeID));
00120
00121 mapNetworkIdCounterBefore = getMap()->idManager.unitnetworkid;
00122
00123 Vehicle* v = new Vehicle( vehicleType, getMap(), owner );
00124 networkid= v->networkid;
00125
00126 mapNetworkIdCounterAfter = getMap()->idManager.unitnetworkid;
00127
00128 v->setMovement ( 0 );
00129
00130
00131 if ( !carrier ) {
00132 v->xpos = pos.x;
00133 v->ypos = pos.y;
00134 v->height = pos.getBitmappedHeight();
00135
00136 ActionResult res = (new UnitFieldRegistration(v, pos, UnitFieldRegistration::RegisterOnField ))->execute( context );
00137 if ( res.successful() )
00138 res = (new ViewRegistration( v, ViewRegistration::AddView ))->execute( context );
00139
00140 evaluateviewcalculation(getMap(), pos, vehicleType->view, 0, false, &context);
00141 return res;
00142 } else {
00143 ContainerBase* hostingCarrier = getMap()->getContainer( carrierID );
00144 if ( !hostingCarrier )
00145 return ActionResult( 21303 );
00146
00147 ActionResult res = (new UnitFieldRegistration(v, pos, UnitFieldRegistration::RegisterInCarrier, hostingCarrier ))->execute( context );
00148 return res;
00149 }
00150
00151 return ActionResult(0);
00152 }
00153
00154 Vehicle* SpawnUnit::getUnit()
00155 {
00156 return getMap()->getUnit( networkid );
00157 }
00158
00159
00160 ActionResult SpawnUnit::undoAction( const Context& context )
00161 {
00162 MapField* fld = getMap()->getField(pos);
00163 if ( !fld )
00164 return ActionResult( 21002, pos );
00165
00166 if ( getMap()->idManager.unitnetworkid != mapNetworkIdCounterAfter )
00167 return ActionResult( 21805 );
00168
00169 getMap()->idManager.unitnetworkid = mapNetworkIdCounterBefore;
00170
00171 const VehicleType* vehicleType = getMap()->getvehicletype_byid( vehicleTypeID );
00172 if ( !vehicleType )
00173 return ActionResult( 21801, "Vehicle id is " + ASCString::toString(vehicleTypeID));
00174
00175 Vehicle* veh = getUnit();
00176 if ( !veh )
00177 return ActionResult( 21802 );
00178
00179 if ( veh->typ->id != vehicleTypeID )
00180 return ActionResult( 21803 );
00181
00182 delete veh;
00183 return ActionResult(0);
00184 }
00185
00186 ActionResult SpawnUnit::verify()
00187 {
00188 if ( getMap()->idManager.unitnetworkid != mapNetworkIdCounterAfter )
00189 return ActionResult( 21805 );
00190
00191 return ActionResult(0);
00192 }
00193
00194
00195 namespace {
00196 const bool r1 = registerAction<SpawnUnit> ( ActionRegistry::SpawnUnit );
00197 }
00198