Advanced Strategic Command
destructcontainer.cpp
Go to the documentation of this file.
1 /*
2  This file is part of Advanced Strategic Command; http://www.asc-hq.de
3  Copyright (C) 1994-2010 Martin Bickel and Marc Schellenberger
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; see the file COPYING. If not, write to the
17  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  Boston, MA 02111-1307 USA
19 */
20 
21 
22 #include "destructcontainer.h"
23 #include "spawnobject.h"
24 #include "action-registry.h"
25 
26 #include "../vehicle.h"
27 #include "../gamemap.h"
28 #include "../viewcalculation.h"
29 
30 DestructContainer::DestructContainer( ContainerBase* container, bool suppressWreckage )
31  : ContainerAction( container ), fieldRegistration( NONE ), unitBuffer(NULL), hostingCarrier(0), cargoSlot(-1), hadViewOnMap(true)
32 {
33  building = container->isBuilding();
34  this->suppressWreckage = suppressWreckage;
35 }
36 
37 
39 {
40  return "Destruct container"; // with ID " + ASCString::toString(unitID);
41 }
42 
43 
44 static const int destructContainerStreamVersion = 5;
45 
47 {
48  int version = stream.readInt();
49  if ( version < 1 || version > destructContainerStreamVersion )
50  throw tinvalidversion ( "DestructUnit", destructContainerStreamVersion, version );
51 
52  ContainerAction::readData( stream );
53  building = stream.readInt();
54 
55  if ( stream.readInt() ) {
56  unitBuffer = new MemoryStreamStorage();
57  unitBuffer->readfromstream( &stream );
58  } else
59  unitBuffer = NULL;
60 
61  if ( version >= 2 )
62  fieldRegistration = (FieldRegistration) stream.readInt();
63 
64  if ( version >= 3 ) {
65  hostingCarrier = stream.readInt();
66  cargoSlot = stream.readInt();
67  }
68 
69  if ( version >= 4 )
70  suppressWreckage = stream.readInt();
71  else
72  suppressWreckage = false;
73 
74  if ( version >= 5 )
75  hadViewOnMap = stream.readInt();
76  else
77  hadViewOnMap = true;
78 };
79 
80 
81 void DestructContainer::writeData ( tnstream& stream ) const
82 {
84 
86  stream.writeInt( building );
87  if ( unitBuffer ) {
88  stream.writeInt( 1 );
89  unitBuffer->writetostream( &stream );
90  } else
91  stream.writeInt( 0 );
92 
93  stream.writeInt( (int)fieldRegistration );
94  stream.writeInt( hostingCarrier );
95  stream.writeInt( cargoSlot );
96  stream.writeInt( suppressWreckage );
97  stream.writeInt( hadViewOnMap );
98 };
99 
100 
102 {
104 }
105 
107 {
108  ContainerBase* container = getContainer();
109 
110  unitBuffer = new MemoryStreamStorage();
111  MemoryStream memstream( unitBuffer, tnstream::writing );
112  container->write( memstream );
113 
114  Vehicle* veh = dynamic_cast<Vehicle*>(container);
115  if ( veh ) {
116  MapField* fld = getMap()->getField(veh->getPosition());
117 
118  if ( fld->vehicle == veh )
119  fieldRegistration = FIRST;
120  else if ( fld->secondvehicle == veh )
121  fieldRegistration = SECOND;
122  else if ( veh->getCarrier() ) {
123  fieldRegistration = CARRIER;
124  hostingCarrier = veh->getCarrier()->getIdentification();
125  const ContainerBase::Cargo& cargo = veh->getCarrier()->getCargo();
126  ContainerBase::Cargo::const_iterator pos = find( cargo.begin(), cargo.end(), veh );
127  if ( pos == cargo.end() )
128  throw ActionResult( 22200, veh->getCarrier() );
129  cargoSlot = pos - cargo.begin();
130  }
131 
132  if ( !veh->typ->wreckageObject.empty() && getMap()->state != GameMap::Destruction && !suppressWreckage ) {
133  if ( fieldRegistration == FIRST || fieldRegistration == SECOND ) {
134  for ( vector<int>::const_iterator i = veh->typ->wreckageObject.begin(); i != veh->typ->wreckageObject.end(); ++i ) {
135  ObjectType* obj = getMap()->getobjecttype_byid( *i );
136  if ( obj ) {
137  GameAction* o = new SpawnObject( getMap(), veh->getPosition(), *i, veh->direction );
138  o->execute( context );
139  }
140  }
141  }
142  }
143  }
144 
145  Building* bld = dynamic_cast<Building*>(container);
146 
147  if ( bld && !suppressWreckage ) {
149  for (int i = 0; i < BuildingType::xdimension; i++)
150  for (int j = 0; j < BuildingType::ydimension; j++)
151  if ( bld->typ->fieldExists ( BuildingType::LocalCoordinate(i,j) ) ) {
152  MapField* fld = bld->getField( BuildingType::LocalCoordinate(i,j) );
153  if ( fld ) {
154  typedef BuildingType::DestructionObjects::const_iterator J;
155  pair<J,J> b = bld->typ->destructionObjects.equal_range(BuildingType::LocalCoordinate(i,j));
156  for ( J o = b.first; o != b.second; ++o)
157  (new SpawnObject( getMap(), bld->getFieldCoordinates(BuildingType::LocalCoordinate(i,j)), o->second ))->execute( context );
158  }
159  }
160  }
161 
162  hadViewOnMap = false;
163  if( fieldRegistration != CARRIER ) {
164  if ( veh && veh->isViewing() ) {
165  veh->removeview();
166  hadViewOnMap = true;
167  } else if ( bld && bld->isViewing() ) {
168  bld->removeview();
169  hadViewOnMap = true;
170  }
171  }
172 
173  MapCoordinate pos = container->getPosition();
174  int viewrange = container->baseType->view;
175 
176  delete container;
177 
178  evaluateviewcalculation( getMap(), pos, viewrange, 0, false, &context );
179 
180 
181  return ActionResult(0);
182 }
183 
184 
186 {
187  MemoryStream memstream( unitBuffer, tnstream::reading );
188  if ( building ) {
189  Building* bld = Building::newFromStream( getMap(), memstream );
190  bld->chainbuildingtofield( bld->getEntry() );
191  if ( bld->getOwner() < bld->getMap()->getPlayerCount() && hadViewOnMap )
192  bld->addview();
193  } else {
194  Vehicle* veh = Vehicle::newFromStream( getMap(), memstream );
195 
196  if ( fieldRegistration == FIRST )
197  getMap()->getField( veh->getPosition() )->vehicle = veh;
198  else if ( fieldRegistration == CARRIER ) {
199  ContainerBase* carrier = getMap()->getContainer( hostingCarrier );
200  carrier->addToCargo( veh, cargoSlot );
201  }
202 
203  /*
204  SECOND is not a permanent registration, so we don't redo it
205  if ( fieldRegistration == SECOND )
206  getMap()->getField( veh->getPosition() )->vehicle = veh;
207  */
208 
209  if ( fieldRegistration != CARRIER && hadViewOnMap )
210  veh->addview();
211  }
212 
213  return ActionResult(0);
214 }
215 
217 {
218  delete unitBuffer;
219 }
220 
221 
222 namespace {
223  const bool r1 = registerAction<DestructContainer> ( ActionRegistry::DestructContainer );
224 }
void writeData(tnstream &stream) const
An in-memory storage of streamed data.
Definition: basestrm.h:172
virtual void writeInt(int i)
Writes a 32 bit signed Integer. In the stream little-endian byte order is used and a translation is p...
Definition: basestrm.cpp:363
virtual void writeData(tnstream &stream) const
const BuildingType * typ
Definition: buildings.h:48
int GameActionID
Definition: action.h:35
Vehicle * vehicle
Definition: mapfield.h:89
virtual void readData(tnstream &stream)
bool isViewing() const
returns true if the units view is currently added to the maps global visibility.
Definition: vehicle.h:342
virtual void write(tnstream &stream, bool includeLoadedUnits=true) const =0
virtual int readInt(void)
Reads a 32 bit signed Integer. In the stream little-endian byte order is used and a translation is pe...
Definition: basestrm.cpp:284
MapCoordinate getFieldCoordinates(const BuildingType::LocalCoordinate &localCoordinates) const
returns the absolute map coordinate of the given part of the building
Definition: buildings.cpp:417
int chainbuildingtofield(const MapCoordinate &entryPos, bool setupImages=true)
registers the building at the given position on the map
Definition: buildings.cpp:268
virtual GameActionID getID() const
int getOwner() const
returns the number of the player this vehicle/building belongs to
ContainerBase * getContainer(int nwid)
Definition: gamemap.cpp:1231
A local coordinate referencing a single field that a building covers.
Definition: buildingtype.h:57
MapCoordinate3D getEntry() const
returns the position of the buildings entry
Definition: buildings.cpp:410
void removeview()
Removes the view and jamming of the building from the player's global radar field.
Definition: buildings.cpp:371
virtual int getIdentification() const =0
virtual bool isBuilding() const =0
MapCoordinate3D getPosition() const
returns the units position
Definition: vehicle.cpp:1552
GameMap * getMap()
Definition: action.h:92
The interface for all kinds of IO stream.
a single field of the map
Definition: mapfield.h:26
virtual ActionResult undoAction(const Context &context)
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
void writetostream(tnstream *stream)
persist the contents in another stream
Definition: basestrm.cpp:2303
int view
the visibility range
static const int destructContainerStreamVersion
bool fieldExists(const LocalCoordinate &localCoordinate) const
returns whether this building covers the given field
Definition: buildingtype.h:108
ActionResult execute(const Context &context)
Definition: action.cpp:41
An object that can be placed on fields. Roads, pipelines and ditches are examples of objects...
Definition: objecttype.h:30
Coordinate on the twodimensional map.
Definition: typen.h:202
MapField * getField(const BuildingType::LocalCoordinate &localCoordinates) const
returns the pointer to the field which the given part of the building is standing on ...
Definition: buildings.cpp:399
int unchainbuildingfromfield(void)
unregister the building from the map position
Definition: buildings.cpp:332
Reads data from or writes data to a MemoryStreamStorage This allows a completely volatile storage of ...
Definition: basestrm.h:204
int evaluateviewcalculation(GameMap *gamemap, int player_fieldcount_mask, bool disableShareView, const Context *context)
evaluates the view on the whole map.
void removeview()
removes the units view to the map.
Definition: vehicle.cpp:1006
static Vehicle * newFromStream(GameMap *gamemap, tnstream &stream, int forceNetworkID=-1)
generates a new unit, loads its parameters from the stream (where they have been previously written w...
Definition: vehicle.cpp:1728
static const int xdimension
Definition: buildingtype.h:39
static const int ydimension
Definition: buildingtype.h:40
ContainerBase * getCarrier() const
if this is a unit and it is inside a building or transport, returns the transport. NULL otherwise.
void addToCargo(Vehicle *veh, int position=-1)
adds the unit to the cargo
const VehicleType * typ
Definition: vehicle.h:83
ContainerBase * getContainer(bool dontThrow=false)
Uint8 direction
the direction in which the unit is facing
Definition: vehicle.h:121
void readfromstream(tnstream *stream)
read persisted contents from another stream
Definition: basestrm.cpp:2316
Vehicle * secondvehicle
two units and the same field are only allowed temporary during movement
Definition: mapfield.h:92
const ContainerBaseType * baseType
the type descriping all non-instance specific properties of the container
Definition: containerbase.h:80
virtual ActionResult runAction(const Context &context)
DestructionObjects destructionObjects
when the building is destroyed, it can leave rubble objects behind. If set to 0 no objects are being ...
Definition: buildingtype.h:71
GameMap * getMap() const
enum GameMap::State state
The parent class of Vehicle and Building; The name Container originates from Battle Isle...
Definition: containerbase.h:40
An actual building on the map, which references a BuildingType Buildings have an owner,.
Definition: buildings.h:38
vector< Vehicle * > Cargo
A GameAction is an modification of something on a map.
Definition: action.h:45
ASCString getDescription() const
static Building * newFromStream(GameMap *gamemap, tnstream &stream, bool chainToField=true)
Definition: buildings.cpp:523
ObjectType * getobjecttype_byid(int id)
Definition: gamemap.cpp:1783
vector< int > wreckageObject
if the unit is destroyed, it can leave an wreckage object behind ( < 0 to disable ) ...
Definition: vehicletype.h:262
bool isViewing() const
returns true if the buildings' view is currently added to the maps global visibility.
Definition: buildings.h:129
const Cargo & getCargo() const
int getPlayerCount() const
Definition: gamemap.h:255
void readData(tnstream &stream)
void addview()
adds the units view to the map.
Definition: vehicle.cpp:990
void addview()
Adds the view and jamming of the building to the player's global radar field.
Definition: buildings.cpp:353
MapField * getField(int x, int y)
Definition: gamemap.h:465
virtual MapCoordinate3D getPosition() const =0