Adds functionality for held items
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2022-02-19 12:19:03 +01:00
parent c40f063683
commit c078d91b0d
8 changed files with 108 additions and 44 deletions

View File

@@ -17,15 +17,20 @@ namespace CreatureLib::Battling {
const Library::TalentIndex& talent, const std::vector<LearnedAttack*>& attacks,
bool allowedExperienceGain)
: _library(library), _species(species), _variant(variant), _level(level), _experience(experience),
_uniqueIdentifier(uid), _gender(gender), _coloring(coloring), _heldItem(heldItem),
_weight(variant->GetWeight()), _height(variant->GetHeight()), _nickname(std::move(nickname)),
_talentIndex(talent), _hasOverridenTalent(false), _attacks(attacks),
_allowedExperienceGain(allowedExperienceGain) {
_uniqueIdentifier(uid), _gender(gender), _coloring(coloring), _weight(variant->GetWeight()),
_height(variant->GetHeight()), _nickname(std::move(nickname)), _talentIndex(talent),
_hasOverridenTalent(false), _attacks(attacks), _allowedExperienceGain(allowedExperienceGain),
_heldItem(heldItem) {
_activeTalent = std::unique_ptr<BattleScript>(
_library->LoadScript(this, ScriptCategory::Talent, GetActiveTalent()->GetEffect()));
if (_activeTalent != nullptr) {
_activeTalent->OnInitialize(_library.GetRaw(), GetActiveTalent()->GetParameters());
}
if (_heldItem.HasValue() && _heldItem.GetValue()->GetBattleTriggerEffect().HasValue()) {
_heldItemTriggerScript = std::unique_ptr<BattleScript>(
_library->LoadScript(this, ScriptCategory::ItemBattleTrigger,
_heldItem.GetValue()->GetBattleTriggerEffect().GetValue()->GetEffectName()));
}
for (auto t : _variant->GetTypes()) {
_types.push_back(t);
}
@@ -283,6 +288,7 @@ namespace CreatureLib::Battling {
}
}
void Creature::GetOwnScripts(ArbUt::List<ScriptWrapper>& scripts) {
scripts.Append(ScriptWrapper::FromScript(&_heldItemTriggerScript));
scripts.Append(ScriptWrapper::FromScript(&_activeTalent));
scripts.Append(ScriptWrapper::FromScript(&_status));
scripts.Append(ScriptWrapper::FromSet(&_volatile));
@@ -318,18 +324,53 @@ namespace CreatureLib::Battling {
return variant;
}
void Creature::SetHeldItem(const ArbUt::BasicStringView& itemName) {
auto v = _library->GetItemLibrary()->TryGet(itemName.GetHash());
if (!v.has_value()) {
THROW("Item not found '", itemName.c_str(), "'.");
if (itemName == ""_cnc) {
_heldItem = {};
_heldItemTriggerScript = {};
} else {
auto v = _library->GetItemLibrary()->TryGet(itemName.GetHash());
if (!v.has_value()) {
THROW("Item not found '", itemName.c_str(), "'.");
}
_heldItem = v.value();
}
_heldItem = v.value();
}
void Creature::SetHeldItem(uint32_t itemNameHash) {
auto v = _library->GetItemLibrary()->TryGet(itemNameHash);
if (!v.has_value()) {
THROW("Item not found.");
if (itemNameHash == ArbUt::StringView::CalculateHash("")) {
_heldItem = {};
_heldItemTriggerScript = {};
} else {
auto v = _library->GetItemLibrary()->TryGet(itemNameHash);
if (!v.has_value()) {
THROW("Item not found.");
}
_heldItem = v.value();
}
_heldItem = v.value();
}
bool Creature::ConsumeHeldItem() {
if (!_heldItem.HasValue()) {
return false;
}
auto* script = _library->GetScriptResolver()->LoadItemScript(_heldItem.GetValue());
auto isCreatureUseItem = script->IsCreatureUseItem();
if (isCreatureUseItem) {
if (!script->IsUseValidForCreature(this)) {
return false;
}
script->OnCreatureUse(this, true);
} else {
script->OnUse(_battleData.Battle.GetValue());
}
auto item = _heldItem;
SetHeldItem(""_cnc);
if (_battleData.Battle.HasValue()) {
HOOK(OnAfterHeldItemConsume, this, this, item.GetValue());
}
return true;
}
BattleScript* Creature::AddVolatileScript(const ArbUt::StringView& name) {
@@ -421,31 +462,30 @@ namespace CreatureLib::Battling {
return c;
}
}
void CreatureLib::Battling::Creature::SetStatus(const ArbUt::StringView& name) {
if (_status != nullptr) {
void Creature::SetStatus(const ArbUt::StringView& name) {
if (_status != nullptr) {
_status->OnRemove();
}
_status = std::unique_ptr<BattleScript>(_library->LoadScript(this, ScriptCategory::Status, name));
if (_battleData.Battle.HasValue()) {
_battleData.Battle.GetValue()->TriggerEventListener<StatusChangeEvent>(this, name);
}
}
void Creature::ClearStatus() {
if (_status == nullptr) {
return;
}
_status->OnRemove();
_status = nullptr;
if (_battleData.Battle.HasValue()) {
_battleData.Battle.GetValue()->TriggerEventListener<StatusChangeEvent>(this, ""_cnc);
}
}
_status =
std::unique_ptr<CreatureLib::Battling::BattleScript>(_library->LoadScript(this, ScriptCategory::Status, name));
if (_battleData.Battle.HasValue()) {
_battleData.Battle.GetValue()->TriggerEventListener<StatusChangeEvent>(this, name);
}
}
void CreatureLib::Battling::Creature::ClearStatus() {
if (_status == nullptr) {
return;
}
_status->OnRemove();
_status = nullptr;
if (_battleData.Battle.HasValue()) {
_battleData.Battle.GetValue()->TriggerEventListener<StatusChangeEvent>(this, ""_cnc);
}
}
Battling::Creature::~Creature() {
if (_battleData.OnBattleField && _battleData.Side.HasValue()) {
_battleData.Side.GetValue()->ForceClearCreature(_battleData.Index.GetCreatureIndex());
Creature::~Creature() {
if (_battleData.OnBattleField && _battleData.Side.HasValue()) {
_battleData.Side.GetValue()->ForceClearCreature(_battleData.Index.GetCreatureIndex());
}
}
}

View File

@@ -33,7 +33,7 @@ namespace CreatureLib::Battling {
uint32_t _uniqueIdentifier;
Library::Gender _gender;
uint8_t _coloring;
ArbUt::OptionalBorrowedPtr<const Library::Item> _heldItem;
uint32_t _currentHealth = -1;
f32 _weight;
@@ -66,6 +66,9 @@ namespace CreatureLib::Battling {
std::vector<u8> _types = {};
ArbUt::OptionalBorrowedPtr<const Library::Item> _heldItem;
std::unique_ptr<BattleScript> _heldItemTriggerScript = nullptr;
private:
void OnFaint(DamageSource damageSource);
@@ -109,6 +112,7 @@ namespace CreatureLib::Battling {
void SetHeldItem(const ArbUt::BasicStringView& itemName);
void SetHeldItem(uint32_t itemNameHash);
inline void SetHeldItem(const ArbUt::BorrowedPtr<const Library::Item>& item) noexcept { _heldItem = item; };
bool ConsumeHeldItem();
inline uint32_t GetCurrentHealth() const noexcept { return _currentHealth; }

View File

@@ -5,6 +5,7 @@
#include <Arbutils/Memory/Memory.hpp>
#include <Arbutils/Misc.hpp>
#include "../../Library/EffectParameter.hpp"
#include "../../Library/Items/Item.hpp"
#include "../../Library/Statistic.hpp"
#include "../Models/DamageSource.hpp"
@@ -117,6 +118,8 @@ namespace CreatureLib::Battling {
virtual void OnDamage(Creature*, DamageSource, _par_ u32 oldHealth, _par_ u32 newHealth){};
virtual void OnFaint(Creature*, DamageSource){};
virtual void OnSwitchIn(Creature*){};
virtual void OnAfterHeldItemConsume(Creature*, const Library::Item*){};
};
}

View File

@@ -2,6 +2,6 @@
#define CREATURELIB_SCRIPTCATEGORY_HPP
#include <Arbutils/Enum.hpp>
ENUM(ScriptCategory, uint8_t, Attack, Talent, Status, Creature, Battle, Side)
ENUM(ScriptCategory, uint8_t, Attack, Talent, Status, Creature, Battle, Side, ItemBattleTrigger)
#endif // CREATURELIB_SCRIPTCATEGORY_HPP

View File

@@ -1 +0,0 @@
#include "ScriptResolver.hpp"