mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
233 lines
8.1 KiB
C++
233 lines
8.1 KiB
C++
#ifndef REBEL_COMMAND_H
|
|
#define REBEL_COMMAND_H
|
|
|
|
#include "CampaignStats.h"
|
|
#include "mapscreen.h"
|
|
#include "Soldier Control.h"
|
|
#include "types.h"
|
|
|
|
#define REBEL_COMMAND_Z_OFFSET 9
|
|
#define REBEL_COMMAND_MAX_ACTIONS_PER_REGION 6
|
|
#define NUM_ARC_AGENT_SLOTS 2
|
|
|
|
namespace RebelCommand
|
|
{
|
|
// applies to RegionSaveInfo.actionLevels: use the MSB as the active flag since I don't expect it to be used otherwise
|
|
constexpr UINT8 ADMIN_ACTION_ACTIVE_BIT = 1 << 7;
|
|
|
|
// the FIRST and SECOND strategic events share the same type (EVENT_REBELCOMMAND - no need to have multiple types yet, I think...)
|
|
// so the 32-bit int will have to block out information for both events
|
|
// FIRST EVENT BREAKDOWN
|
|
// A######B CCCCCCCC DDDDDDDD EEEEEEEE
|
|
// A (1 bit) - always 0 to indicate that this is the FIRST event (ie, keeping a merc busy for a set duration)
|
|
// B (1 bit) - 0 if the player sent a generic rebel agent, 1 if the player sent one of their own mercs
|
|
// C (8 bit) - the profile number of the merc that was sent. invalid if B == 0
|
|
// D (8 bit) - the mission ID. should match up with RebelCommandAgentMissions enum
|
|
// E (8 bit) - the mission duration, in hours. if 0, mission failed.
|
|
// extra bits are mission-specific
|
|
|
|
// SECOND EVENT BREAKDOWN
|
|
// A####### #######B CCCCCCCC DDDDDDDD
|
|
// A (1 bit) - always 1 to indicate that this is the SECOND event (ie, this event fires when the mission bonus expires)
|
|
// B (1 bit) - 0 if the player sent a generic rebel agent, 1 if the player sent one of their own mercs
|
|
// C (8 bit) - the profile number of the merc that was sent. invalid if B == 0
|
|
// D (8 bit) - the mission ID. should match up with RebelCommandAgentMissions enum
|
|
// extra bits are mission-specific
|
|
|
|
enum RebelCommandDirectives
|
|
{
|
|
RCD_NONE = -1,
|
|
RCD_GATHER_SUPPLIES = 0,
|
|
RCD_SUPPORT_MILITIA,
|
|
RCD_TRAIN_MILITIA,
|
|
RCD_CREATE_PROPAGANDA,
|
|
RCD_ELITE_MILITIA,
|
|
RCD_HVT_STRIKES,
|
|
RCD_SPOTTERS,
|
|
RCD_RAID_MINES,
|
|
RCD_CREATE_TURNCOATS,
|
|
RCD_DRAFT,
|
|
|
|
RCD_NUM_DIRECTIVES
|
|
};
|
|
|
|
enum RebelCommandAdminActions
|
|
{
|
|
RCAA_NONE = -1,
|
|
RCAA_SUPPLY_LINE = 0,
|
|
RCAA_REBEL_RADIO,
|
|
RCAA_SAFEHOUSES,
|
|
RCAA_SUPPLY_DISRUPTION,
|
|
RCAA_SCOUTS,
|
|
RCAA_DEAD_DROPS,
|
|
RCAA_SMUGGLERS,
|
|
RCAA_WAREHOUSES,
|
|
RCAA_TAXES,
|
|
RCAA_ASSIST_CIVILIANS,
|
|
RCAA_MERC_SUPPORT,
|
|
RCAA_MINING_POLICY,
|
|
RCAA_PATHFINDERS,
|
|
RCAA_HARRIERS,
|
|
RCAA_FORTIFICATIONS,
|
|
|
|
RCAA_NUM_ACTIONS
|
|
};
|
|
|
|
enum RebelCommandAgentMissions
|
|
{
|
|
RCAM_NONE = -1,
|
|
RCAM_DEEP_DEPLOYMENT = 0,
|
|
RCAM_DISRUPT_ASD, // only available if ASD enabled
|
|
RCAM_FORGE_TRANSPORT_ORDERS,
|
|
RCAM_GET_ENEMY_MOVEMENT_TARGETS, // aka Strategic Intel
|
|
RCAM_IMPROVE_LOCAL_SHOPS,
|
|
RCAM_REDUCE_STRATEGIC_DECISION_SPEED, // aka Slower Strategic Decisions
|
|
RCAM_REDUCE_UNALERTED_ENEMY_VISION, // aka Lower Readiness
|
|
RCAM_SABOTAGE_INFANTRY_EQUIPMENT, // aka Sabotage Equipment
|
|
RCAM_SABOTAGE_MECHANICAL_UNITS, // aka Sabotage Vehicles
|
|
RCAM_SEND_SUPPLIES_TO_TOWN, // ignores minimum loyalty requirement
|
|
RCAM_SOLDIER_BOUNTIES_KINGPIN,
|
|
RCAM_TRAIN_MILITIA_ANYWHERE,
|
|
|
|
RCAM_NUM_MISSIONS,
|
|
|
|
// ideas/unimplemented
|
|
RCAM_BOOST_TOWN_ADMIN_ACTIONS, // store agent location townid in extrabits
|
|
RCAM_PROCURE_ITEMS,
|
|
RCAM_MILITIA_SKILL_TRAITS, // should override militia skill traits ini option - split into multiple (weapon spec, bodybuilding, athletic, night ops)
|
|
RCAM_PURCHASE_SUPPLIES, // increase daily supply income, decrease daily $ income
|
|
RCAM_REDUCE_ENEMY_POOL, // need to make sure enemy pool is not infinite // giReinforcementPool, also gfUnlimitedTroops = zDiffSetting[gGameOptions.ubDifficultyLevel].bUnlimitedPoolOfTroops;
|
|
// militia/mercs get bonus vision (???)
|
|
// share vision with civilians?
|
|
|
|
};
|
|
|
|
enum RegionAdminStatus
|
|
{
|
|
RAS_NONE,
|
|
RAS_ACTIVE,
|
|
RAS_INACTIVE
|
|
};
|
|
|
|
typedef struct Directive {
|
|
std::vector<INT32> iCostToImprove;
|
|
std::vector<FLOAT> fValue1;
|
|
std::vector<FLOAT> fValue2;
|
|
|
|
INT32 GetCostToImprove(INT8 currentLevel) { return iCostToImprove[currentLevel]; }
|
|
FLOAT GetValue1(INT8 currentLevel) { return fValue1[currentLevel]; }
|
|
FLOAT GetValue2(INT8 currentLevel) { return fValue2[currentLevel]; }
|
|
} Directive;
|
|
|
|
typedef struct AdminAction {
|
|
FLOAT fValue1;
|
|
FLOAT fValue2;
|
|
FLOAT fValue3;
|
|
} AdminAction;
|
|
|
|
typedef struct Info {
|
|
std::vector<Directive> directives;
|
|
std::vector<AdminAction> adminActions;
|
|
} Info;
|
|
|
|
extern Info info;
|
|
|
|
typedef struct DirectiveSaveInfo {
|
|
INT8 iLevel;
|
|
RebelCommandDirectives id;
|
|
|
|
BOOLEAN CanImprove() { return id != RCD_NONE && (size_t)iLevel < info.directives[id].iCostToImprove.size() && info.directives[id].GetCostToImprove(iLevel); }
|
|
void Improve() { iLevel++; }
|
|
INT32 GetCostToImprove() { return info.directives[id].GetCostToImprove(iLevel); }
|
|
FLOAT GetValue1() { return info.directives[id].GetValue1(iLevel); }
|
|
FLOAT GetValue2() { return info.directives[id].GetValue2(iLevel); }
|
|
} DirectiveSaveInfo;
|
|
|
|
typedef struct RegionSaveInfo
|
|
{
|
|
RegionAdminStatus adminStatus;
|
|
RebelCommandAdminActions actions[REBEL_COMMAND_MAX_ACTIONS_PER_REGION];
|
|
UINT8 actionLevels[REBEL_COMMAND_MAX_ACTIONS_PER_REGION];
|
|
UINT8 ubMaxLoyalty;
|
|
|
|
BOOLEAN IsActive(UINT8 index) { return (actionLevels[index] & ADMIN_ACTION_ACTIVE_BIT) == 0; }
|
|
// rftr: I know these fly in the face of convention, but I'm lazy and this preserves savegame compatibility without needing to add any additional code
|
|
void SetActive(UINT8 index) { actionLevels[index] &= ~ADMIN_ACTION_ACTIVE_BIT; } // active bit value = 0
|
|
void SetInactive(UINT8 index) { actionLevels[index] |= ADMIN_ACTION_ACTIVE_BIT; } // inactive bit value = 1
|
|
INT32 GetAdminDeployCost(INT16 numAdminTeams) { return 10 * numAdminTeams * numAdminTeams; };
|
|
INT32 GetAdminReactivateCost(INT16 numAdminTeams) { return GetAdminDeployCost(numAdminTeams) / 4; };
|
|
UINT8 GetLevel(INT16 index) { return actionLevels[index] & ~ADMIN_ACTION_ACTIVE_BIT; }
|
|
} RegionSaveInfo;
|
|
|
|
typedef struct SaveInfo
|
|
{
|
|
RegionSaveInfo regions[MAX_TOWNS];
|
|
DirectiveSaveInfo directives[20];
|
|
|
|
INT32 iSupplies;
|
|
INT32 iActiveDirective;
|
|
INT32 iSelectedDirective;
|
|
INT8 iMilitiaStatsLevel;
|
|
UINT8 uSupplyDropCount; // keeping this around for compatibility with old saves
|
|
INT8 availableMissions[NUM_ARC_AGENT_SLOTS];
|
|
UINT16 cachedBountyPayout;
|
|
|
|
INT8 filler[15];
|
|
} SaveInfo;
|
|
|
|
extern SaveInfo rebelCommandSaveInfo;
|
|
|
|
BOOLEAN EnterWebsite();
|
|
void ExitWebsite();
|
|
void RenderWebsite();
|
|
void HandleWebsite();
|
|
|
|
// admin actions
|
|
void ApplyEnemyPenalties(SOLDIERTYPE* pSoldier);
|
|
void ApplyMilitiaBonuses(SOLDIERTYPE* pMilitia);
|
|
UINT8 GetApproximateEnemyLocationResolutionIndex();
|
|
FLOAT GetAssignmentBonus(INT16 x, INT16 y);
|
|
INT32 GetMiningPolicyBonus(INT16 townId);
|
|
void GetBonusMilitia(INT16 x, INT16 y, UINT16& green, UINT16& regular, UINT16& elite, BOOLEAN createGroup);
|
|
INT16 GetFortificationsBonus(UINT8 sector);
|
|
FLOAT GetHarriersSpeedPenalty(UINT8 sector);
|
|
FLOAT GetLoyaltyGainModifier();
|
|
UINT8 GetMaxTownLoyalty(INT8 townId);
|
|
INT16 GetMilitiaTrainingSpeedBonus();
|
|
FLOAT GetMilitiaTrainingCostModifier();
|
|
FLOAT GetMilitiaUpkeepCostModifier();
|
|
FLOAT GetPathfindersSpeedBonus(UINT8 sector);
|
|
BOOLEAN NeutraliseRole(const SOLDIERTYPE* pSoldier);
|
|
void RaidMines(INT32 &playerIncome, INT32 &enemyIncome);
|
|
BOOLEAN ShowApproximateEnemyLocations();
|
|
|
|
// agent missions
|
|
void ApplySoldierBounty(const SOLDIERTYPE* pSoldier);
|
|
void ApplyEnemyMechanicalUnitPenalties(SOLDIERTYPE* pSoldier);
|
|
void ApplyMilitiaTraits(SOLDIERTYPE* pSoldier);
|
|
void ApplyVisionModifier(const SOLDIERTYPE* pSoldier, INT32& sight);
|
|
BOOLEAN CanAssignTraitsToMilitia();
|
|
BOOLEAN CanTrainMilitiaAnywhere();
|
|
UINT8 GetMaxTrainersForTrainMilitiaAnywhere();
|
|
INT16 GetAdditionalDeployRange(const UINT8 insertionCode);
|
|
BOOLEAN GetASDCanDeployUnits();
|
|
FLOAT GetASDIncomeModifier();
|
|
INT8 GetEnemyEquipmentCoolnessModifier();
|
|
INT8 GetEnemyEquipmentStatusModifier(const INT8 initialStatus);
|
|
UINT8 GetMerchantCoolnessBonus();
|
|
FLOAT GetStrategicDecisionSpeedModifier();
|
|
void HandleStrategicEvent(const UINT32 eventParam);
|
|
BOOLEAN ShowEnemyMovementTargets();
|
|
|
|
void DailyUpdate();
|
|
void HourlyUpdate();
|
|
void Init();
|
|
void ShowWebsiteAvailableMessage();
|
|
BOOLEAN Load(HWFILE file);
|
|
BOOLEAN Save(HWFILE file);
|
|
|
|
}
|
|
|
|
#endif
|
|
|