1 /*
2 Copyright © 2011-2012 Clint Bellanger
3 Copyright © 2012 Igor Paliychuk
4 Copyright © 2012-2016 Justin Jacobs
5 
6 This file is part of FLARE.
7 
8 FLARE is free software: you can redistribute it and/or modify it under the terms
9 of the GNU General Public License as published by the Free Software Foundation,
10 either version 3 of the License, or (at your option) any later version.
11 
12 FLARE is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
14 PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License along with
17 FLARE.  If not, see http://www.gnu.org/licenses/
18 */
19 
20 /**
21  * class StatBlock
22  *
23  * Character stats and calculations
24  */
25 
26 #ifndef STAT_BLOCK_H
27 #define STAT_BLOCK_H
28 
29 #include "CommonIncludes.h"
30 #include "EffectManager.h"
31 #include "EventManager.h"
32 #include "Stats.h"
33 #include "Utils.h"
34 
35 class FileParser;
36 
37 class StatBlock {
38 private:
39 	bool loadCoreStat(FileParser *infile);
40 	bool loadSfxStat(FileParser *infile);
41 	bool isNPCStat(FileParser *infile);
42 	void loadHeroStats();
43 	bool checkRequiredSpawns(int req_amount) const;
44 	bool statsLoaded;
45 
46 public:
47 	enum {
48 		AI_POWER_MELEE = 0,
49 		AI_POWER_RANGED = 1,
50 		AI_POWER_BEACON = 2,
51 		AI_POWER_HIT = 3,
52 		AI_POWER_DEATH = 4,
53 		AI_POWER_HALF_DEAD = 5,
54 		AI_POWER_JOIN_COMBAT = 6,
55 		AI_POWER_DEBUFF = 7,
56 		AI_POWER_PASSIVE_POST = 8
57 	};
58 
59 	enum EntityState {
60 		ENTITY_STANCE = 0,
61 		ENTITY_MOVE = 1,
62 		ENTITY_POWER = 2,
63 		ENTITY_SPAWN = 3,
64 		ENTITY_BLOCK = 4,
65 		ENTITY_HIT = 5,
66 		ENTITY_DEAD = 6,
67 		ENTITY_CRITDEAD = 7
68 	};
69 
70 	enum CombatStyle {
71 		COMBAT_DEFAULT = 0,
72 		COMBAT_AGGRESSIVE = 1,
73 		COMBAT_PASSIVE = 2
74 	};
75 
76 	class AIPower {
77 	public:
78 		int type;
79 		PowerID id;
80 		int chance;
81 		Timer cooldown;
82 
AIPower()83 		AIPower()
84 			: type(AI_POWER_MELEE)
85 			, id(0)
86 			, chance(0)
87 			, cooldown()
88 		{}
89 	};
90 
91 	static const bool CAN_USE_PASSIVE = true;
92 	static const bool TAKE_DMG_CRIT = true;
93 
94 	static const float DIRECTION_DELTA_X[8];
95 	static const float DIRECTION_DELTA_Y[8];
96 	static const float SPEED_MULTIPLIER[8];
97 
98 	StatBlock();
99 	~StatBlock();
100 
101 	void load(const std::string& filename);
102 	void takeDamage(int dmg, bool crit, int source_type);
103 	void recalc();
104 	void applyEffects();
105 	void calcBase();
106 	void logic();
107 	void removeSummons();
108 	void removeFromSummons();
109 	bool summonLimitReached(PowerID power_id) const;
110 	void setWanderArea(int r);
111 	void loadHeroSFX();
112 	std::string getShortClass();
113 	std::string getLongClass();
114 	void addXP(int amount);
115 	AIPower* getAIPower(int ai_type);
116 	int getPowerCooldown(PowerID power_id);
117 	void setPowerCooldown(PowerID power_id, int power_cooldown);
118 
119 	bool alive;
120 	bool corpse; // creature is dead and done animating
121 	Timer corpse_timer;
122 	bool hero; // else, enemy or other
123 	bool hero_ally;
124 	bool enemy_ally;
125 	bool npc;
126 	bool humanoid; // true for human, sceleton...; false for wyvern, snake...
127 	bool lifeform;
128 	bool permadeath;
129 	bool transformed;
130 	bool refresh_stats;
131 	bool converted;
132 	bool summoned;
133 	PowerID summoned_power_index;
134 	bool encountered; // enemy only
135 	StatBlock* target_corpse;
136 	StatBlock* target_nearest;
137 	StatBlock* target_nearest_corpse;
138 	float target_nearest_dist;
139 	float target_nearest_corpse_dist;
140 	PowerID block_power;
141 
142 	int movement_type;
143 	bool flying;
144 	bool intangible;
145 	bool facing; // does this creature turn to face the hero
146 
147 	std::vector<std::string> categories;
148 
149 	std::string name;
150 
151 	int level;
152 	unsigned long xp;
153 	bool level_up;
154 	bool check_title;
155 	int stat_points_per_level;
156 	int power_points_per_level;
157 
158 	// base stats ("attributes")
159 	std::vector<int> primary;
160 	std::vector<int> primary_starting;
161 
162 	// combat stats
163 	std::vector<int> starting; // default level 1 values per stat. Read from file and never changes at runtime.
164 	std::vector<int> base; // values before any active effects are applied
165 	std::vector<int> current; // values after all active effects are applied
166 	std::vector<int> per_level; // value increases each level after level 1
167 	std::vector< std::vector<int> > per_primary;
168 
get(Stats::STAT stat)169 	int get(Stats::STAT stat) const {
170 		return current[stat];
171 	}
getDamageMin(size_t dmg_type)172 	int getDamageMin(size_t dmg_type) const {
173 		return current[Stats::COUNT + (dmg_type * 2)];
174 	}
getDamageMax(size_t dmg_type)175 	int getDamageMax(size_t dmg_type) const {
176 		return current[Stats::COUNT + (dmg_type * 2) + 1];
177 	}
178 
179 	// additional values to base stats, given by items
180 	std::vector<int> primary_additional;
181 
182 	// getter for full base stats (character + additional)
get_primary(size_t index)183 	int get_primary(size_t index) const {
184 		return primary[index] + primary_additional[index];
185 	}
186 
187 	// Base class picked when starting a new game. Defaults to "Adventurer".
188 	std::string character_class;
189 	// Class derived from certain properties defined in engine/titles.txt
190 	std::string character_subclass;
191 
192 	// physical stats
193 	int hp;
194 	float hp_f;
195 
196 	// mental stats
197 	int mp;
198 	float mp_f;
199 
200 	float speed_default;
201 
202 	// addition damage and absorb granted from items
203 	std::vector<int> dmg_min_add;
204 	std::vector<int> dmg_max_add;
205 	int absorb_min_add;
206 	int absorb_max_add;
207 
208 	float speed;
209 	float charge_speed;
210 
211 	std::set<std::string> equip_flags;
212 	std::vector<int> vulnerable;
213 	std::vector<int> vulnerable_base;
214 
215 	// buff and debuff stats
216 	int transform_duration;
217 	int transform_duration_total;
218 	bool manual_untransform;
219 	bool transform_with_equipment;
220 	bool untransform_on_hit;
221 	EffectManager effects;
222 	bool blocking;
223 
224 	FPoint pos;
225 	FPoint knockback_speed;
226 	FPoint knockback_srcpos;
227 	FPoint knockback_destpos;
228 	unsigned char direction;
229 
230 	Timer cooldown_hit;
231 	bool cooldown_hit_enabled;
232 
233 	// state
234 	int cur_state;
235 	Timer state_timer;
236 	bool hold_state;
237 	bool prevent_interrupt;
238 
239 	// waypoint patrolling
240 	std::queue<FPoint> waypoints;
241 	Timer waypoint_timer;
242 
243 	// wandering area
244 	bool wander;
245 	Rect wander_area;
246 
247 	// enemy behavioral stats
248 	int chance_pursue;
249 	int chance_flee;
250 
251 	std::vector<PowerID> powers_list;
252 	std::vector<PowerID> powers_list_items;
253 	std::vector<PowerID> powers_passive;
254 	std::vector<AIPower> powers_ai;
255 
256 	bool canUsePower(PowerID powerid, bool allow_passive) const;
257 
258 	float melee_range;
259 	float threat_range;
260 	float threat_range_far;
261 	float flee_range;
262 	int combat_style; // determines how the creature enters combat
263 	int hero_stealth;
264 	int turn_delay;
265 	bool in_combat;
266 	bool join_combat;
267 	Timer cooldown; // global cooldown
268 	AIPower* activated_power;
269 	bool half_dead_power;
270 	bool suppress_hp; // hide an enemy HP bar
271 	Timer flee_timer;
272 	Timer flee_cooldown_timer;
273 	bool perfect_accuracy; // prevents misses & overhits; used for Event powers
274 
275 	std::vector<EventComponent> loot_table;
276 	Point loot_count;
277 
278 	// for the teleport spell
279 	bool teleportation;
280 	FPoint teleport_destination;
281 
282 	// for purchasing tracking
283 	int currency;
284 
285 	// marked for death
286 	bool death_penalty;
287 
288 	// Campaign event interaction
289 	StatusID defeat_status;
290 	StatusID convert_status;
291 	StatusID quest_loot_requires_status;
292 	StatusID quest_loot_requires_not_status;
293 	ItemID quest_loot_id;
294 	ItemID first_defeat_loot;
295 
296 	// player look options
297 	std::string gfx_base; // folder in /images/avatar
298 	std::string gfx_head; // png in /images/avatar/[base]
299 	std::string gfx_portrait; // png in /images/portraits
300 	std::string transform_type;
301 
302 	std::string animations;
303 
304 	// default sounds
305 	std::vector<std::pair<std::string, std::vector<std::string> > > sfx_attack;
306 	std::string sfx_step;
307 	std::vector<std::string> sfx_hit;
308 	std::vector<std::string> sfx_die;
309 	std::vector<std::string> sfx_critdie;
310 	std::vector<std::string> sfx_block;
311 	std::string sfx_levelup;
312 	std::string sfx_lowhp;
313 	bool sfx_lowhp_loop;
314 
315 	// formula numbers
316 	int max_spendable_stat_points;
317 	int max_points_per_stat;
318 
319 	// preserve state before calcs
320 	int prev_maxhp;
321 	int prev_maxmp;
322 	int prev_hp;
323 	int prev_mp;
324 
325 	// links to summoned creatures and the entity which summoned this
326 	std::vector<StatBlock*> summons;
327 	StatBlock* summoner;
328 	std::queue<PowerID> party_buffs;
329 
330 	std::vector<PowerID> power_filter;
331 
332 	std::vector<StatusID> invincible_requires_status;
333 	std::vector<StatusID> invincible_requires_not_status;
334 
335 	bool abort_npc_interact;
336 };
337 
338 #endif
339 
340