Reworks attack scripts to handle effect chance and effect name through data files.
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Deukhoofd 2020-04-06 12:02:29 +02:00
parent e2675d06fb
commit 340520e0e3
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
8 changed files with 68 additions and 21 deletions

View File

@ -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<uint32_t> 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<uint32_t> 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);)
};

View File

@ -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);
}
}
}
}
}

View File

@ -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;
}

View File

@ -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());
}
}
}

View File

@ -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<uint32_t> flags)
SecondaryEffect effect, std::unordered_set<uint32_t> 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();

View File

@ -6,6 +6,7 @@
#include <unordered_set>
#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<uint32_t> _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<uint32_t> flags);
uint8_t baseUsage, AttackTarget target, int8_t priority, SecondaryEffect effect,
std::unordered_set<uint32_t> 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;

View File

@ -0,0 +1,21 @@
#ifndef CREATURELIB_SECONDARYEFFECT_HPP
#define CREATURELIB_SECONDARYEFFECT_HPP
#include <Arbutils/ConstString.hpp>
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

View File

@ -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;
}