From 340520e0e372bf5290df9290a0d23752c65b8335 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Mon, 6 Apr 2020 12:02:29 +0200 Subject: [PATCH] Reworks attack scripts to handle effect chance and effect name through data files. --- CInterface/Library/AttackData.cpp | 10 ++++---- src/Battling/Flow/TurnHandler.cpp | 24 +++++++++++++++---- src/Battling/Library/MiscLibrary.cpp | 6 ++--- src/Battling/TurnChoices/AttackTurnChoice.hpp | 7 ++++-- src/Library/Attacks/AttackData.cpp | 4 ++-- src/Library/Attacks/AttackData.hpp | 9 ++++++- src/Library/Attacks/SecondaryEffect.hpp | 21 ++++++++++++++++ tests/TestLibrary/TestLibrary.cpp | 8 +++---- 8 files changed, 68 insertions(+), 21 deletions(-) create mode 100644 src/Library/Attacks/SecondaryEffect.hpp diff --git a/CInterface/Library/AttackData.cpp b/CInterface/Library/AttackData.cpp index e1d71ae..65953ef 100644 --- a/CInterface/Library/AttackData.cpp +++ b/CInterface/Library/AttackData.cpp @@ -5,11 +5,13 @@ using namespace CreatureLib::Library; export uint8_t CreatureLib_AttackData_Construct(AttackData*& out, const char* name, uint8_t type, AttackCategory category, uint8_t power, uint8_t accuracy, uint8_t baseUsage, AttackTarget target, int8_t priority, - const char* flags[], size_t flagsCount) { - Try(std::unordered_set conversedFlags(flagsCount); - for (size_t i = 0; i < flagsCount; i++) { conversedFlags.insert(ConstString::GetHash(flags[i])); } + int8_t effectChance, const char* effectName, const char* flags[], + size_t flagsCount) { + Try(std::unordered_set conversedFlags(flagsCount); for (size_t i = 0; i < flagsCount; i++) { + conversedFlags.insert(ConstString::GetHash(flags[i])); + } auto effect = SecondaryEffect(effectChance, Arbutils::CaseInsensitiveConstString(effectName)); - out = new AttackData(ConstString(name), type, category, power, accuracy, baseUsage, target, priority, + out = new AttackData(ConstString(name), type, category, power, accuracy, baseUsage, target, priority, effect, conversedFlags);) }; diff --git a/src/Battling/Flow/TurnHandler.cpp b/src/Battling/Flow/TurnHandler.cpp index e502ee3..6133450 100644 --- a/src/Battling/Flow/TurnHandler.cpp +++ b/src/Battling/Flow/TurnHandler.cpp @@ -154,7 +154,9 @@ void TurnHandler::HandleAttackForTarget(ExecutingAttack* attack, Creature* targe hit->SetDamage(dmgLibrary->GetDamage(attack, target, hitIndex)); if (attackData->GetCategory() == Library::AttackCategory::Status) { - HOOK(OnStatusMove, userSource, attack, target, hitIndex); + if (attackData->HasSecondaryEffect()) { + HOOK(OnStatusMove, userSource, attack, target, hitIndex); + } } else { auto damage = hit->GetDamage(); if (damage > target->GetCurrentHealth()) { @@ -164,10 +166,22 @@ void TurnHandler::HandleAttackForTarget(ExecutingAttack* attack, Creature* targe if (damage > 0) { target->Damage(damage, DamageSource::AttackDamage); - bool preventSecondary = false; - HOOK(PreventSecondaryEffects, targetSource, attack, target, hitIndex, &preventSecondary); - if (!preventSecondary) { - HOOK(OnSecondaryEffect, userSource, attack, target, hitIndex); + if (attackData->HasSecondaryEffect()) { + bool preventSecondary = false; + HOOK(PreventSecondaryEffects, targetSource, attack, target, hitIndex, &preventSecondary); + if (!preventSecondary) { + auto effect = attackData->GetSecondaryEffect(); + bool hasSecondaryEffect; + if (effect.GetChance() == -1) { + hasSecondaryEffect = true; + } else { + hasSecondaryEffect = + user->GetBattle()->GetRandom()->EffectChance(effect.GetChance(), attack, target); + } + if (hasSecondaryEffect) { + HOOK(OnSecondaryEffect, userSource, attack, target, hitIndex); + } + } } } } diff --git a/src/Battling/Library/MiscLibrary.cpp b/src/Battling/Library/MiscLibrary.cpp index 3bfff5c..15db0f2 100644 --- a/src/Battling/Library/MiscLibrary.cpp +++ b/src/Battling/Library/MiscLibrary.cpp @@ -15,9 +15,9 @@ static CreatureLib::Library::AttackData* _replacementAttackData = nullptr; static CreatureLib::Library::AttackData* GetReplacementAttackData() { if (_replacementAttackData == nullptr) { - _replacementAttackData = - new CreatureLib::Library::AttackData("replacement"_cnc, 0, CreatureLib::Library::AttackCategory::Physical, - 30, 255, 255, CreatureLib::Library::AttackTarget::Any, 0, {}); + _replacementAttackData = new CreatureLib::Library::AttackData( + "replacement"_cnc, 0, CreatureLib::Library::AttackCategory::Physical, 30, 255, 255, + CreatureLib::Library::AttackTarget::Any, 0, CreatureLib::Library::SecondaryEffect(), {}); } return _replacementAttackData; } diff --git a/src/Battling/TurnChoices/AttackTurnChoice.hpp b/src/Battling/TurnChoices/AttackTurnChoice.hpp index 6e0442a..d5ddeaf 100644 --- a/src/Battling/TurnChoices/AttackTurnChoice.hpp +++ b/src/Battling/TurnChoices/AttackTurnChoice.hpp @@ -21,8 +21,11 @@ namespace CreatureLib::Battling { return; auto battle = user->GetBattle(); if (battle != nullptr) { - auto library = battle->GetLibrary(); - _attackScript = library->LoadScript(ScriptCategory::Attack, _attack->GetAttack()->GetName()); + if (_attack->GetAttack()->HasSecondaryEffect()) { + auto library = battle->GetLibrary(); + _attackScript = library->LoadScript(ScriptCategory::Attack, + _attack->GetAttack()->GetSecondaryEffect().GetEffectName()); + } } } diff --git a/src/Library/Attacks/AttackData.cpp b/src/Library/Attacks/AttackData.cpp index 9749096..5e1ac15 100644 --- a/src/Library/Attacks/AttackData.cpp +++ b/src/Library/Attacks/AttackData.cpp @@ -5,9 +5,9 @@ CreatureLib::Library::AttackData::AttackData(const ConstString& name, uint8_t ty CreatureLib::Library::AttackCategory category, uint8_t power, uint8_t accuracy, uint8_t baseUsage, CreatureLib::Library::AttackTarget target, int8_t priority, - std::unordered_set flags) + SecondaryEffect effect, std::unordered_set flags) : _name(std::move(name)), _type(type), _category(category), _basePower(power), _accuracy(accuracy), - _baseUsages(baseUsage), _target(target), _priority(priority), _flags(std::move(flags)) {} + _baseUsages(baseUsage), _target(target), _priority(priority), _effect(effect), _flags(std::move(flags)) {} bool CreatureLib::Library::AttackData::HasFlag(const ConstString& key) const noexcept { return this->_flags.find(key) != this->_flags.end(); diff --git a/src/Library/Attacks/AttackData.hpp b/src/Library/Attacks/AttackData.hpp index b2f5330..22159ef 100644 --- a/src/Library/Attacks/AttackData.hpp +++ b/src/Library/Attacks/AttackData.hpp @@ -6,6 +6,7 @@ #include #include "AttackCategory.hpp" #include "AttackTarget.hpp" +#include "SecondaryEffect.hpp" using ConstString = Arbutils::CaseInsensitiveConstString; @@ -20,11 +21,13 @@ namespace CreatureLib::Library { uint8_t _baseUsages; AttackTarget _target; int8_t _priority; + SecondaryEffect _effect; std::unordered_set _flags; public: AttackData(const ConstString& name, uint8_t type, AttackCategory category, uint8_t power, uint8_t accuracy, - uint8_t baseUsage, AttackTarget target, int8_t priority, std::unordered_set flags); + uint8_t baseUsage, AttackTarget target, int8_t priority, SecondaryEffect effect, + std::unordered_set flags); virtual ~AttackData() = default; inline const ConstString& GetName() const noexcept { return _name; } @@ -35,6 +38,10 @@ namespace CreatureLib::Library { inline uint8_t GetBaseUsages() const noexcept { return _baseUsages; } inline AttackTarget GetTarget() const noexcept { return _target; } inline int8_t GetPriority() const noexcept { return _priority; } + inline bool HasSecondaryEffect() const noexcept { + return _effect.GetChance() != 0 && _effect.GetEffectName() != ""_cnc; + } + inline const SecondaryEffect& GetSecondaryEffect() const noexcept { return _effect; } bool HasFlag(const ConstString& key) const noexcept; bool HasFlag(uint32_t keyHash) const noexcept; diff --git a/src/Library/Attacks/SecondaryEffect.hpp b/src/Library/Attacks/SecondaryEffect.hpp new file mode 100644 index 0000000..e60d002 --- /dev/null +++ b/src/Library/Attacks/SecondaryEffect.hpp @@ -0,0 +1,21 @@ +#ifndef CREATURELIB_SECONDARYEFFECT_HPP +#define CREATURELIB_SECONDARYEFFECT_HPP + +#include +namespace CreatureLib::Library { + class SecondaryEffect { + private: + float _chance; + Arbutils::CaseInsensitiveConstString _effectName; + + public: + constexpr SecondaryEffect() noexcept : _chance(0), _effectName(""_cnc) {} + constexpr SecondaryEffect(float chance, const Arbutils::CaseInsensitiveConstString& effectName) noexcept + : _chance(chance), _effectName(effectName) {} + + constexpr float GetChance() const noexcept { return _chance; } + constexpr const Arbutils::CaseInsensitiveConstString& GetEffectName() const noexcept { return _effectName; } + }; +} + +#endif // CREATURELIB_SECONDARYEFFECT_HPP diff --git a/tests/TestLibrary/TestLibrary.cpp b/tests/TestLibrary/TestLibrary.cpp index cde89a4..0765d4f 100644 --- a/tests/TestLibrary/TestLibrary.cpp +++ b/tests/TestLibrary/TestLibrary.cpp @@ -33,13 +33,13 @@ SpeciesLibrary* TestLibrary::BuildSpeciesLibrary() { AttackLibrary* TestLibrary::BuildAttackLibrary() { auto l = new AttackLibrary(); l->Insert("standard"_cnc, new AttackData("standard"_cnc, 0, AttackCategory::Physical, 20, 100, 30, - AttackTarget::AdjacentOpponent, 0, {})); + AttackTarget::AdjacentOpponent, 0, SecondaryEffect(), {})); l->Insert("highPriority"_cnc, new AttackData("highPriority"_cnc, 0, AttackCategory::Physical, 20, 100, 30, - AttackTarget::AdjacentOpponent, 1, {})); + AttackTarget::AdjacentOpponent, 1, SecondaryEffect(), {})); l->Insert("higherPriority"_cnc, new AttackData("higherPriority"_cnc, 0, AttackCategory::Physical, 20, 100, 30, - AttackTarget::AdjacentOpponent, 2, {})); + AttackTarget::AdjacentOpponent, 2, SecondaryEffect(), {})); l->Insert("lowPriority"_cnc, new AttackData("lowPriority"_cnc, 0, AttackCategory::Physical, 20, 100, 30, - AttackTarget::AdjacentOpponent, -1, {})); + AttackTarget::AdjacentOpponent, -1, SecondaryEffect(), {})); return l; }