Advanced Strategic Command
unitcostcalculator-pbp.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 
28 #include "unitcostcalculator-pbp.h"
29 
30 #include "vehicletype.h"
31 
32 //Part II beginn calculation
33 
34 
36 {
37  return "PBP";
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  float 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  int unitfactor = 0;
56  int tech = 0;
57 
58  // Check guideSortHelp auf Technologie
59  // ACHTUNG dieser Wert kann nicht definiert sein (guideSortHelp leer) Fehlermeldung abfangen !
60  if ( vehicle->guideSortHelp.size() > 9 && vehicle->guideSortHelp[9] > 0) {
61  tech = vehicle->guideSortHelp[9];
62  }
63 
64  // Check Flugzeugtraeger
65  bool carrierCharge = false;
66  for ( int T=0; T < vehicle->entranceSystems.size(); ++T )
67  if ((( vehicle->entranceSystems[T].container_height < chtieffliegend && (vehicle->entranceSystems[T].height_abs & (chtieffliegend | chfliegend | chhochfliegend | chsatellit))) ||
68  (( vehicle->entranceSystems[T].container_height & ( chfliegend | chhochfliegend | chsatellit)) && (vehicle->entranceSystems[T].height_abs & ( chfliegend | chhochfliegend | chsatellit))))
69  && vehicle->maxLoadableUnits > 6 )
70  carrierCharge = true;
71 
72  // Check maximale Bewegungsreichweite
73  for ( int M=0; M < vehicle->movement.size(); ++M ) {
74  if ( maxmoverange < vehicle->movement[M] ) {
75  maxmoverange = vehicle->movement[M];
76  }
77  }
78  // Check maximale Waffenreichweite
79  if ( vehicle->weapons.count > 0 ) {
80  for ( int WR=0; WR < vehicle->weapons.count; ++WR ) {
81  if ( maxweaponrange < vehicle->weapons.weapon[WR].maxdistance ) {
82  maxweaponrange = vehicle->weapons.weapon[WR].maxdistance;
83  }
84  }
85  }
86 
87 
88 // Part III typecost
89 
90  // Setzen der Typfaktoren
91  if ( vehicle->movemalustyp == MoveMalusType::trooper) {
92  // Soldaten
93  unitfactor = 6;
94  } else if ( vehicle->movemalustyp == MoveMalusType::light_wheeled_vehicle ) {
95  // Bugies, Trikes, Motorraeder, Jeeps
96  unitfactor = 7;
97  } else if ( vehicle->movemalustyp == MoveMalusType::medium_wheeled_vehicle ) {
98  // Servicefahrzeuge, LKWs
99  unitfactor = 8;
100  } else if ( vehicle->movemalustyp == MoveMalusType::heavy_wheeled_vehicle ) {
101  // Selbstfahrlafetten, leichte Panzer, Servicekettenfahrzeuge
102  unitfactor = 9;
103  } else if ( vehicle->movemalustyp == MoveMalusType::light_tracked_vehicle ) {
104  // Kampfroboter, kleine Panzer (Wiesel)
105  unitfactor = 8;
106  } else if ( vehicle->movemalustyp == MoveMalusType::medium_tracked_vehicle ) {
107  // Selbstfahrlafetten, leichte Panzer, Servicekettenfahrzeuge
108  unitfactor = 9;
109  } else if ( vehicle->movemalustyp == MoveMalusType::heavy_tracked_vehicle ) {
110  // Kampfpanzer, fahrende Bunker, grosse Kettenfahrzeuge
111  unitfactor = 10;
112  } else if ( vehicle->movemalustyp == MoveMalusType::hoovercraft) {
113  // Luftkissenfahrzeuge
114  unitfactor = 10;
115  } else if ( vehicle->movemalustyp == MoveMalusType::light_ship ) {
116  // Boote und sehr kleine Schiffe (Boote, Korvette, Mini-U-Boote)
117  unitfactor = 9;
118  } else if ( vehicle->movemalustyp == MoveMalusType::medium_ship ) {
119  // mittlere Schiffe (Fregatten, Zerst�rer, U-Boote)
120  unitfactor = 11;
121  } else if ( vehicle->movemalustyp == MoveMalusType::heavy_ship ) {
122  // gro�e Schiffe (Kreuzer, Schlachtschiffe, Atom-U-Boote)
123  unitfactor = 13;
124  } else if ( vehicle->movemalustyp == MoveMalusType::helicopter ) {
125  // Rotorgetriebene Luftfahrzeuge
126  unitfactor = 13;
127  } else if ( vehicle->movemalustyp == MoveMalusType::light_aircraft ) {
128  // kleine Flugzeuge ( Drohnen, Satelliten )
129  unitfactor = 13;
130  } else if ( vehicle->movemalustyp == MoveMalusType::medium_aircraft ) {
131  unitfactor = 14;
132  } else if ( vehicle->movemalustyp == MoveMalusType::heavy_aircraft ) {
133  unitfactor = 15;
134  } else if ( vehicle->movemalustyp == MoveMalusType::rail_vehicle ) {
135  // Schienenfahrzeuge
136  unitfactor = 10;
137  } else if ( vehicle->movemalustyp == MoveMalusType::structure) {
138  // Gebaeude, Bunker, Geschuetztuerme
139  unitfactor = 10;
140 
141  } else {
142  // Geraete und andere
143  unitfactor = 7;
144  }
145 
146  // Basiskosten Chassis
147  typecostm += vehicle->armor*unitfactor;
148 
149  // Zuschlag fuer U-Boote / Druckhuelle
150  if ( vehicle->height & chgetaucht ) {
152  typecostm += vehicle->armor*unitfactor/4;
153  } else {
154  if ( vehicle->movemalustyp == MoveMalusType::trooper ) {
155  typecostm += vehicle->armor*unitfactor;
156  } else {
157  typecostm += vehicle->armor*unitfactor/2;
158  }
159  }
160  }
161  // Zuschlag fuer U-Boote / Druckhuelle
162  if ( vehicle->height & chtiefgetaucht ) {
164  typecostm += vehicle->armor*unitfactor/4;
165  } else {
166  if ( vehicle->movemalustyp == MoveMalusType::trooper ) {
167  typecostm += vehicle->armor*unitfactor;
168  } else {
169  typecostm += vehicle->armor*unitfactor/2;
170  }
171  }
172  }
173  // Zuschlag fuer orbitalfaehige Einheiten / Druckhuelle
174  if ( vehicle->height & chsatellit ) {
175  typecostm += vehicle->armor*unitfactor/3;
176  }
177  // Zuschlag fuer hochfliegende Einheiten
178  if ( vehicle->height & chhochfliegend ) {
179  typecostm += vehicle->armor*unitfactor/3;
180  }
181  // Zuschlag fuer normal fliegende Einheiten
182  if ( vehicle->height & chfliegend ) {
183  typecostm += vehicle->armor*unitfactor/4;
184  }
185  // Zuschlag fuer tief fliegende Einheiten
186  if ( vehicle->height & chtieffliegend ) {
187  typecostm += vehicle->armor*unitfactor/4;
188  }
189  // Zuschlag fuer Transportkapazitaet
190  if ( vehicle->entranceSystems.size() > 0 ) {
191  typecostm += vehicle->maxLoadableUnits*unitfactor*10;
192  // Zuschlag fr Flugzeugtraeger / Start- und Landeeinrichtungen
193  if ( carrierCharge ) {
194  typecostm += vehicle->maxLoadableUnits*unitfactor*100;
195  }
196  }
197  // Zuschlag fuer Tankkapazitaet
198  if ( vehicle->getStorageCapacity(0).fuel > 20000 ) {
199  typecostm += (vehicle->getStorageCapacity(0).fuel-20000)*unitfactor/100;
200  }
201  // Zuschlag fuer Materialkapazitaet
202  if ( vehicle->getStorageCapacity(0).material > 20000 ) {
203  typecostm += (vehicle->getStorageCapacity(0).material-20000)*unitfactor/100;
204  }
205 
206  // Zuschlag fuer Triebwerke
207  if (maxmoverange > 40 ) {
208  typecostm += (maxmoverange-40)*unitfactor*0.6;
209  }
210  // Zuschlag fuer Triebwerke
211  if (maxmoverange > 80 ) {
212  typecostm += (maxmoverange-80)*unitfactor*0.6;
213  }
214  // Zuschlag fuer Triebwerke 2
215  if (maxmoverange > 120 ) {
216  typecostm += (maxmoverange-120)*unitfactor*0.6;
217  }
218  // Zuschlag fuer Triebwerke 3
219  if (maxmoverange > 160 ) {
220  typecostm += (maxmoverange-160)*unitfactor*0.6;
221  }
222  // Zuschlag fuer Triebwerke 4
223  if (maxmoverange > 200 ) {
224  typecostm += (maxmoverange-200)*unitfactor*0.6;
225  }
226  // Zuschlag fuer Triebwerke 5
227  if (maxmoverange > 240 ) {
228  typecostm += (maxmoverange-240)*unitfactor*0.6;
229  }
230 
231 
232 
233  // Part IV - weaponcost
234 
235  // generelle Waffenreichweite, einmaliger Zuschlag
236 
237  // Kostenbegrenzung
238  // Waffenreichweitenzuschlag Kurzstrecke
239  if (maxweaponrange > 19 ) {
240  weaponcostm += maxweaponrange*70;
241  }
242  // Waffenreichweitenzuschlag Mittelstrecke
243  if (maxweaponrange > 39 ) {
244  weaponcostm += 1000*unitfactor/10;
245  weaponcostm += (maxweaponrange-40)*80;
246  }
247  // Waffenreichweitenzuschlag Langstrecke
248  if (maxweaponrange > 69 ) {
249  weaponcostm += (maxweaponrange-70)*80;
250  }
251  // Waffenreichweitenzuschlag Kontinental
252  if (maxweaponrange > 109 ) {
253  weaponcostm += (maxweaponrange-110)*90;
254  }
255 
256 
257  if ( vehicle->weapons.count > 0 ) {
258  for ( int W=0; W < vehicle->weapons.count; ++W ) {
259  int weaponsinglecostm = 0;
260  if (vehicle->weapons.weapon[W].getScalarWeaponType() == cwminen) {
261  if ( vehicle->weapons.weapon[W].shootable() ) {
262  weaponsinglecostm += vehicle->weapons.weapon[W].maxstrength*unitfactor/10;
263  } else {
264  weaponsinglecostm += 100;
265  }
266  }
268  if ( vehicle->weapons.weapon[W].shootable() ) {
269  weaponsinglecostm += vehicle->weapons.weapon[W].maxstrength*unitfactor/10*5;
270  } else {
271  weaponsinglecostm += 100;
272  }
273  }
275  if ( vehicle->weapons.weapon[W].shootable() ) {
276  weaponsinglecostm += vehicle->weapons.weapon[W].maxstrength*unitfactor/10*7;
277  } else {
278  weaponsinglecostm += 100;
279  }
280  }
282  if ( vehicle->weapons.weapon[W].shootable() ) {
283  weaponsinglecostm += vehicle->weapons.weapon[W].maxstrength*unitfactor/10*15;
284  } else {
285  weaponsinglecostm += 100;
286  }
287  }
288  if (vehicle->weapons.weapon[W].getScalarWeaponType() == cwlasern && vehicle->weapons.weapon[W].shootable() ) {
289  weaponsinglecostm += vehicle->weapons.weapon[W].maxstrength*unitfactor/10*12;
290  }
291  if (vehicle->weapons.weapon[W].service() ) {
292  weaponsinglecostm += 1000;
293  }
294 
295  // Waffenreichweitenzuschlag
296  if (vehicle->weapons.weapon[W].getScalarWeaponType() == cwmachinegunn) {
297  weaponsinglecostm += vehicle->weapons.weapon[W].maxdistance*unitfactor/4;
298  } else {
299  weaponsinglecostm += vehicle->weapons.weapon[W].maxdistance*unitfactor/2;
300 
301  }
302  //Move during reaction fire(MDRF) - Move After Attack(MAM) - No Attack After Move(NAAM) - ReactionFire(RF)
303  int weaponspecial = 0;
304  int weaponRF = vehicle->weapons.weapon[W].reactionFireShots*weaponsinglecostm/2;
305  int weaponMAM = maxmoverange*weaponsinglecostm/150;
306  int weaponNAAM = weaponsinglecostm/2;
307  int weaponMDRF = vehicle->weapons.weapon[W].reactionFireShots*maxmoverange/100;
308  int weaponMDRF_J ;
309  if ( vehicle->jumpDrive.height ) {
310  weaponMDRF_J = vehicle->weapons.weapon[W].reactionFireShots*vehicle->jumpDrive.maxDistance/100;
311  } else {
312  weaponMDRF_J = 0 ;
313  }
314  if ( vehicle->weapons.weapon[W].shootable() ) {
316  if ( vehicle->wait ) {
317  if ( vehicle->hasFunction( ContainerBaseType::MoveAfterAttack ) ) { // MDRF+NAAM+MAM (Defkind,Spear,Stahlschwein)
318  weaponspecial += weaponRF+weaponMDRF+weaponMDRF_J+weaponMAM-weaponNAAM;
319  } else { // MDRF+NAAM (Coma, CM-U-Boote, Def-Panzer,Turrets)
320  weaponspecial += weaponRF+weaponMDRF+weaponMDRF_J-weaponNAAM;
321  }
322  } else {
323  if ( vehicle->hasFunction( ContainerBaseType::MoveAfterAttack ) ) { // MDRF+MAM (Druk, Innocence, Skjold, PHM, Jub-O)
324  weaponspecial += weaponRF+weaponMDRF+weaponMDRF_J+weaponMAM;
325  } else { // MDRF (Schiffe, fahrende Bunker, Luftabwehrpanzer/Trooper)
326  weaponspecial += weaponRF+weaponMDRF+weaponMDRF_J;
327  }
328  }
329  } else {
330  if ( vehicle->wait ) {
331  if ( vehicle->hasFunction( ContainerBaseType::MoveAfterAttack ) ) { // NAAM+MAM (Coma2, K5, PzH2000, Pulsar)
332  weaponspecial += weaponRF+weaponMAM-weaponNAAM;
333  } else { // NAAM (Coma3, BodenCMs, Schienengesch�tze)
334  weaponspecial += weaponRF-weaponNAAM;
335  }
336  } else { // MAM (FAV,Flugzeug,U-Boot,WIG)
338  weaponspecial += weaponRF+weaponMAM;
339  } else { // ohne alles (Panzer/Trooper)
340  weaponspecial += weaponRF;
341  }
342  }
343  }
344  }
345  // Aufrechnung
346  weaponcostm += weaponsinglecostm + weaponspecial ;
347  }
348  }
349 
350  // Part V Specialcost
351  // stealth (typecost) oder jamming (specialcost)
352 
353  if ( vehicle->jamming > 0 && vehicle->hasFunction( ContainerBaseType::JamsOnlyOwnField ) ) {
354  if (vehicle->jamming < 40 ) {
355  typecostm += vehicle->jamming*unitfactor*2; // fuer Trooper oder eigenschaftsbedingt (klein, schnell)
356  } else {
357  typecostm += vehicle->jamming*unitfactor*5; // fuer alle hoeherwirkenden Stealthverfahren, Anstrich, besondere Konstruktion, tarnfeld usw.
358  }
359  } else { // JAMMING
360  specialcostm += vehicle->jamming*unitfactor*20;
361  // Armorzuschlag
362  specialcostm += vehicle->jamming*vehicle->armor*unitfactor/100;
363  // Bewegungszuschlag
364  if (maxmoverange > 70 ) {
365  specialcostm += vehicle->jamming*unitfactor/10*(maxmoverange-70);
366  }
367  if (maxmoverange > 120 ) {
368  specialcostm += vehicle->jamming*unitfactor/10*(maxmoverange-120);
369  }
370  if (maxmoverange > 170 ) {
371  specialcostm += vehicle->jamming*unitfactor/10*(maxmoverange-170);
372  }
373  if (maxmoverange > 200 ) {
374  specialcostm += vehicle->jamming*unitfactor/10*(maxmoverange-200);
375  }
376  }
377 
378  // Baufunktionen
380  specialcostm += 5000;
381  }
383  specialcostm += 5000;
384  }
385  if ( vehicle->objectsBuildable.size() > 0 ||vehicle-> objectGroupsBuildable.size() > 0 ) {
386  specialcostm += 1000;
387  }
388  // Res Search
390  specialcostm += vehicle->digrange*150;
391  }
392  // Generator
394  specialcostm += 5000;
395  }
396  //ParaTrooper
397  if ( vehicle->hasFunction( ContainerBaseType::Paratrooper ) ) {
398  specialcostm += vehicle->armor*unitfactor/10*2 ;
399  }
400  // Reparaturfahrzeug
402  specialcostm += 1000;
403  }
404  // Selbstreparatur / Heilung
405  if ( vehicle->hasFunction( ContainerBaseType::AutoRepair ) ) {
406  specialcostm += vehicle->autorepairrate*vehicle->armor*unitfactor/10 / 15;
407  }
408  // Radar
409  if ( vehicle->view > 51 ) {
410  specialcostm += (vehicle->view-40)*90;
411  specialcostm += maxmoverange*(vehicle->view)/4;
412  }
413  // Satview
414  if ( vehicle->hasFunction( ContainerBaseType::SatelliteView ) ) {
415  specialcostm += vehicle->view*10;
416  }
417  //Sonar
418  if ( vehicle->hasFunction(ContainerBaseType::Sonar) && (vehicle->movemalustyp == MoveMalusType::trooper) ) {
419  specialcostm += vehicle->view*5;
420  } else {
421  if ( vehicle->hasFunction(ContainerBaseType::Sonar)) {
422  specialcostm += vehicle->view*10;
423  }
424  }
425 
426  if ( vehicle->jumpDrive.height ) {
427  int distance = vehicle->jumpDrive.maxDistance;
428  if ( distance > 1000 )
429  distance = 1000;
430  if ( vehicle->hasFunction( ContainerBaseType::MoveWithReactionFire ) && (maxmoverange < 30)) {
431  specialcostm += distance * 20;
432  } else {
433  specialcostm += distance * 10;
434  }
435  }
436 
437  // Part VI - Addition
438  res.material += (int)typecostm + weaponcostm + specialcostm;
439 
440  // Part VII Abschlaege
441  // keine Luftbetankung
443  res.material -= int(typecostm/7);
444  }
445 
446 
447  // low movement
448  if ( maxmoverange < 12 ) {
449  res.material -= int(typecostm/4);
450  }
451 
452  // Part VIII Technologiekorrektur
453  if ( tech > 0 ) {
454  res.material += tech * 1000;
455  if ( res.material > tech * 10000 ) {
456  res.material -= (res.material - tech * 10000) / 2;
457  }
458  }
459  // Kamikazeeinheiten
460  if ( vehicle->hasFunction( ContainerBaseType::KamikazeOnly )) {
461  if (res.material > 5000) {
462  res.material -= int((res.material - 5000)/2);
463  }
464  }
465  // Energiekosten
466  if (maxmoverange < 20 ) {
467  res.energy = res.material/20;
468  } else {
469  res.energy = res.material/4;
470  }
471 
472  return res;
473 }
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
vector< int > guideSortHelp
Definition: vehicletype.h:279
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
#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 chtiefgetaucht
Definition: typen.h:410
#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
Resources getStorageCapacity(int mode) const
returns the Storage capacity of the unit
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
Resources productionCost(const VehicleType *vehicle)
#define cwtorpedon
Definition: vehicletype.h:75
#define chfliegend
Definition: typen.h:415
#define cwlargemissilen
Definition: vehicletype.h:71