1 /*
2  * This file is part of EasyRPG Player.
3  *
4  * EasyRPG Player is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * EasyRPG Player is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef EP_GAME_BATTLER_H
19 #define EP_GAME_BATTLER_H
20 
21 // Headers
22 #include <string>
23 #include <vector>
24 #include <limits>
25 #include <lcf/rpg/state.h>
26 #include <lcf/dbbitarray.h>
27 #include "system.h"
28 #include "state.h"
29 #include "color.h"
30 #include "flash.h"
31 #include "utils.h"
32 #include "point.h"
33 #include "string_view.h"
34 #include "sprite_battler.h"
35 #include "sprite_weapon.h"
36 
37 class Game_Party_Base;
38 class Sprite_Battler;
39 
40 namespace Game_BattleAlgorithm {
41 	class AlgorithmBase;
42 }
43 
44 typedef std::shared_ptr<Game_BattleAlgorithm::AlgorithmBase> BattleAlgorithmRef;
45 
46 /**
47  * Game_Battler class.
48  */
49 class Game_Battler {
50 public:
51 	/** Weapon mode used for various accessors, used to specify which weapons to include in calculation */
52 	enum Weapon {
53 		/** Use all weapons combined */
54 		WeaponAll = -1,
55 		/** Use no weapons */
56 		WeaponNone = 0,
57 		/** Use only primary weapon */
58 		WeaponPrimary = 1,
59 		/** Use only secondary weapon */
60 		WeaponSecondary = 2,
61 	};
62 
63 	/**
64 	 * Constructor.
65 	 */
66 	Game_Battler();
67 
68 	Game_Battler(const Game_Battler&) = delete;
69 	Game_Battler& operator=(const Game_Battler&) = delete;
70 	Game_Battler(Game_Battler&&) noexcept = default;
71 	Game_Battler& operator=(Game_Battler&&) noexcept = default;
72 
73 	virtual ~Game_Battler() = default;
74 
75 	virtual int MaxHpValue() const = 0;
76 
77 	virtual int MaxSpValue() const = 0;
78 
79 	virtual int MaxStatBattleValue() const = 0;
80 
81 	virtual int MaxStatBaseValue() const = 0;
82 
83 	/**
84 	 * Gets if battler has a state.
85 	 *
86 	 * @param state_id database state ID.
87 	 * @return whether the battler has the state.
88 	 */
89 	bool HasState(int state_id) const;
90 
91 	/**
92 	 * Gets battler states.
93 	 *
94 	 * @return vector containing the IDs of all states the battler has.
95 	 */
96 	std::vector<int16_t> GetInflictedStates() const;
97 
98 	/** @return permenant states that cannot be removed */
99 	virtual PermanentStates GetPermanentStates() const;
100 
101 	/**
102 	 * @return true battler evades all physical attacks.
103 	 */
104 	bool EvadesAllPhysicalAttacks() const;
105 
106 	/**
107 	 * Apply effects of Conditions to Battler
108 	 *
109 	 * @return Damage taken to Battler from conditions
110 	 */
111 	int ApplyConditions();
112 
113 	/**
114 	 * Gets battler states.
115 	 * This returns the raw state list with not inflected states set to 0 and
116 	 * inflected states set to at least 1 (this maps to the turn count).
117 	 *
118 	 * @return vector containing state list
119 	 */
120 	virtual const std::vector<int16_t>& GetStates() const = 0;
121 	virtual std::vector<int16_t>& GetStates() = 0;
122 
123 	/**
124 	 * Checks all states and returns the first restriction that different to
125 	 * normal or normal if that is the only restriction.
126 	 *
127 	 * @return First non-normal restriction or normal if not restricted
128 	 */
129 	lcf::rpg::State::Restriction GetSignificantRestriction() const;
130 
131 	/**
132 	 * Gets the Battler ID.
133 	 *
134 	 * @return Battler ID
135 	 */
136 	virtual int GetId() const = 0;
137 
138 	/**
139 	 * Tests if the battler has a "No Action" condition like sleep.
140 	 *
141 	 * @return can act
142 	 */
143 	bool CanAct() const;
144 
145 	/**
146 	 * Tests if the battler has a "No Action" condition which does not auto recover.
147 	 * If all actors have these conditions, the battle is lost.
148 	 *
149 	 * @return true if actor can act or if they cannot act but the state is auto recoverable
150 	 */
151 	bool CanActOrRecoverable() const;
152 
153 	/**
154 	 * Gets current battler state with highest priority.
155 	 *
156 	 * @return the highest priority state affecting the battler.
157 	 *         Returns nullptr if no states.
158 	 */
159 	const lcf::rpg::State* GetSignificantState() const;
160 
161 	/**
162 	 * Gets the state probability by rate (A-E).
163 	 *
164 	 * @param state_id State to test
165 	 * @param rate State rate to get
166 	 * @return state rate (probability)
167 	 */
168 	int GetStateRate(int state_id, int rate) const;
169 
170 	/**
171 	 * Gets the base attribute rate when actor is damaged, without battle attribute shifts.
172 	 *
173 	 * @param attribute_id Attribute to query
174 	 * @return Attribute rate
175 	 */
176 	virtual int GetBaseAttributeRate(int attribute_id) const = 0;
177 
178 	/**
179 	 * Gets the attribute rate when actor is damaged.
180 	 *
181 	 * @param attribute_id Attribute to query
182 	 * @return Attribute rate
183 	 */
184 	int GetAttributeRate(int attribute_id) const;
185 
186 	/**
187 	 * Applies a modifier (buff/debuff) to an attribute rate.
188 	 * GetAttributeModifier will use this shift in the rate lookup.
189 	 * A shift of +1 changed a C to D and a -1 a C to B.
190 	 * The maximum shift value is +-1.
191 	 * Calling this function again applies the new shift to the previous shifts.
192 	 * The shift is cleared after the battle ended.
193 	 *
194 	 * @param attribute_id Attribute to modify
195 	 * @param shift Shift to apply.
196 	 * @return the amount shifted.
197 	 */
198 	int ShiftAttributeRate(int attribute_id, int shift);
199 
200 	/**
201 	 * Checks if we can shift an attribute.
202 	 *
203 	 * @return The amount we are able to shift by.
204 	 */
205 	int CanShiftAttributeRate(int attribute_id, int shift) const;
206 
207 	/**
208 	 * Gets the current modifier (buff/debuff) to an attribute rate.
209 	 * The shift is cleared after the battle ended.
210 	 *
211 	 * @param attribute_id Attribute modified
212 	 * @return shift Shift applied.
213 	 */
214 	int GetAttributeRateShift(int attribute_id) const;
215 
216 	/**
217 	 * Gets probability that a state can be inflicted on this actor.
218 	 *
219 	 * @param state_id State to test
220 	 * @return Probability of state infliction
221 	 */
222 	virtual int GetStateProbability(int state_id) const = 0;
223 
224 	/**
225 	 * Gets the characters name
226 	 *
227 	 * @return Character name
228 	 */
229 	virtual StringView GetName() const = 0;
230 
231 	/**
232 	 * Gets the filename of the character sprite
233 	 *
234 	 * @return Filename of character sprite
235 	 */
236 	virtual StringView GetSpriteName() const = 0;
237 
238 	/**
239 	 * Gets battler HP.
240 	 *
241 	 * @return current HP.
242 	 */
243 	virtual int GetHp() const = 0;
244 
245 	/**
246 	 * Sets the current battler HP.
247 	 *
248 	 * @param hp the new hp value to try to set
249 	 * @return the actual hp set
250 	 */
251 	virtual int SetHp(int hp) = 0;
252 
253 	/**
254 	 * Increases/Decreases hp.
255 	 * Also handles death condition.
256 	 *
257 	 * @param hp relative hp change
258 	 * @param lethal whether this change can kill the battler or not. If not, minimum 1 hp is allowed.
259 	 * @return how much hp was actually changed.
260 	 */
261 	int ChangeHp(int hp, bool lethal);
262 
263 	/**
264 	 * Gets the battler max HP.
265 	 *
266 	 * @return current max HP.
267 	 */
268 	virtual int GetMaxHp() const;
269 
270 	/**
271 	 * Gets if the battler has full hp.
272 	 *
273 	 * @return if battler is healty.
274 	 */
275 	virtual bool HasFullHp() const;
276 
277 	/**
278 	 * Gets battler SP.
279 	 *
280 	 * @return current SP.
281 	 */
282 	virtual int GetSp() const = 0;
283 
284 	/**
285 	 * Sets the current battler SP.
286 	 * @param sp the new sp value to try to set
287 	 * @return the actual sp set
288 	 */
289 	virtual int SetSp(int sp) = 0;
290 
291 	/**
292 	 * Increases/Decreases sp.
293 	 *
294 	 * @param sp relative sp change
295 	 * @return how much hp was actually changed.
296 	 */
297 	int ChangeSp(int sp);
298 
299 	/**
300 	 * Gets the battler max SP.
301 	 *
302 	 * @return current max SP.
303 	 */
304 	virtual int GetMaxSp() const;
305 
306 	/**
307 	 * Gets if the battler has full sp.
308 	 *
309 	 * @return if battler is full of magic.
310 	 */
311 	virtual bool HasFullSp() const;
312 
313 	/**
314 	 * Calculates a value after considering the inflicted states
315 	 * which influence attack.
316 	 *
317 	 * @return the value after considering the inflicted states.
318 	 */
319 	int CalcValueAfterAtkStates(int value) const;
320 
321 	/**
322 	 * Calculates a value after considering the inflicted states
323 	 * which influence defense.
324 	 *
325 	 * @return the value after considering the inflicted states.
326 	 */
327 	int CalcValueAfterDefStates(int value) const;
328 
329 	/**
330 	 * Calculates a value after considering the inflicted states
331 	 * which influence spirit.
332 	 *
333 	 * @return the value after considering the inflicted states.
334 	 */
335 	int CalcValueAfterSpiStates(int value) const;
336 
337 	/**
338 	 * Calculates a value after considering the inflicted states
339 	 * which influence agility.
340 	 *
341 	 * @return the value after considering the inflicted states.
342 	 */
343 	int CalcValueAfterAgiStates(int value) const;
344 
345 	/**
346 	 * Gets the current battler attack.
347 	 *
348 	 * @param weapon Which weapons to include in calculating result.
349 	 * @return current attack.
350 	 */
351 	int GetAtk(Weapon weapon = Game_Battler::WeaponAll) const;
352 
353 	/**
354 	 * Gets the current battler defense.
355 	 *
356 	 * @param weapon Which weapons to include in calculating result.
357 	 * @return current defense.
358 	 */
359 	int GetDef(Weapon weapon = Game_Battler::WeaponAll) const;
360 
361 	/**
362 	 * Gets the current battler spirit.
363 	 *
364 	 * @param weapon Which weapons to include in calculating result.
365 	 * @return current spirit.
366 	 */
367 	int GetSpi(Weapon weapon = Game_Battler::WeaponAll) const;
368 
369 	/**
370 	 * Gets the current battler agility.
371 	 *
372 	 * @param weapon Which weapons to include in calculating result.
373 	 * @return current agility.
374 	 */
375 	int GetAgi(Weapon weapon = Game_Battler::WeaponAll) const;
376 
377 	/**
378 	 * Gets the maximum HP for the current level.
379 	 *
380 	 * @return max HP.
381 	 */
382 	virtual int GetBaseMaxHp() const = 0;
383 
384 	/**
385 	 * Gets the maximum SP for the current level.
386 	 *
387 	 * @return max SP.
388 	 */
389 	virtual int GetBaseMaxSp() const= 0;
390 
391 	/**
392 	 * Gets the attack for the current level.
393 	 *
394 	 * @param weapon Which weapons to include in calculating result.
395 	 * @return attack.
396 	 */
397 	virtual int GetBaseAtk(Weapon weapon = WeaponAll) const = 0;
398 
399 	/**
400 	 * Gets the defense for the current level.
401 	 *
402 	 * @param weapon Which weapons to include in calculating result.
403 	 * @return defense.
404 	 */
405 	virtual int GetBaseDef(Weapon weapon = WeaponAll) const = 0;
406 
407 	/**
408 	 * Gets the spirit for the current level.
409 	 *
410 	 * @param weapon Which weapons to include in calculating result.
411 	 * @return spirit.
412 	 */
413 	virtual int GetBaseSpi(Weapon weapon = WeaponAll) const = 0;
414 
415 	/**
416 	 * Gets the agility for the current level.
417 	 *
418 	 * @param weapon Which weapons to include in calculating result.
419 	 * @return agility.
420 	 */
421 	virtual int GetBaseAgi(Weapon weapon = WeaponAll) const = 0;
422 
423 	/** @return whether the battler is facing the opposite it's normal direction */
424 	bool IsDirectionFlipped() const;
425 
426 	/**
427 	 * Set whether the battler is facing the opposite it's normal direction
428 	 *
429 	 * @param flip to flip or not
430 	 */
431 	void SetDirectionFlipped(bool flip);
432 
433 	void SetHidden(bool hidden);
434 	bool IsHidden() const;
435 	virtual bool IsImmortal() const;
436 
437 	/** @return true if this battler is in it's party */
438 	virtual bool IsInParty() const = 0;
439 
440 	bool Exists() const;
441 	bool IsDead() const;
442 
443 	/**
444 	 * Kills the battler
445 	 */
446 	void Kill();
447 
448 	/**
449 	 * Checks if the actor can use the skill.
450 	 *
451 	 * @param skill_id ID of skill to check.
452 	 * @return true if skill can be used.
453 	 */
454 	virtual bool IsSkillUsable(int skill_id) const;
455 
456 	/**
457 	 * Applies the effects of an item.
458 	 * Tests if using that item makes any sense (e.g. for HP healing
459 	 * items if there are any HP to heal)
460 	 *
461 	 * @param item_id ID if item to use
462 	 * @return true if item affected anything
463 	 */
464 	virtual bool UseItem(int item_id, const Game_Battler* source);
465 
466 	/**
467 	 * Applies the effects of a skill.
468 	 * Tests if using that skill makes any sense (e.g. for HP healing
469 	 * skills if there are any HP to heal)
470 	 * Does not reduce the MP, use Game_Party->UseSkill for this.
471 	 *
472 	 * @param skill_id ID of skill to use
473 	 * @param source battler who threw the skill
474 	 * @return true if skill affected anything
475 	 */
476 	virtual bool UseSkill(int skill_id, const Game_Battler* source);
477 
478 	/**
479 	 * Calculates the Skill costs including all modifiers.
480 	 *
481 	 * @param skill_id ID of skill to calculate.
482 	 * @return needed skill cost.
483 	 */
484 	virtual int CalculateSkillCost(int skill_id) const;
485 
486 	/**
487 	 * Calculates the Sp cost for attacking with a weapon.
488 	 *
489 	 * @param weapon which weapons to include in calculating result.
490 	 * @return sp cost for attacking with weapon.
491 	 */
492 	virtual int CalculateWeaponSpCost(Weapon weapon = WeaponAll) const;
493 
494 	/**
495 	 * Sets the battler attack modifier.
496 	 *
497 	 * @param modifier attack modifier
498 	 */
499 	void SetAtkModifier(int modifier);
500 
501 	/**
502 	 * Sets the battler defense modifier.
503 	 *
504 	 * @param modifier defense modifier.
505 	 */
506 	void SetDefModifier(int modifier);
507 
508 	/**
509 	 * Sets the battler spirity modifier.
510 	 *
511 	 * @param modifier spirity modifier.
512 	 */
513 	void SetSpiModifier(int modifier);
514 
515 	/**
516 	 * Sets the battler agility modifier.
517 	 *
518 	 * @param modifier agility modifier.
519 	 */
520 	void SetAgiModifier(int modifier);
521 
522 	/**
523 	 * Increases/Decreases battler attack modifier.
524 	 *
525 	 * @param modifier relative modifier change
526 	 * @return how much the modifier was actually changed.
527 	 */
528 	int ChangeAtkModifier(int modifier);
529 
530 	/**
531 	 * Increases/Decreases battler defense modifier.
532 	 *
533 	 * @param modifier relative modifier change
534 	 * @return how much the modifier was actually changed.
535 	 */
536 	int ChangeDefModifier(int modifier);
537 
538 	/**
539 	 * Increases/Decreases battler spirit modifier.
540 	 *
541 	 * @param modifier relative modifier change
542 	 * @return how much the modifier was actually changed.
543 	 */
544 	int ChangeSpiModifier(int modifier);
545 
546 	/**
547 	 * Increases/Decreases battler agility modifier.
548 	 *
549 	 * @param modifier relative modifier change
550 	 * @return how much the modifier was actually changed.
551 	 */
552 	int ChangeAgiModifier(int modifier);
553 
554 	/**
555 	 * Check if we can increases or decreases battler attack modifier.
556 	 *
557 	 * @param modifier relative modifier change
558 	 * @return how much the modifier will change.
559 	 */
560 	int CanChangeAtkModifier(int modifier) const;
561 
562 	/**
563 	 * Check if we can increases or decreases battler defense modifier.
564 	 *
565 	 * @param modifier relative modifier change
566 	 * @return how much the modifier will change.
567 	 */
568 	int CanChangeDefModifier(int modifier) const;
569 
570 	/**
571 	 * Check if we can increases or decreases battler spirit modifier.
572 	 *
573 	 * @param modifier relative modifier change
574 	 * @return how much the modifier will change.
575 	 */
576 	int CanChangeSpiModifier(int modifier) const;
577 
578 	/**
579 	 * Check if we can increases or decreases battler agility modifier.
580 	 *
581 	 * @param modifier relative modifier change
582 	 * @return how much the modifier will change.
583 	 */
584 	int CanChangeAgiModifier(int modifier) const;
585 
586 	/**
587 	 * Add a State.
588 	 *
589 	 * @param state_id ID of state to add.
590 	 * @param allow_battle_states allow adding of battle only states
591 	 *
592 	 * @return true if the state was added
593 	 */
594 	bool AddState(int state_id, bool allow_battle_states);
595 
596 	/**
597 	 * Removes a State.
598 	 *
599 	 * @param state_id ID of state to remove.
600 	 * @param always_remove_battle_states remove battle states even if permanent
601 	 *
602 	 * @return true if the state was removed
603 	 */
604 	bool RemoveState(int state_id, bool always_remove_battle_states);
605 
606 	/**
607 	 * Removes all states which end after battle.
608 	 */
609 	void RemoveBattleStates();
610 
611 	/**
612 	 * Removes all states.
613 	 */
614 	void RemoveAllStates();
615 
616 	/**
617 	 * Tests if the battler has a state that provides reflect.
618 	 * Attack skills targeted at this battler will be reflected to the source.
619 	 *
620 	 * @return Reflect is enabled.
621 	 */
622 	bool HasReflectState() const;
623 
624 	/* @return current (x,y) position in the battle scene */
625 	Point GetBattlePosition() const;
626 
627 	/**
628 	 *  Set (x,y) position in the battle scene.
629 	 *
630 	 *  @param pos new position to set
631 	 */
632 	void SetBattlePosition(Point pos);
633 
634 	/** @return original (x,y) position from the database */
635 	virtual Point GetOriginalPosition() const  = 0;
636 
637 	/** @return Adjusted X position on the screen.  */
638 	int GetDisplayX() const;
639 
640 	/** @return Adjusted Y position on the screen.  */
641 	int GetDisplayY() const;
642 
643 	virtual int GetBattleAnimationId() const = 0;
644 
645 	/**
646 	 * Gets the chance to hit for a normal attack.
647 	 *
648 	 * @param weapon Which weapons to include in calculating result.
649 	 * @return hit rate. [0-100]
650 	 */
651 	virtual int GetHitChance(Weapon weapon = WeaponAll) const = 0;
652 
653 	/**
654 	 * Gets the chance to critical hit for a normal attack.
655 	 *
656 	 * @param weapon Which weapons to include in calculating result.
657 	 * @return critical hit rate [0.0f-1.0f]
658 	 */
659 	virtual float GetCriticalHitChance(Weapon weapon = WeaponAll) const = 0;
660 
661 	/**
662 	 * @return If battler is charged (next attack double damages)
663 	 */
664 	bool IsCharged() const;
665 
666 	/**
667 	 * Sets charge state (next attack double damages)
668 	 *
669 	 * @param charge new charge state
670 	 */
671 	void SetCharged(bool charge);
672 
673 	/**
674 	 * @return If battler is defending (next turn, defense is doubled)
675 	 */
676 	bool IsDefending() const;
677 
678 	/**
679 	 * Set whether the battler is defending
680 	 *
681 	 * @param val whether battler is defending.
682 	 */
683 	void SetIsDefending(bool val);
684 
685 	/**
686 	 * @return If battler has strong defense (defense is tripled when defending)
687 	 */
688 	virtual bool HasStrongDefense() const;
689 
690 	/**
691 	 * Tests if the battler has a weapon that grants preemption.
692 	 *
693 	 * @param weapon Which weapons to include in calculating result.
694 	 * @return true if a weapon is having preempt attribute
695 	 */
696 	virtual bool HasPreemptiveAttack(Weapon weapon = WeaponAll) const;
697 
698 	/**
699 	 * Returns the number of times the battler will attack.
700 	 *
701 	 * @param weapon Which weapons to include in calculating result.
702 	 * @return the number of attacks.
703 	 */
704 	virtual int GetNumberOfAttacks(Weapon weapon = WeaponAll) const;
705 
706 	/**
707 	 * Tests if the battler has a weapon that grants attack all
708 	 *
709 	 * @param weapon Which weapons to include in calculating result.
710 	 * @return true if a weapon is having attack all attribute
711 	 */
712 	virtual bool HasAttackAll(Weapon weapon = WeaponAll) const;
713 
714 
715 	enum BattlerType {
716 		Type_Ally,
717 		Type_Enemy
718 	};
719 
720 	virtual BattlerType GetType() const = 0;
721 
722 	/**
723 	 * Convenience function to access the party based on the type of this
724 	 * battler. This function does not ensure that the battler is in the
725 	 * party.
726 	 * @return Party this member probably belongs to.
727 	 */
728 	Game_Party_Base& GetParty() const;
729 
730 	/**
731 	 * Gets the maximal atb gauge value.
732 	 * When GetAtbGauge() >= this, the battler can act.
733 	 * Used by RPG2k3 battle system.
734  	 */
735 	static constexpr int GetMaxAtbGauge();
736 
737 	/**
738 	 * Gets the current value of the atb gauge.
739 	 * Used by RPG2k3 battle system.
740 	 *
741 	 * @return atb gauge value
742 	 */
743 	int GetAtbGauge() const;
744 
745 	/**
746 	 * Sets the gauge to the specified value.
747 	 * Used by RPG2k3 battle system.
748 	 *
749 	 * @param value the new value to set
750 	 */
751 	void SetAtbGauge(int value);
752 
753 	/**
754 	 * Increments the gauge by specified amount.
755 	 * Used by RPG2k3 battle system.
756 	 *
757 	 * @param value the value to add
758 	 */
759 	void IncrementAtbGauge(int value);
760 
761 	/**
762 	 * Tests if the battler is ready for an action.
763 	 * Used by RPG2k3 battle system.
764 	 *
765 	 * @return If gauge is full
766 	 */
767 	bool IsAtbGaugeFull() const;
768 
769 	/**
770 	 * @return Offset of flying enemies
771 	 */
772 	virtual int GetFlyingOffset() const;
773 
774 	/**
775 	 * Updates the Battler
776 	 */
777 	virtual void UpdateBattle();
778 
779 	/**
780 	 * Gets the current BattleAlgorithm (action to execute in battle)
781 	 *
782 	 * @return Current algorithm or NULL if none
783 	 */
784 	const BattleAlgorithmRef GetBattleAlgorithm() const;
785 
786 	/**
787 	 * Assigns a new battle algorithm (action to execute in battle) to the
788 	 * battler.
789 	 *
790 	 * @param battle_algorithm New algorithm to assign
791 	 */
792 	void SetBattleAlgorithm(const BattleAlgorithmRef battle_algorithm);
793 
794 	/** @return the battle sprite for the battler */
795 	Sprite_Battler* GetBattleSprite() const;
796 
797 	/**
798 	 * Sets the battle sprite
799 	 * @param s the new sprite
800 	 */
801 	void SetBattleSprite(std::unique_ptr<Sprite_Battler> s);
802 
803 	/** @return the weapon sprite for the battler */
804 	Sprite_Weapon* GetWeaponSprite() const;
805 
806 	/**
807 	 * Sets the weapon sprite
808 	 * @param w the new sprite
809 	 */
810 	void SetWeaponSprite(std::unique_ptr<Sprite_Weapon> w);
811 
812 	/**
813 	 * @return Current turn in battle
814 	 */
815 	int GetBattleTurn() const;
816 
817 	/**
818 	 * Increases the turn counter of the actor and heals states that reached
819 	 * the required numbers of turns.
820 	 *
821 	 * @return Healed states
822 	 */
823 	void NextBattleTurn();
824 
825 	/**
826 	 * Increases the internal turn counter of states and heals states that
827 	 * reached the required numbers of turns.
828 	 *
829 	 * @return Healed states
830 	 */
831 	std::vector<int16_t> BattleStateHeal();
832 
833 	void SetBattleOrderAgi(int val);
834 	int GetBattleOrderAgi();
835 
836 	void SetLastBattleAction(int battle_action);
837 
838 	int GetLastBattleAction() const;
839 
840 	/**
841 	 * Setup the combo command
842 	 *
843 	 * @param which battle command to enable combos
844 	 * @param times how many times to repeat
845 	 */
846 	void SetBattleCombo(int command_id, int times);
847 
848 	/** @return combo command id */
849 	int GetBattleComboCommand() const;
850 
851 	/** @return combo command number of times */
852 	int GetBattleComboTimes() const;
853 
854 	/**
855 	 * Initializes battle related data to there default values.
856 	 */
857 	virtual void ResetBattle();
858 
859 	/**
860 	 * @return Effective physical hit rate modifier from inflicted states.
861 	 */
862 	int GetHitChanceModifierFromStates() const;
863 
864 	/**
865 	 * Animate a shake for the sprite
866 	 *
867 	 * @param strength strength of the shake
868 	 * @param speed speed of the shake
869 	 * @param frames how many frames to shake
870 	 */
871 	void ShakeOnce(int strength, int speed, int frames);
872 
873 	/**
874 	 * Begins a flash.
875 	 *
876 	 * @param r red color
877 	 * @param g blue color
878 	 * @param b green color
879 	 * @param power power of the flash
880 	 * @param frames Duration of the flash in frames
881 	 */
882 	void Flash(int r, int g, int b, int power, int frames);
883 
884 	/** @return current flash color */
885 	Color GetFlashColor() const;
886 
887 	/** @return battle frame counter */
888 	int GetBattleFrameCounter() const;
889 
890 	/** @return inflicted states as state objects ordered by priority */
891 	const std::vector<lcf::rpg::State*> GetInflictedStatesOrderedByPriority() const;
892 
893 protected:
894 	/** Gauge for RPG2k3 Battle */
895 	int gauge = 0;
896 
897 	/** Battle action for next turn */
898 	BattleAlgorithmRef battle_algorithm;
899 	int atk_modifier = 0;
900 	int def_modifier = 0;
901 	int spi_modifier = 0;
902 	int agi_modifier = 0;
903 	int battle_turn = 0;
904 	int frame_counter = 0;
905 	int last_battle_action = -1;
906 	int battle_combo_command_id = -1;
907 	int battle_combo_times = 1;
908 	Point position = { 0, 0 };
909 	bool defending = false;
910 	bool charged = false;
911 	bool hidden = false;
912 	bool direction_flipped = false;
913 
914 	std::unique_ptr<Sprite_Battler> battle_sprite;
915 	std::unique_ptr<Sprite_Weapon> weapon_sprite;
916 	std::vector<int> attribute_shift;
917 
918 	int battle_order = 0;
919 
920 	struct ShakeData {
921 		int32_t position = 0;
922 		int32_t time_left = 0;
923 		int32_t strength = 0;
924 		int32_t speed = 0;
925 	};
926 	ShakeData shake;
927 
928 	struct FlashData {
929 		int32_t red = 0;
930 		int32_t green = 0;
931 		int32_t blue = 0;
932 		int32_t time_left = 0;
933 		double current_level = 0.0;
934 	};
935 	FlashData flash;
936 };
937 
GetFlashColor()938 inline Color Game_Battler::GetFlashColor() const {
939 	return Flash::MakeColor(flash.red, flash.green, flash.blue, flash.current_level);
940 }
941 
Kill()942 inline void Game_Battler::Kill() {
943 	ChangeHp(-GetHp(), true);
944 }
945 
IsDead()946 inline bool Game_Battler::IsDead() const {
947 	// RPG_RT compatibility requires checking the death state and not hp.
948 	return GetHp() == 0;
949 }
950 
Exists()951 inline bool Game_Battler::Exists() const {
952 	return !IsHidden() && !IsDead() && IsInParty();
953 }
954 
SetAtkModifier(int modifier)955 inline void Game_Battler::SetAtkModifier(int modifier) {
956 	atk_modifier = modifier;
957 }
958 
SetDefModifier(int modifier)959 inline void Game_Battler::SetDefModifier(int modifier) {
960 	def_modifier = modifier;
961 }
962 
SetSpiModifier(int modifier)963 inline void Game_Battler::SetSpiModifier(int modifier) {
964 	spi_modifier = modifier;
965 }
966 
SetAgiModifier(int modifier)967 inline void Game_Battler::SetAgiModifier(int modifier) {
968 	agi_modifier = modifier;
969 }
970 
IsCharged()971 inline bool Game_Battler::IsCharged() const {
972 	return charged;
973 }
974 
SetCharged(bool charge)975 inline void Game_Battler::SetCharged(bool charge) {
976 	charged = charge;
977 }
978 
IsDefending()979 inline bool Game_Battler::IsDefending() const {
980 	return defending;
981 }
982 
SetIsDefending(bool val)983 inline void Game_Battler::SetIsDefending(bool val) {
984 	defending = val;
985 }
986 
HasStrongDefense()987 inline bool Game_Battler::HasStrongDefense() const {
988 	return false;
989 }
990 
HasPreemptiveAttack(Weapon)991 inline bool Game_Battler::HasPreemptiveAttack(Weapon) const {
992 	return false;
993 }
994 
GetNumberOfAttacks(Weapon)995 inline int Game_Battler::GetNumberOfAttacks(Weapon) const {
996 	return 1;
997 }
998 
HasAttackAll(Weapon)999 inline bool Game_Battler::HasAttackAll(Weapon) const {
1000 	return false;
1001 }
1002 
SetHidden(bool _hidden)1003 inline void Game_Battler::SetHidden(bool _hidden) {
1004 	hidden = _hidden;
1005 }
1006 
IsHidden()1007 inline bool Game_Battler::IsHidden() const {
1008 	return hidden;
1009 }
1010 
IsImmortal()1011 inline bool Game_Battler::IsImmortal() const {
1012 	return false;
1013 }
1014 
GetMaxAtbGauge()1015 constexpr int Game_Battler::GetMaxAtbGauge() {
1016 	return 300000;
1017 }
1018 
SetAtbGauge(int value)1019 inline void Game_Battler::SetAtbGauge(int value) {
1020 	gauge = Utils::Clamp(value, 0, GetMaxAtbGauge());
1021 }
1022 
GetAtbGauge()1023 inline int Game_Battler::GetAtbGauge() const {
1024 	return gauge;
1025 }
1026 
IncrementAtbGauge(int amount)1027 inline void Game_Battler::IncrementAtbGauge(int amount) {
1028 	SetAtbGauge(GetAtbGauge() + amount);
1029 }
1030 
IsAtbGaugeFull()1031 inline bool Game_Battler::IsAtbGaugeFull() const {
1032 	return gauge >= GetMaxAtbGauge();
1033 }
1034 
GetFlyingOffset()1035 inline int Game_Battler::GetFlyingOffset() const {
1036 	return 0;
1037 }
1038 
GetBattleAlgorithm()1039 inline const BattleAlgorithmRef Game_Battler::GetBattleAlgorithm() const {
1040 	return battle_algorithm;
1041 }
1042 
SetBattleAlgorithm(BattleAlgorithmRef battle_algorithm)1043 inline void Game_Battler::SetBattleAlgorithm(BattleAlgorithmRef battle_algorithm) {
1044 	this->battle_algorithm = battle_algorithm;
1045 }
1046 
GetBattleSprite()1047 inline Sprite_Battler* Game_Battler::GetBattleSprite() const {
1048 	return battle_sprite.get();
1049 }
1050 
SetBattleSprite(std::unique_ptr<Sprite_Battler> s)1051 inline void Game_Battler::SetBattleSprite(std::unique_ptr<Sprite_Battler> s) {
1052 	battle_sprite = std::move(s);
1053 }
1054 
GetWeaponSprite()1055 inline Sprite_Weapon* Game_Battler::GetWeaponSprite() const {
1056 	return weapon_sprite.get();
1057 }
1058 
SetWeaponSprite(std::unique_ptr<Sprite_Weapon> w)1059 inline void Game_Battler::SetWeaponSprite(std::unique_ptr<Sprite_Weapon> w) {
1060 	weapon_sprite = std::move(w);
1061 }
1062 
NextBattleTurn()1063 inline void Game_Battler::NextBattleTurn() {
1064 	++battle_turn;
1065 }
1066 
GetBattleTurn()1067 inline int Game_Battler::GetBattleTurn() const {
1068 	return battle_turn;
1069 }
1070 
SetLastBattleAction(int battle_action)1071 inline void Game_Battler::SetLastBattleAction(int battle_action) {
1072 	last_battle_action = battle_action;
1073 }
1074 
GetLastBattleAction()1075 inline int Game_Battler::GetLastBattleAction() const {
1076 	return last_battle_action;
1077 }
1078 
SetBattleCombo(int command_id,int times)1079 inline void Game_Battler::SetBattleCombo(int command_id, int times) {
1080 	battle_combo_command_id = command_id;
1081 	battle_combo_times = times;
1082 }
1083 
GetBattleComboCommand()1084 inline int Game_Battler::GetBattleComboCommand() const {
1085 	return battle_combo_command_id;
1086 }
1087 
GetBattleComboTimes()1088 inline int Game_Battler::GetBattleComboTimes() const {
1089 	return std::max(1, battle_combo_times);
1090 }
1091 
SetBattleOrderAgi(int val)1092 inline void Game_Battler::SetBattleOrderAgi(int val) {
1093 	battle_order = val;
1094 }
1095 
GetBattleOrderAgi()1096 inline int Game_Battler::GetBattleOrderAgi() {
1097 	return battle_order;
1098 }
1099 
GetBattlePosition()1100 inline Point Game_Battler::GetBattlePosition() const {
1101 	return position;
1102 }
1103 
SetBattlePosition(Point pos)1104 inline void Game_Battler::SetBattlePosition(Point pos) {
1105 	position = pos;
1106 }
1107 
IsDirectionFlipped()1108 inline bool Game_Battler::IsDirectionFlipped() const {
1109 	return direction_flipped;
1110 }
1111 
SetDirectionFlipped(bool flip)1112 inline void Game_Battler::SetDirectionFlipped(bool flip) {
1113 	direction_flipped = flip;
1114 }
1115 
GetBattleFrameCounter()1116 inline int Game_Battler::GetBattleFrameCounter() const {
1117 	return frame_counter;
1118 }
1119 
CalculateWeaponSpCost(Weapon)1120 inline int Game_Battler::CalculateWeaponSpCost(Weapon) const {
1121 	return 0;
1122 }
1123 
1124 #endif
1125