From dd20478a015dfc74a8100a1f2da02091d59b06db Mon Sep 17 00:00:00 2001 From: Lucy <44952533+Skyliegirl33@users.noreply.github.com> Date: Mon, 6 Mar 2023 23:06:59 +0100 Subject: [PATCH] Add basic modifier impl for Chara --- src/world/Actor/Chara.cpp | 54 +++++++++++++++++++++++++++++++++++++-- src/world/Actor/Chara.h | 12 ++++++++- 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/src/world/Actor/Chara.cpp b/src/world/Actor/Chara.cpp index 23f652b5..66f8ef46 100644 --- a/src/world/Actor/Chara.cpp +++ b/src/world/Actor/Chara.cpp @@ -5,7 +5,6 @@ #include #include - #include "Forwards.h" #include "Territory/Territory.h" @@ -26,6 +25,7 @@ #include "Player.h" #include "Manager/TerritoryMgr.h" #include "Manager/MgrUtil.h" +#include "Manager/PlayerMgr.h" #include "Common.h" using namespace Sapphire::Common; @@ -559,7 +559,17 @@ void Sapphire::Entity::Chara::addStatusEffectByIdIfNotExist( uint32_t id, int32_ auto effect = StatusEffect::make_StatusEffect( id, source.getAsChara(), getAsChara(), duration, 3000 ); effect->setParam( param ); addStatusEffect( effect ); +} +void Sapphire::Entity::Chara::addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source, + std::vector< World::Action::StatusModifier >& modifiers, uint16_t param ) +{ + if( hasStatusEffect( id ) ) + return; + + auto effect = StatusEffect::make_StatusEffect( id, source.getAsChara(), getAsChara(), duration, modifiers, 3000 ); + effect->setParam( param ); + addStatusEffect( effect ); } int8_t Sapphire::Entity::Chara::getStatusEffectFreeSlot() @@ -644,7 +654,6 @@ void Sapphire::Entity::Chara::sendStatusEffectUpdate() { uint64_t currentTimeMs = Util::getTimeMs(); - auto statusEffectList = makeZonePacket< FFXIVIpcStatus >( getId() ); uint8_t slot = 0; for( const auto& effectIt : m_statusEffectMap ) @@ -785,6 +794,47 @@ void Sapphire::Entity::Chara::setStatValue( Common::BaseParam baseParam, uint32_ m_baseStats[ index ] = value; } +float Sapphire::Entity::Chara::getModifier( Common::ParamModifier paramModifier ) const +{ + if( m_modifiers.find( paramModifier ) == m_modifiers.end() ) + return paramModifier >= Common::ParamModifier::StrengthPercent ? 1.0f : 0; + + auto& mod = m_modifiers.at( paramModifier ); + if( paramModifier >= Common::ParamModifier::StrengthPercent ) + { + auto valPercent = 1.0f; + for( const auto val : mod ) + valPercent *= 1.0f + ( val / 100.0f ); + return valPercent; + } + else + { + return std::accumulate( mod.begin(), mod.end(), 0 ); + } +} + +void Sapphire::Entity::Chara::addModifier( Common::ParamModifier paramModifier, int32_t value ) +{ + m_modifiers[ paramModifier ].push_back( value ); + + if( auto pPlayer = this->getAsPlayer(); pPlayer ) + Common::Service< World::Manager::PlayerMgr >::ref().sendDebug( *pPlayer, "Modifier: {}, value: {}", static_cast< int32_t >( paramModifier ), getModifier( paramModifier ) ); +} + +void Sapphire::Entity::Chara::delModifier( Common::ParamModifier paramModifier, int32_t value ) +{ + assert( m_modifiers.count( paramModifier ) != 0 ); + auto& mod = m_modifiers.at( paramModifier ); + + mod.erase( std::remove( mod.begin(), mod.end(), value ), mod.end() ); + + if( mod.size() == 0 ) + m_modifiers.erase( paramModifier ); + + if( auto pPlayer = this->getAsPlayer(); pPlayer ) + Common::Service< World::Manager::PlayerMgr >::ref().sendDebug( *pPlayer, "Modifier: {}, value: {}", static_cast< int32_t >( paramModifier ), getModifier( paramModifier ) ); +} + void Sapphire::Entity::Chara::onTick() { uint32_t thisTickDmg = 0; diff --git a/src/world/Actor/Chara.h b/src/world/Actor/Chara.h index 20449f16..dab108a6 100644 --- a/src/world/Actor/Chara.h +++ b/src/world/Actor/Chara.h @@ -1,6 +1,7 @@ #pragma once #include +#include "Action/ActionLut.h" #include "Forwards.h" #include "GameObject.h" @@ -26,10 +27,13 @@ namespace Sapphire::Entity public: using ActorStatsArray = std::array< uint32_t, STAT_ARRAY_SIZE >; + using ActorModifiersMap = std::unordered_map< Common::ParamModifier, std::vector< int32_t > >; ActorStatsArray m_baseStats{ 0 }; ActorStatsArray m_bonusStats{ 0 }; + ActorModifiersMap m_modifiers{ 0 }; + protected: char m_name[34]; /*! Last tick time for the actor ( in ms ) */ @@ -133,9 +137,9 @@ namespace Sapphire::Entity // add a status effect by id void addStatusEffectById( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param = 0 ); - // add a status effect by id if it doesn't exist void addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param = 0 ); + void addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source, std::vector< World::Action::StatusModifier >& modifiers, uint16_t param = 0 ); // remove a status effect by id void removeSingleStatusEffectFromId( uint32_t id ); @@ -159,6 +163,12 @@ namespace Sapphire::Entity void setStatValue( Common::BaseParam baseParam, uint32_t value ); + float getModifier( Common::ParamModifier paramModifier ) const; + + void addModifier( Common::ParamModifier paramModifier, int32_t value ); + + void delModifier( Common::ParamModifier paramModifier, int32_t value ); + uint32_t getHp() const; uint32_t getHpPercent() const;