From c3bfbb569ed8ce471acf8ec7318f711bc847701b Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Fri, 8 Nov 2019 18:45:43 +0100 Subject: [PATCH] Initial setup for script hooks (likely to be revamped) --- src/Battling/Flow/TurnHandler.cpp | 3 ++ src/Battling/Models/Creature.hpp | 9 ++++++ src/Battling/ScriptHandling/Hooks.hpp | 15 ++++++++++ src/Battling/ScriptHandling/Script.hpp | 27 ++++++++++++++++++ src/Battling/ScriptHandling/ScriptSet.hpp | 34 +++++++++++++++++++++++ 5 files changed, 88 insertions(+) create mode 100644 src/Battling/ScriptHandling/Hooks.hpp create mode 100644 src/Battling/ScriptHandling/Script.hpp create mode 100644 src/Battling/ScriptHandling/ScriptSet.hpp diff --git a/src/Battling/Flow/TurnHandler.cpp b/src/Battling/Flow/TurnHandler.cpp index 4e4c623..81e8053 100644 --- a/src/Battling/Flow/TurnHandler.cpp +++ b/src/Battling/Flow/TurnHandler.cpp @@ -78,12 +78,15 @@ void TurnHandler::ExecuteAttackChoice(const AttackTurnChoice *choice) { void TurnHandler::HandleAttackForTarget(ExecutingAttack &attack, Creature *target, ExecutingAttack::TargetData &targetData) { //HOOK: Check if attack fails on target + target->ExecuteScripts(Hook::IncomingAttackFails, {std::any(attack), std::any(target)}); //HOOK: Check if target is invulnerable + target->ExecuteScripts(Hook::IsInvulnerable, {std::any(attack), std::any(target)}); if (!targetData.IsHit()){ //HOOK: On attack miss. + target->ExecuteScripts(Hook::AttackMiss, {std::any(attack), std::any(target)}); return; } diff --git a/src/Battling/Models/Creature.hpp b/src/Battling/Models/Creature.hpp index 4d8149c..031497b 100644 --- a/src/Battling/Models/Creature.hpp +++ b/src/Battling/Models/Creature.hpp @@ -6,6 +6,7 @@ #include "../../Library/Items/Item.hpp" #include "LearnedAttack.hpp" #include "DamageSource.hpp" +#include "../ScriptHandling/ScriptSet.hpp" namespace CreatureLib::Battling{ // Forward declare battle class @@ -40,6 +41,9 @@ namespace CreatureLib::Battling{ int8_t _talentIndex; std::vector _attacks; + Script* _status = nullptr; + ScriptSet _volatile = {}; + public: Creature(const Library::CreatureSpecies* species, const Library::SpeciesVariant* variant, uint8_t level, uint32_t experience, Core::StatisticSet statExp, Core::StatisticSet statPotential, @@ -59,6 +63,11 @@ namespace CreatureLib::Battling{ [[nodiscard]] const std::vector& GetTypes() const; [[nodiscard]] bool HasType(uint8_t type) const; + void ExecuteScripts(Hook hook, const std::vector& args){ + _status->Execute(hook, args); + _volatile.Execute(hook, args); + } + //region Stat APIs void SetBattle(Battle* battle); diff --git a/src/Battling/ScriptHandling/Hooks.hpp b/src/Battling/ScriptHandling/Hooks.hpp new file mode 100644 index 0000000..adef1a6 --- /dev/null +++ b/src/Battling/ScriptHandling/Hooks.hpp @@ -0,0 +1,15 @@ +#ifndef CREATURELIB_HOOKS_HPP +#define CREATURELIB_HOOKS_HPP + +#include + +namespace CreatureLib::Battling{ + enum class Hook : uint8_t{ + IncomingAttackFails, + IsInvulnerable, + AttackMiss, + ChangeMove, + }; +} + +#endif //CREATURELIB_HOOKS_HPP diff --git a/src/Battling/ScriptHandling/Script.hpp b/src/Battling/ScriptHandling/Script.hpp new file mode 100644 index 0000000..d6460e2 --- /dev/null +++ b/src/Battling/ScriptHandling/Script.hpp @@ -0,0 +1,27 @@ +#ifndef CREATURELIB_SCRIPT_HPP +#define CREATURELIB_SCRIPT_HPP + +#include +#include +#include +#include +#include "Hooks.hpp" + +namespace CreatureLib::Battling{ + class Script{ + const std::string _name; + + public: + explicit Script(std::string name) :_name(std::move(name)){} + virtual ~Script() = default; + + virtual void Execute(Hook hook, const std::vector& args){}; + virtual void Stack(){}; + + const std::string& GetName(){ + return _name; + } + }; +} + +#endif //CREATURELIB_SCRIPT_HPP diff --git a/src/Battling/ScriptHandling/ScriptSet.hpp b/src/Battling/ScriptHandling/ScriptSet.hpp new file mode 100644 index 0000000..8e9a774 --- /dev/null +++ b/src/Battling/ScriptHandling/ScriptSet.hpp @@ -0,0 +1,34 @@ +#ifndef CREATURELIB_SCRIPTSET_HPP +#define CREATURELIB_SCRIPTSET_HPP + +#include +#include +#include "Script.hpp" + +namespace CreatureLib::Battling{ + class ScriptSet{ + std::unordered_map _scripts; + public: + void Execute(Hook hook, const std::vector& args){ + for (auto s: _scripts){ + s.second->Execute(hook, args); + } + } + + void Add(Script* script){ + auto f = _scripts.find(script->GetName()); + if (f != _scripts.end()){ + f->second->Stack(); + } + else{ + _scripts.insert({script->GetName(), script}); + } + } + + void Remove(const std::string& key){ + _scripts.erase(key); + } + }; +} + +#endif //CREATURELIB_SCRIPTSET_HPP