00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "FSServer.h"
00027
00028
00029
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;
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;
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
00109 long RacialTrait::BuiltinScan(const Player * player, HullType hc, bool PenScan, long pop ) const
00110 {
00111 long Scan = 0;
00112 if (mBISPopFactor > 0.0) {
00113
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
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
00184 } else if (stricmp(child1->Value(), "ShipDesign") == 0) {
00185
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 }