CnC_Remastered_Collection/REDALERT/RULES.CPP
PG-SteveT 03416d24e1 Initial Source Code commit
Initial commit of original Tiberian Dawn and Red Alert source code converted to build as DLLs, and compatible with the release version of Command & Conquer Remastered.
2020-05-27 12:16:20 -07:00

1074 lines
53 KiB
C++

//
// Copyright 2020 Electronic Arts Inc.
//
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
// software: you can redistribute it and/or modify it under the terms of
// the GNU General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
// in the hope that it will be useful, but with permitted additional restrictions
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
// distributed with this program. You should have received a copy of the
// GNU General Public License along with permitted additional restrictions
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
/* $Header: /CounterStrike/RULES.CPP 1 3/03/97 10:25a Joe_bostic $ */
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Command & Conquer *
* *
* File Name : RULES.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 05/12/96 *
* *
* Last Update : September 10, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* Difficulty_Get -- Fetch the difficulty bias values. *
* RulesClass::AI -- Processes the AI control constants from the database. *
* RulesClass::General -- Process the general main game rules. *
* RulesClass::Heap_Maximums -- Fetch and process the heap override values. *
* RulesClass::IQ -- Fetches the IQ control values from the INI database. *
* RulesClass::Land_Types -- Inits the land type values. *
* RulesClass::MPlayer -- Fetch and process the multiplayer default settings. *
* RulesClass::Powerups -- Process the powerup values from the database. *
* RulesClass::Process -- Fetch the bulk of the rule data from the control file. *
* RulesClass::Recharge -- Process the super weapon recharge statistics. *
* RulesClass::RulesClass -- Default constructor for rules class object. *
* RulesClass::Themes -- Fetches the theme control values from the INI database. *
* Techno_Get -- Get rule data common for all techno type objects. *
* _Scale_To_256 -- Scales a 1..100 number into a 1..255 number. *
* RulesClass::Difficulty -- Fetch the various difficulty group settings. *
* RulesClass::Objects -- Fetch all the object characteristic values. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#include "vortex.h"
/***********************************************************************************************
* _Scale_To_256 -- Scales a 1..100 number into a 1..255 number. *
* *
* This is a helper routine that will take a decimal percentage number and convert it *
* into a game based fixed point number. *
* *
* INPUT: val -- Decimal percent number to convert. *
* *
* OUTPUT: Returns with the decimal percent number converted to a game fixed point number. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/17/1996 JLB : Created. *
*=============================================================================================*/
static inline int _Scale_To_256(int val)
{
val = fixed(100, 256) * val;
val = min(val, 255);
return(val);
}
/***********************************************************************************************
* RulesClass::RulesClass -- Default constructor for rules class object. *
* *
* This is the default constructor for the rules class object. Although it initializes the *
* rule data with default values, it is expected that they will all be overridden by the *
* rules control file. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/17/1996 JLB : Created. *
*=============================================================================================*/
RulesClass::RulesClass(void) :
TurboBoost("1.5"),
AttackInterval(3),
AttackDelay(5),
PowerEmergencyFraction(fixed::_3_4),
BadgerBombCount(1),
AirstripRatio(".12"),
AirstripLimit(5),
HelipadRatio(".12"),
HelipadLimit(5),
TeslaRatio(".16"),
TeslaLimit(10),
AARatio(".14"),
AALimit(10),
DefenseRatio(".5"),
DefenseLimit(40),
WarRatio(".1"),
WarLimit(2),
BarracksRatio(".16"),
BarracksLimit(2),
RefineryLimit(4),
RefineryRatio(".16"),
BaseSizeAdd(3),
PowerSurplus(50),
InfantryReserve(2000),
InfantryBaseMult(2),
ChronoDuration(3),
WaterCrateChance(".2"),
SoloCrateMoney(2000),
GPSTechLevel(0),
UnitCrateType(UNIT_NONE),
PatrolTime(".016"),
TeamDelay(".6"),
CloakDelay(0),
GameSpeedBias(1),
NervousBias(1),
VortexRange(10*CELL_LEPTON_W),
VortexSpeed((MPHType)10),
VortexDamage(200),
VortexChance(".2"),
ExplosionSpread(fixed::_1_2),
SupressRadius(CELL_LEPTON_W),
ParaInfantryTechLevel(10),
SpyPlaneTechLevel(10),
ParaBombTechLevel(10),
MaxIQ(5),
IQSuperWeapons(4),
IQProduction(5),
IQGuardArea(4),
IQRepairSell(3),
IQCrush(2),
IQScatter(3),
IQContentScan(4),
IQAircraft(4),
IQHarvester(3),
IQSellBack(2),
SilverCrate(CRATE_HEAL_BASE),
WoodCrate(CRATE_MONEY),
WaterCrate(CRATE_MONEY),
CrateMinimum(1),
CrateMaximum(255),
LZScanRadius(16*CELL_LEPTON_W),
MPDefaultMoney(3000),
MPMaxMoney(10000),
IsMPShadowGrow(true),
IsMPBasesOn(true),
IsMPTiberiumGrow(true),
IsMPCrates(true),
IsMPAIPlayers(false),
IsMPCaptureTheFlag(false),
DropZoneRadius(4*CELL_LEPTON_W),
MessageDelay(".6"),
SavourDelay(".03"),
AVMineDamage(1200),
APMineDamage(1000),
MaxPlayers(8),
BaseDefenseDelay(fixed::_1_4),
SuspendPriority(20),
SuspendDelay(2),
SurvivorFraction(fixed::_1_2),
ReloadRate(".05"),
AutocreateTime(5),
BuildupTime(".05"),
OreDumpRate(2),
AtomDamage(1000),
IsComputerParanoid(true),
IsCurleyShuffle(false),
IsFlashLowPower(true),
IsCompEasyBonus(true),
IsFineDifficulty(false),
IsExplosiveHarvester(false),
IsMCVDeploy(false),
IsAllyReveal(true),
IsSeparate(false),
IsTreeTarget(false),
IsMineAware(true),
IsTGrowth(true),
IsTSpread(true),
IsNamed(false),
IsAutoCrush(false),
IsSmartDefense(false),
IsScatter(false),
IsChronoKill(true),
ProneDamageBias(fixed::_1_2),
QuakeDamagePercent(".33"),
QuakeChance(".2"),
GrowthRate(2),
ShroudRate(4),
CrateTime(10),
TimerWarning(2),
ChronoTechLevel(1),
SonarTime(14),
ChronoTime(3),
ParaBombTime(14),
ParaInfantryTime(2),
ParaSaboteurTime(14),
SpyTime(2),
IronCurtainTime(14),
GPSTime(1),
NukeTime(14),
SpeakDelay(2),
DamageDelay(1),
Gravity(3),
GapShroudRadius(10),
GapRegenInterval(".1"),
RadarJamRadius(10*CELL_LEPTON_W),
Incoming(MPH_IMMOBILE),
MinDamage(1),
MaxDamage(1000),
RepairStep(5),
RepairPercent(fixed::_1_4),
URepairStep(5),
URepairPercent(fixed::_1_4),
RepairRate(".016"),
ConditionGreen(1),
ConditionYellow(fixed::_1_2),
ConditionRed(fixed::_1_4),
RandomAnimateTime(".083"),
BailCount(28),
GoldValue(35),
GemValue(110),
AircraftMax(100),
AnimMax(100),
BuildingMax(500),
BulletMax(40),
FactoryMax(20),
InfantryMax(500),
OverlayMax(1),
SmudgeMax(1),
TeamMax(60),
TeamTypeMax(60),
TemplateMax(1),
TerrainMax(500),
TriggerMax(60),
UnitMax(500),
VesselMax(100),
ProjectileMax(20),
WeaponMax(20),
WarheadMax(20),
TrigTypeMax(80),
CloseEnoughDistance(0x0280),
StrayDistance(0x0200),
CrushDistance(0x0180),
CrateRadius(0x0280),
HomingScatter(0x0200),
BallisticScatter(0x0100),
RefundPercent(fixed::_1_2),
IronCurtainDuration(fixed::_1_2),
BridgeStrength(1000),
BuildSpeedBias(1),
C4Delay(".03"),
RepairThreshhold(1000),
PathDelay(".016"),
MovieTime(fixed::_1_4),
TiberiumShortScan(0x0600),
TiberiumLongScan(0x2000),
HealthBarDisplayMode(HB_SELECTED),
ResourceBarDisplayMode(RB_SELECTED)
{
#ifdef FIXIT_CSII // checked - ajw 9/28/98
NewUnitsEnabled = SecretUnitsEnabled = 0;
MTankDistance = 30;
QuakeUnitDamage = 0x080;
QuakeBuildingDamage = 0x040;
QuakeInfantryDamage = 0;
QuakeDelay = 120;
ChronoTankDuration = 0x300;
#ifdef FIXIT_ENGINEER // checked - ajw 9/28/98
EngineerDamage=(fixed)1 / (fixed)3; // Amount of damage an engineer does
EngineerCaptureLevel=ConditionRed; // Building damage level before engineer can capture
#endif
#ifdef FIXIT_CARRIER // checked - ajw 9/28/98
CarrierLaunchDelay = 60;
#endif
#endif
}
/***********************************************************************************************
* Difficulty_Get -- Fetch the difficulty bias values. *
* *
* This will fetch the difficulty bias values for the section specified. *
* *
* INPUT: ini -- Reference the INI database to fetch the values from. *
* *
* diff -- Reference to the difficulty class object to fill in with the values. *
* *
* section -- The section identifier to lift the values from. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/11/1996 JLB : Created. *
*=============================================================================================*/
static void Difficulty_Get(CCINIClass & ini, DifficultyClass & diff, char const * section)
{
if (ini.Is_Present(section)) {
diff.FirepowerBias = ini.Get_Fixed(section, "FirePower", 1);
diff.GroundspeedBias = ini.Get_Fixed(section, "Groundspeed", 1);
diff.AirspeedBias = ini.Get_Fixed(section, "Airspeed", 1);
diff.ArmorBias = ini.Get_Fixed(section, "Armor", 1);
diff.ROFBias = ini.Get_Fixed(section, "ROF", 1);
diff.CostBias = ini.Get_Fixed(section, "Cost", 1);
diff.RepairDelay = ini.Get_Fixed(section, "RepairDelay", ".02");
diff.BuildDelay = ini.Get_Fixed(section, "BuildDelay", ".03");
diff.IsBuildSlowdown = ini.Get_Bool(section, "BuildSlowdown", false);
diff.BuildSpeedBias = ini.Get_Fixed(section, "BuildTime", 1);
diff.IsWallDestroyer = ini.Get_Bool(section, "DestroyWalls", true);
diff.IsContentScan = ini.Get_Bool(section, "ContentScan", false);
}
}
/***********************************************************************************************
* RulesClass::Process -- Fetch the bulk of the rule data from the control file. *
* *
* This routine will fetch the rule data from the control file. *
* *
* INPUT: file -- Reference to the rule file to process. *
* *
* OUTPUT: bool; Was the rule file processed? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/17/1996 JLB : Created. *
*=============================================================================================*/
bool RulesClass::Process(CCINIClass & ini)
{
BStart(BENCH_RULES);
General(ini);
MPlayer(ini);
Recharge(ini);
Heap_Maximums(ini);
AI(ini);
Powerups(ini);
Land_Types(ini);
Themes(ini);
IQ(ini);
Objects(ini);
Difficulty(ini);
BEnd(BENCH_RULES);
return(true);
}
/***********************************************************************************************
* RulesClass::General -- Process the general main game rules. *
* *
* This fetches the control constants uses for regular game processing. Any game behavior *
* controlling values that don't properly fit in any of the other catagories will be *
* stored here. *
* *
* INPUT: ini -- Reference to the database to fetch the values from. *
* *
* OUTPUT: bool; Was the general section found and processed? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/08/1996 JLB : Created. *
*=============================================================================================*/
bool RulesClass::General(CCINIClass & ini)
{
static char const * const GENERAL = "General";
#ifdef FIXIT_CSII // checked - ajw 9/28/98
static char const * const AFTERMATH = "Aftermath";
if(ini.Is_Present(AFTERMATH)) {
//debugprint( "NewUnitsEnabled previously %i\n", NewUnitsEnabled );
NewUnitsEnabled = ini.Get_Int(AFTERMATH, "NewUnitsEnabled", 0);
//debugprint( "NewUnitsEnabled set to %i by Rules\n", NewUnitsEnabled );
MTankDistance = ini.Get_Int(AFTERMATH,"MTankDistance",MTankDistance);
QuakeUnitDamage = ini.Get_Fixed(AFTERMATH, "QuakeUnitDamage", QuakeUnitDamage);
QuakeBuildingDamage = ini.Get_Fixed(AFTERMATH, "QuakeBuildingDamage", QuakeBuildingDamage);
QuakeInfantryDamage = ini.Get_Int(AFTERMATH,"QuakeInfantryDamage",QuakeInfantryDamage);
QuakeDelay = ini.Get_Int(AFTERMATH,"QuakeDelay",QuakeDelay);
ChronoTankDuration = ini.Get_Fixed(AFTERMATH, "ChronoTankDuration", ChronoTankDuration);
//Mono_Set_Cursor(0,0);Mono_Printf("Chrono duration: %08x \n",ChronoTankDuration);Keyboard->Get();Keyboard->Get();
#ifdef FIXIT_CARRIER // checked - ajw 9/28/98
CarrierLaunchDelay = ini.Get_Int(AFTERMATH,"CarrierLaunchDelay",120);
#endif
#ifdef FIXIT_ENGINEER // checked - ajw 9/28/98
// Engineer changing fields were specifically left out of Aftrmath.ini, thus these values are not found to set. ajw
// Implies interesting security hole if user creates a separate Aftrmath.ini file!
EngineerDamage = ini.Get_Fixed(AFTERMATH, "EngineerDamage", EngineerDamage); // Amount of damage an engineer does
EngineerCaptureLevel = ini.Get_Fixed(AFTERMATH, "EngineerCaptureLevel", EngineerCaptureLevel); // Building damage level before engineer can capture
#endif
}
#endif
if (ini.Is_Present(GENERAL)) {
TurboBoost = ini.Get_Fixed(GENERAL, "TurboBoost", TurboBoost);
BadgerBombCount = ini.Get_Int(GENERAL, "BadgerBombCount", BadgerBombCount);
IsCurleyShuffle = ini.Get_Bool(GENERAL, "CurleyShuffle", IsCurleyShuffle);
IsFlashLowPower = ini.Get_Bool(GENERAL, "FlashLowPower", IsFlashLowPower);
IsChronoKill = ini.Get_Bool(GENERAL, "ChronoKillCargo", IsChronoKill);
ChronoDuration = ini.Get_Fixed(GENERAL, "ChronoDuration", ChronoDuration);
IsFineDifficulty = ini.Get_Bool(GENERAL, "FineDiffControl", IsFineDifficulty);
WaterCrateChance = ini.Get_Fixed(GENERAL, "WaterCrateChance", WaterCrateChance);
SoloCrateMoney = ini.Get_Int(GENERAL, "SoloCrateMoney", SoloCrateMoney);
ParaBombTechLevel = ini.Get_Int(GENERAL, "ParabombTech", ParaBombTechLevel);
GPSTechLevel = ini.Get_Int(GENERAL, "GPSTechLevel", GPSTechLevel);
UnitCrateType = ini.Get_UnitType(GENERAL, "UnitCrateType", UnitCrateType);
IsExplosiveHarvester = ini.Get_Fixed(GENERAL, "OreExplosive", IsExplosiveHarvester);
GapRegenInterval = ini.Get_Fixed(GENERAL, "GapRegenInterval", GapRegenInterval);
TeamDelay = ini.Get_Fixed(GENERAL, "TeamDelay", TeamDelay);
CloakDelay = ini.Get_Fixed(GENERAL, "SubmergeDelay", CloakDelay);
GameSpeedBias = ini.Get_Fixed(GENERAL, "GameSpeedBias", GameSpeedBias);
NervousBias = ini.Get_Fixed(GENERAL, "BaseBias", NervousBias);
ExplosionSpread = ini.Get_Fixed(GENERAL, "ExpSpread", ExplosionSpread);
SupressRadius = ini.Get_Lepton(GENERAL, "FireSupress", SupressRadius);
ParaInfantryTechLevel = ini.Get_Int(GENERAL, "ParaTech", ParaInfantryTechLevel);
SpyPlaneTechLevel = ini.Get_Int(GENERAL, "SpyPlaneTech", SpyPlaneTechLevel);
SilverCrate = ini.Get_CrateType(GENERAL, "SilverCrate", SilverCrate);
WoodCrate = ini.Get_CrateType(GENERAL, "WoodCrate", WoodCrate);
WaterCrate = ini.Get_CrateType(GENERAL, "WaterCrate", WaterCrate);
CrateMinimum = ini.Get_Int(GENERAL, "CrateMinimum", CrateMinimum);
CrateMaximum = ini.Get_Int(GENERAL, "CrateMaximum", CrateMaximum);
IsScatter = ini.Get_Bool(GENERAL, "PlayerScatter", IsScatter);
IsSmartDefense = ini.Get_Bool(GENERAL, "PlayerReturnFire", IsSmartDefense);
IsAutoCrush = ini.Get_Bool(GENERAL, "PlayerAutoCrush", IsAutoCrush);
IsNamed = ini.Get_Bool(GENERAL, "NamedCivilians", IsNamed);
IsTGrowth = ini.Get_Bool(GENERAL, "OreGrows", IsTGrowth);
IsTSpread = ini.Get_Bool(GENERAL, "OreSpreads", IsTSpread);
IsMineAware = ini.Get_Bool(GENERAL, "MineAware", IsMineAware);
IsTreeTarget = ini.Get_Bool(GENERAL, "TreeTargeting", IsTreeTarget);
IsSeparate = ini.Get_Bool(GENERAL, "SeparateAircraft", IsSeparate);
DropZoneRadius = ini.Get_Lepton(GENERAL, "DropZoneRadius", DropZoneRadius);
MessageDelay = ini.Get_Fixed(GENERAL, "MessageDelay", MessageDelay);
SavourDelay = ini.Get_Fixed(GENERAL, "SavourDelay", SavourDelay);
AVMineDamage = ini.Get_Int(GENERAL, "AVMineDamage", AVMineDamage);
APMineDamage = ini.Get_Int(GENERAL, "APMineDamage", APMineDamage);
BaseDefenseDelay = ini.Get_Fixed(GENERAL, "BaseDefenseDelay", BaseDefenseDelay);
SuspendPriority = ini.Get_Int(GENERAL, "SuspendPriority", SuspendPriority);
SuspendDelay = ini.Get_Fixed(GENERAL, "SuspendDelay", SuspendDelay);
SurvivorFraction = ini.Get_Fixed(GENERAL, "SurvivorRate", SurvivorFraction);
RadarJamRadius = ini.Get_Lepton(GENERAL, "RadarJamRadius", RadarJamRadius);
ReloadRate = ini.Get_Fixed(GENERAL, "ReloadRate", ReloadRate);
RandomAnimateTime = ini.Get_Fixed(GENERAL, "IdleActionFrequency", RandomAnimateTime);
BuildupTime = ini.Get_Fixed(GENERAL, "BuildupTime", BuildupTime);
OreDumpRate = ini.Get_Int(GENERAL, "OreTruckRate", OreDumpRate);
AtomDamage = ini.Get_Int(GENERAL, "AtomDamage", AtomDamage);
BailCount = ini.Get_Int(GENERAL, "BailCount", BailCount);
BallisticScatter = ini.Get_Lepton(GENERAL, "BallisticScatter", BallisticScatter);
BridgeStrength = ini.Get_Int(GENERAL, "BridgeStrength", BridgeStrength);
BuildSpeedBias = ini.Get_Fixed(GENERAL, "BuildSpeed", BuildSpeedBias);
ConditionGreen = 1;
ConditionRed = ini.Get_Fixed(GENERAL, "ConditionRed", ConditionRed);
ConditionYellow = ini.Get_Fixed(GENERAL, "ConditionYellow", ConditionYellow);
CrateRadius = ini.Get_Lepton(GENERAL, "CrateRadius", CrateRadius);
CrushDistance = ini.Get_Lepton(GENERAL, "Crush", CrushDistance);
DamageDelay = ini.Get_Fixed(GENERAL, "DamageDelay", DamageDelay);
GapShroudRadius = ini.Get_Int(GENERAL, "GapRadius", GapShroudRadius);
GemValue = ini.Get_Int(GENERAL, "GemValue", GemValue);
GoldValue = ini.Get_Int(GENERAL, "GoldValue", GoldValue);
Gravity = ini.Get_Int(GENERAL, "Gravity", Gravity);
GrowthRate = ini.Get_Fixed(GENERAL, "GrowthRate", GrowthRate);
HomingScatter = ini.Get_Lepton(GENERAL, "HomingScatter", HomingScatter);
Incoming = ini.Get_MPHType(GENERAL, "Incoming", MPH_IMMOBILE);
IronCurtainDuration = ini.Get_Fixed(GENERAL, "IronCurtain", IronCurtainDuration);
IsAllyReveal = ini.Get_Bool(GENERAL, "AllyReveal", IsAllyReveal);
IsMCVDeploy = ini.Get_Bool(GENERAL, "MCVUndeploy", IsMCVDeploy);
MaxDamage = ini.Get_Int(GENERAL, "MaxDamage", MaxDamage);
MinDamage = ini.Get_Int(GENERAL, "MinDamage", MinDamage);
ProneDamageBias = ini.Get_Fixed(GENERAL, "ProneDamage", ProneDamageBias);
QuakeDamagePercent = ini.Get_Fixed(GENERAL, "QuakeDamage", QuakeDamagePercent);
QuakeChance = ini.Get_Fixed(GENERAL, "QuakeChance", QuakeChance);
RefundPercent = ini.Get_Fixed(GENERAL, "RefundPercent", RefundPercent);
RepairPercent = ini.Get_Fixed(GENERAL, "RepairPercent", RepairPercent);
RepairStep = ini.Get_Int(GENERAL, "RepairStep", RepairStep);
URepairPercent = ini.Get_Fixed(GENERAL, "URepairPercent", URepairPercent);
URepairStep = ini.Get_Int(GENERAL, "URepairStep", URepairStep);
RepairRate = ini.Get_Fixed(GENERAL, "RepairRate", RepairRate);
ShroudRate = ini.Get_Fixed(GENERAL, "ShroudRate", ShroudRate);
SpeakDelay = ini.Get_Fixed(GENERAL, "SpeakDelay", SpeakDelay);
StrayDistance = ini.Get_Lepton(GENERAL, "Stray", StrayDistance);
CloseEnoughDistance = ini.Get_Lepton(GENERAL, "CloseEnough", CloseEnoughDistance);
TimerWarning = ini.Get_Fixed(GENERAL, "TimerWarning", TimerWarning);
MovieTime = ini.Get_Fixed(GENERAL, "MovieTime", MovieTime);
C4Delay = ini.Get_Fixed(GENERAL, "C4Delay", C4Delay);
ChronoTechLevel = ini.Get_Int(GENERAL, "ChronoTechLevel", ChronoTechLevel);
CrateTime = ini.Get_Fixed(GENERAL, "CrateRegen", CrateTime);
VortexRange = ini.Get_Lepton(GENERAL, "VortexRange", VortexRange);
VortexSpeed = MPHType(_Scale_To_256(ini.Get_Int(GENERAL, "VortexSpeed", VortexSpeed)));
VortexDamage = ini.Get_Int(GENERAL, "VortexDamage", VortexDamage);
VortexChance = ini.Get_Fixed(GENERAL, "VortexChance", VortexChance);
ChronalVortex.Set_Range(VortexRange / CELL_LEPTON_W);
ChronalVortex.Set_Speed(VortexSpeed);
ChronalVortex.Set_Damage(VortexDamage);
//ChronalVortex.Set_Range ( ini.Get_Int (GENERAL, "VortexRange", ChronalVortex.Get_Range() ) );
//ChronalVortex.Set_Speed ( ini.Get_Int (GENERAL, "VortexSpeed", ChronalVortex.Get_Speed() ) );
//ChronalVortex.Set_Damage ( ini.Get_Int (GENERAL, "VortexDamage", ChronalVortex.Get_Damage() ) );
return(true);
}
return(false);
}
/***********************************************************************************************
* RulesClass::MPlayer -- Fetch and process the multiplayer default settings. *
* *
* This is used to set the default settings for the multiplayer system. *
* *
* INPUT: ini -- Reference to the INI database. *
* *
* OUTPUT: bool; Was the multiplayer default override section found and processed? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/08/1996 JLB : Created. *
*=============================================================================================*/
bool RulesClass::MPlayer(CCINIClass & ini)
{
static char const * const MPLAYER = "MultiplayerDefaults";
if (ini.Is_Present(MPLAYER)) {
MPDefaultMoney = ini.Get_Int(MPLAYER, "Money", MPDefaultMoney);
MPMaxMoney = ini.Get_Int(MPLAYER, "MaxMoney", MPMaxMoney);
IsMPShadowGrow = ini.Get_Bool(MPLAYER, "ShadowGrow", IsMPShadowGrow);
IsMPBasesOn = ini.Get_Bool(MPLAYER, "Bases", IsMPBasesOn);
IsMPTiberiumGrow = ini.Get_Bool(MPLAYER, "OreGrows", IsMPTiberiumGrow);
IsMPCrates = ini.Get_Bool(MPLAYER, "Crates", IsMPCrates);
IsMPCaptureTheFlag = ini.Get_Bool(MPLAYER, "CaptureTheFlag", IsMPCaptureTheFlag);
return(true);
}
return(false);
}
/***********************************************************************************************
* RulesClass::Recharge -- Process the super weapon recharge statistics. *
* *
* Use this to set the recharge times for the various super weapons available. *
* *
* INPUT: ini -- Reference to the database. *
* *
* OUTPUT: bool; Was the recharge section found and processed? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/08/1996 JLB : Created. *
*=============================================================================================*/
bool RulesClass::Recharge(CCINIClass & ini)
{
static char const * const RECHARGE = "Recharge";
if (ini.Is_Present(RECHARGE)) {
SonarTime = ini.Get_Fixed(RECHARGE, "Sonar", SonarTime);
ChronoTime = ini.Get_Fixed(RECHARGE, "Chrono", ChronoTime);
ParaBombTime = ini.Get_Fixed(RECHARGE, "ParaBomb", ParaBombTime);
ParaInfantryTime = ini.Get_Fixed(RECHARGE, "Paratrooper", ParaInfantryTime);
SpyTime = ini.Get_Fixed(RECHARGE, "SpyPlane", SpyTime);
IronCurtainTime = ini.Get_Fixed(RECHARGE, "IronCurtain", IronCurtainTime);
GPSTime = ini.Get_Fixed(RECHARGE, "GPS", GPSTime);
NukeTime = ini.Get_Fixed(RECHARGE, "Nuke", NukeTime);
return(true);
}
return(false);
}
/***********************************************************************************************
* RulesClass::Heap_Maximums -- Fetch and process the heap override values. *
* *
* This fetches the maximum heap sizes from the database specified. The heaps will be *
* initialized by this routine as indicated. *
* *
* INPUT: ini -- Reference to the INI database. *
* *
* OUTPUT: bool; Was the maximum section found and processed? *
* *
* WARNINGS: This process is catastrophic to any data currently existing in the heaps *
* modified. This should only be processed during the game initialization stage. *
* *
* HISTORY: *
* 08/08/1996 JLB : Created. *
*=============================================================================================*/
bool RulesClass::Heap_Maximums(CCINIClass & ini)
{
/*
** Heap maximum values.
*/
static char const * const MAXIMUMS = "Maximums";
if (ini.Is_Present(MAXIMUMS)) {
MaxPlayers = ini.Get_Int(MAXIMUMS, "Players", MaxPlayers);
AircraftMax = ini.Get_Int(MAXIMUMS, "Aircraft", AircraftMax);
AnimMax = ini.Get_Int(MAXIMUMS, "Anim", AnimMax);
BuildingMax = ini.Get_Int(MAXIMUMS, "Building", BuildingMax);
BulletMax = ini.Get_Int(MAXIMUMS, "Bullet", BulletMax);
FactoryMax = ini.Get_Int(MAXIMUMS, "Factory", FactoryMax);
InfantryMax = ini.Get_Int(MAXIMUMS, "Infantry", InfantryMax);
OverlayMax = ini.Get_Int(MAXIMUMS, "Overlay", OverlayMax);
SmudgeMax = ini.Get_Int(MAXIMUMS, "Smudge", SmudgeMax);
TeamMax = ini.Get_Int(MAXIMUMS, "Team", TeamMax);
TeamTypeMax = ini.Get_Int(MAXIMUMS, "TeamType", TeamTypeMax);
TemplateMax = ini.Get_Int(MAXIMUMS, "Template", TemplateMax);
TerrainMax = ini.Get_Int(MAXIMUMS, "Terrain", TerrainMax);
TriggerMax = ini.Get_Int(MAXIMUMS, "Trigger", TriggerMax);
UnitMax = ini.Get_Int(MAXIMUMS, "Unit", UnitMax);
VesselMax = ini.Get_Int(MAXIMUMS, "Vessel", VesselMax);
ProjectileMax = ini.Get_Int(MAXIMUMS, "Projectile", ProjectileMax);
WeaponMax = ini.Get_Int(MAXIMUMS, "Weapon", WeaponMax);
WarheadMax = ini.Get_Int(MAXIMUMS, "Warhead", WarheadMax);
TrigTypeMax = ini.Get_Int(MAXIMUMS, "TrigType", TrigTypeMax);
}
/*
** Special case: double maximum animations to accomodate lots of action
*/
AnimMax = max(AnimMax, 200);
/*
** Any heaps that use the maximums that were just loaded, must
** be initialized as necessary.
*/
Warheads.Set_Heap(WarheadMax);
new WarheadTypeClass("SA");
new WarheadTypeClass("HE");
new WarheadTypeClass("AP");
new WarheadTypeClass("Fire");
new WarheadTypeClass("HollowPoint");
new WarheadTypeClass("Super");
new WarheadTypeClass("Organic");
new WarheadTypeClass("Nuke");
#ifdef FIXIT_CSII // checked - ajw 9/28/98
new WarheadTypeClass("Mechanical");
#endif
Weapons.Set_Heap(WeaponMax);
new WeaponTypeClass("Colt45");
new WeaponTypeClass("ZSU-23");
new WeaponTypeClass("Vulcan");
new WeaponTypeClass("Maverick");
new WeaponTypeClass("Camera");
new WeaponTypeClass("FireballLauncher");
new WeaponTypeClass("Sniper");
new WeaponTypeClass("ChainGun");
new WeaponTypeClass("Pistol");
new WeaponTypeClass("M1Carbine");
new WeaponTypeClass("Dragon");
new WeaponTypeClass("Hellfire");
new WeaponTypeClass("Grenade");
new WeaponTypeClass("75mm");
new WeaponTypeClass("90mm");
new WeaponTypeClass("105mm");
new WeaponTypeClass("120mm");
new WeaponTypeClass("TurretGun");
new WeaponTypeClass("MammothTusk");
new WeaponTypeClass("155mm");
new WeaponTypeClass("M60mg");
new WeaponTypeClass("Napalm");
new WeaponTypeClass("TeslaZap");
new WeaponTypeClass("Nike");
new WeaponTypeClass("8Inch");
new WeaponTypeClass("Stinger");
new WeaponTypeClass("TorpTube");
new WeaponTypeClass("2Inch");
new WeaponTypeClass("DepthCharge");
new WeaponTypeClass("ParaBomb");
new WeaponTypeClass("DogJaw");
new WeaponTypeClass("Heal");
new WeaponTypeClass("SCUD");
new WeaponTypeClass("Flamer");
new WeaponTypeClass("RedEye");
#ifdef FIXIT_ANTS
new WeaponTypeClass("Mandible");
#endif
#ifdef FIXIT_CSII // checked - ajw 9/28/98
new WeaponTypeClass("PortaTesla");
new WeaponTypeClass("GoodWrench");
new WeaponTypeClass("SubSCUD");
new WeaponTypeClass("TTankZap");
new WeaponTypeClass("APTusk");
new WeaponTypeClass("Democharge");
#endif
#ifdef FIXIT_CARRIER // checked - ajw 9/28/98
new WeaponTypeClass("AirAssault");
#endif
return(true);
}
/***********************************************************************************************
* RulesClass::AI -- Processes the AI control constants from the database. *
* *
* This will examine the database specified and set the AI override values accordingly. *
* *
* INPUT: ini -- Reference to the INI database that holds the AI overrides. *
* *
* OUTPUT: bool; Was the AI section found and processed? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/08/1996 JLB : Created. *
*=============================================================================================*/
bool RulesClass::AI(CCINIClass & ini)
{
static char const * const AI = "AI";
if (ini.Is_Present(AI)) {
AttackInterval = ini.Get_Fixed(AI, "AttackInterval", AttackInterval);
AttackDelay = ini.Get_Fixed(AI, "AttackDelay", AttackDelay);
PatrolTime = ini.Get_Fixed(AI, "PatrolScan", PatrolTime);
RepairThreshhold = ini.Get_Int(AI, "CreditReserve", RepairThreshhold);
PathDelay = ini.Get_Fixed(AI, "PathDelay", PathDelay);
TiberiumShortScan = ini.Get_Lepton(AI, "OreNearScan", TiberiumShortScan);
TiberiumLongScan = ini.Get_Lepton(AI, "OreFarScan", TiberiumLongScan);
AutocreateTime = ini.Get_Fixed(AI, "AutocreateTime", AutocreateTime);
InfantryReserve = ini.Get_Int(AI, "InfantryReserve", InfantryReserve);
InfantryBaseMult = ini.Get_Int(AI, "InfantryBaseMult", InfantryBaseMult);
PowerSurplus = ini.Get_Int(AI, "PowerSurplus", PowerSurplus);
BaseSizeAdd = ini.Get_Int(AI, "BaseSizeAdd", BaseSizeAdd);
RefineryRatio = ini.Get_Fixed(AI, "RefineryRatio", RefineryRatio);
RefineryLimit = ini.Get_Int(AI, "RefineryLimit", RefineryLimit);
BarracksRatio = ini.Get_Fixed(AI, "BarracksRatio", BarracksRatio);
BarracksLimit = ini.Get_Int(AI, "BarracksLimit", BarracksLimit);
WarRatio = ini.Get_Fixed(AI, "WarRatio", WarRatio);
WarLimit = ini.Get_Int(AI, "WarLimit", WarLimit);
DefenseRatio = ini.Get_Fixed(AI, "DefenseRatio", DefenseRatio);
DefenseLimit = ini.Get_Int(AI, "DefenseLimit", DefenseLimit);
AARatio = ini.Get_Fixed(AI, "AARatio", AARatio);
AALimit = ini.Get_Int(AI, "AALimit", AALimit);
TeslaRatio = ini.Get_Fixed(AI, "TeslaRatio", TeslaRatio);
TeslaLimit = ini.Get_Int(AI, "TeslaLimit", TeslaLimit);
HelipadRatio = ini.Get_Fixed(AI, "HelipadRatio", HelipadRatio);
HelipadLimit = ini.Get_Int(AI, "HelipadLimit", HelipadLimit);
AirstripRatio = ini.Get_Fixed(AI, "AirstripRatio", AirstripRatio);
AirstripLimit = ini.Get_Int(AI, "AirstripLimit", AirstripLimit);
IsCompEasyBonus = ini.Get_Bool(AI, "CompEasyBonus", IsCompEasyBonus);
IsComputerParanoid = ini.Get_Bool(AI, "Paranoid", IsComputerParanoid);
PowerEmergencyFraction = ini.Get_Fixed(AI, "PowerEmergency", PowerEmergencyFraction);
return(true);
}
return(false);
}
/***********************************************************************************************
* RulesClass::Powerups -- Process the powerup values from the database. *
* *
* This will examine the database and initialize the powerup override values accordingly. *
* *
* INPUT: ini -- Reference to the INI database the the powerup values are to be *
* initialized from. *
* *
* OUTPUT: bool; Was the powerup section found and processed? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/08/1996 JLB : Created. *
*=============================================================================================*/
bool RulesClass::Powerups(CCINIClass & ini)
{
static char const * const POWERUPS = "Powerups";
if (ini.Is_Present(POWERUPS)) {
for (CrateType crate = CRATE_FIRST; crate < CRATE_COUNT; crate++) {
char buffer[128];
if (ini.Get_String(POWERUPS, CrateNames[crate], "0,NONE", buffer, sizeof(buffer))) {
/*
** Share odds.
*/
char * token = strtok(buffer, ",");
if (token) {
strtrim(token);
CrateShares[crate] = atoi(token);
}
/*
** Animation to use.
*/
token = strtok(NULL, ",");
if (token) {
strtrim(token);
CrateAnims[crate] = Anim_From_Name(token);
}
/*
** Optional data number.
*/
token = strtok(NULL, ",");
if (token != NULL) {
if (strpbrk(token, ".%") != NULL) {
CrateData[crate] = fixed(token) * 256;
} else {
strtrim(token);
CrateData[crate] = atoi(token);
}
}
}
}
return(true);
}
return(false);
}
/***********************************************************************************************
* RulesClass::Land_Types -- Inits the land type values. *
* *
* This will set the land movement attributes from the database specified. *
* *
* INPUT: ini -- Reference to the database that has the land value overrides. *
* *
* OUTPUT: bool; Was the land type sections found and processed? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/08/1996 JLB : Created. *
*=============================================================================================*/
bool RulesClass::Land_Types(CCINIClass & ini)
{
/*
** Fetch the movement characteristic data for terrain types.
*/
for (LandType land = LAND_FIRST; land < LAND_COUNT; land++) {
static char const * _lands[LAND_COUNT] = {
"Clear",
"Road",
"Water",
"Rock",
"Wall",
"Ore",
"Beach",
"Rough",
"River"
};
GroundType * gptr = &Ground[land];
if (ini.Is_Present(_lands[land])) {
gptr->Cost[SPEED_FOOT] = ini.Get_Fixed(_lands[land], "Foot", 1);
gptr->Cost[SPEED_TRACK] = ini.Get_Fixed(_lands[land], "Track", 1);
gptr->Cost[SPEED_WHEEL] = ini.Get_Fixed(_lands[land], "Wheel", 1);
gptr->Cost[SPEED_WINGED] = fixed(1);
gptr->Cost[SPEED_FLOAT] = ini.Get_Fixed(_lands[land], "Float", 1);
gptr->Build = ini.Get_Bool(_lands[land], "Buildable", false);
}
}
return(true);
}
/***********************************************************************************************
* RulesClass::Themes -- Fetches the theme control values from the INI database. *
* *
* The musical theme availability is controlled by the scenario and the player's house *
* choice. These controls can be specified in the theme control section of the INI *
* database. *
* *
* INPUT: ini -- Reference to the INI database to process. *
* *
* OUTPUT: bool; Was the theme section found and processed? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/11/1996 JLB : Created. *
*=============================================================================================*/
bool RulesClass::Themes(CCINIClass & ini)
{
static char const * const THEMECONTROL = "ThemeControl";
if (ini.Is_Present(THEMECONTROL)) {
for (ThemeType theme = THEME_FIRST; theme < THEME_COUNT; theme++) {
if (ini.Is_Present(THEMECONTROL, Theme.Base_Name(theme))) {
char buffer[128];
int scen = 1;
int owners = HOUSEF_ALLIES | HOUSEF_SOVIET | HOUSEF_OTHERS;
ini.Get_String(THEMECONTROL, Theme.Base_Name(theme), "", buffer, sizeof(buffer));
char const * token = strtok(buffer, ",");
if (token != NULL) {
scen = atoi(token);
}
token = strtok(NULL, ",");
if (token != NULL) {
owners = Owner_From_Name(token);
}
Theme.Set_Theme_Data(theme, scen, owners);
}
}
return(true);
}
return(false);
}
/***********************************************************************************************
* RulesClass::IQ -- Fetches the IQ control values from the INI database. *
* *
* This will scan the database specified and retrieve the IQ control values from it. These *
* IQ control values are what gives the IQ rating meaning. It fundimentally controls how *
* the computer behaves. *
* *
* INPUT: ini -- Reference to the INI database to read the IQ controls from. *
* *
* OUTPUT: bool; Was the IQ section found and processed? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/11/1996 JLB : Created. *
*=============================================================================================*/
bool RulesClass::IQ(CCINIClass & ini)
{
static char const * const IQCONTROL = "IQ";
if (ini.Is_Present(IQCONTROL)) {
MaxIQ = ini.Get_Int(IQCONTROL, "MaxIQLevels", MaxIQ);
IQSuperWeapons = ini.Get_Int(IQCONTROL, "SuperWeapons", IQSuperWeapons);
IQProduction = ini.Get_Int(IQCONTROL, "Production", IQProduction);
IQGuardArea = ini.Get_Int(IQCONTROL, "GuardArea", IQGuardArea);
IQRepairSell = ini.Get_Int(IQCONTROL, "RepairSell", IQRepairSell);
IQCrush = ini.Get_Int(IQCONTROL, "AutoCrush", IQCrush);
IQScatter = ini.Get_Int(IQCONTROL, "Scatter", IQScatter);
IQContentScan = ini.Get_Int(IQCONTROL, "ContentScan", IQContentScan);
IQAircraft = ini.Get_Int(IQCONTROL, "Aircraft", IQAircraft);
IQHarvester = ini.Get_Int(IQCONTROL, "Harvester", IQHarvester);
IQSellBack = ini.Get_Int(IQCONTROL, "SellBack", IQSellBack);
return(true);
}
return(false);
}
/***********************************************************************************************
* RulesClass::Objects -- Fetch all the object characteristic values. *
* *
* This will parse the specified INI database and fetch all the object characteristic *
* values specified therein. *
* *
* INPUT: ini -- Reference to the ini database to scan. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/10/1996 JLB : Created. *
*=============================================================================================*/
bool RulesClass::Objects(CCINIClass & ini)
{
/*
** Fetch the game object values from the rules file.
*/
for (int index = 0; index < Warheads.Count(); index++) {
Warheads.Ptr(index)->Read_INI(ini);
}
for (int proj = 0; proj < BulletTypes.Count(); proj++) {
BulletTypes.Ptr(proj)->Read_INI(ini);
}
for (int windex = 0; windex < Weapons.Count(); windex++) {
Weapons.Ptr(windex)->Read_INI(ini);
}
for (int uindex = 0; uindex < UnitTypes.Count(); uindex++) {
UnitTypes.Ptr(uindex)->Read_INI(ini);
}
for (int iindex = 0; iindex < InfantryTypes.Count(); iindex++) {
InfantryTypes.Ptr(iindex)->Read_INI(ini);
}
for (int vindex = 0; vindex < VesselTypes.Count(); vindex++) {
VesselTypes.Ptr(vindex)->Read_INI(ini);
}
for (int aindex = 0; aindex < AircraftTypes.Count(); aindex++) {
AircraftTypes.Ptr(aindex)->Read_INI(ini);
}
for (int bindex = 0; bindex < BuildingTypes.Count(); bindex++) {
BuildingTypes.Ptr(bindex)->Read_INI(ini);
}
/*
** Fetch the house attribute override values.
*/
for (HousesType house = HOUSE_FIRST; house < HOUSE_COUNT; house++) {
HouseTypeClass::As_Reference(house).Read_INI(ini);
}
/*
** Fetch the mission control values.
*/
for (MissionType mission = MISSION_FIRST; mission < MISSION_COUNT; mission++) {
MissionControlClass * miss = &MissionControl[mission];
miss->Mission = mission;
miss->Read_INI(ini);
}
return(true);
}
/***********************************************************************************************
* RulesClass::Difficulty -- Fetch the various difficulty group settings. *
* *
* This routine is used to fetch the various group settings for the difficulty levels. *
* *
* INPUT: ini -- Reference to the INI database that has the difficulty setting values. *
* *
* OUTPUT: bool; Was the difficulty section found and processed. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/10/1996 JLB : Created. *
*=============================================================================================*/
bool RulesClass::Difficulty(CCINIClass & ini)
{
#if 0
Difficulty_Get(ini, Diff[DIFF_EASY], "Easy");
Difficulty_Get(ini, Diff[DIFF_NORMAL], "Normal");
Difficulty_Get(ini, Diff[DIFF_HARD], "Difficult");
#endif
return(true);
}
/***********************************************************************************************
* Is_MCV_Deploy -- Check if MCV can be deployed. *
* *
* This routine is used to check if the Construction Yard can revert back into an MCV. *
* It allows the special variables to override anything set by the rules. *
* *
* INPUT: none *
* *
* OUTPUT: bool; Can the Construction Yard revert back into an MCV. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 10/24/2019 SKY : Created. *
*=============================================================================================*/
bool Is_MCV_Deploy()
{
return Special.UseMCVDeploy ? Special.IsMCVDeploy : Rule.IsMCVDeploy;
}