1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-28 15:17:46 +00:00

Move modifiers to statuseffect

This commit is contained in:
Lucy 2023-03-09 00:14:48 +01:00
parent df4977cca5
commit 38a0cd12ca
7 changed files with 88 additions and 61 deletions

View file

@ -3,6 +3,7 @@
#include <Actor/Player.h>
#include <Action/CommonAction.h>
#include <Action/Action.h>
#include <StatusEffect/StatusEffect.h>
using namespace Sapphire;
using namespace Sapphire::World::Action;
@ -25,8 +26,8 @@ public:
if( !pPlayer )
return;
if( !pPlayer->hasStatusEffect( Unchained ) )
pPlayer->delModifier( Common::ParamModifier::DamageDealtPercent, -25 );
if( auto status = pPlayer->getStatusEffectById( Defiance ); status )
status->setModifier( Common::ParamModifier::DamageDealtPercent, 0 );
auto dmg = action.calcDamage( Potency );
action.getEffectbuilder()->damage( pSource, pTarget, dmg.first, dmg.second );
@ -38,7 +39,10 @@ public:
{ StatusModifier{ Common::ParamModifier::DamageTakenPercent, -20 } } );
if( !pPlayer->hasStatusEffect( Unchained ) )
pPlayer->addModifier( Common::ParamModifier::DamageDealtPercent, -25 );
{
if( auto status = pPlayer->getStatusEffectById( Defiance ); status )
status->setModifier( Common::ParamModifier::DamageDealtPercent, -25 );
}
}
};

View file

@ -3,6 +3,7 @@
#include <Actor/Player.h>
#include <Action/CommonAction.h>
#include <Action/Action.h>
#include <StatusEffect/StatusEffect.h>
using namespace Sapphire;
using namespace Sapphire::World::Action;
@ -21,7 +22,8 @@ public:
if( !pPlayer )
return;
pPlayer->delModifier( Common::ParamModifier::DamageDealtPercent, -25 );
if( auto status = pPlayer->getStatusEffectById( Defiance ); status )
status->setModifier( Common::ParamModifier::DamageDealtPercent, 0 );
action.applyStatusEffectSelf( Unchained );
pPlayer->addStatusEffectByIdIfNotExist( Unchained, 20000, *pPlayer->getAsChara() );

View file

@ -2,6 +2,7 @@
#include <ScriptObject.h>
#include <Actor/Player.h>
#include <Action/CommonAction.h>
#include <StatusEffect/StatusEffect.h>
using namespace Sapphire;
using namespace Sapphire::World::Action;
@ -15,8 +16,8 @@ public:
void onExpire( Entity::Chara& actor ) override
{
if( actor.hasStatusEffect( Defiance ) )
actor.addModifier( Common::ParamModifier::DamageDealtPercent, -25 );
if( auto status = actor.getStatusEffectById( Defiance ); status )
status->setModifier( Common::ParamModifier::DamageDealtPercent, -25 );
}
};

View file

@ -643,6 +643,17 @@ std::map< uint8_t, Sapphire::StatusEffect::StatusEffectPtr > Sapphire::Entity::C
return m_statusEffectMap;
}
Sapphire::StatusEffect::StatusEffectPtr Sapphire::Entity::Chara::getStatusEffectById( uint32_t id ) const
{
for( const auto& effectIt : m_statusEffectMap )
{
if( effectIt.second->getId() == id )
return effectIt.second;
}
return nullptr;
}
const uint8_t* Sapphire::Entity::Chara::getLookArray() const
{
return m_customize;
@ -815,45 +826,23 @@ void Sapphire::Entity::Chara::setStatValue( Common::BaseParam baseParam, uint32_
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 result = paramModifier >= Common::ParamModifier::StrengthPercent ? 1.0f : 0;
auto& mod = m_modifiers.at( paramModifier );
if( paramModifier >= Common::ParamModifier::StrengthPercent )
for( const auto& [ key, status ] : m_statusEffectMap )
{
auto valPercent = 1.0f;
for( const auto val : mod )
valPercent *= 1.0f + ( val / 100.0f );
return valPercent;
for( const auto& [ mod, val ] : status->getModifiers() )
{
if( mod != paramModifier )
continue;
if( paramModifier >= Common::ParamModifier::StrengthPercent )
result *= 1.0f + ( val / 100.0f );
else
result += val;
}
}
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 )
{
if( m_modifiers.find( paramModifier ) == m_modifiers.end() )
return;
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 ) );
return result;
}
void Sapphire::Entity::Chara::onTick()

View file

@ -28,13 +28,10 @@ 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 ) */
@ -131,6 +128,8 @@ namespace Sapphire::Entity
std::map< uint8_t, Sapphire::StatusEffect::StatusEffectPtr > getStatusEffectMap() const;
Sapphire::StatusEffect::StatusEffectPtr getStatusEffectById( uint32_t id ) const;
void sendStatusEffectUpdate();
/*! return a const pointer to the look array */
@ -169,10 +168,6 @@ namespace Sapphire::Entity
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;

View file

@ -6,13 +6,17 @@
#include <algorithm>
#include <Service.h>
#include "Manager/PlayerMgr.h"
#include "Actor/Chara.h"
#include "Actor/Player.h"
#include "Actor/GameObject.h"
#include "Script/ScriptMgr.h"
#include "StatusEffect.h"
using namespace Sapphire;
using namespace Sapphire::Common;
using namespace Sapphire::Network::Packets;
//using namespace Sapphire::Network::Packets::WorldPackets::Server;
@ -21,7 +25,7 @@ Sapphire::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::CharaPt
uint32_t duration, std::vector< World::Action::StatusModifier >& modifiers, uint32_t tickRate ) :
StatusEffect( id, sourceActor, targetActor, duration, tickRate )
{
m_modifiers = std::move( modifiers );
setModifiers( modifiers );
}
Sapphire::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::CharaPtr sourceActor, Entity::CharaPtr targetActor,
@ -88,21 +92,49 @@ uint16_t Sapphire::StatusEffect::StatusEffect::getParam() const
return m_param;
}
void Sapphire::StatusEffect::StatusEffect::applyStatus()
std::unordered_map< Common::ParamModifier, int32_t >& Sapphire::StatusEffect::StatusEffect::getModifiers()
{
m_startTime = Util::getTimeMs();
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
return m_modifiers;
}
for( const auto& mod : m_modifiers )
void Sapphire::StatusEffect::StatusEffect::setModifiers( std::vector< World::Action::StatusModifier > modifiers )
{
for( const auto& mod : modifiers )
{
// TODO: ticks
if( mod.modifier != Common::ParamModifier::TickDamage && mod.modifier != Common::ParamModifier::TickHeal )
m_targetActor->addModifier( mod.modifier, mod.value );
setModifier( mod.modifier, mod.value );
else if( mod.modifier == Common::ParamModifier::TickDamage )
registerTickEffect( mod.modifier, mod.value );
else if( mod.modifier == Common::ParamModifier::TickHeal )
registerTickEffect( mod.modifier, mod.value );
}
}
void Sapphire::StatusEffect::StatusEffect::setModifier( Common::ParamModifier paramModifier, int32_t value )
{
m_modifiers[ paramModifier ] = value;
if( auto pPlayer = m_targetActor->getAsPlayer(); pPlayer )
Common::Service< World::Manager::PlayerMgr >::ref().sendDebug( *pPlayer, "Modifier: {}, value: {}", static_cast< int32_t >( paramModifier ),
pPlayer->getModifier( paramModifier ) );
}
void Sapphire::StatusEffect::StatusEffect::delModifier( Common::ParamModifier paramModifier )
{
if( m_modifiers.find( paramModifier ) == m_modifiers.end() )
return;
m_modifiers.erase( paramModifier );
if( auto pPlayer = m_targetActor->getAsPlayer(); pPlayer )
Common::Service< World::Manager::PlayerMgr >::ref().sendDebug( *pPlayer, "Modifier: {}, value: {}", static_cast< int32_t >( paramModifier ),
pPlayer->getModifier( paramModifier ) );
}
void Sapphire::StatusEffect::StatusEffect::applyStatus()
{
m_startTime = Util::getTimeMs();
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
m_targetActor->calculateStats();
@ -131,11 +163,7 @@ void Sapphire::StatusEffect::StatusEffect::removeStatus()
{
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
for( const auto& mod : m_modifiers )
{
if( mod.modifier != Common::ParamModifier::TickDamage && mod.modifier != Common::ParamModifier::TickHeal )
m_targetActor->delModifier( mod.modifier, mod.value );
}
m_modifiers.clear();
m_targetActor->calculateStats();

View file

@ -21,6 +21,14 @@ public:
void onTick();
std::unordered_map< Common::ParamModifier, int32_t >& getModifiers();
void setModifiers( std::vector< World::Action::StatusModifier > modifiers );
void setModifier( Common::ParamModifier paramModifier, int32_t value );
void delModifier( Common::ParamModifier paramModifier );
void applyStatus();
void removeStatus();
@ -62,7 +70,7 @@ private:
uint16_t m_param;
std::string m_name;
std::pair< Common::ParamModifier, uint32_t > m_currTickEffect;
std::vector< World::Action::StatusModifier > m_modifiers;
std::unordered_map< Common::ParamModifier, int32_t > m_modifiers;
};
}