Advanced Strategic Command
controls.cpp
Go to the documentation of this file.
1 
7 /*
8  This file is part of Advanced Strategic Command; http://www.asc-hq.de
9  Copyright (C) 1994-2010 Martin Bickel and Marc Schellenberger
10 
11  This program is free software; you can redistribute it and/or modify
12  it under the terms of the GNU General Public License as published by
13  the Free Software Foundation; either version 2 of the License, or
14  (at your option) any later version.
15 
16  This program is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  GNU General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with this program; see the file COPYING. If not, write to the
23  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
24  Boston, MA 02111-1307 USA
25 */
26 
27 #include <stdio.h>
28 #include <cstring>
29 #include <math.h>
30 #include <stdarg.h>
31 #include <ctime>
32 
33 #include "buildingtype.h"
34 #include "vehicletype.h"
35 #include "typen.h"
36 
37 #include "spfst.h"
38 #include "loaders.h"
39 #include "controls.h"
40 #include "attack.h"
41 #include "gameoptions.h"
42 #include "errors.h"
43 #include "viewcalculation.h"
44 #include "replay.h"
45 #include "resourcenet.h"
46 #include "stack.h"
47 
48 
49 bool checkUnitsForCrash( Player& player, ASCString& text )
50 {
51  bool endangeredUnits = false;
52 
53  for ( Player::VehicleList::const_iterator i = player.vehicleList.begin(); i != player.vehicleList.end(); ++i ) {
54  int endurance = UnitHooveringLogic::getEndurance( *i );
55  if ( endurance>= 0 && endurance <= CGameOptions::Instance()->aircraftCrashWarningTime ) {
56  endangeredUnits = true;
57  text += (*i)->getName() + " " + (*i)->getPosition().toString() + "\n";
58  }
59 
60  }
61  return endangeredUnits;
62 }
63 
64 pair<int,int> calcMoveMalus( const MapCoordinate3D& start,
65  const MapCoordinate3D& dest,
66  const Vehicle* vehicle,
67  WindMovement* wm,
68  bool* inhibitAttack,
69  bool container2container )
70 {
71  int direc = getdirection ( start.x, start.y, dest.x, dest.y );
72 
73 
74  int fuelcost = 10;
75  int movecost;
76  bool checkHemming = true;
77  bool checkWind = wm != NULL;
78  int dist = 1;
79 
80  if ( start.getNumericalHeight() >= 0 && dest.getNumericalHeight() >= 0 ) {
81 
82  // changing height
83  if ( (start.getNumericalHeight() != dest.getNumericalHeight()) && !container2container ) {
84  const VehicleType::HeightChangeMethod* hcm = vehicle->getHeightChange( start.getNumericalHeight() < dest.getNumericalHeight() ? 1 : -1, start.getBitmappedHeight());
85  if ( !hcm || hcm->dist != beeline ( start, dest )/maxmalq )
86  fatalError("Calcmovemalus called with invalid height change distance");
87  dist = hcm->dist;
88  movecost = hcm->moveCost;
89  fuelcost = max(hcm->dist*10,10);
90  if ( inhibitAttack && !hcm->canAttack )
91  *inhibitAttack = !hcm->canAttack;
92  checkHemming = false;
93  if ( start.getNumericalHeight() < 4 || dest.getNumericalHeight() < 4 )
94  checkWind = false;
95  } else
96  // flying
97  if (start.getNumericalHeight() >= 4 )
98  movecost = maxmalq;
99  else
100  if ( start.getNumericalHeight() <= 1 ) {
101  movecost = submarineMovement;
102  checkWind = false;
103  } else {
104  // not flying
105  MapField* fld = vehicle->getMap()->getField( dest.x, dest.y );
106  if ( fld->building )
107  movecost = maxmalq;
108  else
109  movecost = fld->getmovemalus( vehicle );
110  checkWind = false;
111  }
112 
113  } else
114  if ( dest.getNumericalHeight() >= 0 ) {
115  // moving out of container
116  int mm;
117  const ContainerBaseType::TransportationIO* unloadSystem = vehicle->getMap()->getField( start.x, start.y )->getContainer()->vehicleUnloadSystem( vehicle->typ, dest.getBitmappedHeight() );
118  if ( unloadSystem )
119  mm = unloadSystem->movecost;
120  else
121  mm = 0;
122 
123  if ( mm > 0 )
124  movecost = mm;
125  else {
126  if ( dest.getNumericalHeight() >= 4 )
127  // flying
128  movecost = maxmalq;
129  else {
130  if ( dest.getNumericalHeight() <= 1 ) {
131  movecost = submarineMovement;
132  checkWind = false;
133  } else {
134  movecost = vehicle->getMap()->getField( dest.x, dest.y )->getmovemalus( vehicle );
135  }
136  }
137  }
138  } else {
139  // moving from one container to another
140  movecost = maxmalq;
141  checkHemming = false;
142  checkWind = false;
143  }
144 
145  static const int movemalus[6] = { 0, 3, 5, 0, 5, 3 };
146 
147  if ( checkHemming && dest.getNumericalHeight() >= 0 )
148  for (int c = 0; c < sidenum; c++) {
149  int x = dest.x + getnextdx ( c, dest.y );
150  int y = dest.y + getnextdy ( c );
151  MapField* fld = vehicle->getMap()->getField ( x, y );
152  if ( fld ) {
153  int d = (c - direc);
154 
155  if (d >= sidenum)
156  d -= sidenum;
157 
158  if (d < 0)
159  d += sidenum;
160 
161  if ( fld->vehicle ) {
162  if ( vehicle->getMap()->getPlayer(vehicle).diplomacy.isHostile( fld->vehicle->getOwner() ) )
163  if ( attackpossible28(fld->vehicle,vehicle, NULL, dest.getBitmappedHeight() ))
164  movecost += movemalus[d];
165 
166  }
167  }
168  }
169 
170  /*******************************/
171  /* Wind calculation */
172  /*******************************/
173  if ( wm && checkWind && direc >= 0 && direc <= 5 )
174  if (dest.getNumericalHeight() >= 4 && dest.getNumericalHeight() <= 6 &&
175  start.getNumericalHeight() >= 4 && start.getNumericalHeight() <= 6 &&
176  vehicle->getMap()->weather.windSpeed ) {
177  movecost -= wm->getDist( direc ) * dist;
178  fuelcost -= wm->getDist ( direc ) * dist;
179 
180  if ( movecost < 1 )
181  movecost = 1;
182 
183  if ( fuelcost <= 0 )
184  fuelcost = 0;
185  }
186  return make_pair(movecost,fuelcost);
187 }
188 
189 
190 
191 
192 
193 
195 {
196  for ( int i = 0; i < 3; i++ )
197  if ( !getMap()->isResourceGlobal(i) ) {
198  if ( netcontrol & (cnet_moveenergyout << i )) {
199  npush ( netcontrol );
200  netcontrol |= (cnet_stopenergyinput << i );
202  npop ( netcontrol );
203  } else
204  if ( netcontrol & (cnet_storeenergy << i )) {
205  npush ( netcontrol );
207  actstorage.resource(i) += getResource ( getStorageCapacity().resource(i) - actstorage.resource(i), i, false );
208  npop ( netcontrol );
209  }
210  }
211 
212 }
213 
214  /* modes: 0 = energy ohne abbuchen
215  1 = material ohne abbuchen
216  2 = fuel ohne abbuchen
217 
218  +4 mit abbuchen /
219  +8 nur Tributzahlungen kassieren /
220  +16 plus zurueckliefern < diese Bits schliessen sich gegenseitig aus
221  +32 usage zurueckliefern \
222  +64 tank zurueckliefern \
223  */
224 
225 
226 int Building :: putResource ( int need, int resourcetype, bool queryonly, int scope, int player )
227 {
228  if ( need < 0 )
229  return -getResource( -need, resourcetype, queryonly, scope, player );
230  else {
231  int placed;
232  {
233  PutResource putresource ( getMap(), scope );
234  placed = putresource.getresource ( entryPosition.x, entryPosition.y, resourcetype, need, queryonly, player >= 0 ? player : getMap()->actplayer, scope );
235  }
236  // if ( !queryonly && placed > 0 )
237  // resourceChanged();
238  return placed;
239  }
240 }
241 
242 
243 int Building :: getResource ( int need, int resourcetype, bool queryonly, int scope, int player )
244 {
245  if ( need < 0 )
246  return -putResource( -need, resourcetype, queryonly, scope, player );
247  else {
248  int got;
249  {
250  GetResource gr ( getMap(), scope );
251  got = gr.getresource ( entryPosition.x, entryPosition.y, resourcetype, need, queryonly, player >= 0 ? player : getMap()->actplayer, scope );
252  }
253  // if ( !queryonly && got > 0 )
254  // resourceChanged();
255  return got;
256 
257  }
258 }
259 
260 int Building :: getAvailableResource ( int need, int resourcetype, int scope ) const
261 {
262  int got;
263  {
264  GetResource gr ( getMap(), scope );
265  got = gr.getresource ( entryPosition.x, entryPosition.y, resourcetype, need, true, getMap()->actplayer, scope );
266  }
267  return got;
268 }
269 
The (base-) classes which are thrown as exceptions.
Player & getPlayer(PlayerID p)
Definition: gamemap.h:257
map accessing and usage routines used by ASC and the mapeditor
#define npush(a)
Definition: stack.h:53
Vehicle * vehicle
Definition: mapfield.h:89
bool isHostile(PlayerID towardsPlayer) const
Definition: player.h:80
int getresource(int x, int y, int resource, int _need, int _queryonly, int _player, int _scope)
Resources getStorageCapacity() const
returns the local storage capacity for the given resource, which depends on the resource mode of the ...
DiplomaticStateVector diplomacy
Definition: player.h:209
int getOwner() const
returns the number of the player this vehicle/building belongs to
int getNumericalHeight() const
Definition: typen.h:242
ContainerBase * getContainer()
returns a pointer to the ContainerBase of the field or NULL if there is none
Definition: mapfield.cpp:331
a single field of the map
Definition: mapfield.h:26
struct GameMap::Weather weather
int netcontrol
a bitmapped variable containing the status of the resource-net connection.
Definition: buildings.h:57
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
const VehicleType::HeightChangeMethod * getHeightChange(int dir, int height=0) const
returns the method for changing the height in the specified direction, or none if there is none...
Definition: vehicle.cpp:777
int getAvailableResource(int amount, int resourcetype, int scope=1) const
Definition: controls.cpp:260
Handling the connection of buildings by pipelines, powerlines etc.
int getDist(int dir)
int beeline(const Vehicle *a, const Vehicle *b)
returns the distance between the units a and b
pair< int, int > calcMoveMalus(const MapCoordinate3D &start, const MapCoordinate3D &dest, const Vehicle *vehicle, WindMovement *wm, bool *inhibitAttack, bool container2container)
Definition: controls.cpp:64
const int sidenum
the number of sides that a field has; is now fixed at 6;
Definition: typen.h:438
bool attackpossible28(const Vehicle *attacker, const Vehicle *target, AttackWeap *atw, int targetHeight)
Is attacker able to attack target ? Distance is assumed one field.
Definition: attack.cpp:983
static ASCString toString(int i)
converts the parameter to a String
Definition: ascstring.cpp:193
#define maxmalq
Constants that specify the layout of ASC.
Definition: typen.h:429
static int getEndurance(const Vehicle *veh)
calculates the time until the unit crashes because of lack of fuel
Definition: vehicle.cpp:1816
VehicleList vehicleList
a list of all units
Definition: player.h:135
Interface for recording and playing replays.
int putResource(int amount, int resourcetype, bool queryonly, int scope=1, int player=-1)
scope: 0 = local 1 = resource network 2 = global in all buildings 3 = map wide pool( used only intern...
Definition: controls.cpp:226
Interface for all the fighting routines of ASC.
The interface for the buildingtype class.
int getnextdx(int dir, int y)
Definition: mapalgorithms.h:77
void execnetcontrol(void)
executes the resource net operations, like filling the tanks with fuel.
Definition: controls.cpp:194
static CGameOptions * Instance()
returns the only Instance
Definition: gameoptions.cpp:38
#define npop(a)
Definition: stack.h:54
int getnextdy(int dir)
Definition: mapalgorithms.h:80
caches some calculations for the effects that wind has on the movement of units
#define cnet_stopenergyinput
Definition: typen.h:517
Resources actstorage
the current storage of Resources
Definition: buildings.h:91
const ContainerBaseType::TransportationIO * vehicleUnloadSystem(const VehicleType *vehicle, int height)
returns the unloading system
int & resource(int type)
Definition: typen.h:105
#define cnet_storeenergy
Definition: typen.h:509
int getBitmappedHeight() const
Definition: typen.h:241
procedure for loading and writing savegames, maps etc.
const VehicleType * typ
Definition: vehicle.h:83
int getResource(int amount, int resourcetype, bool queryonly, int scope=1, int player=-1)
Definition: controls.cpp:243
Coordinate on the map including height.
Definition: typen.h:238
Building * building
Definition: mapfield.h:102
#define cnet_stopenergyoutput
Definition: typen.h:521
GameMap * getMap() const
const T & max(const T &a, const T &b, const T &c)
Definition: misc.h:97
the different players in ASC. There may be 8 players (0..7) and neutral units (8) ...
Definition: player.h:99
bool checkUnitsForCrash(Player &player, ASCString &text)
Definition: controls.cpp:49
void fatalError(const ASCString &string)
int getdirection(const MapCoordinate &start, const MapCoordinate &dest)
#define cnet_moveenergyout
Definition: typen.h:513
int getmovemalus(const Vehicle *veh)
Definition: mapfield.cpp:552
Interface for a small general-purpose stack (not type safe)
const int submarineMovement
the movemalus for all submerged units
Definition: typen.h:482
MapField * getField(int x, int y)
Definition: gamemap.h:465