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);