1 #ifndef __STRATEGIC_TOWN_LOYALTY_H
2 #define __STRATEGIC_TOWN_LOYALTY_H
3 
4 #include "JA2Types.h"
5 #include <vector>
6 
7 
8 // gain pts per real loyalty pt
9 #define GAIN_PTS_PER_LOYALTY_PT 500
10 
11 
12 // --- LOYALTY BONUSES ---
13 // Omerta
14 #define LOYALTY_BONUS_MIGUEL_READS_LETTER									(10 * GAIN_PTS_PER_LOYALTY_PT)	// multiplied by 4.5 due to Omerta's high seniment, so it's 45%
15 // Drassen
16 #define LOYALTY_BONUS_CHILDREN_FREED_DOREEN_KILLED				(10 * GAIN_PTS_PER_LOYALTY_PT)	// +50% bonus for Drassen
17 #define LOYALTY_BONUS_CHILDREN_FREED_DOREEN_SPARED				(20 * GAIN_PTS_PER_LOYALTY_PT)	// +50% bonus for Drassen
18 // Cambria
19 #define LOYALTY_BONUS_MARTHA_WHEN_JOEY_RESCUED						(15 * GAIN_PTS_PER_LOYALTY_PT)	// -25% for low Cambria sentiment
20 #define LOYALTY_BONUS_KEITH_WHEN_HILLBILLY_SOLVED					(15 * GAIN_PTS_PER_LOYALTY_PT)	// -25% for low Cambria sentiment
21 // Chitzena
22 #define LOYALTY_BONUS_YANNI_WHEN_CHALICE_RETURNED_LOCAL		(20 * GAIN_PTS_PER_LOYALTY_PT)	// +75% higher in Chitzena
23 #define LOYALTY_BONUS_YANNI_WHEN_CHALICE_RETURNED_GLOBAL	(10 * GAIN_PTS_PER_LOYALTY_PT)	// for ALL towns!
24 // Alma
25 #define LOYALTY_BONUS_AUNTIE_WHEN_BLOODCATS_KILLED				(20 * GAIN_PTS_PER_LOYALTY_PT)	// Alma's increases reduced by half due to low rebel sentiment
26 #define LOYALTY_BONUS_MATT_WHEN_DYNAMO_FREED							(20 * GAIN_PTS_PER_LOYALTY_PT)	// Alma's increases reduced by half due to low rebel sentiment
27 #define LOYALTY_BONUS_FOR_SERGEANT_KROTT									(20 * GAIN_PTS_PER_LOYALTY_PT)	// Alma's increases reduced by half due to low rebel sentiment
28 // Everywhere
29 #define LOYALTY_BONUS_TERRORISTS_DEALT_WITH								( 5 * GAIN_PTS_PER_LOYALTY_PT)
30 #define LOYALTY_BONUS_KILL_QUEEN_MONSTER									(10 * GAIN_PTS_PER_LOYALTY_PT)
31 // Anywhere
32 // loyalty bonus for completing town training
33 #define LOYALTY_BONUS_FOR_TOWN_TRAINING										( 2 * GAIN_PTS_PER_LOYALTY_PT )		// 2%
34 
35 
36 
37 // --- LOYALTY PENALTIES ---
38 // Cambria
39 #define LOYALTY_PENALTY_MARTHA_HEART_ATTACK								(20 * GAIN_PTS_PER_LOYALTY_PT)
40 #define LOYALTY_PENALTY_JOEY_KILLED												(10 * GAIN_PTS_PER_LOYALTY_PT)
41 // Balime
42 #define LOYALTY_PENALTY_ELDIN_KILLED											(20 * GAIN_PTS_PER_LOYALTY_PT)	// effect is double that!
43 // Any mine
44 #define LOYALTY_PENALTY_HEAD_MINER_ATTACKED								(20 * GAIN_PTS_PER_LOYALTY_PT)	// exact impact depends on rebel sentiment in that town
45 // Loyalty penalty for being inactive, per day after the third
46 #define LOYALTY_PENALTY_INACTIVE													(10 * GAIN_PTS_PER_LOYALTY_PT)
47 
48 enum GlobalLoyaltyEventTypes
49 {
50 	// There are only for distance-adjusted global loyalty effects.  Others go into list above instead!
51 	GLOBAL_LOYALTY_BATTLE_WON,
52 	GLOBAL_LOYALTY_BATTLE_LOST,
53 	GLOBAL_LOYALTY_ENEMY_KILLED,
54 	GLOBAL_LOYALTY_NATIVE_KILLED,
55 	GLOBAL_LOYALTY_GAIN_TOWN_SECTOR,
56 	GLOBAL_LOYALTY_LOSE_TOWN_SECTOR,
57 	GLOBAL_LOYALTY_LIBERATE_WHOLE_TOWN,		// awarded only the first time it happens
58 	GLOBAL_LOYALTY_ABANDON_MILITIA,
59 	GLOBAL_LOYALTY_GAIN_MINE,
60 	GLOBAL_LOYALTY_LOSE_MINE,
61 	GLOBAL_LOYALTY_GAIN_SAM,
62 	GLOBAL_LOYALTY_LOSE_SAM,
63 	GLOBAL_LOYALTY_QUEEN_BATTLE_WON,
64 };
65 
66 
67 struct TOWN_LOYALTY
68 {
69 	UINT8			ubRating;
70 	INT16			sChange;
71 	BOOLEAN		fStarted;		// starting loyalty of each town is initialized only when player first enters that town
72 	BOOLEAN		fLiberatedAlready;
73 };
74 
75 
76 // the loyalty variables for each town
77 extern TOWN_LOYALTY gTownLoyalty[];
78 
79 // whether town maintains/displays loyalty or not
80 extern BOOLEAN gfTownUsesLoyalty[];
81 
82 
83 struct TownSectorInfo
84 {
85 	UINT8 town;
86 	UINT8 sector;
87 };
88 
89 extern std::vector<TownSectorInfo> g_town_sectors;
90 
91 #define FOR_EACH_TOWN_SECTOR(iter) \
92 	for (auto iter = g_town_sectors.begin(); iter != g_town_sectors.end(); ++iter)
93 
94 #define FOR_EACH_SECTOR_IN_TOWN(iter, town_) \
95 	FOR_EACH_TOWN_SECTOR(iter) if (iter->town != (town_)) continue; else
96 
97 
98 // initialize a specific town's loyalty if it hasn't already been
99 void StartTownLoyaltyIfFirstTime( INT8 bTownId );
100 
101 // set a speciafied town's loyalty rating
102 void SetTownLoyalty( INT8 bTownId, UINT8 ubLoyaltyValue );
103 
104 // increment the town loyalty rating (hundredths!)
105 void IncrementTownLoyalty( INT8 bTownId, UINT32 uiLoyaltyIncrease );
106 
107 // decrement the town loyalty rating (hundredths!)
108 void DecrementTownLoyalty( INT8 bTownId, UINT32 uiLoyaltyDecrease );
109 
110 // init town loyalty lists
111 void InitTownLoyalty( void );
112 
113 // handle the death of a civ
114 void HandleMurderOfCivilian(const SOLDIERTYPE* pSoldier);
115 
116 // handle town loyalty adjustment for recruitment
117 void HandleTownLoyaltyForNPCRecruitment( SOLDIERTYPE *pSoldier );
118 
119 // remove random item from this sector
120 void RemoveRandomItemsInSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, UINT8 ubChance );
121 
122 // build list of town sectors
123 void BuildListOfTownSectors( void );
124 
125 
126 void LoadStrategicTownLoyaltyFromSavedGameFile(HWFILE);
127 void SaveStrategicTownLoyaltyToSaveGameFile(HWFILE);
128 
129 void ReduceLoyaltyForRebelsBetrayed(void);
130 
131 // how many towns under player control?
132 INT32 GetNumberOfWholeTownsUnderControl( void );
133 
134 // is all the sectors of this town under control by the player
135 INT32 IsTownUnderCompleteControlByPlayer( INT8 bTownId );
136 
137 // used when monsters attack a town sector without going through tactical and they win
138 void AdjustLoyaltyForCivsEatenByMonsters( INT16 sSectorX, INT16 sSectorY, UINT8 ubHowMany);
139 
140 // these are used to handle global loyalty events (ones that effect EVERY town on the map)
141 void IncrementTownLoyaltyEverywhere( UINT32 uiLoyaltyIncrease );
142 void DecrementTownLoyaltyEverywhere( UINT32 uiLoyaltyDecrease );
143 void HandleGlobalLoyaltyEvent( UINT8 ubEventType, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ);
144 
145 // handle a town being liberated for the first time
146 void CheckIfEntireTownHasBeenLiberated( INT8 bTownId, INT16 sSectorX, INT16 sSectorY );
147 void CheckIfEntireTownHasBeenLost( INT8 bTownId, INT16 sSectorX, INT16 sSectorY );
148 
149 void HandleLoyaltyChangeForNPCAction( UINT8 ubNPCProfileId );
150 
151 bool DidFirstBattleTakePlaceInThisTown(INT8 town);
152 void SetTheFirstBattleSector( INT16 sSectorValue );
153 
154 // gte number of whole towns but exclude this one
155 INT32 GetNumberOfWholeTownsUnderControlButExcludeCity( INT8 bCityToExclude );
156 
157 //Function assumes that mercs have retreated already.  Handles two cases, one for general merc retreat
158 //which slightly demoralizes the mercs, the other handles abandonment of militia forces which poses
159 //as a serious loyalty penalty.
160 
161 #define RETREAT_TACTICAL_TRAVERSAL 0
162 #define RETREAT_PBI 1
163 #define RETREAT_AUTORESOLVE 2
164 void HandleLoyaltyImplicationsOfMercRetreat( INT8 bRetreatCode, INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ );
165 
166 void MaximizeLoyaltyForDeidrannaKilled( void );
167 
168 #endif
169