Advanced Strategic Command
constructbuildingcommand.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 
23 
24 #include "../vehicle.h"
25 #include "../mapfield.h"
26 #include "../gamemap.h"
27 #include "../viewcalculation.h"
28 #include "../spfst.h"
29 #include "../mapdisplayinterface.h"
30 #include "action-registry.h"
31 #include "../itemrepository.h"
32 #include "../containercontrols.h"
33 #include "changeunitproperty.h"
34 #include "spawnbuilding.h"
35 #include "changeunitmovement.h"
36 #include "consumeresource.h"
37 
38 
39 
40 
42 {
43  if ( !eht )
44  return false;
45 
47  return false;
48 
49  if ( eht->attacked == false && !eht->hasMoved() )
50  if ( eht->getOwner() == eht->getMap()->actplayer )
52  return true;
53 
54  return false;
55 }
56 
57 
58 ConstructBuildingCommand :: ConstructBuildingCommand ( Vehicle* container )
59  : UnitCommand ( container ), buildingTypeID(-1)
60 {
61 
62 }
63 
64 
65 Resources ConstructBuildingCommand::getProductionCost( const BuildingType* bld ) const
66 {
69 
70  if ( !mf )
71  mf = 100;
72  if ( !ff )
73  ff = 100;
74 
75  return Resources( 0, bld->productionCost.material * mf / 100, bld->productionCost.fuel * ff / 100 );
76 }
77 
78 
80 {
81  int l = 0;
82 
83  if ( !type->techDependency.available ( getMap()->getPlayer(getUnit()).research))
84  l |= Lack::Research;
85 
86 
87  int hd = getheightdelta ( getFirstBit ( getUnit()->height ), getFirstBit ( type->height ));
88 
89  if ( hd != 0 )
90  l |= Lack::Level;
91 
92 
93  Resources cost = getProductionCost( type );
94  Resources avail = getUnit()->getResource( cost );
95  for ( int r = 0; r < Resources::count ; ++r )
96  if ( cost.resource(r) > avail.resource(r) )
97  l |= 1 << r;
98 
99  return Lack(l);
100 }
101 
103 {
104  Producables entries;
105  if ( !avail( getUnit() ) )
106  return entries;
107 
108  for ( int i = 0; i < buildingTypeRepository.getNum(); i++) {
109  const BuildingType* bld = buildingTypeRepository.getObject_byPos( i );
110 
111  for ( int j = 0; j < getUnit()->typ->buildingsBuildable.size(); j++ )
112  if ( getUnit()->typ->buildingsBuildable[j].from <= bld->id &&
113  getUnit()->typ->buildingsBuildable[j].to >= bld->id ) {
114 
115  entries.push_back ( ProductionEntry ( bld, getProductionCost( bld ), buildingProductionPrerequisites( bld ) ));
116 
117  }
118  }
119  return entries;
120 }
121 
122 void ConstructBuildingCommand :: fieldChecker( const MapCoordinate& pos )
123 {
124  MapField* fld = getMap()->getField(pos);
125  if ( !fld )
126  return;
127 
128  if ( fld->vehicle || fld->building )
129  return;
130 }
131 
133 {
134 
135  MapField* entryfield = getMap()->getField(entry);
136  if ( !entryfield )
137  return false;
138 
139  BuildingType* bld = buildingTypeRepository.getObject_byID( buildingTypeID );
140 
141  if ( bld ) {
142  bool b = true;
143  for ( int y1 = 0; y1 <= 5; y1++)
144  for ( int x1 = 0; x1 <= 3; x1++)
145  if ( bld->fieldExists ( BuildingType::LocalCoordinate(x1, y1)) ) {
146  MapField* fld = getMap()->getField ( bld->getFieldCoordinate( entry, BuildingType::LocalCoordinate(x1,y1) ));
147  if ( fld ) {
148  if ( fld->vehicle != NULL ) // && fld->vehicle->height <= chfahrend )
149  b = false;
150 
151  if ( bld->height <= chfahrend )
152  if ( bld->terrainaccess.accessible ( fld->bdt ) <= 0 )
153  b = false;
154 
155  if (fld->building != NULL) {
156  if (fld->building->typ != bld)
157  b = false;
158  if (fld->building->getCompletion() == fld->building->typ->construction_steps - 1)
159  b = false;
160  if ( (entryfield->bdt & getTerrainBitType(cbbuildingentry) ).none() )
161  b = false;
162  }
163  if (entryfield->building != fld->building)
164  b = false;
165  } else
166  b = false;
167  }
168  return b;
169  }
170 
171  return false;
172 }
173 
174 
175 vector<MapCoordinate> ConstructBuildingCommand::getFields()
176 {
177  vector<MapCoordinate> fields;
178  Vehicle* veh = getUnit();
179  BuildingType* bld = buildingTypeRepository.getObject_byID( buildingTypeID );
180  if ( bld ) {
181  for ( int d = 0; d < 6; ++d ) {
183  if ( buildingFits( pos ))
184  fields.push_back( pos );
185  }
186  }
187 
188  return fields;
189 }
190 
192 {
193  vector<MapCoordinate> fields = getFields();
194  return find( fields.begin(), fields.end(), pos ) != fields.end() ;
195 }
196 
197 
199 {
200  this->target = pos;
201  MapField* fld = getMap()->getField(target);
202 
203  if ( !fld )
204  throw ActionResult(21002);
205 
206  if ( buildingTypeID > 0 )
207  setState( SetUp );
208 
209 }
210 
211 
212 
214 {
215  if ( getState() != SetUp )
216  return ActionResult(22000);
217 
218  if ( !avail( getUnit() ))
219  return ActionResult(22506);
220 
221  BuildingType* bld = buildingTypeRepository.getObject_byID( buildingTypeID );
222 
223  if ( !bld )
224  return ActionResult( 22504 );
225 
227  if ( !l.ok() )
228  return ActionResult(22505);
229 
230  if ( !isFieldUsable( target ))
231  return ActionResult(22503);
232 
233 
234 
235  auto_ptr<SpawnBuilding> sb ( new SpawnBuilding( getMap(), target, buildingTypeID, getUnit()->getOwner() ));
236  ActionResult res = sb->execute( context );
237  if ( res.successful() )
238  sb.release();
239  else
240  return res;
241 
242  Resources cost = getProductionCost( bld );
243 
244  auto_ptr<ConsumeResource> cr ( new ConsumeResource( getUnit(), cost ));
245  res = cr->execute( context );
246  if ( res.successful() )
247  cr.release();
248  else
249  return res;
250 
251  auto_ptr<ChangeUnitMovement> cum ( new ChangeUnitMovement( getUnit(), 0 ));
252  res = cum->execute( context );
253  if ( res.successful() )
254  cum.release();
255  else
256  return res;
257 
258  auto_ptr<ChangeUnitProperty> cup ( new ChangeUnitProperty( getUnit(), ChangeUnitProperty::AttackedFlag, 1 ));
259  res = cup->execute( context );
260  if ( res.successful() )
261  cup.release();
262  else
263  return res;
264 
265  if ( context.display )
266  context.display->repaintDisplay();
267 
268  return ActionResult(0);
269 }
270 
272 {
273  return NULL;
274 }
275 
276 
277 static const int ConstructBuildingCommandVersion = 1;
278 
280 {
281  UnitCommand::readData( stream );
282  int version = stream.readInt();
283  if ( version > ConstructBuildingCommandVersion )
284  throw tinvalidversion ( "ConstructBuildingCommand", ConstructBuildingCommandVersion, version );
285  target.read( stream );
286  buildingTypeID = stream.readInt();
287 }
288 
290 {
291  UnitCommand::writeData( stream );
292  stream.writeInt( ConstructBuildingCommandVersion );
293  target.write( stream );
294  stream.writeInt( buildingTypeID );
295 }
296 
298 {
299  buildingTypeID = type->id;
300 }
301 
302 
304 {
305  ASCString c;
306  c.format("constructBuilding ( map, %d, asc.MapCoordinate(%d, %d), %d )", getUnitID(), target.x, target.y, buildingTypeID );
307  return c;
308 }
309 
311 {
313 }
314 
316 {
317  ASCString s = "Construct ";
318 
319  const BuildingType* bt = getMap()->getbuildingtype_byid( buildingTypeID );
320  if ( bt )
321  s += bt->name;
322  else
323  s += "building";
324 
325  if ( getUnit() ) {
326  s += " by " + getUnit()->getName();
327  }
328  s += " at " + target.toString();
329  return s;
330 }
331 
332 namespace
333 {
334 const bool r1 = registerAction<ConstructBuildingCommand> ( ActionRegistry::ConstructBuildingCommand );
335 }
336 
int fuel
Definition: typen.h:101
vector< MapCoordinate > getFields()
void writeData(tnstream &stream) const
Definition: unitcommand.cpp:67
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
MapCoordinate getFieldCoordinate(const MapCoordinate &entryOnMap, const LocalCoordinate &localCoordinate) const
returns the Mapcoordinate of a buildings field
const BuildingType * typ
Definition: buildings.h:48
int GameActionID
Definition: action.h:35
int getResource(int amount, int resourcetype, bool queryonly, int scope=1, int player=-1)
Definition: vehicle.cpp:328
int getUnitID() const
Definition: unitcommand.h:37
Vehicle * vehicle
Definition: mapfield.h:89
int getheightdelta(const ContainerBase *c1, const ContainerBase *c2)
calculate the height difference between two levels of height.
Definition: spfst.cpp:393
TechAdapterDependency techDependency
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
static bool avail(const Vehicle *eht)
int getFirstBit(int zahl)
Count the number of zero bits on the LSB side of "zahl".
Definition: misc.cpp:45
bool hasFunction(ContainerFunctions function) const
vector< IntRange > buildingsBuildable
the ids of buildings this unit can construct
Definition: vehicletype.h:227
int getOwner() const
returns the number of the player this vehicle/building belongs to
A local coordinate referencing a single field that a building covers.
Definition: buildingtype.h:57
bool buildingFits(const MapCoordinate &entry)
State getState() const
Definition: command.h:125
void read(tnstream &stream)
Definition: typen.h:213
MapCoordinate3D getPosition() const
returns the units position
Definition: vehicle.cpp:1552
void setBuildingType(const BuildingType *type)
GameMap * getMap()
Definition: action.h:92
ItemRepositoryLoader< BuildingType > buildingTypeRepository("buildingtype")
ASCString toString(bool coordinates=false) const
Definition: typen.cpp:304
The interface for all kinds of IO stream.
a single field of the map
Definition: mapfield.h:26
ASCString & format(const charT *pFormat,...)
Definition: ascstring.cpp:78
int getCompletion() const
returns the completion of the building.
Definition: buildings.h:164
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
ActionResult go(const Context &context)
bool fieldExists(const LocalCoordinate &localCoordinate) const
returns whether this building covers the given field
Definition: buildingtype.h:108
The class describing properties that are common to all buildings of a certain kind.
Definition: buildingtype.h:35
vector< ConstructBuildingCommand::ProductionEntry > Producables
TerrainBits getTerrainBitType(TerrainBitTypes tbt)
void write(tnstream &stream) const
Definition: typen.h:212
Coordinate on the twodimensional map.
Definition: typen.h:202
ASCString getName() const
returns the units name or, if it does not exist, the unit type's name or description ...
Definition: vehicle.cpp:1569
int accessible(const TerrainBits &bts) const
checks whether a field with the given terrainbits is accessible.
int material
Definition: typen.h:100
void setState(State state)
Definition: command.cpp:44
signed char actplayer
the player who is currently making his moves (may be human or AI)
Definition: gamemap.h:232
bool isFieldUsable(const MapCoordinate &pos)
BuildingType * getbuildingtype_byid(int id)
Definition: gamemap.cpp:1805
TerrainAccess terrainaccess
the terrain properties which are necessary for the building to be constructed there ...
Definition: buildingtype.h:86
bool successful() const
#define chfahrend
Definition: typen.h:413
MapDisplayInterface * display
Definition: context.h:39
TerrainBits bdt
the terraintype properties. They determine which units can move over the field. This variable is reca...
Definition: mapfield.h:161
Lack buildingProductionPrerequisites(const BuildingType *type) const
int getgameparameter(GameParameter num) const
Definition: gamemap.cpp:1047
int height
the levels of height which this unit can enter
bool hasMoved(void) const
did the unit move this turn
Definition: vehicle.cpp:552
int & resource(int type)
Definition: typen.h:105
int construction_steps
the number of stages that are required to construct a building using a construction unit...
Definition: buildingtype.h:89
const VehicleType * typ
Definition: vehicle.h:83
bool attacked
did the unit already attack this turn
Definition: vehicle.h:109
Building * building
Definition: mapfield.h:102
void readData(tnstream &stream)
Definition: unitcommand.cpp:52
static const int count
Definition: typen.h:103
GameMap * getMap() const
An actual building on the map, which references a BuildingType Buildings have an owner,.
Definition: buildings.h:38
Resources are basically the currency of ASC.
Definition: typen.h:97
bool available(const Research &research) const
Definition: research.cpp:412
void setTargetPosition(const MapCoordinate &pos)
static const int ConstructBuildingCommandVersion
virtual void repaintDisplay()=0
ASCString name
a short name, for example B-52
const Vehicle * getUnit() const
Definition: unitcommand.cpp:26
MapCoordinate3D getNeighbouringFieldCoordinate(const MapCoordinate3D &pos, int direc)
returns the coordinate of the field that is adjecent to the given field in the direction of direc ...
MapField * getField(int x, int y)
Definition: gamemap.h:465
void writeData(tnstream &stream) const