Advanced Strategic Command
unitcostcalculator-standard.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * *
3  * This program is free software; you can redistribute it and/or modify *
4  * it under the terms of the GNU General Public License as published by *
5  * the Free Software Foundation; either version 2 of the License, or *
6  * (at your option) any later version. *
7  * *
8  ***************************************************************************/
9 
10 /***************************************************************************
11  Preiskalkulation - description
12  -------------------
13  begin : So Aug 15 2004
14  copyright : (C) 2001 by Martin Bickel & Steffen Froelich
15  email : bickel@asc-hq.org
16 
17 Part I -description
18 Part II -beginn calculation
19 Part III -typecost
20 part IV -weaponcost
21 Part V -specialcost
22 Part VI -addition
23 Part VII -malus
24 
25  ***************************************************************************/
26 
27 
29 
30 #include "vehicletype.h"
31 
32 //Part II beginn calculation
33 
34 
36 {
37  return "standard";
38 }
39 
41 {
42  Resources res;
43  // Anfang -> Abschluss
44  res.energy = 0;
45  res.material = 0;
46  res.fuel = 0;
47  int typecoste = 0;
48  int typecostm = 0;
49  int weaponcoste = 0;
50  int weaponcostm = 0;
51  int specialcoste = 0;
52  int specialcostm = 0;
53  int maxmoverange = 0;
54  int maxweaponrange = 0;
55 
56  // Check Flugzeugtraeger
57  bool carrierCharge = false;
58  for ( int T=0; T < vehicle->entranceSystems.size(); ++T )
59  if ((( vehicle->entranceSystems[T].container_height < chtieffliegend && (vehicle->entranceSystems[T].height_abs & (chtieffliegend | chfliegend | chhochfliegend | chsatellit))) ||
60  (( vehicle->entranceSystems[T].container_height & ( chfliegend | chhochfliegend | chsatellit)) && (vehicle->entranceSystems[T].height_abs & ( chfliegend | chhochfliegend | chsatellit))))
61  && vehicle->maxLoadableUnits > 6 )
62  carrierCharge = true;
63 
64  // Check maximale Bewegungsreichweite
65  for ( int M=0; M < vehicle->movement.size(); ++M ) {
66  if ( maxmoverange < vehicle->movement[M] ) {
67  maxmoverange = vehicle->movement[M];
68  }
69  }
70  // Check maximale Waffenreichweite
71  if ( vehicle->weapons.count > 0 ) {
72  for ( int WR=0; WR < vehicle->weapons.count; ++WR ) {
73  if ( maxweaponrange < vehicle->weapons.weapon[WR].maxdistance ) {
74  maxweaponrange = vehicle->weapons.weapon[WR].maxdistance;
75  }
76  }
77  }
78 
79 // Part III typecost
80 
81  if ( vehicle->movemalustyp == MoveMalusType::trooper) {
82  typecoste += vehicle->armor*3;
83  typecostm += vehicle->armor*3;
84  } else if ( vehicle->movemalustyp == MoveMalusType::light_wheeled_vehicle ) {
85  typecoste += vehicle->armor*6;
86  typecostm += vehicle->armor*6;
88  typecoste += vehicle->armor*7;
89  typecostm += vehicle->armor*7;
91  typecoste += vehicle->armor*8;
92  typecostm += vehicle->armor*8;
93  } else if ( vehicle->movemalustyp == MoveMalusType::heavy_tracked_vehicle ) {
94  typecoste += vehicle->armor*9;
95  typecostm += vehicle->armor*9;
96  } else if ( vehicle->movemalustyp == MoveMalusType::hoovercraft) {
97  typecoste += vehicle->armor*9;
98  typecostm += vehicle->armor*9;
99  } else if ( vehicle->movemalustyp == MoveMalusType::light_ship ) {
100  typecoste += vehicle->armor*8;
101  typecostm += vehicle->armor*8;
102  } else if ( vehicle->movemalustyp == MoveMalusType::medium_ship ) {
103  typecoste += vehicle->armor*10;
104  typecostm += vehicle->armor*10;
105  } else if ( vehicle->movemalustyp == MoveMalusType::heavy_ship ) {
106  typecoste += vehicle->armor*12;
107  typecostm += vehicle->armor*12;
108  } else if ( vehicle->movemalustyp == MoveMalusType::helicopter ) {
109  typecoste += vehicle->armor*14;
110  typecostm += vehicle->armor*14;
111  } else if ( vehicle->movemalustyp == MoveMalusType::light_aircraft ) {
112  typecoste += vehicle->armor*16;
113  typecostm += vehicle->armor*16;
115  typecoste += vehicle->armor*18;
116  typecostm += vehicle->armor*18;
117 
118  } else {
119  typecoste += vehicle->armor*6;
120  typecostm += vehicle->armor*6;
121  }
122 
123  // Zuschlag fuer Eisbrecher
124  if ( vehicle->hasFunction( ContainerBaseType::IceBreaker ) ) {
125  typecoste += vehicle->armor *2;
126  typecostm += vehicle->armor *2;
127  }
128  // Zuschlag fuer U-Boote / Druckhuelle
129  if ( vehicle->height & chgetaucht ) {
131  typecoste += vehicle->armor*2;
132  typecostm += vehicle->armor*2;
133  } else {
134  if ( vehicle->movemalustyp == MoveMalusType::trooper ) {
135  typecoste += vehicle->armor*10;
136  typecostm += vehicle->armor*10;
137  } else {
138  typecoste += vehicle->armor*6;
139  typecostm += vehicle->armor*6;
140  }
141  }
142  }
143  // Zuschlag fuer orbitalfaehige Einheiten / Druckhuelle
144  if ( vehicle->height & chsatellit ) {
145  typecoste += vehicle->armor*3;
146  typecostm += vehicle->armor*2;
147  }
148  // Zuschlag fuer hochfliegende Einheiten
149  if ( vehicle->height & chhochfliegend ) {
150  typecoste += vehicle->armor*4;
151  typecostm += vehicle->armor*4;
152  }
153  // Zuschlag fuer normal fliegende Einheiten
154  if ( vehicle->height & chfliegend ) {
155  typecoste += vehicle->armor*3;
156  typecostm += vehicle->armor*3;
157  }
158  // Zuschlag fuer tief fliegende Einheiten
159  if ( vehicle->height & chtieffliegend ) {
160  typecoste += vehicle->armor*2;
161  typecostm += vehicle->armor*2;
162  }
163  // Zuschlag fuer Transportkapazitaet
164  if ( vehicle->entranceSystems.size() > 0 ) {
165  typecoste += vehicle->maxLoadableUnits*100;
166  typecostm += vehicle->maxLoadableUnits*100;
167  // Zuschlag fr Flugzeugtraeger / Start- und Landeeinrichtungen
168  if ( carrierCharge ) {
169  typecoste += vehicle->maxLoadableUnits*1000;
170  typecostm += vehicle->maxLoadableUnits*1000;
171  }
172  }
173  // Zuschlag fuer Triebwerke
174  if (maxmoverange > 60 ) {
175  typecoste += (maxmoverange-60)*10;
176  typecostm += (maxmoverange-60)*5;
177  }
178  // Zuschlag fr Flugzeugtriebwerke
179  if (maxmoverange > 110 ) {
180  typecoste += (maxmoverange-110)*10;
181  typecostm += (maxmoverange-110)*5;
182  }
183  // Zuschlag fr Hochleistungsflugzeugtriebwerke
184  if (maxmoverange > 150 ) {
185  typecoste += (maxmoverange-150)*10;
186  typecostm += (maxmoverange-150)*5;
187  }
188  // Zuschlag fr Spezialflugzeugtriebwerke
189  if (maxmoverange > 190 ) {
190  typecoste += (maxmoverange-190)*10;
191  typecostm += (maxmoverange-190)*5;
192  }
193 
194 
195 
196  // Part IV - weaponcost
197 
198  if ( vehicle->weapons.count > 0 ) {
199  for ( int W=0; W < vehicle->weapons.count; ++W ) {
200  int weaponsinglecoste = 0;
201  int weaponsinglecostm = 0;
202  if (vehicle->weapons.weapon[W].getScalarWeaponType() == cwminen) {
203  if ( vehicle->weapons.weapon[W].shootable() ) {
204  weaponsinglecoste += vehicle->weapons.weapon[W].maxstrength;
205  weaponsinglecostm += vehicle->weapons.weapon[W].maxstrength;
206  } else {
207  weaponsinglecoste += 100;
208  weaponsinglecostm += 50;
209  }
210  }
212  if ( vehicle->weapons.weapon[W].shootable() ) {
213  weaponsinglecoste += vehicle->weapons.weapon[W].maxstrength*5;
214  weaponsinglecostm += vehicle->weapons.weapon[W].maxstrength*5;
215  } else {
216  weaponsinglecoste += 100;
217  weaponsinglecostm += 50;
218  }
219  }
221  if ( vehicle->weapons.weapon[W].shootable() ) {
222  weaponsinglecoste += vehicle->weapons.weapon[W].maxstrength*10;
223  weaponsinglecostm += vehicle->weapons.weapon[W].maxstrength*10;
224  } else {
225  weaponsinglecoste += 100;
226  weaponsinglecostm += 50;
227  }
228  }
230  if ( vehicle->weapons.weapon[W].shootable() ) {
231  weaponsinglecoste += vehicle->weapons.weapon[W].maxstrength*15;
232  weaponsinglecostm += vehicle->weapons.weapon[W].maxstrength*15;
233  } else {
234  weaponsinglecoste += 100;
235  weaponsinglecostm += 50;
236  }
237  }
238  if (vehicle->weapons.weapon[W].getScalarWeaponType() == cwlasern && vehicle->weapons.weapon[W].shootable() ) {
239  weaponsinglecoste += vehicle->weapons.weapon[W].maxstrength*12;
240  weaponsinglecostm += vehicle->weapons.weapon[W].maxstrength*10;
241  }
242  if (vehicle->weapons.weapon[W].service() ) {
243  weaponsinglecoste += 1000;
244  weaponsinglecostm += 500;
245  }
246  if (vehicle->weapons.weapon[W].canRefuel() ) {
247  weaponsinglecoste += 100;
248  weaponsinglecostm += 50;
249  }
250  // Waffenreichweitenzuschlag Kurzstrecke
251  if (vehicle->weapons.weapon[W].maxdistance > 19 ) {
252  weaponsinglecoste += (vehicle->weapons.weapon[W].maxdistance-10)*80;
253  weaponsinglecostm += (vehicle->weapons.weapon[W].maxdistance-10)*80;
254  }
255  // Waffenreichweitenzuschlag Mittelstrecke
256  if (vehicle->weapons.weapon[W].maxdistance > 69 ) {
257  weaponsinglecoste += (vehicle->weapons.weapon[W].maxdistance-60)*150;
258  weaponsinglecostm += (vehicle->weapons.weapon[W].maxdistance-60)*140;
259  }
260  // Waffenreichweitenzuschlag Langstrecke
261  if (vehicle->weapons.weapon[W].maxdistance > 99 ) {
262  weaponsinglecoste += (vehicle->weapons.weapon[W].maxdistance-90)*220;
263  weaponsinglecostm += (vehicle->weapons.weapon[W].maxdistance-90)*200;
264  }
265  // Waffenreichweitenzuschlag Interkontinental
266  if (vehicle->weapons.weapon[W].maxdistance > 129 ) {
267  weaponsinglecoste += (vehicle->weapons.weapon[W].maxdistance-120)*250;
268  weaponsinglecostm += (vehicle->weapons.weapon[W].maxdistance-120)*250;
269  }
270  //Move during reaction fire(MDRF) - Move After Attack(MAM) - No Attack After Move(NAAM) - ReactionFire(RF)
271  int weaponspecial = 0;
272  int weaponRF = vehicle->weapons.weapon[W].reactionFireShots*weaponsinglecostm/10;
273  int weaponMAM = maxmoverange*weaponsinglecostm/500;
274  int weaponNAAM = weaponsinglecostm/4;
275  int weaponMDRF = vehicle->weapons.weapon[W].reactionFireShots*weaponsinglecostm*maxmoverange/400;
276 
277  if ( vehicle->weapons.weapon[W].shootable() ) {
279  if ( vehicle->wait ) {
280  if ( vehicle->hasFunction( ContainerBaseType::MoveAfterAttack ) ) { // MDRF+NAAM+MAM (Defkind,Spear,Stahlschwein)
281  weaponspecial += weaponMDRF+weaponMAM-weaponNAAM;
282  } else { // MDRF+NAAM (Coma, CM-U-Boote, Def-Panzer,Turrets)
283  weaponspecial += weaponMDRF-weaponNAAM;
284  }
285  } else {
286  if ( vehicle->hasFunction( ContainerBaseType::MoveAfterAttack ) ) { // MDRF+MAM (Druk, Innocence, Skjold, PHM, Jub-O)
287  weaponspecial += weaponMDRF+weaponMAM;
288  } else { // MDRF (Schiffe, fahrende Bunker, Luftabwehrpanzer/Trooper)
289  weaponspecial += weaponMDRF;
290  }
291  }
292  } else {
293  if ( vehicle->wait ) {
294  if ( vehicle->hasFunction( ContainerBaseType::MoveAfterAttack ) ) { // NAAM+MAM (Coma2, K5, PzH2000, Pulsar)
295  weaponspecial += weaponRF+weaponMAM-weaponNAAM;
296  } else { // NAAM (Coma3, BodenCMs, Schienengesch´┐Żtze)
297  weaponspecial += weaponRF-weaponNAAM;
298  }
299  } else { // MAM (FAV,Flugzeug,U-Boot,WIG)
301  weaponspecial += weaponRF+weaponMAM;
302  } else { // ohne alles (Panzer/Trooper)
303  weaponspecial += weaponRF;
304  }
305  }
306  }
307  }
308  // Aufrechnung
309  weaponcoste += weaponsinglecoste + weaponspecial ;
310  weaponcostm += weaponsinglecostm + weaponspecial ;
311  }
312  }
313 
314  // Part V Specialcost
315  // stealth (typecost) oder jamming (specialcost)
316 
317  if ( vehicle->jamming > 0 && vehicle->hasFunction( ContainerBaseType::JamsOnlyOwnField ) ) {
318  if (vehicle->jamming < 31 ) {
319  typecoste += vehicle->jamming*20; // fuer Trooper oder eigenschaftsbedingt (klein, schnell)
320  typecostm += vehicle->jamming*10;
321  } else {
322  typecoste += vehicle->jamming*60; // fuer alle hoeherwirkenden Stealthverfahren, Anstrich, besondere Konstruktion, tarnfeld usw.
323  typecostm += vehicle->jamming*50;
324  }
325  } else { // JAMMING
326  specialcoste += vehicle->jamming*200;
327  specialcostm += vehicle->jamming*150;
328  // Armorzuschlag
329  specialcostm += vehicle->jamming*vehicle->armor/10;
330  // Bewegungszuschlag
331  if (maxmoverange > 70 ) {
332  specialcostm += vehicle->jamming*(maxmoverange-70);
333  }
334  if (maxmoverange > 120 ) {
335  specialcostm += vehicle->jamming*(maxmoverange-120);
336  }
337  if (maxmoverange > 170 ) {
338  specialcostm += vehicle->jamming*(maxmoverange-170);
339  }
340  if (maxmoverange > 200 ) {
341  specialcostm += vehicle->jamming*(maxmoverange-200);
342  }
343  }
344 
345  // Baufunktionen
347  specialcoste += 1000;
348  specialcostm += 500;
349  }
351  specialcoste += 1000;
352  specialcostm += 500;
353  }
354  if ( vehicle->objectsBuildable.size() > 0 ||vehicle-> objectGroupsBuildable.size() > 0 ) {
355  specialcoste += 1000;
356  specialcostm += 500;
357  }
358  // Res Search
360  specialcoste += vehicle->digrange*150;
361  specialcostm += vehicle->digrange*100;
362  }
363  // Generator
365  specialcoste += 1000;
366  specialcostm += 500;
367  }
368  //ParaTrooper
369  if ( vehicle->hasFunction( ContainerBaseType::Paratrooper ) ) {
370  specialcoste += vehicle->armor*2 ;
371  specialcostm += vehicle->armor ;
372  }
373  // Reparaturfahrzeug
375  specialcoste += 1000;
376  specialcostm += 500;
377  }
378  // Selbstreparatur / Heilung
379  if ( vehicle->hasFunction( ContainerBaseType::AutoRepair ) ) {
380  specialcoste += vehicle->autorepairrate*vehicle->armor / 15;
381  specialcostm += vehicle->autorepairrate*vehicle->armor / 15;
382  }
383  // Radar
384  if ( vehicle->view > 40 ) {
385  specialcoste += (vehicle->view-40)*90;
386  specialcostm += (vehicle->view-40)*75;
387  specialcoste += maxmoverange*(vehicle->view-40)/3;
388  specialcostm += maxmoverange*(vehicle->view-40)/5;
389  }
390  // Satview
391  if ( vehicle->hasFunction( ContainerBaseType::SatelliteView ) ) {
392  specialcoste += vehicle->view*20;
393  specialcostm += vehicle->view*8;
394  }
395  //Sonar
396  if ( vehicle->hasFunction(ContainerBaseType::Sonar) && (vehicle->movemalustyp == MoveMalusType::trooper) ) {
397  specialcoste += vehicle->view*10;
398  specialcostm += vehicle->view*4;
399  } else {
400  if ( vehicle->hasFunction(ContainerBaseType::Sonar)) {
401  specialcoste += vehicle->view*20;
402  specialcostm += vehicle->view*10;
403  }
404  }
405  //Move during reaction fire
406 // if ( vehicle->hasFunction( MoveWithReactionFire )) {
407 // int rfweapcount = 0;
408 // for ( int i = 0; i < vehicle->weapons.count; ++i )
409 // if ( vehicle->weapons.weapon[i].shootable() )
410 // rfweapcount += vehicle->weapons.weapon[i].reactionFireShots;
411 
412 // specialcoste += rfweapcount * 100;
413 // specialcostm += rfweapcount * 50;
414 // }
415 
416  //move after attack
417 // if ( vehicle->hasFunction( MoveAfterAttack ) ) {
418 // specialcoste += maxmoverange*10;
419 // specialcostm += maxmoverange*5;
420 // }
421 
422  if ( vehicle->jumpDrive.height ) {
423  int distance = vehicle->jumpDrive.maxDistance;
424  if ( distance > 1000 )
425  distance = 1000;
426  if ( vehicle->hasFunction( ContainerBaseType::MoveWithReactionFire ) && (maxmoverange < 30)) {
427  specialcoste += distance * 14;
428  specialcostm += distance * 12;
429  } else {
430  specialcoste += distance * 7;
431  specialcostm += distance * 5;
432  }
433  }
434 
435  // Part VI - Addition
436  res.energy += typecoste + weaponcoste + specialcoste;
437  res.material += typecostm + weaponcostm + specialcostm;
438 
439  // Part VII Abschlaege
440  // keine Luftbetankung
442  res.energy -= typecoste/6;
443  res.material -= typecostm/6;
444  }
445 
446  // Kamikazeeinheiten
447  if ( vehicle->hasFunction( ContainerBaseType::KamikazeOnly )) {
448  res.energy -= (typecoste+weaponcoste)/2;
449  res.material -= (typecostm+weaponcostm)/2;
450  }
451 
452  // low movement
453  //if (maxmoverange < 20 ) {
454  // res.energy -= typecoste/4;
455  // res.material -= typecostm/4;
456  //}
457 
458  // low movement
459  //if (maxmoverange < 10 ) {
460  // res.energy -= typecoste/4;
461  // res.material -= typecostm/4;
462  //}
463  // Part VIII Abschluss
464 
465  return res;
466 }
int fuel
Definition: typen.h:101
vector< IntRange > objectsBuildable
the ids of objects this unit can construct
Definition: vehicletype.h:233
bool wait
If the unit cannot attack in the same turn after it has moved, it has to wait.
Definition: vehicletype.h:197
struct VehicleType::JumpDrive jumpDrive
int maxLoadableUnits
the maximum number of units that can be loaded
bool service(void) const
#define cwmachinegunn
Definition: vehicletype.h:77
#define cwsmallmissilen
Definition: vehicletype.h:73
int energy
Definition: typen.h:99
#define cwcruisemissilen
Definition: vehicletype.h:65
#define cwbombn
Definition: vehicletype.h:69
UnitWeapon weapons
The weapons.
Definition: vehicletype.h:248
bool shootable(void) const
bool hasFunction(ContainerFunctions function) const
bool canRefuel(void) const
#define chhochfliegend
Definition: typen.h:416
SingleWeapon weapon[16]
Definition: vehicletype.h:170
#define cwlasern
Definition: vehicletype.h:84
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
vector< int > movement
the distance a unit can travel each round. One value for each of the 8 levels of height ...
Definition: vehicletype.h:203
int view
the visibility range
int digrange
radius of the circle in which a unit can search for mineral resolures (measured in number of fields...
Definition: vehicletype.h:212
int getScalarWeaponType(void) const
The class describing properties that are common to all vehicles of a certain kind.
Definition: vehicletype.h:177
#define cwcannonn
Definition: vehicletype.h:79
#define chtieffliegend
Definition: typen.h:414
int reactionFireShots
Definition: vehicletype.h:145
int movemalustyp
The category of the unit. Original used only to distinguish only between different movement costs for...
Definition: vehicletype.h:206
int jamming
the radar jamming power
int height
bitmapped: on these levels of height the jump drive can be activated
Definition: vehicletype.h:310
EntranceSystems entranceSystems
int maxdistance
the maximum distance the weapon can shoot
Definition: vehicletype.h:111
int material
Definition: typen.h:100
int autorepairrate
the damage this unit can repair itself automatically each turn.
Definition: vehicletype.h:251
#define cwminen
Definition: vehicletype.h:67
#define chsatellit
Definition: typen.h:417
int height
the levels of height which this unit can enter
int maxstrength
strength of the weapon when fired over the minimal distance
Definition: vehicletype.h:120
Resources are basically the currency of ASC.
Definition: typen.h:97
#define chgetaucht
Definition: typen.h:411
#define cwtorpedon
Definition: vehicletype.h:75
Resources productionCost(const VehicleType *vehicle)
#define chfliegend
Definition: typen.h:415
#define cwlargemissilen
Definition: vehicletype.h:71