1 /*-------------------------------------------------------------------------------
2 
3 	BARONY
4 	File: stat.hpp
5 	Desc: header for stat.cpp (contains Stat class definition)
6 
7 	Copyright 2013-2016 (c) Turning Wheel LLC, all rights reserved.
8 	See LICENSE for details.
9 
10 -------------------------------------------------------------------------------*/
11 
12 #pragma once
13 
14 #ifdef USE_FMOD
15 #include "fmod.h"
16 #endif
17 
18 class Item;
19 enum Monster : int;
20 //enum Item;
21 //enum Status;
22 //enum Category;
23 
24 
25 // effects
26 static const int EFF_ASLEEP = 0;
27 static const int EFF_POISONED = 1;
28 static const int EFF_STUNNED = 2;
29 static const int EFF_CONFUSED = 3;
30 static const int EFF_DRUNK = 4;
31 static const int EFF_INVISIBLE = 5;
32 static const int EFF_BLIND = 6;
33 static const int EFF_GREASY = 7;
34 static const int EFF_MESSY = 8;
35 static const int EFF_FAST = 9;
36 static const int EFF_PARALYZED = 10;
37 static const int EFF_LEVITATING = 11;
38 static const int EFF_TELEPATH = 12;
39 static const int EFF_VOMITING = 13;
40 static const int EFF_BLEEDING = 14;
41 static const int EFF_SLOW = 15;
42 static const int EFF_MAGICRESIST = 16;
43 static const int EFF_MAGICREFLECT = 17;
44 static const int EFF_VAMPIRICAURA = 18;
45 static const int EFF_SHRINE_RED_BUFF = 19;
46 static const int EFF_SHRINE_GREEN_BUFF = 20;
47 static const int EFF_SHRINE_BLUE_BUFF = 21;
48 static const int EFF_HP_REGEN = 22;
49 static const int EFF_MP_REGEN = 23;
50 static const int EFF_PACIFY = 24;
51 static const int EFF_POLYMORPH = 25;
52 static const int EFF_KNOCKBACK = 26;
53 static const int EFF_WITHDRAWAL = 27;
54 static const int EFF_POTION_STR = 28;
55 static const int EFF_SHAPESHIFT = 29;
56 static const int EFF_WEBBED = 30;
57 static const int EFF_FEAR = 31;
58 static const int EFF_MAGICAMPLIFY = 32;
59 static const int EFF_DISORIENTED = 33;
60 static const int EFF_SHADOW_TAGGED = 34;
61 static const int EFF_TROLLS_BLOOD = 35;
62 static const int EFF_FLUTTER = 36;
63 static const int EFF_DASH = 37;
64 static const int EFF_DISTRACTED_COOLDOWN = 38;
65 static const int NUMEFFECTS = 40;
66 
67 // stats
68 static const int STAT_STR = 0;
69 static const int STAT_DEX = 1;
70 static const int STAT_CON = 2;
71 static const int STAT_INT = 3;
72 static const int STAT_PER = 4;
73 static const int STAT_CHR = 5;
74 
75 static const int NUMSTATS = 6;
76 
77 // proficiencies
78 static const int PRO_LOCKPICKING = 0;   // base attribute: dex
79 static const int PRO_STEALTH = 1;       // base attribute: dex
80 static const int PRO_TRADING = 2;       // base attribute: chr
81 static const int PRO_APPRAISAL = 3;     // base attribute: per
82 static const int PRO_SWIMMING = 4;      // base attribute: con
83 static const int PRO_LEADERSHIP = 5;    // base attribute: chr
84 static const int PRO_SPELLCASTING = 6;  // base attribute: int
85 static const int PRO_MAGIC = 7;         // base attribute: int
86 static const int PRO_RANGED = 8;        // base attribute: dex
87 static const int PRO_SWORD = 9;         // base attribute: str
88 static const int PRO_MACE = 10;         // base attribute: str
89 static const int PRO_AXE = 11;          // base attribute: str
90 static const int PRO_POLEARM = 12;      // base attribute: str
91 static const int PRO_SHIELD = 13;       // base attribute: con
92 static const int PRO_UNARMED = 14;       // base attribute: str
93 static const int PRO_ALCHEMY = 15;       // base attribute: int
94 static const int NUMPROFICIENCIES = 16;
95 
96 //Start levels for the various proficiency ranges.
97 //0 = "none"
98 static const int SKILL_LEVEL_NOVICE = 1;
99 static const int SKILL_LEVEL_BASIC = 20;
100 static const int SKILL_LEVEL_SKILLED = 40;
101 static const int SKILL_LEVEL_EXPERT = 60;
102 static const int SKILL_LEVEL_MASTER = 80;
103 static const int SKILL_LEVEL_LEGENDARY = 100;
104 
105 static const int CAPSTONE_LOCKPICKING_UNLOCK = SKILL_LEVEL_LEGENDARY;
106 static const int CAPSTONE_UNLOCK_LEVEL[NUMPROFICIENCIES] =
107 {
108 		100,		//Lockpicking
109 		100,		//Stealth
110 		100,		//Trading
111 		100,		//Appraisal
112 		100,		//Swimming
113 		100,		//Leadership
114 		100,		//Spellcasting
115 		100,		//Magic
116 		100,		//Ranged
117 		100,		//Sword
118 		100,		//Mace
119 		100,		//Axe
120 		100,		//Polearm
121 		100,		//Shield
122 		100,		//Unarmed
123 		100			//Alchemy
124 };
125 
126 static const int CAPSTONE_LOCKPICKING_CHEST_GOLD_AMOUNT = 100;
127 
128 static const int NUMCATEGORIES = 14;
129 
130 #define ITEM_SLOT_NUMPROPERTIES 7
131 #define ITEM_SLOT_HELM 0
132 #define ITEM_SLOT_WEAPON ITEM_SLOT_HELM + ITEM_SLOT_NUMPROPERTIES
133 #define ITEM_SLOT_SHIELD ITEM_SLOT_WEAPON + ITEM_SLOT_NUMPROPERTIES
134 #define ITEM_SLOT_ARMOR ITEM_SLOT_SHIELD + ITEM_SLOT_NUMPROPERTIES
135 #define ITEM_SLOT_BOOTS ITEM_SLOT_ARMOR + ITEM_SLOT_NUMPROPERTIES
136 #define ITEM_SLOT_RING ITEM_SLOT_BOOTS + ITEM_SLOT_NUMPROPERTIES
137 #define ITEM_SLOT_AMULET ITEM_SLOT_RING + ITEM_SLOT_NUMPROPERTIES
138 #define ITEM_SLOT_CLOAK ITEM_SLOT_AMULET + ITEM_SLOT_NUMPROPERTIES
139 #define ITEM_SLOT_MASK ITEM_SLOT_CLOAK + ITEM_SLOT_NUMPROPERTIES
140 #define ITEM_SLOT_GLOVES ITEM_SLOT_MASK + ITEM_SLOT_NUMPROPERTIES
141 #define ITEM_SLOT_INV_1 ITEM_SLOT_GLOVES + ITEM_SLOT_NUMPROPERTIES
142 #define ITEM_SLOT_INV_2 ITEM_SLOT_INV_1 + ITEM_SLOT_NUMPROPERTIES
143 #define ITEM_SLOT_INV_3 ITEM_SLOT_INV_2 + ITEM_SLOT_NUMPROPERTIES
144 #define ITEM_SLOT_INV_4 ITEM_SLOT_INV_3 + ITEM_SLOT_NUMPROPERTIES
145 #define ITEM_SLOT_INV_5 ITEM_SLOT_INV_4 + ITEM_SLOT_NUMPROPERTIES
146 #define ITEM_SLOT_INV_6 ITEM_SLOT_INV_5 + ITEM_SLOT_NUMPROPERTIES
147 #define ITEM_CHANCE 5
148 #define ITEM_SLOT_CATEGORY 6
149 #define ITEM_CUSTOM_SLOT_LIMIT 6
150 #define ITEM_SLOT_NUM ITEM_SLOT_INV_6 + ITEM_SLOT_NUMPROPERTIES
151 
152 //--Stat Flag constants--
153 static const int STAT_FLAG_NPC = 0;
154 static const int STAT_FLAG_SNEAK = 1;
155 static const int STAT_FLAG_ALLY_PICKUP = 2;
156 static const int STAT_FLAG_ALLY_CLASS = 3;
157 static const int STAT_FLAG_PLAYER_RACE = 4;
158 static const int STAT_FLAG_POLYMORPH_STORAGE = 5;
159 static const int STAT_FLAG_ALLY_SUMMON_LVLHP = 6;
160 static const int STAT_FLAG_ALLY_SUMMON_STRDEXCONINT = 7;
161 static const int STAT_FLAG_ALLY_SUMMON_PERCHR = 8;
162 static const int STAT_FLAG_ALLY_SUMMON2_LVLHP = 9;
163 static const int STAT_FLAG_ALLY_SUMMON2_STRDEXCONINT = 10;
164 static const int STAT_FLAG_ALLY_SUMMON2_PERCHR = 11;
165 static const int STAT_FLAG_MYSTERIOUS_SHOPKEEP = 16;
166 static const int STAT_FLAG_NO_DROP_ITEMS = 19;
167 static const int STAT_FLAG_FORCE_ALLEGIANCE_TO_PLAYER = 20;
168 static const int STAT_FLAG_DISABLE_MINIBOSS = 21;
169 static const int STAT_FLAG_XP_PERCENT_AWARD = 22;
170 static const int STAT_FLAG_MONSTER_CAST_INVENTORY_SPELLBOOKS = 23;
171 static const int STAT_FLAG_SHOPKEEPER_CUSTOM_PROPERTIES = 24;
172 static const int STAT_FLAG_MONSTER_NAME_GENERIC = 25;
173 static const int STAT_FLAG_MONSTER_DISABLE_HC_SCALING = 26;
174 
175 typedef enum
176 {
177 	MALE,
178 	FEMALE
179 } sex_t;
180 
181 class Stat
182 {
183 public:
184 	Monster type;
185 	sex_t sex;
186 	Uint32 appearance;
187 	char name[128];
188 	char obituary[128];
189 	Uint32 poisonKiller; // uid of the entity which killed me via burning/poison
190 
191 	// attributes
192 	Sint32 HP, MAXHP, OLDHP;
193 	Sint32 MP, MAXMP;
194 	Sint32 STR, DEX, CON, INT, PER, CHR;
195 	Sint32 EXP, LVL;
196 	Sint32 GOLD, HUNGER;
197 	// randomised additional values to add to attributes
198 	Sint32 RANDOM_STR, RANDOM_DEX, RANDOM_CON, RANDOM_INT, RANDOM_PER, RANDOM_CHR;
199 	Sint32 RANDOM_MAXHP, RANDOM_HP, RANDOM_MAXMP, RANDOM_MP;
200 	Sint32 RANDOM_LVL;
201 	Sint32 RANDOM_GOLD;
202 	// flags to set for future entity behaviour
203 	Sint32 MISC_FLAGS[32];
204 
205 	// flags for player stats only
206 	Sint32 PLAYER_LVL_STAT_BONUS[NUMSTATS];
207 	Sint32 PLAYER_LVL_STAT_TIMER[NUMSTATS * 2];
208 
209 	// skills and effects
210 	Sint32 PROFICIENCIES[NUMPROFICIENCIES];
211 	bool EFFECTS[NUMEFFECTS];
212 	Sint32 EFFECTS_TIMERS[NUMEFFECTS];
213 	bool defending;
214 	Sint32& sneaking; // MISC_FLAGS[1]
215 	Sint32& allyItemPickup; // MISC_FLAGS[2]
216 	Sint32& allyClass; // MISC_FLAGS[3]
217 	Sint32& playerRace; // MISC_FLAGS[4]
218 	Sint32& playerPolymorphStorage; // MISC_FLAGS[5]
219 	Sint32& playerSummonLVLHP; // MISC_FLAGS[6]
220 	Sint32& playerSummonSTRDEXCONINT; // MISC_FLAGS[7]
221 	Sint32& playerSummonPERCHR; // MISC_FLAGS[8]
222 	Sint32& playerSummon2LVLHP; // MISC_FLAGS[9]
223 	Sint32& playerSummon2STRDEXCONINT; // MISC_FLAGS[10]
224 	Sint32& playerSummon2PERCHR; // MISC_FLAGS[11]
225 	Sint32& monsterIsCharmed; // MISC_FLAGS[12]
226 	Sint32& playerShapeshiftStorage; // MISC_FLAGS[13]
227 	Sint32& monsterTinkeringStatus; // MISC_FLAGS[14]
228 	Sint32& monsterDemonHasBeenExorcised; // MISC_FLAGS[15]
229 	Sint32& bleedInflictedBy; // MISC_FLAGS[17]
230 	Sint32& burningInflictedBy; // MISC_FLAGS[18]
231 	Sint32& monsterNoDropItems; // MISC_FLAGS[19]
232 	Sint32& monsterForceAllegiance; // MISC_FLAGS[20]
233 
234 	// group think
235 	Uint32 leader_uid;
236 	list_t FOLLOWERS;
237 	int stache_x1, stache_x2;
238 	int stache_y1, stache_y2;
239 
240 	// equipment
241 	list_t inventory;
242 	Item* helmet;
243 	Item* breastplate;
244 	Item* gloves;
245 	Item* shoes;
246 	Item* shield;
247 	Item* weapon;
248 	Item* cloak;
249 	Item* amulet;
250 	Item* ring;
251 	Item* mask;
252 
253 	// misc
254 #ifdef USE_FMOD
255 	FMOD_CHANNEL* monster_sound; //TODO: Do?
256 #else
257 	void* monster_sound;
258 #endif
259 	int monster_idlevar;
260 
261 	list_t magic_effects; //Makes things like the invisibility spell work.
262 	Stat(Sint32 sprite);
263 	~Stat();
264 	void clearStats();
265 	void freePlayerEquipment();
266 	Stat* copyStats();
267 	void copyNPCStatsAndInventoryFrom(Stat& src);
268 	void printStats();
269 	Sint32 EDITOR_ITEMS[ITEM_SLOT_NUM];
270 	int pickRandomEquippedItem(Item** returnItem, bool excludeWeapon, bool excludeShield, bool excludeArmor, bool excludeJewelry);
271 	enum MonsterForceAllegiance : int
272 	{
273 		MONSTER_FORCE_ALLEGIANCE_NONE = 0,
274 		MONSTER_FORCE_PLAYER_ALLY,
275 		MONSTER_FORCE_PLAYER_ENEMY,
276 		MONSTER_FORCE_PLAYER_RECRUITABLE
277 	};
278 };
279 extern Stat* stats[MAXPLAYERS];
280 
skillCapstoneUnlocked(int player,int proficiency)281 inline bool skillCapstoneUnlocked(int player, int proficiency)
282 {
283 	return (stats[player]->PROFICIENCIES[proficiency] >= CAPSTONE_UNLOCK_LEVEL[proficiency]);
284 }
285 
286 void setDefaultMonsterStats(Stat* stats, int sprite);
287 bool isMonsterStatsDefault(Stat& myStats);
288 char* getSkillLangEntry(int skill);