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_BATTLEALGORITHM_H
19 #define EP_GAME_BATTLEALGORITHM_H
20
21 #include <string>
22 #include <vector>
23 #include <bitset>
24 #include <lcf/rpg/fwd.h>
25 #include <lcf/rpg/state.h>
26 #include "string_view.h"
27 #include "game_battler.h"
28
29 class Game_Battler;
30 class Game_Party_Base;
31
32 /**
33 * Contains algorithms to handle the different battle attacks, skills and items.
34 * The algorithms support single targets and party targets.
35 * For party targets the caller is responsible for retargeting using TargetNext.
36 *
37 * The action is simulated using Execute and the results can be applied after the
38 * simulation by calling Apply.
39 */
40 namespace Game_BattleAlgorithm {
41
42 enum class Type {
43 None,
44 Normal,
45 Skill,
46 Item,
47 Defend,
48 Observe,
49 Charge,
50 SelfDestruct,
51 Escape,
52 Transform,
53 DoNothing,
54 };
55
56 struct StateEffect {
57 enum Effect : int16_t {
58 None,
59 Inflicted,
60 AlreadyInflicted,
61 Healed,
62 HealedByAttack
63 };
64 int16_t state_id = 0;
65 Effect effect = None;
66
67 StateEffect() = default;
StateEffectStateEffect68 StateEffect(int state_id, Effect effect)
69 : state_id(state_id), effect(effect) {}
70 };
71
72 struct AttributeEffect {
73 int16_t attr_id = 0;
74 int16_t shift = 0;
75
76 AttributeEffect() = default;
AttributeEffectAttributeEffect77 AttributeEffect(int id, int shift)
78 : attr_id(id), shift(shift) {}
79 };
80
81 class AlgorithmBase {
82 public:
~AlgorithmBase()83 virtual ~AlgorithmBase() {}
84
85 /** @return the source of the battle action. */
86 Game_Battler* GetSource() const;
87
88 /** @return current target battler */
89 Game_Battler* GetTarget() const;
90
91 /** @return If the action was reflected, returns the target which triggered the reflect */
92 Game_Battler* GetReflectTarget() const;
93
94 /** @return true if this algorithm targets a party */
95 Game_Party_Base* GetOriginalPartyTarget() const;
96
97 /** @return the original targets of the action before reflect or other modifications */
98 Span<Game_Battler* const> GetOriginalTargets() const;
99
100 /** @return If the action originally had a single target, return that target. Otherwise return nullptr */
101 Game_Battler* GetOriginalSingleTarget() const;
102
103 /** @return the current repetition of the algorithm */
104 int GetCurrentRepeat() const;
105
106 /** @return the total number of times this algo will repeat */
107 int GetTotalRepetitions() const;
108
109 /** Initializes targetting and performs any initial actions such as sp cost reduction for the user. */
110 void Start();
111
112 /**
113 * If IsReflected(target) true on any target, will reflect the action back on the source or the source's party.
114 *
115 * @return true if this algo was reflected.
116 */
117 bool ReflectTargets();
118
119 /**
120 * Add a new target to the algo.
121 *
122 * @param target the target to add
123 * @param set_current Whether or not to reset the current target to this one
124 */
125 void AddTarget(Game_Battler* target, bool set_current);
126
127 /**
128 * Add all party targets to the algo.
129 *
130 * @param targets the party to add
131 * @param set_current Whether or not to reset the current target to the first member of the party
132 */
133 void AddTargets(Game_Party_Base* party, bool set_current);
134
135 /**
136 * Changes the target reference to the next target.
137 * When reaches the last target, will return false and reset back to first target.
138 *
139 * @return true if there was a next target available.
140 */
141 bool TargetNext();
142
143 /**
144 * Performs the next repeated action.
145 *
146 * @param require_valid_target only repeat if current target is valid.
147 * @return true if the action should be repeated. Once false is returned, the repetition resets.
148 */
149 bool RepeatNext(bool require_valid_target);
150
151 /**
152 * Defines switches that will be switched on after the action is finished.
153 * Multiple calls to this function will add additional switches to the list.
154 *
155 * @param switch_id Switch to turn on
156 */
157 void SetSwitchEnable(int switch_id);
158
159 /**
160 * Defines switches that will be switched off after the action is finished.
161 * Multiple calls to this function will add additional switches to the list.
162 *
163 * @param switch_id Switch to turn off
164 */
165 void SetSwitchDisable(int switch_id);
166
167 /** @return activated switch id or 0 when algorithm didn't affect a switch */
168 int GetAffectedSwitch() const;
169
170 /** @return true if this action affects hp. */
171 bool IsAffectHp() const;
172
173 /** @return true if this action absorbs hp. */
174 bool IsAbsorbHp() const;
175
176 /** @return true if this action affects sp. */
177 bool IsAffectSp() const;
178
179 /** @return true if this action absorbs sp. */
180 bool IsAbsorbSp() const;
181
182 /** @return true if this action affects atk. */
183 bool IsAffectAtk() const;
184
185 /** @return true if this action absorbs atk. */
186 bool IsAbsorbAtk() const;
187
188 /** @return true if this action affects def. */
189 bool IsAffectDef() const;
190
191 /** @return true if this action absorbs def. */
192 bool IsAbsorbDef() const;
193
194 /** @return true if this action affects spi. */
195 bool IsAffectSpi() const;
196
197 /** @return true if this action absorbs spi. */
198 bool IsAbsorbSpi() const;
199
200 /** @return true if this action affects agi. */
201 bool IsAffectAgi() const;
202
203 /** @return true if this action affects agi. */
204 bool IsAbsorbAgi() const;
205
206 /** @return signed value of how much hp is to be gained or lost */
207 int GetAffectedHp() const;
208
209 /** @return signed value of how much sp is to be gained or lost */
210 int GetAffectedSp() const;
211
212 /** @return signed value of how much attack is to be gained or lost */
213 int GetAffectedAtk() const;
214
215 /** @return signed value of how much defense is to be gained or lost */
216 int GetAffectedDef() const;
217
218 /** @return signed value of how much spirit is to be gained or lost */
219 int GetAffectedSpi() const;
220
221 /** @return signed value of how much agility is to be gained or lost */
222 int GetAffectedAgi() const;
223
224 /** @return all states changes caused by this action in order. */
225 const std::vector<StateEffect>& GetStateEffects() const;
226
227 /** @return all attributes which are shifited by this action. */
228 const std::vector<AttributeEffect>& GetShiftedAttributes() const;
229
230 /**
231 * Returns whether the action hit the target.
232 * This function returns the same as the last Execute-call.
233 *
234 * @return if the action hit the target
235 */
236 bool IsSuccess() const;
237
238 /** @return Whether action was positive (e.g. healing) instead of damage. */
239 bool IsPositive() const;
240
241 /** @return Whether target will be revived from death */
242 bool IsRevived() const;
243
244 /** @return if the last action was a critical hit. */
245 bool IsCriticalHit() const;
246
247 /**
248 * Gets the Battle Animation that is assigned to the Algorithm
249 *
250 * @param i Which animation to fetch, starting from 0.
251 * @return Battle Animation id or 0 if no animation is assigned
252 */
253 virtual int GetAnimationId(int i) const;
254
255 /**
256 * Plays the battle animation on all valid targets starting from the current target to the last target.
257 * Takes care of single and multi-target animations.
258 *
259 * @param anim_id the ID of the animation to play.
260 * @param sound_only Only play sounds
261 * @param cutoff If >= 0 maximum number of frames to play
262 * @param invert Flips the animation
263 * @return the number of frames the animation will play
264 */
265 int PlayAnimation(int anim_id, bool sound_only = false, int cutoff = -1, bool invert = false);
266
267 /**
268 * Executes the algorithm. Must be called before using the other functions.
269 * This function only simulates the Algorithm, call Apply to add the
270 * changes of the last Execute call to the target.
271 *
272 * @return true if the action was successful, false if failed/dodged
273 */
274 bool Execute();
275
276 /** Apply custom effects */
277 virtual void ApplyCustomEffect();
278
279 /**
280 * Apply switch enabled by action
281 * @return the switch id enabled, or 0 if none.
282 */
283 int ApplySwitchEffect();
284
285 /**
286 * Apply hp damage or healing.
287 * @note Hp healing is not applied if the action revivies
288 * @return the amount of hp changed.
289 */
290 int ApplyHpEffect();
291
292 /**
293 * Apply sp increase or decrease.
294 * @return the amount of sp changed.
295 */
296 int ApplySpEffect();
297
298 /**
299 * Apply atk increase or decrease.
300 * @return the amount of atk changed.
301 */
302 int ApplyAtkEffect();
303
304 /**
305 * Apply def increase or decrease.
306 * @return the amount of def changed.
307 */
308 int ApplyDefEffect();
309
310 /**
311 * Apply spi increase or decrease.
312 * @return the amount of spi changed.
313 */
314 int ApplySpiEffect();
315
316 /**
317 * Apply agi increase or decrease.
318 * @return the amount of agi changed.
319 */
320 int ApplyAgiEffect();
321
322 /**
323 * Apply the given state effect.
324 * @return true if state was successfully added or removed.
325 */
326 bool ApplyStateEffect(StateEffect se);
327
328 /** Apply all state effects */
329 void ApplyStateEffects();
330
331 /**
332 * Apply the given attribute effect
333 * @return the amount the attribute was shifted.
334 */
335 int ApplyAttributeShiftEffect(AttributeEffect ae);
336
337 /** Apply all attribute effects */
338 void ApplyAttributeShiftEffects();
339
340 /** Apply all effects in order */
341 void ApplyAll();
342
343 /** Apply switches set on the action externally (e.g. enemy actions) */
344 void ProcessPostActionSwitches();
345
346 /**
347 * Tests if it makes sense to apply an action on the target.
348 * E.g. when it is dead.
349 *
350 * @param target the target to check
351 * @return true if valid, in case of false another target should be selected.
352 */
353 virtual bool IsTargetValid(const Game_Battler& target) const;
354
355 /** @return whether the current target is valid */
356 bool IsCurrentTargetValid() const;
357
358 /**
359 * Gets the first line message that is displayed when the action is invoked.
360 * Usually of style "[Name] uses/casts [Weapon/Item/Skill]".
361 *
362 * @param line which line of the message to fetch
363 * @return message
364 */
365 virtual std::string GetStartMessage(int line) const;
366
367 /** @return the pose the source should be in when performing the action */
368 virtual int GetSourcePose() const;
369
370 /** @return the CBA movement to use when performing the action */
371 virtual int GetCBAMovement() const;
372
373 /** @return the CBA afterimage setting to use when performing the action */
374 virtual int GetCBAAfterimage() const;
375
376 /** @return true if it is still possible to perform this action now. */
377 virtual bool ActionIsPossible() const;
378
379 /** @return the weapon animation data for this action (if applicable) */
380 virtual const lcf::rpg::BattlerAnimationItemSkill* GetWeaponAnimationData() const;
381
382 /** @return the weapon data for this action (if applicable) */
383 virtual const lcf::rpg::Item* GetWeaponData() const;
384
385 /**
386 * Gets the sound effect that is played when the action is starting.
387 *
388 * @return start se
389 */
390 virtual const lcf::rpg::Sound* GetStartSe() const;
391
392 /**
393 * Gets the sound effect that is played then the action fails.
394 *
395 * @return result se
396 */
397 virtual const lcf::rpg::Sound* GetFailureSe() const;
398
399 /**
400 * Returns the message used when the action fails.
401 *
402 * @return failure message
403 */
404 virtual std::string GetFailureMessage() const;
405
406 /**
407 * Returns whether the attack would be reflected if used upon the target.
408 *
409 * @param the target to check
410 * @return true when reflected
411 */
412 virtual bool IsReflected(const Game_Battler& target) const;
413
414 /**
415 * Returns the algorithm type of this object.
416 */
417 Type GetType() const;
418
419 /**
420 * Set number of times to repeat the same action on a target
421 */
422 void SetRepeat(int repeat);
423
424 /**
425 * Apply a combo number of hits to repeat the action.
426 *
427 * @param hits the number of combo hits
428 */
429 virtual void ApplyComboHitsMultiplier(int hits);
430
431 /**
432 * Set the affected switch id
433 * @param s the switch id
434 */
435 int SetAffectedSwitch(int s);
436
437 /**
438 * Set the affected hp
439 * @param hp the signed hp gain/loss value
440 */
441 int SetAffectedHp(int hp);
442
443 /**
444 * Set whether the effect will absorb hp from the target
445 * @param a whether to absorb or not.
446 */
447 bool SetIsAbsorbHp(bool a);
448
449 /**
450 * Set the affected sp
451 * @param hp the signed sp gain/loss value
452 */
453 int SetAffectedSp(int sp);
454
455 /**
456 * Set whether the effect will absorb sp from the target
457 * @param a whether to absorb or not.
458 */
459 bool SetIsAbsorbSp(bool a);
460
461 /**
462 * Set the affected atk
463 * @param hp the signed atk gain/loss value
464 */
465 int SetAffectedAtk(int hp);
466
467 /**
468 * Set whether the effect will absorb atk from the target
469 * @param a whether to absorb or not.
470 */
471 bool SetIsAbsorbAtk(bool a);
472
473 /**
474 * Set the affected def
475 * @param hp the signed def gain/loss value
476 */
477 int SetAffectedDef(int hp);
478
479 /**
480 * Set whether the effect will absorb def from the target
481 * @param a whether to absorb or not.
482 */
483 bool SetIsAbsorbDef(bool a);
484
485 /**
486 * Set the affected spi
487 * @param hp the signed spi gain/loss value
488 */
489 int SetAffectedSpi(int hp);
490
491 /**
492 * Set whether the effect will absorb spi from the target
493 * @param a whether to absorb or not.
494 */
495 bool SetIsAbsorbSpi(bool a);
496
497 /**
498 * Set the affected agi
499 * @param hp the signed agi gain/loss value
500 */
501 int SetAffectedAgi(int hp);
502
503 /**
504 * Set whether the effect will absorb agi from the target
505 * @param a whether to absorb or not.
506 */
507 bool SetIsAbsorbAgi(bool a);
508
509 /**
510 * Add a state effect
511 * @param se the state effect to add
512 */
513 void AddAffectedState(StateEffect se);
514
515 /**
516 * Add an attribute shift effect
517 * @param se the attribute shift effect to add
518 */
519 void AddAffectedAttribute(AttributeEffect ae);
520
521 /**
522 * Set if the original intention was positive (healing)
523 * @param p if positive or not
524 */
525 bool SetIsPositive(bool p);
526
527 /**
528 * Set if the effect was a critical hit
529 * @param c if critical hit or not
530 */
531 bool SetIsCriticalHit(bool c);
532
533 /** Set if the algo was a success */
534 bool SetIsSuccess();
535
536 /**
537 * Set the algo to successful if the condition is true. If it's false, no change.
538 * @param x condition to check
539 */
540 bool SetIsSuccessIf(bool x);
541
542 /** Set if the algo failed */
543 bool SetIsFailure();
544
545 protected:
546 AlgorithmBase(Type t, Game_Battler* source, Game_Battler* target);
547 AlgorithmBase(Type t, Game_Battler* source, std::vector<Game_Battler*> targets);
548 AlgorithmBase(Type t, Game_Battler* source, Game_Party_Base* target);
549 virtual bool vStart();
550 virtual bool vExecute();
551
552 void Reset();
553
554 /**
555 * Implements logic of TargetNext but ignores reflect.
556 * Used by const-functions that restore the old state afterwards.
557 * So technically this function is non-const but due to the help of the
558 * other functions the behaviour to the callee is const...
559 *
560 * @return true if there was a next target available
561 */
562 bool TargetNextInternal();
563
564 void BattlePhysicalStateHeal(int physical_rate, std::vector<int16_t>& target_states, const PermanentStates& ps);
565
566 private:
567 Type type = Type::None;
568 Game_Battler* source = nullptr;
569 std::vector<Game_Battler*> targets;
570 std::vector<Game_Battler*>::iterator current_target;
571 Game_Party_Base* party_target = nullptr;
572 Game_Battler* reflect_target = nullptr;
573
574 int hp = 0;
575 int sp = 0;
576 int attack = 0;
577 int defense = 0;
578 int spirit = 0;
579 int agility = 0;
580 int switch_id = 0;
581
582 enum Flag {
583 eSuccess,
584 ePositive,
585 eCriticalHit,
586 eRevived,
587 eAffectHp,
588 eAbsorbHp,
589 eAffectSp,
590 eAbsorbSp,
591 eAffectAtk,
592 eAbsorbAtk,
593 eAffectDef,
594 eAbsorbDef,
595 eAffectSpi,
596 eAbsorbSpi,
597 eAffectAgi,
598 eAbsorbAgi,
599 };
600 std::bitset<64> flags = {};
601 int num_original_targets = 0;
602 int cur_repeat = 0;
603 int repeat = 1;
604
605 std::vector<StateEffect> states;
606 std::vector<AttributeEffect> attributes;
607 std::vector<int> switch_on;
608 std::vector<int> switch_off;
609
610 bool SetFlag(Flag f, bool value);
611 bool GetFlag(Flag f) const;
612 };
613
614 // Special algorithm for handling non-moving because of states
615 class None : public AlgorithmBase {
616 public:
617 None(Game_Battler* source);
618 };
619
620
621 class Normal : public AlgorithmBase {
622 public:
623 enum Style {
624 /** 2k style, single combined attack with both weapons */
625 Style_Combined,
626 /** 2k3 style, multiple attacks, one per weapon */
627 Style_MultiHit,
628 };
629
630 static Style GetDefaultStyle();
631
632 Normal(Game_Battler* source, Game_Battler* target, int hits_multiplier = 1, Style style = GetDefaultStyle());
633 Normal(Game_Battler* source, Game_Party_Base* target, int hits_multiplier = 1, Style style = GetDefaultStyle());
634
635 bool vExecute() override;
636 bool vStart() override;
637
638 int GetAnimationId(int i) const override;
639 std::string GetStartMessage(int line) const override;
640 int GetSourcePose() const override;
641 int GetCBAMovement() const override;
642 int GetCBAAfterimage() const override;
643 const lcf::rpg::BattlerAnimationItemSkill* GetWeaponAnimationData() const override;
644 const lcf::rpg::Item* GetWeaponData() const override;
645 const lcf::rpg::Sound* GetStartSe() const override;
646 Game_Battler::Weapon GetWeapon() const;
647 void ApplyComboHitsMultiplier(int hits) override;
648
649 // Emulates an RPG_RT bug where whenver an actor attacks an enemy, the hit rate and damage
650 // is adjusted as if the enemy were in the front row.
651 void SetTreatEnemiesAsIfInFrontRow(bool v);
652
653 // Return true if this is a charged attack.
654 bool IsChargedAttack() const;
655 private:
656 void Init(Style style);
657 int hits_multiplier = 1;
658 int weapon_style = -1;
659 bool charged_attack = false;
660 bool treat_enemies_asif_in_front_row = false;
661 };
662
663 class Skill : public AlgorithmBase {
664 public:
665 Skill(Game_Battler* source, Game_Battler* target, const lcf::rpg::Skill& skill, const lcf::rpg::Item* item = NULL);
666 Skill(Game_Battler* source, Game_Party_Base* target, const lcf::rpg::Skill& skill, const lcf::rpg::Item* item = NULL);
667 Skill(Game_Battler* source, const lcf::rpg::Skill& skill, const lcf::rpg::Item* item = NULL);
668
669 bool IsTargetValid(const Game_Battler&) const override;
670 bool vExecute() override;
671 bool vStart() override;
672
673 int GetAnimationId(int i) const override;
674 std::string GetStartMessage(int line) const override;
675 int GetSourcePose() const override;
676 int GetCBAMovement() const override;
677 int GetCBAAfterimage() const override;
678 const lcf::rpg::Sound* GetStartSe() const override;
679 const lcf::rpg::Sound* GetFailureSe() const override;
680 std::string GetFailureMessage() const override;
681 bool IsReflected(const Game_Battler&) const override;
682 bool ActionIsPossible() const override;
683
684 const lcf::rpg::Skill& GetSkill() const;
685 const lcf::rpg::Item* GetItem() const;
686
687 private:
688 void Init();
689 std::string GetFirstStartMessage() const;
690 std::string GetSecondStartMessage() const;
691 const lcf::rpg::Skill& skill;
692 const lcf::rpg::Item* item;
693 };
694
695 class Item : public AlgorithmBase {
696 public:
697 Item(Game_Battler* source, Game_Battler* target, const lcf::rpg::Item& item);
698 Item(Game_Battler* source, Game_Party_Base* target, const lcf::rpg::Item& item);
699 Item(Game_Battler* source, const lcf::rpg::Item& item);
700
701 bool IsTargetValid(const Game_Battler&) const override;
702 bool vExecute() override;
703 bool vStart() override;
704
705 std::string GetStartMessage(int line) const override;
706 int GetSourcePose() const override;
707 int GetCBAMovement() const override;
708 const lcf::rpg::Sound* GetStartSe() const override;
709 bool ActionIsPossible() const override;
710
711 private:
712 std::string GetFirstStartMessage() const;
713 std::string GetSecondStartMessage() const;
714 const lcf::rpg::Item& item;
715 };
716
717 class Defend : public AlgorithmBase {
718 public:
719 Defend(Game_Battler* source);
720
721 std::string GetStartMessage(int line) const override;
722 int GetSourcePose() const override;
723 };
724
725 class Observe : public AlgorithmBase {
726 public:
727 Observe(Game_Battler* source);
728
729 std::string GetStartMessage(int line) const override;
730 };
731
732 class Charge : public AlgorithmBase {
733 public:
734 Charge(Game_Battler* source);
735
736 std::string GetStartMessage(int line) const override;
737 void ApplyCustomEffect() override;
738 };
739
740 class SelfDestruct : public AlgorithmBase {
741 public:
742 SelfDestruct(Game_Battler* source, Game_Party_Base* target);
743
744 std::string GetStartMessage(int line) const override;
745 const lcf::rpg::Sound* GetStartSe() const override;
746 bool vExecute() override;
747 void ApplyCustomEffect() override;
748 private:
749 bool animate = true;
750 };
751
752 class Escape : public AlgorithmBase {
753 public:
754 Escape(Game_Battler* source);
755
756 std::string GetStartMessage(int line) const override;
757 int GetSourcePose() const override;
758 const lcf::rpg::Sound* GetStartSe() const override;
759 void ApplyCustomEffect() override;
760 };
761
762 class Transform : public AlgorithmBase {
763 public:
764 Transform(Game_Battler* source, int new_monster_id);
765
766 std::string GetStartMessage(int line) const override;
767 void ApplyCustomEffect() override;
768
769 private:
770 int new_monster_id;
771 };
772
773 // EnemyAi "Do Nothing" action. Handled slightly differently than None.
774 class DoNothing : public AlgorithmBase {
775 public:
776 DoNothing(Game_Battler* source);
777 };
778
GetType()779 inline Type AlgorithmBase::GetType() const {
780 return type;
781 }
782
GetStateEffects()783 inline const std::vector<StateEffect>& AlgorithmBase::GetStateEffects() const {
784 return states;
785 }
786
GetOriginalPartyTarget()787 inline Game_Party_Base* AlgorithmBase::GetOriginalPartyTarget() const {
788 return party_target;
789 }
790
GetAffectedHp()791 inline int Game_BattleAlgorithm::AlgorithmBase::GetAffectedHp() const {
792 return hp;
793 }
794
GetAffectedSp()795 inline int Game_BattleAlgorithm::AlgorithmBase::GetAffectedSp() const {
796 return sp;
797 }
798
GetAffectedAtk()799 inline int Game_BattleAlgorithm::AlgorithmBase::GetAffectedAtk() const {
800 return attack;
801 }
802
GetAffectedDef()803 inline int Game_BattleAlgorithm::AlgorithmBase::GetAffectedDef() const {
804 return defense;
805 }
806
GetAffectedSpi()807 inline int Game_BattleAlgorithm::AlgorithmBase::GetAffectedSpi() const {
808 return spirit;
809 }
810
GetAffectedAgi()811 inline int Game_BattleAlgorithm::AlgorithmBase::GetAffectedAgi() const {
812 return agility;
813 }
814
GetShiftedAttributes()815 inline const std::vector<Game_BattleAlgorithm::AttributeEffect>& Game_BattleAlgorithm::AlgorithmBase::GetShiftedAttributes() const {
816 return attributes;
817 }
818
GetAffectedSwitch()819 inline int Game_BattleAlgorithm::AlgorithmBase::GetAffectedSwitch() const {
820 return switch_id;
821 }
822
IsPositive()823 inline bool Game_BattleAlgorithm::AlgorithmBase::IsPositive() const {
824 return GetFlag(ePositive);
825 }
826
IsRevived()827 inline bool Game_BattleAlgorithm::AlgorithmBase::IsRevived() const {
828 return GetFlag(eRevived);
829 }
830
ActionIsPossible()831 inline bool Game_BattleAlgorithm::AlgorithmBase::ActionIsPossible() const {
832 return true;
833 }
834
GetAnimationId(int)835 inline int Game_BattleAlgorithm::AlgorithmBase::GetAnimationId(int) const {
836 return 0;
837 }
838
IsAffectHp()839 inline bool Game_BattleAlgorithm::AlgorithmBase::IsAffectHp() const {
840 return GetFlag(eAffectHp);
841 }
842
IsAbsorbHp()843 inline bool Game_BattleAlgorithm::AlgorithmBase::IsAbsorbHp() const {
844 return GetFlag(eAbsorbHp);
845 }
846
IsAffectSp()847 inline bool Game_BattleAlgorithm::AlgorithmBase::IsAffectSp() const {
848 return GetFlag(eAffectSp);
849 }
850
IsAbsorbSp()851 inline bool Game_BattleAlgorithm::AlgorithmBase::IsAbsorbSp() const {
852 return GetFlag(eAbsorbSp);
853 }
854
IsAffectAtk()855 inline bool Game_BattleAlgorithm::AlgorithmBase::IsAffectAtk() const {
856 return GetFlag(eAffectAtk);
857 }
858
IsAbsorbAtk()859 inline bool Game_BattleAlgorithm::AlgorithmBase::IsAbsorbAtk() const {
860 return GetFlag(eAbsorbAtk);
861 }
862
IsAffectDef()863 inline bool Game_BattleAlgorithm::AlgorithmBase::IsAffectDef() const {
864 return GetFlag(eAffectDef);
865 }
866
IsAbsorbDef()867 inline bool Game_BattleAlgorithm::AlgorithmBase::IsAbsorbDef() const {
868 return GetFlag(eAbsorbDef);
869 }
870
IsAffectSpi()871 inline bool Game_BattleAlgorithm::AlgorithmBase::IsAffectSpi() const {
872 return GetFlag(eAffectSpi);
873 }
874
IsAbsorbSpi()875 inline bool Game_BattleAlgorithm::AlgorithmBase::IsAbsorbSpi() const {
876 return GetFlag(eAbsorbSpi);
877 }
878
IsAffectAgi()879 inline bool Game_BattleAlgorithm::AlgorithmBase::IsAffectAgi() const {
880 return GetFlag(eAffectAgi);
881 }
882
IsAbsorbAgi()883 inline bool Game_BattleAlgorithm::AlgorithmBase::IsAbsorbAgi() const {
884 return GetFlag(eAbsorbAgi);
885 }
886
887
GetReflectTarget()888 inline Game_Battler* Game_BattleAlgorithm::AlgorithmBase::GetReflectTarget() const {
889 return reflect_target;
890 }
891
GetOriginalTargets()892 inline Span<Game_Battler* const> Game_BattleAlgorithm::AlgorithmBase::GetOriginalTargets() const {
893 assert(num_original_targets <= static_cast<int>(targets.size()));
894 return Span<Game_Battler* const>(targets.data(), num_original_targets);
895 }
896
GetOriginalSingleTarget()897 inline Game_Battler* Game_BattleAlgorithm::AlgorithmBase::GetOriginalSingleTarget() const {
898 assert(num_original_targets <= static_cast<int>(targets.size()));
899 return (GetOriginalPartyTarget() == nullptr && num_original_targets == 1) ? targets.front() : nullptr;
900 }
901
SetAffectedSwitch(int s)902 inline int Game_BattleAlgorithm::AlgorithmBase::SetAffectedSwitch(int s) {
903 return this->switch_id = s;
904 }
905
SetAffectedHp(int hp)906 inline int Game_BattleAlgorithm::AlgorithmBase::SetAffectedHp(int hp) {
907 SetFlag(eAffectHp, true);
908 return this->hp = hp;
909 }
910
SetAffectedSp(int sp)911 inline int Game_BattleAlgorithm::AlgorithmBase::SetAffectedSp(int sp) {
912 SetFlag(eAffectSp, true);
913 return this->sp = sp;
914 }
915
SetAffectedAtk(int atk)916 inline int Game_BattleAlgorithm::AlgorithmBase::SetAffectedAtk(int atk) {
917 SetFlag(eAffectAtk, true);
918 return this->attack = atk;
919 }
920
SetAffectedDef(int def)921 inline int Game_BattleAlgorithm::AlgorithmBase::SetAffectedDef(int def) {
922 SetFlag(eAffectDef, true);
923 return this->defense = def;
924 }
925
SetAffectedSpi(int spi)926 inline int Game_BattleAlgorithm::AlgorithmBase::SetAffectedSpi(int spi) {
927 SetFlag(eAffectSpi, true);
928 return this->spirit = spi;
929 }
930
SetAffectedAgi(int agi)931 inline int Game_BattleAlgorithm::AlgorithmBase::SetAffectedAgi(int agi) {
932 SetFlag(eAffectAgi, true);
933 return this->agility = agi;
934 }
935
SetIsPositive(bool p)936 inline bool Game_BattleAlgorithm::AlgorithmBase::SetIsPositive(bool p) {
937 return SetFlag(ePositive, p);
938 }
939
SetIsCriticalHit(bool c)940 inline bool Game_BattleAlgorithm::AlgorithmBase::SetIsCriticalHit(bool c) {
941 return SetFlag(eCriticalHit, c);
942 }
943
SetIsSuccess()944 inline bool Game_BattleAlgorithm::AlgorithmBase::SetIsSuccess() {
945 return SetFlag(eSuccess, true);
946 }
947
SetIsSuccessIf(bool x)948 inline bool Game_BattleAlgorithm::AlgorithmBase::SetIsSuccessIf(bool x) {
949 return SetFlag(eSuccess, GetFlag(eSuccess) | x);
950 }
951
SetIsFailure()952 inline bool Game_BattleAlgorithm::AlgorithmBase::SetIsFailure() {
953 return SetFlag(eSuccess, false);
954 }
955
IsSuccess()956 inline bool Game_BattleAlgorithm::AlgorithmBase::IsSuccess() const {
957 return GetFlag(eSuccess);
958 }
959
IsCriticalHit()960 inline bool Game_BattleAlgorithm::AlgorithmBase::IsCriticalHit() const {
961 return GetFlag(eCriticalHit);
962 }
963
GetSource()964 inline Game_Battler* Game_BattleAlgorithm::AlgorithmBase::GetSource() const {
965 return source;
966 }
967
GetCurrentRepeat()968 inline int Game_BattleAlgorithm::AlgorithmBase::GetCurrentRepeat() const {
969 return cur_repeat;
970 }
971
GetTotalRepetitions()972 inline int Game_BattleAlgorithm::AlgorithmBase::GetTotalRepetitions() const {
973 return repeat;
974 }
975
SetFlag(Flag f,bool value)976 inline bool Game_BattleAlgorithm::AlgorithmBase::SetFlag(Flag f, bool value) {
977 flags.set(uint64_t(f), value);
978 return value;
979 }
980
GetFlag(Flag f)981 inline bool Game_BattleAlgorithm::AlgorithmBase::GetFlag(Flag f) const {
982 return flags.test(uint64_t(f));
983 }
984
SetIsAbsorbHp(bool a)985 inline bool Game_BattleAlgorithm::AlgorithmBase::SetIsAbsorbHp(bool a) {
986 SetFlag(eAbsorbHp, a);
987 return a;
988 }
989
SetIsAbsorbSp(bool a)990 inline bool Game_BattleAlgorithm::AlgorithmBase::SetIsAbsorbSp(bool a) {
991 SetFlag(eAbsorbSp, a);
992 return a;
993 }
994
SetIsAbsorbAtk(bool a)995 inline bool Game_BattleAlgorithm::AlgorithmBase::SetIsAbsorbAtk(bool a) {
996 SetFlag(eAbsorbAtk, a);
997 return a;
998 }
999
SetIsAbsorbDef(bool a)1000 inline bool Game_BattleAlgorithm::AlgorithmBase::SetIsAbsorbDef(bool a) {
1001 SetFlag(eAbsorbDef, a);
1002 return a;
1003 }
1004
SetIsAbsorbSpi(bool a)1005 inline bool Game_BattleAlgorithm::AlgorithmBase::SetIsAbsorbSpi(bool a) {
1006 SetFlag(eAbsorbSpi, a);
1007 return a;
1008 }
1009
SetIsAbsorbAgi(bool a)1010 inline bool Game_BattleAlgorithm::AlgorithmBase::SetIsAbsorbAgi(bool a) {
1011 SetFlag(eAbsorbAgi, a);
1012 return a;
1013 }
1014
SetTreatEnemiesAsIfInFrontRow(bool v)1015 inline void Game_BattleAlgorithm::Normal::SetTreatEnemiesAsIfInFrontRow(bool v) {
1016 treat_enemies_asif_in_front_row = v;
1017 }
1018
IsChargedAttack()1019 inline bool Game_BattleAlgorithm::Normal::IsChargedAttack() const {
1020 return charged_attack;
1021 }
1022
GetSkill()1023 inline const lcf::rpg::Skill& Game_BattleAlgorithm::Skill::GetSkill() const {
1024 return skill;
1025 }
1026
GetItem()1027 inline const lcf::rpg::Item* Game_BattleAlgorithm::Skill::GetItem() const {
1028 return item;
1029 }
1030
1031 } //namespace Game_BattleAlgorithm
1032
1033 #endif
1034