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

RacialTrait.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 
00029 //#pragma warning(disable : 4786)       // identifier was truncated to '255' characters in the debug information
00030 #include "RacialTrait.h"
00031 
00032 #include "Hull.h"
00033 
00034 #ifdef _DEBUG
00035 #define new DEBUG_NEW
00036 #endif
00037 
00038 RacialTrait::RacialTrait()
00039 {
00040         mGroundAttackFactor = 1.0;
00041         mGroundDefenseFactor = 1.0;
00042         mGrowthRateFactor = 1.0;
00043         mPopulationFactor = 1.0;
00044         mInherentCloakHull = HC_NONE;
00045         mInherentCloakAmount = 0;
00046         mCloakCargo = false;
00047         mMineSpeedBonus = 0;
00048         mSpyTechBonus = 0.0;
00049         mBattleSpeedBonus = 0.0;
00050         mPermaformChance = 0.0;
00051         mCanSeeHabSettings = false;
00052         mTemporaryTerraform = false;
00053         mScanDesign = false;
00054         mRepairFactor = 1.0;
00055         mFreighterReproduction = 0.0;
00056         mMineFieldScanning = false;
00057         mCanRemoteDetonate = false;
00058         mMineDecayFactor = 1.0;
00059 
00060         mPacketTerraform = false;
00061         mPacketScanning = false;
00062         mPacketCostMinFactor = 1.1;     // Default 10% penalty to minerals in packets
00063         mPacketSizeOneMin = 100;
00064         mPacketSizeMixed = 40;
00065         mPacketCostResources = 10;
00066         mPacketDecayFactor = 1.0;
00067         mPacketCatchFactor = 1.0;
00068 
00069         mStartAtBonus = 3;
00070         mSecondPlanet = false;
00071         mGateCargo = false;
00072         mOvergateLossFactor = 1.0;
00073         mGateScanning = false;
00074         mARTechType = -1;
00075         mFuelFactor = 1.0;
00076         mGeneralResearch = false;
00077         mUltimateRecycle = false;
00078         mEngineFailureSpeed = Rules::GetConstant("MaxSpeed");
00079         mEngineFailureRate = 0.0;
00080         mSpaceScanFactor = 1.0;
00081         mPenScanFactor = 1.0;   // mostly not used, normally only applies to AR builtin scanning
00082         mStartingPopFactor = 1.0;
00083         mMaxMiniturize = 0.75;
00084         mMiniturizeRate = 0.04;
00085         mZeroTechCost = 1.0;
00086         mShieldFactor = 1.0;
00087         mArmorFactor = 1.0;
00088         mShieldRegenRate = 0.0;
00089         mStartingTech.insert(mStartingTech.begin(), Rules::MaxTechType, 0);
00090 
00091         mBISHull = HC_NONE;
00092         mBISHullPen = HC_NONE;
00093         mBISTech = -1;
00094         mBISMultiplier = 0;
00095         mBISCheckPenFactor = false;
00096         mBISPopFactor = 0.0;
00097 
00098         mDefenseFactor = 1.0;
00099 }
00100 
00101 RacialTrait::~RacialTrait()
00102 {
00103         int i;
00104         for (i = 0; i < mShipDesigns.size(); ++i)
00105                 delete mShipDesigns[i];
00106 }
00107 
00108 // Builtin scanning -- JOAT and AR in base rules
00109 long RacialTrait::BuiltinScan(const Player * player, HullType hc, bool PenScan, long pop /*= 0*/) const
00110 {
00111         long Scan = 0;
00112         if (mBISPopFactor > 0.0) {
00113                 // AR scanning: Dependant on population
00114                 if (hc & mBISHull) {
00115                         Scan = long(sqrt(pop * mBISPopFactor));
00116                         if (PenScan) {
00117                                 Scan /= 2;
00118                                 if (mBISCheckPenFactor)
00119                                         Scan = long(Scan * PenScanFactor());
00120                                 if (!(hc & mBISHullPen))
00121                                         Scan = 0;
00122                         }
00123                 }
00124         } else if (mBISTech >= 0) {
00125                 // JOAT scanning: Dependant on tech and multiplier
00126                 if (hc & mBISHull) {
00127                         Scan = player->GetTechLevel(mBISTech) * mBISMultiplier;
00128                         if (PenScan) {
00129                                 Scan /= 2;
00130                                 if (mBISCheckPenFactor)
00131                                         Scan = long(Scan * PenScanFactor());
00132                                 if (!(hc & mBISHullPen))
00133                                         Scan = 0;
00134                         }
00135                 }
00136         }
00137 
00138         return Scan;
00139 }
00140 
00141 double RacialTrait::ComponentCostFactor(ComponentType ct) const
00142 {
00143         deque<ComponentType>::const_iterator iter;
00144         iter = find(mComponentCostType.begin(), mComponentCostType.end(), ct);
00145         if (iter != mComponentCostType.end()) {
00146                 return mComponentCostFactor[iter - mComponentCostType.begin()];
00147         } else
00148                 return 1.0;
00149 }
00150 
00151 void RacialTrait::ParseStartShips(const TiXmlNode * node)
00152 {
00153         const TiXmlNode * child1;
00154         for (child1 = node->FirstChild("ShipDesign"); child1; child1 = child1->NextSibling("ShipDesign")) {
00155                 Ship * sd = new Ship();
00156                 sd->SetCannotBuild(TheGame->ParseComponent(GetString(child1->FirstChild("IfCannotBuild"))));
00157                 if (sd->ParseNode(child1, NULL, false)) {
00158                         mShipDesigns.insert(mShipDesigns.end(), sd);
00159                         mShipCounts.insert(mShipCounts.end(), GetLong(child1->FirstChild("ShipCount")));
00160                         mShip2ndCounts.insert(mShip2ndCounts.end(), GetLong(child1->FirstChild("SecondPlanet")));
00161                 } else
00162                         delete sd;
00163         }
00164 }
00165 
00166 RacialTrait * RacialTrait::ParseNode(const TiXmlNode * node)
00167 {
00168         RacialTrait * rt = new RacialTrait();
00169 
00170         const TiXmlNode * child1;
00171         const TiXmlNode * child2;
00172         const char * ptr;
00173 
00174         for (child1 = node->FirstChild(); child1; child1 = child1->NextSibling()) {
00175                 if (child1->Type() == TiXmlNode::COMMENT)
00176                         continue;
00177 
00178                 if (stricmp(child1->Value(), "Name") == 0) {
00179                         ptr = GetString(child1);
00180                         if (ptr != NULL)
00181                                 rt->mName = ptr;
00182                 } else if (stricmp(child1->Value(), "Cost") == 0) {
00183                         // Skip cost for now
00184                 } else if (stricmp(child1->Value(), "ShipDesign") == 0) {
00185                         // Ship desgns are read after components are loaded, so skip for now
00186                 } else if (stricmp(child1->Value(), "GroundAttackFactor") == 0) {
00187                         rt->mGroundAttackFactor = GetDouble(child1, 1.0);
00188                 } else if (stricmp(child1->Value(), "GroundDefenseFactor") == 0) {
00189                         rt->mGroundDefenseFactor = GetDouble(child1, 1.0);
00190                 } else if (stricmp(child1->Value(), "GrowthRateFactor") == 0) {
00191                         rt->mGrowthRateFactor = GetDouble(child1, 1.0);
00192                 } else if (stricmp(child1->Value(), "PopulationFactor") == 0) {
00193                         rt->mPopulationFactor = GetDouble(child1, 1.0);
00194                 } else if (stricmp(child1->Value(), "InherentCloaking") == 0) {
00195                         child2 = child1->FirstChild("HullType");
00196                         rt->mInherentCloakHull = Component::ParseHullType(GetString(child2));
00197                         child2 = child1->FirstChild("Cloaking");
00198                         rt->mInherentCloakAmount = GetLong(child2);
00199                 } else if (stricmp(child1->Value(), "CloakCargo") == 0) {
00200                         rt->mCloakCargo = GetBool(child1);
00201                 } else if (stricmp(child1->Value(), "MineSpeedBonus") == 0) {
00202                         rt->mMineSpeedBonus = GetLong(child1);
00203                 } else if (stricmp(child1->Value(), "SpyTechBonus") == 0) {
00204                         rt->mSpyTechBonus = GetDouble(child1, 0.0);
00205                 } else if (stricmp(child1->Value(), "BattleSpeedBonus") == 0) {
00206                         rt->mBattleSpeedBonus = GetDouble(child1, 0.0);
00207                 } else if (stricmp(child1->Value(), "ComponentCostFactor") == 0) {
00208                         child2 = child1->FirstChild("ComponentType");
00209                         rt->mComponentCostType.insert(rt->mComponentCostType.end(), Component::ParseCompType(GetString(child2)));
00210                         child2 = child1->FirstChild("CostFactor");
00211                         rt->mComponentCostFactor.insert(rt->mComponentCostFactor.end(), GetDouble(child2, 1.0));
00212                 } else if (stricmp(child1->Value(), "PermaformChance") == 0) {
00213                         rt->mPermaformChance = GetDouble(child1, 0.0);
00214                 } else if (stricmp(child1->Value(), "CanSeeHabSettings") == 0) {
00215                         rt->mCanSeeHabSettings = GetBool(child1);
00216                 } else if (stricmp(child1->Value(), "TemporaryTerraform") == 0) {
00217                         rt->mTemporaryTerraform = GetBool(child1);
00218                 } else if (stricmp(child1->Value(), "ScanDesign") == 0) {
00219                         rt->mScanDesign = GetBool(child1);
00220                 } else if (stricmp(child1->Value(), "RepairFactor") == 0) {
00221                         rt->mRepairFactor = GetDouble(child1, 1.0);
00222                 } else if (stricmp(child1->Value(), "FreighterReproduction") == 0) {
00223                         rt->mFreighterReproduction = GetDouble(child1, 0.0);
00224                 } else if (stricmp(child1->Value(), "MineFieldScanning") == 0) {
00225                         rt->mMineFieldScanning = GetBool(child1);
00226                 } else if (stricmp(child1->Value(), "CanRemoteDetonate") == 0) {
00227                         rt->mCanRemoteDetonate = GetBool(child1);
00228                 } else if (stricmp(child1->Value(), "MineDecayFactor") == 0) {
00229                         rt->mMineDecayFactor = GetDouble(child1, 1.0);
00230                 } else if (stricmp(child1->Value(), "PacketTerraform") == 0) {
00231                         rt->mPacketTerraform = GetBool(child1);
00232                 } else if (stricmp(child1->Value(), "PacketScanning") == 0) {
00233                         rt->mPacketScanning = GetBool(child1);
00234                 } else if (stricmp(child1->Value(), "PacketCostMinFactor") == 0) {
00235                         rt->mPacketCostMinFactor = GetDouble(child1, 1.0);
00236                 } else if (stricmp(child1->Value(), "PacketSizeOneMin") == 0) {
00237                         rt->mPacketSizeOneMin = GetLong(child1, 100);
00238                 } else if (stricmp(child1->Value(), "PacketSizeMixed") == 0) {
00239                         rt->mPacketSizeMixed = GetLong(child1, 40);
00240                 } else if (stricmp(child1->Value(), "PacketCostResources") == 0) {
00241                         rt->mPacketCostResources = GetLong(child1, 10);
00242                 } else if (stricmp(child1->Value(), "PacketDecayFactor") == 0) {
00243                         rt->mPacketDecayFactor = GetDouble(child1, 1.0);
00244                 } else if (stricmp(child1->Value(), "PacketCatchFactor") == 0) {
00245                         rt->mPacketCatchFactor = GetDouble(child1, 1.0);
00246                 } else if (stricmp(child1->Value(), "PacketDecayPenalty") == 0) {
00247                         rt->mPacketDecayPenalty = GetLong(child1);
00248 
00249                 } else if (stricmp(child1->Value(), "StartingTech") == 0) {
00250                         Rules::ParseArray(child1, rt->mStartingTech, TECHS);
00251                 } else if (stricmp(child1->Value(), "StartAtBonus") == 0) {
00252                         rt->mStartAtBonus = GetLong(child1, 3);
00253                 } else if (stricmp(child1->Value(), "SecondPlanet") == 0) {
00254                         rt->mSecondPlanet = GetBool(child1);
00255                 } else if (stricmp(child1->Value(), "GateCargo") == 0) {
00256                         rt->mGateCargo = GetBool(child1);
00257                 } else if (stricmp(child1->Value(), "OvergateLossFactor") == 0) {
00258                         rt->mOvergateLossFactor = GetDouble(child1, 1.0);
00259                 } else if (stricmp(child1->Value(), "GateScanning") == 0) {
00260                         rt->mGateScanning = GetBool(child1);
00261                 } else if (stricmp(child1->Value(), "ARTechType") == 0) {
00262                         rt->mARTechType = Rules::TechID(GetString(child1));
00263                         if (rt->mARTechType < 0) {
00264                                 rt->mARTechType = 0;
00265                                 TheGame->AddMessage("Invalid AR Tech Type");
00266                         }
00267                 } else if (stricmp(child1->Value(), "FuelFactor") == 0) {
00268                         rt->mFuelFactor = GetDouble(child1, 1.0);
00269                 } else if (stricmp(child1->Value(), "GeneralResearch") == 0) {
00270                         rt->mGeneralResearch = GetBool(child1);
00271                 } else if (stricmp(child1->Value(), "UltimateRecycle") == 0) {
00272                         rt->mUltimateRecycle = GetBool(child1);
00273                 } else if (stricmp(child1->Value(), "EngineFailureSpeed") == 0) {
00274                         rt->mEngineFailureSpeed = GetLong(child1, 0);
00275                 } else if (stricmp(child1->Value(), "EngineFailureRate") == 0) {
00276                         rt->mEngineFailureRate = GetDouble(child1, 0.0);
00277                 } else if (stricmp(child1->Value(), "SpaceScanFactor") == 0) {
00278                         rt->mSpaceScanFactor = GetDouble(child1, 1.0);
00279                 } else if (stricmp(child1->Value(), "PenScanFactor") == 0) {
00280                         rt->mPenScanFactor = GetDouble(child1, 1.0);
00281                 } else if (stricmp(child1->Value(), "StartingPopFactor") == 0) {
00282                         rt->mStartingPopFactor = GetDouble(child1, 1.0);
00283                 } else if (stricmp(child1->Value(), "MaxMiniturize") == 0) {
00284                         rt->mMaxMiniturize = GetDouble(child1, 0.75);
00285                 } else if (stricmp(child1->Value(), "MiniturizeRate") == 0) {
00286                         rt->mMiniturizeRate = GetDouble(child1, 0.04);
00287                 } else if (stricmp(child1->Value(), "ZeroTechCost") == 0) {
00288                         rt->mZeroTechCost = GetDouble(child1, 1.0);
00289                 } else if (stricmp(child1->Value(), "ShieldFactor") == 0) {
00290                         rt->mShieldFactor = GetDouble(child1, 1.0);
00291                 } else if (stricmp(child1->Value(), "ArmorFactor") == 0) {
00292                         rt->mArmorFactor = GetDouble(child1, 1.0);
00293                 } else if (stricmp(child1->Value(), "ShieldRegenRate") == 0) {
00294                         rt->mShieldRegenRate = GetDouble(child1, 0.0);
00295                 } else if (stricmp(child1->Value(), "BuiltInScan") == 0) {
00296                         child2 = child1->FirstChild("HullType");
00297                         rt->mBISHull = Component::ParseHullType(GetString(child2));
00298                         child2 = child1->FirstChild("PenScanHullType");
00299                         rt->mBISHullPen = Component::ParseHullType(GetString(child2));
00300                         child2 = child1->FirstChild("TechType");
00301                         rt->mBISTech = GetLong(child2, -1);
00302                         child2 = child1->FirstChild("Multiplier");
00303                         rt->mBISMultiplier = GetLong(child2, 20);
00304                         child2 = child1->FirstChild("CheckPenFactor");
00305                         rt->mBISCheckPenFactor = GetBool(child2);
00306                         child2 = child1->FirstChild("PopFactor");
00307                         rt->mBISPopFactor = GetDouble(child2, 0.0);
00308                 } else if (stricmp(child1->Value(), "DefenseFactor") == 0) {
00309                         rt->mDefenseFactor = GetDouble(child1, 1.0);
00310                 } else {
00311                         Message * mess = TheGame->AddMessage("Warning: Unknown section");
00312                         mess->AddItem("Racial trait", rt->mName);
00313                         mess->AddItem("Section", child1->Value());
00314                         continue;
00315                 }
00316         }
00317 
00318         return rt;
00319 }

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