Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List

Component.cpp

00001 /*
00002 Copyright 2003 - 2005 Elliott Kleinrock, Dan Neely, Kurt W. Over, Damon Domjan
00003 
00004 This file is part of FreeStars, a free clone of the Stars! game.
00005 
00006 FreeStars is free software; you can redistribute it and/or modify
00007 it under the terms of the GNU General Public License as published by
00008 the Free Software Foundation; either version 2 of the License, or
00009 (at your option) any later version.
00010 
00011 FreeStars is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License
00017 along with FreeStars; if not, write to the Free Software
00018 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 The full GPL Copyright notice should be in the file COPYING.txt
00021 
00022 Contact:
00023 Email Elliott at 9jm0tjj02@sneakemail.com
00024 */
00025 
00026 #include "FSServer.h"
00027 
00028 #include <stdlib.h>
00029 #include "Hull.h"
00030 
00031 #ifdef _DEBUG
00032 #define new DEBUG_NEW
00033 #endif
00034 
00035 deque<string> Component::Subtypes;
00036 
00037 long Component::MaxID = 1;
00038 Cost * Component::mDefenseCost = NULL;
00039 Cost * Component::mScannerCost = NULL;
00040 
00041 Component::Component()
00042 //:     mCost()
00043 {
00044         init();
00045 }
00046 
00047 void Component::init()
00048 {
00049         ID = MaxID++;
00050         Type = 0;               // Base type, can also have other capabilities
00051         Mass = 0;
00052         MTGift = false;
00053         Tech.insert(Tech.begin(), Rules::MaxTechType, -1);
00054         mHullType = HC_ALL;
00055 
00056         // specific stuff, most will be defaults
00057         // armor and shield
00058         Armor = 0;              // armor DP
00059         Shield = 0;             // shield DP
00060 
00061         // weapons
00062         WeaponType = -1;        // type of weapon
00063         Power = 0;              // damage power
00064         Range = 0;              // weapon range
00065         Init = 0;               // weapon initiative
00066         Accuracy = 0.0; // base accuracy
00067 
00068         // bombs
00069         BombType = -1;
00070         Killper = 0.0;  // Bomb kill percentage
00071         MinKill = 0;    // Bomb min killed
00072         InstKill = 0;   // Bomb damage to instalations
00073 
00074         // electrical
00075         Cloaking = 0;           // cloaking units
00076         CompPower = 1.0;        // affect on inaccuracy of your missiles 1 for no affect, .8 is +20%
00077         Jamming = 1.0;          // affect on accuracy of incoming missiles 1 for no affect, .8 is 20% jamming
00078         InitAdj = 0;            // adjustment to init
00079         Capacitors = 1.0;       // beam damage multiplier - 1.1 and 1.2 for capacitors
00080         Deflection = 1.0;       // beam damage multiplier - .9 for deflectors
00081         Tachyon = 0.0;
00082 
00083         // mechanical
00084         Colonize = false;       // true if it allows colonization
00085         CargoCapacity = 0;      // cargo capacity
00086         FuelCapacity = 0;       // Fuel capacity
00087         FuelGen = 0;    // Fuel generation ability
00088         RepairRate = 0.0;       // Repair Rate
00089         SpeedBonus = 0.0;       // bonus (.25 for Maneuver Jet)
00090         Dampener = 0.0; // Dampener effect (slows all ships in combat if this item is present)
00091 
00092         // engines
00093         Radiation = -1; // hab type it radiates in, killing pop traveling with it (rad-ram)
00094         SafeSpeed = 9;  // normally 9, some engines allow warp 10
00095         MaxSpeed = 10;  // For expantion
00096         BattleSpeed     = 0;    // battle speed of the engine, normaly dependant on FuelUsage
00097         FreeSpeed = 1;
00098 
00099         // Mine layers
00100         MineType = 0;   // 1 standards, 2 Heavies, 3 speed traps
00101         MineAmount = 0; // number laid per year
00102 
00103         // remote mining
00104         Mines = 0;              // Number of remote mines
00105         RemTerra = 0;   // Remote terraform: 0x01 - deterra only, 0x02 improve only, 0x03 both deterra: 0x10 to initial, 0x20 terra tech (OAs are therefore 0x23, bombs are 0x11)
00106         TerraPower = 0; // power of the remote terraformer
00107 
00108         // Orbitals
00109         GateMass = 0;   // -1 for infinite
00110         GateRange = 0;  // -1 for infinite
00111         DriverSpeed = 0;        // mass driver speed
00112         JumpGate = false;
00113 
00114         // Scanners
00115         ScanSpace = 0;  // deep space (red) scanning coverage
00116         ScanPen = -1;   // orbital (yellow) scanning coverage - every scanner can see a world it is in orbit of but non scanners cannot see details
00117         StealShip = false;              // can steal cargo from ships
00118         StealPlanet = false;    // can steal cargo from planets
00119 
00120         // Terraforming
00121         TerraType = 0;  // -1 for any
00122         TerraLimit = 0; // max amount of terraforming at this tech
00123         DefPower = 0.0; // Defensive power at this tech
00124 
00125         // Station attributes
00126         Refuel = false; // can this station refuel
00127         Dock = 0;               // max ship size built here -1 for infinite
00128         ARMaxPop = 0;   // Max pop for AR races, in cargo units (100 pop a unit)
00129 
00130         // Specials
00131         PlanetReset = false;    // building this resets the planet
00132 }
00133 
00134 Component::~Component()
00135 {
00136         FuelUsage.clear();
00137         PRTNeeded.clear();
00138         PRTDenied.clear();
00139         LRTNeeded.clear();
00140         LRTDenied.clear();
00141 }
00142 
00143 void Component::Cleanup()
00144 {
00145         Subtypes.clear();
00146 }
00147 
00148 bool Component::LoadComponents(const TiXmlNode * comps, deque<Component *> &CompList)
00149 {
00150         const TiXmlNode * child1;
00151         const TiXmlNode * child2;
00152         const char * ptr;
00153 
00154         Component * temp = NULL;
00155         for (child1 = comps->FirstChild("Component"); child1; child1 = child1->NextSibling("Component")) {
00156                 temp = NULL;
00157                 ptr = GetString(child1->FirstChild("Type"));
00158                 if (ptr == NULL)
00159                         return false;
00160 
00161                 ComponentType ct = ParseCompType(ptr);
00162                 if (ct == CT_HULL) {
00163                         temp = new Hull();
00164                         temp->mHullType = HC_NONE;
00165                 } else if (ct == CT_BASE) {
00166                         temp = new Hull();
00167                         temp->mHullType = HC_NONE;
00168                 } else
00169                         temp = new Component();
00170 
00171                 temp->Type = ct;
00172 
00173                 for (child2 = child1->FirstChild(); child2; child2 = child2->NextSibling()) {
00174                         if (child2->Type() != TiXmlNode::ELEMENT)
00175                                 continue;
00176 
00177                         if (stricmp(child2->Value(), "Type") == 0) {
00178                                 // already done, skip it here
00179                         } else if (stricmp(child2->Value(), "Name") == 0) {
00180                                 ptr = GetString(child2);
00181                                 if (ptr != NULL)
00182                                         temp->Name = ptr;
00183                         } else if (stricmp(child2->Value(), "HullType") == 0) {
00184                                 if (temp->mHullType == HC_ALL)
00185                                         temp->mHullType = HC_NONE;
00186 
00187                                 if ((temp->Type == CT_HULL || temp->Type == CT_BASE) && temp->mHullType != HC_NONE) {
00188                                         Message * mess = TheGame->AddMessage("Error: More then one HullType specified");
00189                                         mess->AddItem("Component", temp->Name);
00190                                         continue;
00191                                 }
00192                                 temp->mHullType |= ParseHullType(GetString(child2));
00193                         } else if (stricmp(child2->Value(), "Costs") == 0) {
00194                                 temp->mCost.ReadCosts(child2);
00195                         } else if (stricmp(child2->Value(), "TechReq") == 0) {
00196                                 Rules::ParseArray(child2, temp->Tech, TECHS);
00197                         } else if (stricmp(child2->Value(), "Mass") == 0) {
00198                                 temp->Mass = GetLong(child2);
00199                         } else if (stricmp(child2->Value(), "PRTNeeded") == 0) {
00200                                 const RacialTrait * rt;
00201                                 ptr = GetString(child2);
00202                                 rt = TheGame->ParsePRT(ptr);
00203                                 if (rt == NULL) {
00204                                         Message * mess = TheGame->AddMessage("Error: Unknown PRT");
00205                                         mess->AddItem("Component", temp->Name);
00206                                         mess->AddItem("PRT", ptr);
00207                                         return false;
00208                                 }
00209 
00210                                 temp->PRTNeeded.push_back(rt);
00211                         } else if (stricmp(child2->Value(), "PRTDenied") == 0) {
00212                                 const RacialTrait * rt;
00213                                 ptr = GetString(child2);
00214                                 rt = TheGame->ParsePRT(ptr);
00215                                 if (rt == NULL) {
00216                                         Message * mess = TheGame->AddMessage("Error: Unknown PRT");
00217                                         mess->AddItem("Component", temp->Name);
00218                                         mess->AddItem("PRT", ptr);
00219                                         return false;
00220                                 }
00221 
00222                                 temp->PRTDenied.push_back(rt);
00223                         } else if (stricmp(child2->Value(), "LRTNeeded") == 0) {
00224                                 const RacialTrait * rt;
00225                                 ptr = GetString(child2);
00226                                 rt = TheGame->ParseLRT(ptr);
00227                                 if (rt == NULL) {
00228                                         Message * mess = TheGame->AddMessage("Error: Unknown LRT");
00229                                         mess->AddItem("Component", temp->Name);
00230                                         mess->AddItem("LRT", ptr);
00231                                         return false;
00232                                 }
00233 
00234                                 temp->LRTNeeded.push_back(rt);
00235                         } else if (stricmp(child2->Value(), "LRTDenied") == 0) {
00236                                 const RacialTrait * rt;
00237                                 ptr = GetString(child2);
00238                                 rt = TheGame->ParseLRT(ptr);
00239                                 if (rt == NULL) {
00240                                         Message * mess = TheGame->AddMessage("Error: Unknown LRT");
00241                                         mess->AddItem("Component", temp->Name);
00242                                         mess->AddItem("LRT", ptr);
00243                                         return false;
00244                                 }
00245 
00246                                 temp->LRTDenied.push_back(rt);
00247                         } else if (stricmp(child2->Value(), "Armor") == 0) {
00248                                 temp->Armor = GetLong(child2);
00249                         } else if (stricmp(child2->Value(), "Shield") == 0) {
00250                                 temp->Shield = GetLong(child2);
00251                         } else if (stricmp(child2->Value(), "Power") == 0) {
00252                                 temp->Power = GetLong(child2);
00253                         } else if (stricmp(child2->Value(), "Range") == 0) {
00254                                 temp->Range = GetLong(child2);
00255                         } else if (stricmp(child2->Value(), "Init") == 0) {
00256                                 temp->Init = GetLong(child2);
00257                         } else if (stricmp(child2->Value(), "Accuracy") == 0) {
00258                                 temp->Accuracy = GetDouble(child2);
00259                         } else if (stricmp(child2->Value(), "Killper") == 0) {
00260                                 temp->Killper = GetDouble(child2);
00261                         } else if (stricmp(child2->Value(), "MinKill") == 0) {
00262                                 temp->MinKill = GetLong(child2);
00263                         } else if (stricmp(child2->Value(), "InstKill") == 0) {
00264                                 temp->InstKill = GetLong(child2);
00265                         } else if (stricmp(child2->Value(), "Cloak") == 0) {
00266                                 temp->Cloaking = GetLong(child2);
00267                         } else if (stricmp(child2->Value(), "InitAdj") == 0) {
00268                                 temp->InitAdj = GetLong(child2);
00269                         } else if (stricmp(child2->Value(), "Tachyon") == 0) {
00270                                 temp->Tachyon = GetDouble(child2);
00271                         } else if (stricmp(child2->Value(), "CompPower") == 0) {
00272                                 temp->CompPower = GetDouble(child2);
00273                         } else if (stricmp(child2->Value(), "Jamming") == 0) {
00274                                 temp->Jamming = GetDouble(child2);
00275                         } else if (stricmp(child2->Value(), "Capacitors") == 0) {
00276                                 temp->Capacitors = GetDouble(child2);
00277                         } else if (stricmp(child2->Value(), "Deflection") == 0) {
00278                                 temp->Deflection = GetDouble(child2);
00279                         } else if (stricmp(child2->Value(), "CargoCapacity") == 0) {
00280                                 temp->CargoCapacity = GetLong(child2);
00281                         } else if (stricmp(child2->Value(), "CargoLeft") == 0 && temp->Type == CT_HULL) {
00282                                 dynamic_cast<Hull *>(temp)->SetCargoLeft(GetLong(child2));
00283                         } else if (stricmp(child2->Value(), "CargoTop") == 0 && temp->Type == CT_HULL) {
00284                                 dynamic_cast<Hull *>(temp)->SetCargoTop(GetLong(child2));
00285                         } else if (stricmp(child2->Value(), "CargoWidth") == 0 && temp->Type == CT_HULL) {
00286                                 dynamic_cast<Hull *>(temp)->SetCargoWidth(GetLong(child2));
00287                         } else if (stricmp(child2->Value(), "CargoHeight") == 0 && temp->Type == CT_HULL) {
00288                                 dynamic_cast<Hull *>(temp)->SetCargoHeight(GetLong(child2));
00289                         } else if (stricmp(child2->Value(), "FuelCapacity") == 0) {
00290                                 temp->FuelCapacity = GetLong(child2);
00291                         } else if (stricmp(child2->Value(), "FuelGen") == 0) {
00292                                 temp->FuelGen = GetLong(child2);
00293                         } else if (stricmp(child2->Value(), "Colonize") == 0) {
00294                                 temp->Colonize = GetBool(child2);
00295                         } else if (stricmp(child2->Value(), "RepairRate") == 0) {
00296                                 temp->RepairRate = GetDouble(child2);
00297                         } else if (stricmp(child2->Value(), "SpeedBonus") == 0) {
00298                                 temp->SpeedBonus = GetDouble(child2);
00299                         } else if (stricmp(child2->Value(), "Radiation") == 0) {
00300                                 temp->Radiation = GetLong(child2, -1);
00301                         } else if (stricmp(child2->Value(), "SafeSpeed") == 0) {
00302                                 temp->SafeSpeed = GetLong(child2);
00303                         } else if (stricmp(child2->Value(), "MaxSpeed") == 0) {
00304                                 temp->MaxSpeed = GetLong(child2);
00305                                 if (temp->MaxSpeed > Rules::GetConstant("MaxSpeed")) {
00306                                         temp->MaxSpeed = Rules::GetConstant("MaxSpeed");
00307                                         Message * mess = TheGame->AddMessage("Error: Max speed too high");
00308                                         mess->AddItem("Component", temp->Name);
00309                                         return false;
00310                                 }
00311                         } else if (stricmp(child2->Value(), "BattleSpeed") == 0) {
00312                                 temp->BattleSpeed = GetLong(child2);
00313                         } else if (stricmp(child2->Value(), "FuelUsage") == 0) {
00314                                 if (temp->FuelUsage.size() > 0) {
00315                                         Message * mess = TheGame->AddMessage("Warning: Duplicate FuelUsage");
00316                                         mess->AddItem("Component", temp->Name);
00317                                         return false;
00318                                 }
00319                                 temp->FuelUsage.insert(temp->FuelUsage.begin(), Rules::GetConstant("MaxSpeed"), 0);
00320                                 Rules::ParseArrayFloat(child2, "Warp", "Speed", temp->FuelUsage, NULL);
00321                         } else if (stricmp(child2->Value(), "MineAmount") == 0) {
00322                                 temp->MineAmount = GetLong(child2);
00323                         } else if (stricmp(child2->Value(), "Mines") == 0) {
00324                                 temp->Mines = GetLong(child2);
00325                         } else if (stricmp(child2->Value(), "GateMass") == 0) {
00326                                 temp->GateMass = GetLong(child2);
00327                         } else if (stricmp(child2->Value(), "GateRange") == 0) {
00328                                 temp->GateRange = GetLong(child2);
00329                         } else if (stricmp(child2->Value(), "DriverSpeed") == 0) {
00330                                 temp->DriverSpeed = GetLong(child2);
00331                         } else if (stricmp(child2->Value(), "JumpGate") == 0) {
00332                                 temp->JumpGate = GetBool(child2);
00333                         } else if (stricmp(child2->Value(), "ScanSpace") == 0) {
00334                                 temp->ScanSpace = GetLong(child2);
00335                         } else if (stricmp(child2->Value(), "ScanPen") == 0) {
00336                                 temp->ScanPen = GetLong(child2);
00337                         } else if (stricmp(child2->Value(), "WeaponType") == 0) {
00338                                 ptr = GetString(child2);
00339                                 if (ptr == NULL)
00340                                         return false;
00341 
00342                                 if (stricmp(ptr, "Beam") == 0)
00343                                         temp->WeaponType = WT_BEAM;
00344                                 else if (stricmp(ptr, "Gatling") == 0)
00345                                         temp->WeaponType = WT_GATLING;
00346                                 else if (stricmp(ptr, "Sapper") == 0)
00347                                         temp->WeaponType = WT_SAPPER;
00348                                 else if (stricmp(ptr, "Torpedo") == 0)
00349                                         temp->WeaponType = WT_TORP;
00350                                 else if (stricmp(ptr, "Missile") == 0)
00351                                         temp->WeaponType = WT_MISSILE;
00352                                 else {
00353                                         Message * mess = TheGame->AddMessage("Warning: Unkown weapon type");
00354                                         mess->AddItem("Component", temp->Name);
00355                                         mess->AddItem("Type", ptr);
00356                                 }
00357                         } else if (stricmp(child2->Value(), "BombType") == 0) {
00358                                 ptr = GetString(child2);
00359                                 if (ptr == NULL)
00360                                         return false;
00361 
00362                                 if (stricmp(ptr, "Standard") == 0)
00363                                         temp->BombType = BT_NORMAL;
00364                                 else if (stricmp(ptr, "Smart") == 0)
00365                                         temp->BombType = BT_SMART;
00366                                 else if (stricmp(ptr, "Terra") == 0)
00367                                         temp->BombType = BT_TERRA;
00368                                 else {
00369                                         Message * mess = TheGame->AddMessage("Warning: Unknown bomb type");
00370                                         mess->AddItem("Component", temp->Name);
00371                                         mess->AddItem("Type", ptr);
00372                                 }
00373                         } else if (stricmp(child2->Value(), "MineType") == 0) {
00374                                 ptr = GetString(child2);
00375                                 if (ptr == NULL)
00376                                         return false;
00377 
00378                                 temp->MineType = Rules::MineID(ptr);
00379                                 if (temp->MineType < 0) {
00380                                         Message * mess = TheGame->AddMessage("Warning: Unknown mine type");
00381                                         mess->AddItem("Component", temp->Name);
00382                                         mess->AddItem("Type", ptr);
00383                                 }
00384                         } else if (stricmp(child2->Value(), "RemTerra") == 0) {
00385                                 ptr = GetString(child2);
00386                                 if (ptr == NULL)
00387                                         return false;
00388 
00389                                 if (stricmp(ptr, "DeTerraform") == 0)
00390                                         temp->RemTerra |= TERRA_DETERRA;
00391                                 else if (stricmp(ptr, "Terraforming") == 0)
00392                                         temp->RemTerra |= TERRA_POSTERRA;
00393                                 else if (stricmp(ptr, "To Initial Value") == 0)
00394                                         temp->RemTerra |= TERRA_TOINIT;
00395                                 else if (stricmp(ptr, "To Tech Limit") == 0)
00396                                         temp->RemTerra |= TERRA_TOTECH;
00397                                 else if (stricmp(ptr, "Both") == 0)
00398                                         temp->RemTerra |= TERRA_TERRABOTH;
00399                                 else if (stricmp(ptr, "Bomb") == 0)
00400                                         temp->RemTerra |= TERRA_BOMB;
00401                                 else if (stricmp(ptr, "Terraform phase") == 0)
00402                                         temp->RemTerra |= TERRA_REMOTE;
00403                                 else {
00404                                         Message * mess = TheGame->AddMessage("Warning: Unknown terraformer type");
00405                                         mess->AddItem("Component", temp->Name);
00406                                         mess->AddItem("Type", ptr);
00407                                 }
00408                         } else if (stricmp(child2->Value(), "TerraPower") == 0) {
00409                                 temp->TerraPower = GetLong(child2);
00410                         } else if (stricmp(child2->Value(), "Thieving") == 0) {
00411                                 ptr = GetString(child2);
00412                                 if (ptr == NULL)
00413                                         return false;
00414 
00415                                 if (stricmp(ptr, "Ship") == 0)
00416                                         temp->StealShip = true;
00417                                 else if (stricmp(ptr, "Planet") == 0)
00418                                         temp->StealPlanet = true;
00419                                 else if (stricmp(ptr, "Both") == 0) {
00420                                         temp->StealShip = true;
00421                                         temp->StealPlanet = true;
00422                                 } else {
00423                                         Message * mess = TheGame->AddMessage("Warning: Unknown thieving type");
00424                                         mess->AddItem("Component", temp->Name);
00425                                         mess->AddItem("Type", ptr);
00426                                 }
00427                         } else if (stricmp(child2->Value(), "TerraType") == 0) {
00428                                 ptr = GetString(child2);
00429                                 if (ptr == NULL)
00430                                         return false;
00431 
00432                                 if (stricmp(ptr, "Any") == 0 || stricmp(ptr, "All") == 0 || stricmp(ptr, "Total") == 0)
00433                                         temp->TerraType = -1;
00434                                 else
00435                                         temp->TerraType = Rules::HabID(ptr);
00436                         } else if (stricmp(child2->Value(), "TerraLimit") == 0) {
00437                                 temp->TerraLimit = GetLong(child2);
00438                         } else if (stricmp(child2->Value(), "DefPower") == 0) {
00439                                 temp->DefPower = GetDouble(child2);
00440                         } else if (stricmp(child2->Value(), "FreeSpeed") == 0) {
00441                                 temp->FreeSpeed = GetLong(child2);
00442                         } else if (stricmp(child2->Value(), "MTGift") == 0) {
00443                                 temp->MTGift = GetBool(child2);
00444                         } else if (stricmp(child2->Value(), "PlanetReset") == 0) {
00445                                 temp->PlanetReset = GetBool(child2);
00446                         } else if (stricmp(child2->Value(), "Dampener") == 0) {
00447                                 temp->Dampener = GetDouble(child2, 0.0);
00448                         } else if (stricmp(child2->Value(), "Refuel") == 0) {
00449                                 temp->Refuel = GetBool(child2);
00450                         } else if (stricmp(child2->Value(), "Dock") == 0) {
00451                                 temp->Dock = GetLong(child2);
00452                         } else if (stricmp(child2->Value(), "ARMaxPop") == 0) {
00453                                 temp->ARMaxPop = GetLong(child2);
00454                         } else if (stricmp(child2->Value(), "EngineType") == 0) {
00455                                 // For expansion
00456                         } else if (stricmp(child2->Value(), "Slot") == 0) {
00457                                 if (!dynamic_cast<Hull *>(temp) || !dynamic_cast<Hull *>(temp)->LoadSlot(child2)) {
00458                                         Message * mess = TheGame->AddMessage("Error: Slot problem on hull");
00459                                         mess->AddItem("Component", temp->Name);
00460                                         return false;
00461                                 }
00462                         } else if (stricmp(child2->Value(), "Value") == 0) {
00463                                 temp->SubTypeIndex.push_back(Component::ParseSubType(GetString(child2->FirstChild("Type")), true));
00464                                 temp->SubTypeValue.push_back(GetLong(child2->FirstChild("Score")));
00465                         } else {
00466                                 Message * mess = TheGame->AddMessage("Warning: Unknown Section in Component");
00467                                 mess->AddItem("Component", temp->Name);
00468                                 mess->AddItem("Section", child2->Value());
00469                         }
00470                 }
00471 
00472                 if (temp->Type == CT_HULL && ((temp->mHullType & HC_BASE) || temp->mHullType == HC_ALL || temp->mHullType == HC_UNARMED || temp->mHullType == HC_ARMED)) {
00473                         Message * mess = TheGame->AddMessage( "Error: Invalid HullType");
00474                         mess->AddItem("Component", temp->Name);
00475                         continue;
00476                         
00477                 } else if (temp->Type == CT_BASE && !(temp->mHullType & HC_BASE)) {
00478                         Message * mess = TheGame->AddMessage( "Error: Invalid HullType");
00479                         mess->AddItem("Component", temp->Name);
00480                         continue;
00481                 } else if (temp->Type == CT_DEFENSE) {
00482                         mDefenseCost = &temp->mCost;
00483                 } else if (temp->Type == CT_PLANSCAN) {
00484                         mScannerCost = &temp->mCost;
00485                 }
00486 
00487                 CompList.insert(CompList.end(), temp);
00488         }
00489 
00490         return true;
00491 }
00492 
00493 long Component::ParseSubType(const char * ptr, bool insert)
00494 {
00495         deque<string>::iterator iter;
00496         iter = find(Subtypes.begin(), Subtypes.end(), ptr);
00497         if (iter == Subtypes.end()) {
00498                 if (insert)
00499                         iter = Subtypes.insert(iter, ptr);
00500                 else
00501                         return -1;
00502         }
00503 
00504         return iter - Subtypes.begin();
00505 }
00506 
00507 ComponentType Component::ParseCompType(const char * ptr)
00508 {
00509         if (ptr == NULL || *ptr == '\0') {
00510                 TheGame->AddMessage("Error: Missing Component type");
00511                 return CT_NONE;
00512         }
00513 
00514         if (stricmp(ptr, "Hull") == 0)
00515                 return CT_HULL;
00516         else if (stricmp(ptr, "Base") == 0)
00517                 return CT_BASE;
00518         else if (stricmp(ptr, "Armor") == 0)
00519                 return CT_ARMOR;
00520         else if (stricmp(ptr, "Shield") == 0)
00521                 return CT_SHIELD;
00522         else if (stricmp(ptr, "Weapon") == 0)
00523                 return CT_WEAPON;
00524         else if (stricmp(ptr, "Bomb") == 0)
00525                 return CT_BOMB;
00526         else if (stricmp(ptr, "Electrical") == 0)
00527                 return CT_ELEC;
00528         else if (stricmp(ptr, "Planetary Scanner") == 0)
00529                 return CT_PLANSCAN;
00530         else if (stricmp(ptr, "Planetary") == 0)
00531                 return CT_PLANET_SPECIAL;
00532         else if (stricmp(ptr, "Defense") == 0)
00533                 return CT_DEFENSE;
00534         else if (stricmp(ptr, "Terraforming") == 0)
00535                 return CT_TERRAFORM;
00536         else if (stricmp(ptr, "Engine") == 0)
00537                 return CT_ENGINE;
00538         else if (stricmp(ptr, "Gate") == 0)
00539                 return CT_GATE;
00540         else if (stricmp(ptr, "Driver") == 0)
00541                 return CT_DRIVER;
00542         else if (stricmp(ptr, "Mine Layer") == 0)
00543                 return CT_MINELAY;
00544         else if (stricmp(ptr, "Remote Miner") == 0)
00545                 return CT_MINER;
00546         else if (stricmp(ptr, "Mechanical") == 0)
00547                 return CT_MECH;
00548         else if (stricmp(ptr, "Scanner") == 0)
00549                 return CT_SCANNER;
00550         else if (stricmp(ptr, "Alchemy") == 0)
00551                 return CT_ALCHEMY;
00552         else {
00553                 Message* mess = TheGame->AddMessage("Error: Invalid Component type");
00554                 mess->AddItem("Type", ptr);
00555                 return CT_NONE;
00556         }
00557 }
00558 
00559 HullType Component::ParseHullType(const char * ptr)
00560 {
00561         if (ptr == NULL || *ptr == '\0') {
00562                 TheGame->AddMessage("Error: Missing HullType");
00563                 return HC_NONE;
00564         }
00565 
00566         if (stricmp(ptr, "Scout") == 0)
00567                 return HC_SCOUT;
00568         else if (stricmp(ptr, "Mine Layer") == 0)
00569                 return HC_LAYER;
00570         else if (stricmp(ptr, "Mini Colony") == 0)
00571                 return HC_MINICOL;
00572         else if (stricmp(ptr, "Warship") == 0)
00573                 return HC_WARSHIP;
00574         else if (stricmp(ptr, "Bomber") == 0)
00575                 return HC_BOMBER;
00576         else if (stricmp(ptr, "Remote Miner") == 0)
00577                 return HC_MINER;
00578         else if (stricmp(ptr, "Colony") == 0)
00579                 return HC_COLONY;
00580         else if (stricmp(ptr, "Freighter") == 0)
00581                 return HC_FREIGHTER;
00582         else if (stricmp(ptr, "Utility") == 0)
00583                 return HC_UTILITY;
00584         else if (stricmp(ptr, "Fuel Transport") == 0)
00585                 return HC_FUEL;
00586         else if (stricmp(ptr, "Station") == 0)
00587                 return HC_SMALLBASE;
00588         else if (stricmp(ptr, "SuperStation") == 0)
00589                 return HC_BIGBASE;
00590         else if (stricmp(ptr, "Base") == 0)
00591                 return HC_BASE;
00592         else if (stricmp(ptr, "Unarmed") == 0)
00593                 return HC_UNARMED;
00594         else if (stricmp(ptr, "All") == 0)
00595                 return HC_ALL;
00596         else {
00597                 Message* mess = TheGame->AddMessage("Error: Invalid HullType");
00598                 mess->AddItem("Type", ptr);
00599                 return HC_NONE;
00600         }
00601 }
00602 
00603 long Component::GetSweeping(long RangeBonus) const
00604 {
00605         if (WeaponType == WT_BEAM)
00606                 return Power * (Range + RangeBonus) * (Range + RangeBonus);
00607         else if (WeaponType == WT_GATLING)
00608                 return Power * (Range + RangeBonus + 2) * (Range + RangeBonus + 2);
00609         else
00610                 return 0;
00611 }
00612 
00613 bool Component::IsBuildable(const Player * player) const        // can this player build this component (right LRT and tech levels)
00614 {
00615         // tech first
00616         for (TechType tt = 0; tt < Rules::MaxTechType; ++tt) {
00617                 if (Tech[tt] > player->GetTechLevel(tt))
00618                         return false;
00619         }
00620 
00621         if (find(PRTDenied.begin(), PRTDenied.end(), player->GetPRT()) != PRTDenied.end())
00622                 return false;
00623 
00624         if (PRTNeeded.size() > 0 && find(PRTNeeded.begin(), PRTNeeded.end(), player->GetPRT()) == PRTNeeded.end())
00625                 return false;
00626 
00627         if (LRTNeeded.size() > 0) {
00628                 deque<const RacialTrait *>::const_iterator i;
00629                 for (i = LRTNeeded.begin(); i != LRTNeeded.end(); ++i) {
00630                         if (player->HasLRT(*i))
00631                                 break;
00632                 }
00633 
00634                 if (i == LRTNeeded.end())
00635                         return false;
00636         }
00637 
00638         if (LRTDenied.size() > 0) {
00639                 deque<const RacialTrait *>::const_iterator i;
00640                 for (i = LRTDenied.begin(); i != LRTDenied.end(); ++i) {
00641                         if (player->HasLRT(*i))
00642                                 return false;
00643                 }
00644         }
00645 
00646         return true;
00647 }
00648 
00649 long Component::GetScore(const Component * check, long ValueType)
00650 {
00651         for (unsigned long i = 0; i < check->SubTypeIndex.size(); ++i) {
00652                 if (check->SubTypeIndex[i] == ValueType)
00653                         return check->SubTypeValue[i];
00654         }
00655 
00656         return 0;
00657 }
00658 
00659 Cost Component::GetCost(const Player * owner) const
00660 {
00661         Cost c;
00662         double reduc = owner->Miniturize(this);
00663         for (CargoType ct = RESOURCES; ct < Rules::MaxMinType; ++ct) {
00664                 c[ct] = GetCost()[ct] - long(GetCost()[ct] * reduc + .5);
00665                 if (c[ct] == 0 && GetCost()[ct] > 0)
00666                         c[ct] = 1;
00667         }
00668 
00669         return c;
00670 }

Generated on Mon Aug 8 21:33:42 2005 for Freestars by  doxygen 1.4.2-20050421