1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-27 22:57:45 +00:00

Merge pull request #903 from Skyliegirl33/status-fix

[3.x] StatusEffect and HudParam fixes
This commit is contained in:
Mordred 2023-02-22 17:02:02 +01:00 committed by GitHub
commit 6ea6f8e190
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 16 deletions

View file

@ -15,6 +15,7 @@
#include "Network/PacketWrappers/ActorControlTargetPacket.h"
#include "Network/PacketWrappers/UpdateHpMpTpPacket.h"
#include "Network/PacketWrappers/EffectPacket1.h"
#include "Network/PacketWrappers/HudParamPacket.h"
#include "StatusEffect/StatusEffect.h"
#include "Action/Action.h"
@ -601,11 +602,11 @@ void Sapphire::Entity::Chara::removeSingleStatusEffectById( uint32_t id )
}
}
void Sapphire::Entity::Chara::removeStatusEffect( uint8_t effectSlotId )
std::map< uint8_t, Sapphire::StatusEffect::StatusEffectPtr >::iterator Sapphire::Entity::Chara::removeStatusEffect( uint8_t effectSlotId )
{
auto pEffectIt = m_statusEffectMap.find( effectSlotId );
if( pEffectIt == m_statusEffectMap.end() )
return;
return pEffectIt;
statusEffectFreeSlot( effectSlotId );
@ -614,9 +615,14 @@ void Sapphire::Entity::Chara::removeStatusEffect( uint8_t effectSlotId )
server().queueForPlayers( getInRangePlayerIds( isPlayer() ), makeActorControl( getId(), StatusEffectLose, pEffect->getId() ) );
m_statusEffectMap.erase( effectSlotId );
auto it = m_statusEffectMap.erase( pEffectIt );
sendStatusEffectUpdate();
if( isPlayer() )
server().queueForPlayers( getInRangePlayerIds( isPlayer() ), makeHudParam( *getAsPlayer() ) );
else if( isBattleNpc() )
server().queueForPlayers( getInRangePlayerIds( isPlayer() ), makeHudParam( *getAsBNpc() ) );
return it;
}
std::map< uint8_t, Sapphire::StatusEffect::StatusEffectPtr > Sapphire::Entity::Chara::getStatusEffectMap() const
@ -668,10 +674,10 @@ void Sapphire::Entity::Chara::updateStatusEffects()
{
uint64_t currentTimeMs = Util::getTimeMs();
for( const auto& effectIt : m_statusEffectMap )
for( auto effectIt = m_statusEffectMap.begin(); effectIt != m_statusEffectMap.end(); )
{
uint8_t effectIndex = effectIt.first;
auto effect = effectIt.second;
uint8_t effectIndex = effectIt->first;
auto effect = effectIt->second;
uint64_t lastTick = effect->getLastTickMs();
uint64_t startTime = effect->getStartTimeMs();
@ -679,12 +685,9 @@ void Sapphire::Entity::Chara::updateStatusEffects()
uint32_t tickRate = effect->getTickRate();
if( duration > 0 && ( currentTimeMs - startTime ) > duration )
{
// remove status effect
removeStatusEffect( effectIndex );
// break because removing invalidates iterators
break;
}
effectIt = removeStatusEffect( effectIndex );
else
++effectIt;
if( ( currentTimeMs - lastTick ) > tickRate )
{

View file

@ -106,7 +106,7 @@ namespace Sapphire::Entity
/// Status effect functions
void addStatusEffect( StatusEffect::StatusEffectPtr pEffect );
void removeStatusEffect( uint8_t effectSlotId );
std::map< uint8_t, StatusEffect::StatusEffectPtr >::iterator removeStatusEffect( uint8_t effectSlotId );
void removeSingleStatusEffectById( uint32_t id );

View file

@ -3,6 +3,8 @@
#include <Network/GamePacket.h>
#include <StatusEffect/StatusEffect.h>
#include <Util/Util.h>
#include <Actor/Player.h>
#include <Actor/BNpc.h>
#include "Forwards.h"
namespace Sapphire::Network::Packets::WorldPackets::Server
@ -19,6 +21,11 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
initialize( player );
};
HudParamPacket( Entity::BNpc& bnpc ) : ZoneChannelPacket< FFXIVIpcHudParam >( bnpc.getId(), bnpc.getId() )
{
initialize( bnpc );
};
private:
void initialize( Entity::Player& player )
{
@ -32,19 +39,58 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
m_data.HpMax = player.getMaxHp();
m_data.MpMax = player.getMaxMp();
for( int i = 0; i < 30; ++i )
m_data.effect[ i ] = { 0, 0, 0.0f, 0 };
auto statusMap = player.getStatusEffectMap();
int i = 0;
for( const auto& [ key, val ] : statusMap )
{
auto timeLeft = static_cast< int32_t >( val->getDuration() - ( Common::Util::getTimeMs() - val->getStartTimeMs() ) );
m_data.effect[ i ].Id = val->getId();
m_data.effect[ i ].Source = val->getSrcActorId();
m_data.effect[ i ].SystemParam = val->getParam();
m_data.effect[ i ].Time = ( val->getDuration() - ( Common::Util::getTimeMs() - val->getStartTimeMs() ) ) / 1000.f;
if( timeLeft <= 0 )
m_data.effect[ i ].Time = 0.f;
else
m_data.effect[ i ].Time = timeLeft / 1000.f;
i++;
}
};
}
void initialize( Entity::BNpc& bnpc )
{
m_data.ClassJob = static_cast< uint8_t >( bnpc.getClass() );
m_data.Lv = bnpc.getLevel();
m_data.OrgLv = bnpc.getLevel();
m_data.LvSync = 0;
m_data.Hp = bnpc.getHp();
m_data.Mp = bnpc.getMp();
m_data.Tp = bnpc.getTp();
m_data.HpMax = bnpc.getMaxHp();
m_data.MpMax = bnpc.getMaxMp();
for( int i = 0; i < 30; ++i )
m_data.effect[ i ] = { 0, 0, 0.0f, 0 };
auto statusMap = bnpc.getStatusEffectMap();
int i = 0;
for( const auto& [ key, val ] : statusMap )
{
auto timeLeft = static_cast< int32_t >( val->getDuration() - ( Common::Util::getTimeMs() - val->getStartTimeMs() ) );
m_data.effect[ i ].Id = val->getId();
m_data.effect[ i ].Source = val->getSrcActorId();
m_data.effect[ i ].SystemParam = val->getParam();
if( timeLeft <= 0 )
m_data.effect[ i ].Time = 0.f;
else
m_data.effect[ i ].Time = timeLeft / 1000.f;
i++;
}
}
};
template< typename... Args >
std::shared_ptr< HudParamPacket > makeHudParam( Args... args )