unitcostcalculator-standard.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                                                         *
00003  *   This program is free software; you can redistribute it and/or modify  *
00004  *   it under the terms of the GNU General Public License as published by  *
00005  *   the Free Software Foundation; either version 2 of the License, or     *
00006  *   (at your option) any later version.                                   *
00007  *                                                                         *
00008  ***************************************************************************/
00009 
00010 /***************************************************************************
00011                           Preiskalkulation  -  description
00012                              -------------------
00013     begin                : So Aug 15 2004
00014     copyright            : (C) 2001 by Martin Bickel & Steffen Froelich
00015     email                : bickel@asc-hq.org
00016 
00017 Part I   -description
00018 Part II  -beginn calculation
00019 Part III -typecost
00020 part IV  -weaponcost
00021 Part V   -specialcost
00022 Part VI  -addition
00023 Part VII -malus
00024 
00025  ***************************************************************************/
00026 
00027 
00028 #include "unitcostcalculator-standard.h"
00029 
00030 #include "vehicletype.h"
00031 
00032 //Part II beginn calculation
00033 
00034 
00035 ASCString StandardUnitCostCalculator::getCalculatorName()
00036 {
00037    return "standard";
00038 }
00039 
00040 Resources StandardUnitCostCalculator :: productionCost( const VehicleType* vehicle )
00041 {
00042    Resources res;
00043    // Anfang -> Abschluss
00044    res.energy = 0;
00045    res.material = 0;
00046    res.fuel = 0;
00047    int typecoste = 0;
00048    int typecostm = 0;
00049    int weaponcoste = 0;
00050    int weaponcostm = 0;
00051    int specialcoste = 0;
00052    int specialcostm = 0;
00053    int maxmoverange = 0;
00054    int maxweaponrange = 0;
00055 
00056    // Check Flugzeugtraeger
00057    bool carrierCharge = false;
00058    for ( int T=0; T < vehicle->entranceSystems.size(); ++T )
00059       if ((( vehicle->entranceSystems[T].container_height < chtieffliegend && (vehicle->entranceSystems[T].height_abs & (chtieffliegend | chfliegend | chhochfliegend | chsatellit))) ||
00060              (( vehicle->entranceSystems[T].container_height & ( chfliegend | chhochfliegend | chsatellit)) && (vehicle->entranceSystems[T].height_abs & ( chfliegend | chhochfliegend | chsatellit))))
00061              && vehicle->maxLoadableUnits > 6 )
00062          carrierCharge = true;
00063 
00064    // Check maximale Bewegungsreichweite
00065    for ( int M=0; M < vehicle->movement.size(); ++M ) {
00066       if ( maxmoverange < vehicle->movement[M] ) {
00067          maxmoverange = vehicle->movement[M];
00068       }
00069    }
00070    // Check maximale Waffenreichweite
00071    if ( vehicle->weapons.count > 0 ) {
00072       for ( int WR=0; WR < vehicle->weapons.count; ++WR ) {
00073          if ( maxweaponrange < vehicle->weapons.weapon[WR].maxdistance ) {
00074             maxweaponrange = vehicle->weapons.weapon[WR].maxdistance;
00075          }
00076       }
00077    }
00078 
00079 // Part III typecost
00080 
00081    if ( vehicle->movemalustyp == MoveMalusType::trooper) {
00082       typecoste += vehicle->armor*3;
00083       typecostm += vehicle->armor*3;
00084    } else if ( vehicle->movemalustyp == MoveMalusType::light_wheeled_vehicle ) {
00085       typecoste += vehicle->armor*6;
00086       typecostm += vehicle->armor*6;
00087    } else if ( vehicle->movemalustyp == MoveMalusType::light_tracked_vehicle || vehicle->movemalustyp == MoveMalusType::medium_wheeled_vehicle ) {
00088       typecoste += vehicle->armor*7;
00089       typecostm += vehicle->armor*7;
00090    } else if ( vehicle->movemalustyp == MoveMalusType::medium_tracked_vehicle || vehicle->movemalustyp == MoveMalusType::heavy_wheeled_vehicle || vehicle->movemalustyp == MoveMalusType::rail_vehicle || vehicle->movemalustyp == MoveMalusType::structure) {
00091       typecoste += vehicle->armor*8;
00092       typecostm += vehicle->armor*8;
00093    } else if ( vehicle->movemalustyp == MoveMalusType::heavy_tracked_vehicle ) {
00094       typecoste += vehicle->armor*9;
00095       typecostm += vehicle->armor*9;
00096    } else if ( vehicle->movemalustyp == MoveMalusType::hoovercraft) {
00097       typecoste += vehicle->armor*9;
00098       typecostm += vehicle->armor*9;
00099    } else if ( vehicle->movemalustyp == MoveMalusType::light_ship ) {
00100       typecoste += vehicle->armor*8;
00101       typecostm += vehicle->armor*8;
00102    } else if ( vehicle->movemalustyp == MoveMalusType::medium_ship ) {
00103       typecoste += vehicle->armor*10;
00104       typecostm += vehicle->armor*10;
00105    } else if ( vehicle->movemalustyp == MoveMalusType::heavy_ship ) {
00106       typecoste += vehicle->armor*12;
00107       typecostm += vehicle->armor*12;
00108    } else if ( vehicle->movemalustyp == MoveMalusType::helicopter ) {
00109       typecoste += vehicle->armor*14;
00110       typecostm += vehicle->armor*14;
00111    } else if ( vehicle->movemalustyp == MoveMalusType::light_aircraft ) {
00112       typecoste += vehicle->armor*16;
00113       typecostm += vehicle->armor*16;
00114    } else if ( vehicle->movemalustyp == MoveMalusType::medium_aircraft || vehicle->movemalustyp == MoveMalusType::heavy_aircraft ) {
00115       typecoste += vehicle->armor*18;
00116       typecostm += vehicle->armor*18;
00117 
00118    } else {
00119       typecoste += vehicle->armor*6;
00120       typecostm += vehicle->armor*6;
00121    }
00122 
00123    // Zuschlag fuer Eisbrecher
00124    if ( vehicle->hasFunction( ContainerBaseType::IceBreaker ) ) {
00125       typecoste += vehicle->armor *2;
00126       typecostm += vehicle->armor *2;
00127    }
00128    // Zuschlag fuer U-Boote / Druckhuelle
00129    if ( vehicle->height & chgetaucht ) {
00130       if ( vehicle->movemalustyp == MoveMalusType::light_ship || vehicle->movemalustyp == MoveMalusType::medium_ship || vehicle->movemalustyp == MoveMalusType::heavy_ship ) {
00131          typecoste += vehicle->armor*2;
00132          typecostm += vehicle->armor*2;
00133       } else {
00134          if ( vehicle->movemalustyp == MoveMalusType::trooper ) {
00135             typecoste += vehicle->armor*10;
00136             typecostm += vehicle->armor*10;
00137          } else {
00138             typecoste += vehicle->armor*6;
00139             typecostm += vehicle->armor*6;
00140          }
00141       }
00142    }
00143    // Zuschlag fuer orbitalfaehige Einheiten / Druckhuelle
00144    if ( vehicle->height & chsatellit ) {
00145       typecoste += vehicle->armor*3;
00146       typecostm += vehicle->armor*2;
00147    }
00148    // Zuschlag fuer hochfliegende Einheiten
00149    if ( vehicle->height & chhochfliegend ) {
00150       typecoste += vehicle->armor*4;
00151       typecostm += vehicle->armor*4;
00152    }
00153    // Zuschlag fuer normal fliegende Einheiten
00154    if ( vehicle->height & chfliegend ) {
00155       typecoste += vehicle->armor*3;
00156       typecostm += vehicle->armor*3;
00157    }
00158    // Zuschlag fuer tief fliegende Einheiten
00159    if ( vehicle->height & chtieffliegend ) {
00160       typecoste += vehicle->armor*2;
00161       typecostm += vehicle->armor*2;
00162    }
00163    // Zuschlag fuer Transportkapazitaet
00164    if ( vehicle->entranceSystems.size() > 0 ) {
00165       typecoste += vehicle->maxLoadableUnits*100;
00166       typecostm += vehicle->maxLoadableUnits*100;
00167       // Zuschlag fr Flugzeugtraeger / Start- und Landeeinrichtungen
00168       if ( carrierCharge ) {
00169          typecoste += vehicle->maxLoadableUnits*1000;
00170          typecostm += vehicle->maxLoadableUnits*1000;
00171       }
00172    }
00173    // Zuschlag fuer Triebwerke
00174    if (maxmoverange > 60 ) {
00175       typecoste += (maxmoverange-60)*10;
00176       typecostm += (maxmoverange-60)*5;
00177    }
00178    // Zuschlag fr Flugzeugtriebwerke
00179    if (maxmoverange > 110 ) {
00180       typecoste += (maxmoverange-110)*10;
00181       typecostm += (maxmoverange-110)*5;
00182    }
00183    // Zuschlag fr Hochleistungsflugzeugtriebwerke
00184    if (maxmoverange > 150 ) {
00185       typecoste += (maxmoverange-150)*10;
00186       typecostm += (maxmoverange-150)*5;
00187    }
00188    // Zuschlag fr Spezialflugzeugtriebwerke
00189    if (maxmoverange > 190 ) {
00190       typecoste += (maxmoverange-190)*10;
00191       typecostm += (maxmoverange-190)*5;
00192    }
00193 
00194 
00195 
00196    // Part IV - weaponcost
00197 
00198    if ( vehicle->weapons.count > 0 ) {
00199       for ( int W=0; W < vehicle->weapons.count; ++W ) {
00200          int weaponsinglecoste = 0;
00201          int weaponsinglecostm = 0;
00202          if (vehicle->weapons.weapon[W].getScalarWeaponType() == cwminen) {
00203             if ( vehicle->weapons.weapon[W].shootable() ) {
00204                weaponsinglecoste += vehicle->weapons.weapon[W].maxstrength;
00205                weaponsinglecostm += vehicle->weapons.weapon[W].maxstrength;
00206             } else {
00207                weaponsinglecoste += 100;
00208                weaponsinglecostm += 50;
00209             }
00210          }
00211          if (vehicle->weapons.weapon[W].getScalarWeaponType() == cwmachinegunn || vehicle->weapons.weapon[W].getScalarWeaponType() == cwsmallmissilen || vehicle->weapons.weapon[W].getScalarWeaponType() == cwbombn) {
00212             if ( vehicle->weapons.weapon[W].shootable() ) {
00213                weaponsinglecoste += vehicle->weapons.weapon[W].maxstrength*5;
00214                weaponsinglecostm += vehicle->weapons.weapon[W].maxstrength*5;
00215             } else {
00216                weaponsinglecoste += 100;
00217                weaponsinglecostm += 50;
00218             }
00219          }
00220          if (vehicle->weapons.weapon[W].getScalarWeaponType() == cwlargemissilen || vehicle->weapons.weapon[W].getScalarWeaponType() == cwtorpedon) {
00221             if ( vehicle->weapons.weapon[W].shootable() ) {
00222                weaponsinglecoste += vehicle->weapons.weapon[W].maxstrength*10;
00223                weaponsinglecostm += vehicle->weapons.weapon[W].maxstrength*10;
00224             } else {
00225                weaponsinglecoste += 100;
00226                weaponsinglecostm += 50;
00227             }
00228          }
00229          if (vehicle->weapons.weapon[W].getScalarWeaponType() == cwcannonn || vehicle->weapons.weapon[W].getScalarWeaponType() == cwcruisemissile) {
00230             if ( vehicle->weapons.weapon[W].shootable() ) {
00231                weaponsinglecoste += vehicle->weapons.weapon[W].maxstrength*15;
00232                weaponsinglecostm += vehicle->weapons.weapon[W].maxstrength*15;
00233             } else {
00234                weaponsinglecoste += 100;
00235                weaponsinglecostm += 50;
00236             }
00237          }
00238          if (vehicle->weapons.weapon[W].getScalarWeaponType() == cwlasern && vehicle->weapons.weapon[W].shootable() ) {
00239             weaponsinglecoste += vehicle->weapons.weapon[W].maxstrength*12;
00240             weaponsinglecostm += vehicle->weapons.weapon[W].maxstrength*10;
00241          }
00242          if (vehicle->weapons.weapon[W].service() ) {
00243             weaponsinglecoste += 1000;
00244             weaponsinglecostm += 500;
00245          }
00246          if (vehicle->weapons.weapon[W].canRefuel() ) {
00247             weaponsinglecoste += 100;
00248             weaponsinglecostm += 50;
00249          }
00250          // Waffenreichweitenzuschlag Kurzstrecke
00251          if (vehicle->weapons.weapon[W].maxdistance > 19 ) {
00252             weaponsinglecoste += (vehicle->weapons.weapon[W].maxdistance-10)*80;
00253             weaponsinglecostm += (vehicle->weapons.weapon[W].maxdistance-10)*80;
00254          }
00255          // Waffenreichweitenzuschlag Mittelstrecke
00256          if (vehicle->weapons.weapon[W].maxdistance > 69 ) {
00257             weaponsinglecoste += (vehicle->weapons.weapon[W].maxdistance-60)*150;
00258             weaponsinglecostm += (vehicle->weapons.weapon[W].maxdistance-60)*140;
00259          }
00260          // Waffenreichweitenzuschlag Langstrecke
00261          if (vehicle->weapons.weapon[W].maxdistance > 99 ) {
00262             weaponsinglecoste += (vehicle->weapons.weapon[W].maxdistance-90)*220;
00263             weaponsinglecostm += (vehicle->weapons.weapon[W].maxdistance-90)*200;
00264          }
00265          // Waffenreichweitenzuschlag Interkontinental
00266          if (vehicle->weapons.weapon[W].maxdistance > 129 ) {
00267             weaponsinglecoste += (vehicle->weapons.weapon[W].maxdistance-120)*250;
00268             weaponsinglecostm += (vehicle->weapons.weapon[W].maxdistance-120)*250;
00269          }
00270          //Move during reaction fire(MDRF) - Move After Attack(MAM) - No Attack After Move(NAAM) - ReactionFire(RF)
00271          int weaponspecial = 0;
00272          int weaponRF = vehicle->weapons.weapon[W].reactionFireShots*weaponsinglecostm/10;
00273          int weaponMAM = maxmoverange*weaponsinglecostm/500;
00274          int weaponNAAM = weaponsinglecostm/4;
00275          int weaponMDRF = vehicle->weapons.weapon[W].reactionFireShots*weaponsinglecostm*maxmoverange/400;
00276 
00277          if ( vehicle->weapons.weapon[W].shootable() ) {
00278             if ( vehicle->hasFunction( ContainerBaseType::MoveWithReactionFire ) ) {
00279                if ( vehicle->wait ) {
00280                   if ( vehicle->hasFunction( ContainerBaseType::MoveAfterAttack ) ) {  // MDRF+NAAM+MAM (Defkind,Spear,Stahlschwein)
00281                      weaponspecial += weaponMDRF+weaponMAM-weaponNAAM;
00282                   } else {                                 // MDRF+NAAM     (Coma, CM-U-Boote, Def-Panzer,Turrets)
00283                      weaponspecial += weaponMDRF-weaponNAAM;
00284                   }
00285                } else {
00286                   if ( vehicle->hasFunction( ContainerBaseType::MoveAfterAttack ) ) {  // MDRF+MAM      (Druk, Innocence, Skjold, PHM, Jub-O)
00287                      weaponspecial += weaponMDRF+weaponMAM;
00288                   } else {                                 // MDRF          (Schiffe, fahrende Bunker, Luftabwehrpanzer/Trooper)
00289                      weaponspecial += weaponMDRF;
00290                   }
00291                }
00292             } else {
00293                if ( vehicle->wait ) {
00294                   if ( vehicle->hasFunction( ContainerBaseType::MoveAfterAttack ) ) {  // NAAM+MAM      (Coma2, K5, PzH2000, Pulsar)
00295                      weaponspecial += weaponRF+weaponMAM-weaponNAAM;
00296                   } else {                                 // NAAM          (Coma3, BodenCMs, Schienengesch�tze)
00297                      weaponspecial += weaponRF-weaponNAAM;
00298                   }
00299                } else {                                    // MAM           (FAV,Flugzeug,U-Boot,WIG)
00300                   if ( vehicle->hasFunction( ContainerBaseType::MoveAfterAttack ) ) {
00301                      weaponspecial += weaponRF+weaponMAM;
00302                   } else {                                 // ohne alles    (Panzer/Trooper)
00303                      weaponspecial += weaponRF;
00304                   }
00305                }
00306             }
00307          }
00308          // Aufrechnung
00309          weaponcoste += weaponsinglecoste + weaponspecial ;
00310          weaponcostm += weaponsinglecostm + weaponspecial ;
00311       }
00312    }
00313 
00314    // Part V Specialcost
00315    // stealth (typecost) oder jamming (specialcost)
00316 
00317    if ( vehicle->jamming > 0 && vehicle->hasFunction( ContainerBaseType::JamsOnlyOwnField ) ) {
00318       if (vehicle->jamming < 31 ) {
00319          typecoste += vehicle->jamming*20;  //  fuer Trooper oder eigenschaftsbedingt (klein, schnell)
00320          typecostm += vehicle->jamming*10;
00321       } else {
00322          typecoste += vehicle->jamming*60;  //  fuer alle hoeherwirkenden Stealthverfahren, Anstrich, besondere Konstruktion, tarnfeld usw.
00323          typecostm += vehicle->jamming*50;
00324       }
00325    } else { // JAMMING
00326       specialcoste += vehicle->jamming*200;
00327       specialcostm += vehicle->jamming*150;
00328       // Armorzuschlag
00329       specialcostm += vehicle->jamming*vehicle->armor/10;
00330       // Bewegungszuschlag
00331       if (maxmoverange > 70 ) {
00332          specialcostm += vehicle->jamming*(maxmoverange-70);
00333       }
00334       if (maxmoverange > 120 ) {
00335          specialcostm += vehicle->jamming*(maxmoverange-120);
00336       }
00337       if (maxmoverange > 170 ) {
00338          specialcostm += vehicle->jamming*(maxmoverange-170);
00339       }
00340       if (maxmoverange > 200 ) {
00341          specialcostm += vehicle->jamming*(maxmoverange-200);
00342       }
00343    }
00344 
00345    // Baufunktionen
00346    if ( vehicle->hasFunction( ContainerBaseType::ConstructBuildings )) {
00347       specialcoste += 1000;
00348       specialcostm += 500;
00349    }
00350    if ( vehicle->hasFunction( ContainerBaseType::InternalVehicleProduction ) || vehicle->hasFunction( ContainerBaseType::ExternalVehicleProduction )) {
00351       specialcoste += 1000;
00352       specialcostm += 500;
00353    }
00354    if ( vehicle->objectsBuildable.size() > 0 ||vehicle-> objectGroupsBuildable.size() > 0 ) {
00355       specialcoste += 1000;
00356       specialcostm += 500;
00357    }
00358    // Res Search
00359    if ( vehicle->hasFunction( ContainerBaseType::DetectsMineralResources )) {
00360       specialcoste += vehicle->digrange*150;
00361       specialcostm += vehicle->digrange*100;
00362    }
00363    // Generator
00364    if ( vehicle->hasFunction( ContainerBaseType::MatterConverter) ) {
00365       specialcoste += 1000;
00366       specialcostm += 500;
00367    }
00368    //ParaTrooper
00369    if ( vehicle->hasFunction( ContainerBaseType::Paratrooper ) ) {
00370       specialcoste += vehicle->armor*2 ;
00371       specialcostm += vehicle->armor ;
00372    }
00373    // Reparaturfahrzeug
00374    if ( vehicle->hasFunction(ContainerBaseType::InternalUnitRepair) || vehicle->hasFunction(ContainerBaseType::ExternalRepair) ) {
00375       specialcoste += 1000;
00376       specialcostm += 500;
00377    }
00378    // Selbstreparatur / Heilung
00379    if ( vehicle->hasFunction( ContainerBaseType::AutoRepair ) ) {
00380       specialcoste += vehicle->autorepairrate*vehicle->armor / 15;
00381       specialcostm += vehicle->autorepairrate*vehicle->armor / 15;
00382    }
00383    // Radar
00384    if ( vehicle->view > 40 ) {
00385       specialcoste += (vehicle->view-40)*90;
00386       specialcostm += (vehicle->view-40)*75;
00387       specialcoste += maxmoverange*(vehicle->view-40)/3;
00388       specialcostm += maxmoverange*(vehicle->view-40)/5;
00389    }
00390    // Satview
00391    if ( vehicle->hasFunction( ContainerBaseType::SatelliteView ) ) {
00392       specialcoste += vehicle->view*20;
00393       specialcostm += vehicle->view*8;
00394    }
00395    //Sonar
00396    if ( vehicle->hasFunction(ContainerBaseType::Sonar) && (vehicle->movemalustyp == MoveMalusType::trooper) ) {
00397       specialcoste += vehicle->view*10;
00398       specialcostm += vehicle->view*4;
00399    } else {
00400       if ( vehicle->hasFunction(ContainerBaseType::Sonar)) {
00401          specialcoste += vehicle->view*20;
00402          specialcostm += vehicle->view*10;
00403       }
00404    }
00405    //Move during reaction fire
00406 //   if ( vehicle->hasFunction( MoveWithReactionFire )) {
00407 //      int rfweapcount = 0;
00408 //      for ( int i = 0; i < vehicle->weapons.count; ++i )
00409 //         if ( vehicle->weapons.weapon[i].shootable() )
00410 //            rfweapcount += vehicle->weapons.weapon[i].reactionFireShots;
00411 
00412 //      specialcoste += rfweapcount * 100;
00413 //      specialcostm += rfweapcount * 50;
00414 //   }
00415 
00416    //move after attack
00417 //   if ( vehicle->hasFunction( MoveAfterAttack ) ) {
00418 //      specialcoste += maxmoverange*10;
00419 //      specialcostm += maxmoverange*5;
00420 //   }
00421 
00422    if ( vehicle->jumpDrive.height ) {
00423       int distance = vehicle->jumpDrive.maxDistance;
00424       if ( distance > 1000 )
00425          distance = 1000;
00426       if ( vehicle->hasFunction( ContainerBaseType::MoveWithReactionFire ) && (maxmoverange < 30)) {
00427          specialcoste += distance * 14;
00428          specialcostm += distance * 12;
00429       } else {
00430          specialcoste += distance * 7;
00431          specialcostm += distance * 5;
00432       }
00433    }
00434 
00435    // Part VI - Addition
00436    res.energy += typecoste + weaponcoste + specialcoste;
00437    res.material += typecostm + weaponcostm + specialcostm;
00438 
00439    // Part VII Abschlaege
00440    // keine Luftbetankung
00441    if ( vehicle->hasFunction( ContainerBaseType::NoInairRefuelling )) {
00442       res.energy -= typecoste/6;
00443       res.material -= typecostm/6;
00444    }
00445 
00446    // Kamikazeeinheiten
00447    if ( vehicle->hasFunction( ContainerBaseType::KamikazeOnly )) {
00448       res.energy -= (typecoste+weaponcoste)/2;
00449       res.material -= (typecostm+weaponcostm)/2;
00450    }
00451 
00452    // low movement
00453    if (maxmoverange < 20 ) {
00454       res.energy -= typecoste/4;
00455       res.material -= typecostm/4;
00456    }
00457 
00458    // low movement
00459    if (maxmoverange < 10 ) {
00460       res.energy -= typecoste/4;
00461       res.material -= typecostm/4;
00462    }
00463    // Part VIII Abschluss
00464 
00465    return res;
00466 }

Generated on Mon May 21 01:26:38 2012 for Advanced Strategic Command by  doxygen 1.5.1