mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-01 08:27:46 +00:00
Status effect rework for actionintegrity.
This commit is contained in:
parent
5d353de158
commit
72f06fb072
9 changed files with 76 additions and 62 deletions
|
@ -17,10 +17,7 @@ public:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint32_t duration = ( sourceChara->getAsPlayer()->getTp() / 50 ) * 1000;
|
uint32_t duration = ( sourceChara->getAsPlayer()->getTp() / 50 ) * 1000;
|
||||||
|
action.getActionResultBuilder()->applyStatusEffect( sourceChara, 50, duration, 30, false );
|
||||||
action.getActionResultBuilder()->applyStatusEffect( sourceChara, 50, 30 );
|
|
||||||
|
|
||||||
sourceChara->getAsPlayer()->addStatusEffectByIdIfNotExist( 50, duration, *sourceChara, 30 );
|
|
||||||
sourceChara->getAsPlayer()->setTp( 0 );
|
sourceChara->getAsPlayer()->setTp( 0 );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "Actor/Chara.h"
|
#include "Actor/Chara.h"
|
||||||
#include "Actor/Player.h"
|
#include "Actor/Player.h"
|
||||||
|
#include "StatusEffect/StatusEffect.h"
|
||||||
|
|
||||||
using namespace Sapphire;
|
using namespace Sapphire;
|
||||||
using namespace Sapphire::World::Action;
|
using namespace Sapphire::World::Action;
|
||||||
|
@ -70,11 +71,15 @@ void ActionResult::comboSucceed()
|
||||||
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_COMBO_HIT;
|
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_COMBO_HIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResult::applyStatusEffect( uint16_t statusId, uint8_t param )
|
void ActionResult::applyStatusEffect( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param, bool shouldOverride )
|
||||||
{
|
{
|
||||||
m_result.Value = static_cast< int16_t >( statusId );
|
m_result.Value = static_cast< int16_t >( id );
|
||||||
m_result.Arg2 = param;
|
m_result.Arg2 = param;
|
||||||
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS;
|
m_result.Type = Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS;
|
||||||
|
|
||||||
|
m_bOverrideStatus = shouldOverride;
|
||||||
|
m_pStatus = StatusEffect::make_StatusEffect( id, source.getAsChara(), m_target, duration, 3000 );
|
||||||
|
m_pStatus->setParam( param );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResult::mount( uint16_t mountId )
|
void ActionResult::mount( uint16_t mountId )
|
||||||
|
@ -89,6 +94,11 @@ const Common::CalcResultParam& ActionResult::getCalcResultParam() const
|
||||||
return m_result;
|
return m_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const StatusEffect::StatusEffectPtr ActionResult::getStatusEffect() const
|
||||||
|
{
|
||||||
|
return m_pStatus;
|
||||||
|
}
|
||||||
|
|
||||||
void ActionResult::execute()
|
void ActionResult::execute()
|
||||||
{
|
{
|
||||||
if( !m_target )
|
if( !m_target )
|
||||||
|
@ -114,6 +124,15 @@ void ActionResult::execute()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Common::ActionEffectType::CALC_RESULT_TYPE_SET_STATUS:
|
||||||
|
{
|
||||||
|
if( !m_bOverrideStatus )
|
||||||
|
m_target->addStatusEffectByIdIfNotExist( m_pStatus->getId(), m_pStatus->getDuration(), *m_pStatus->getSrcActor(), m_pStatus->getParam() );
|
||||||
|
else
|
||||||
|
m_target->addStatusEffectById( m_pStatus->getId(), m_pStatus->getDuration(), *m_pStatus->getSrcActor(), m_pStatus->getParam() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Common::ActionEffectType::CALC_RESULT_TYPE_MOUNT:
|
case Common::ActionEffectType::CALC_RESULT_TYPE_MOUNT:
|
||||||
{
|
{
|
||||||
auto pPlayer = m_target->getAsPlayer();
|
auto pPlayer = m_target->getAsPlayer();
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace Sapphire::World::Action
|
||||||
void restoreMP( uint32_t amount, Common::ActionResultFlag flag = Common::ActionResultFlag::None );
|
void restoreMP( uint32_t amount, Common::ActionResultFlag flag = Common::ActionResultFlag::None );
|
||||||
void startCombo( uint16_t actionId );
|
void startCombo( uint16_t actionId );
|
||||||
void comboSucceed();
|
void comboSucceed();
|
||||||
void applyStatusEffect( uint16_t statusId, uint8_t param );
|
void applyStatusEffect( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param, bool shouldOverride );
|
||||||
void mount( uint16_t mountId );
|
void mount( uint16_t mountId );
|
||||||
|
|
||||||
Entity::CharaPtr getTarget() const;
|
Entity::CharaPtr getTarget() const;
|
||||||
|
@ -27,6 +27,7 @@ namespace Sapphire::World::Action
|
||||||
uint64_t getDelay();
|
uint64_t getDelay();
|
||||||
|
|
||||||
const Common::CalcResultParam& getCalcResultParam() const;
|
const Common::CalcResultParam& getCalcResultParam() const;
|
||||||
|
const Sapphire::StatusEffect::StatusEffectPtr getStatusEffect() const;
|
||||||
|
|
||||||
void execute();
|
void execute();
|
||||||
|
|
||||||
|
@ -37,6 +38,9 @@ namespace Sapphire::World::Action
|
||||||
|
|
||||||
Common::CalcResultParam m_result;
|
Common::CalcResultParam m_result;
|
||||||
|
|
||||||
|
bool m_bOverrideStatus { false };
|
||||||
|
Sapphire::StatusEffect::StatusEffectPtr m_pStatus;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using ActionResultList = std::vector< ActionResultPtr >;
|
using ActionResultList = std::vector< ActionResultPtr >;
|
||||||
|
|
|
@ -81,10 +81,10 @@ void ActionResultBuilder::comboSucceed( Entity::CharaPtr& target )
|
||||||
addResultToActor( target, nextResult );
|
addResultToActor( target, nextResult );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResultBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint8_t param )
|
void ActionResultBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param, bool shouldOverride )
|
||||||
{
|
{
|
||||||
ActionResultPtr nextResult = make_ActionResult( target, 0 );
|
ActionResultPtr nextResult = make_ActionResult( target, 0 );
|
||||||
nextResult->applyStatusEffect( statusId, param );
|
nextResult->applyStatusEffect( statusId, duration, *m_sourceChara, param, shouldOverride );
|
||||||
addResultToActor( target, nextResult );
|
addResultToActor( target, nextResult );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +122,8 @@ std::shared_ptr< FFXIVPacketBase > ActionResultBuilder::createActionResultPacket
|
||||||
actionResult->setRequestId( m_requestId );
|
actionResult->setRequestId( m_requestId );
|
||||||
actionResult->setResultId( m_resultId );
|
actionResult->setResultId( m_resultId );
|
||||||
actionResult->setEffectFlags( Common::ActionEffectDisplayType::HideActionName );
|
actionResult->setEffectFlags( Common::ActionEffectDisplayType::HideActionName );
|
||||||
|
if( !m_actorResultsMap.empty() )
|
||||||
|
taskMgr.queueTask( World::makeActionIntegrityTask( m_resultId, m_sourceChara, m_actorResultsMap.begin()->second, 300 ) );
|
||||||
m_actorResultsMap.clear();
|
m_actorResultsMap.clear();
|
||||||
return actionResult;
|
return actionResult;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace Sapphire::World::Action
|
||||||
|
|
||||||
void comboSucceed( Entity::CharaPtr& target );
|
void comboSucceed( Entity::CharaPtr& target );
|
||||||
|
|
||||||
void applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint8_t param );
|
void applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param, bool shouldOverride );
|
||||||
|
|
||||||
void mount( Entity::CharaPtr& target, uint16_t mountId );
|
void mount( Entity::CharaPtr& target, uint16_t mountId );
|
||||||
|
|
||||||
|
|
|
@ -500,37 +500,8 @@ void Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEffect )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pEffect->applyStatus();
|
pEffect->applyStatus();
|
||||||
|
pEffect->setSlot( nextSlot );
|
||||||
m_statusEffectMap[ nextSlot ] = pEffect;
|
m_statusEffectMap[ nextSlot ] = pEffect;
|
||||||
|
|
||||||
auto statusEffectAdd = makeZonePacket< FFXIVIpcActionIntegrity >( getId() );
|
|
||||||
|
|
||||||
statusEffectAdd->data().ResultId = pZone->getNextActionResultId();
|
|
||||||
statusEffectAdd->data().Target = pEffect->getTargetActorId();
|
|
||||||
statusEffectAdd->data().Hp = getHp();
|
|
||||||
statusEffectAdd->data().Mp = static_cast< uint16_t >( getMp() );
|
|
||||||
statusEffectAdd->data().Tp = static_cast< uint16_t >( getTp() );
|
|
||||||
statusEffectAdd->data().HpMax = getMaxHp();
|
|
||||||
statusEffectAdd->data().MpMax = static_cast< uint16_t >( getMaxMp() );
|
|
||||||
statusEffectAdd->data().ClassJob = static_cast< uint8_t >( getClass() );
|
|
||||||
statusEffectAdd->data().StatusCount = 1;
|
|
||||||
statusEffectAdd->data().unknown_E0 = 0xE0;
|
|
||||||
|
|
||||||
// set all status sources to u32 invalid game obj
|
|
||||||
// todo: chara status effect map should be filled instead, since hudparam also uses invalid gameobj
|
|
||||||
for( int i = 0; i < 4; ++i )
|
|
||||||
{
|
|
||||||
statusEffectAdd->data().Status[ i ].Source = INVALID_GAME_OBJECT_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& status = statusEffectAdd->data().Status[ 0 ];
|
|
||||||
|
|
||||||
status.Source = pEffect->getSrcActorId();
|
|
||||||
status.Time = static_cast< float >( pEffect->getDuration() ) / 1000;
|
|
||||||
status.Id = static_cast< uint16_t >( pEffect->getId() );
|
|
||||||
status.Slot = static_cast< uint8_t >( nextSlot );
|
|
||||||
status.SystemParam = static_cast< int16_t >( pEffect->getParam() );
|
|
||||||
|
|
||||||
server().queueForPlayers( getInRangePlayerIds( isPlayer() ), statusEffectAdd );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \param StatusEffectPtr to be applied to the actor */
|
/*! \param StatusEffectPtr to be applied to the actor */
|
||||||
|
|
|
@ -72,6 +72,11 @@ uint32_t Sapphire::StatusEffect::StatusEffect::getSrcActorId() const
|
||||||
return m_sourceActor->getId();
|
return m_sourceActor->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Sapphire::Entity::CharaPtr Sapphire::StatusEffect::StatusEffect::getSrcActor() const
|
||||||
|
{
|
||||||
|
return m_sourceActor;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t Sapphire::StatusEffect::StatusEffect::getTargetActorId() const
|
uint32_t Sapphire::StatusEffect::StatusEffect::getTargetActorId() const
|
||||||
{
|
{
|
||||||
return m_targetActor->getId();
|
return m_targetActor->getId();
|
||||||
|
@ -86,25 +91,6 @@ void Sapphire::StatusEffect::StatusEffect::applyStatus()
|
||||||
{
|
{
|
||||||
m_startTime = Util::getTimeMs();
|
m_startTime = Util::getTimeMs();
|
||||||
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
||||||
|
|
||||||
// this is only right when an action is being used by the player
|
|
||||||
// else you probably need to use an actorcontrol
|
|
||||||
|
|
||||||
//GamePacketNew< FFXIVIpcEffect > effectPacket( m_sourceActor->getId() );
|
|
||||||
//effectPacket.data().targetId = m_sourceActor->getId();
|
|
||||||
//effectPacket.data().actionAnimationId = 3;
|
|
||||||
//effectPacket.data().unknown_3 = 1;
|
|
||||||
//effectPacket.data().actionTextId = 3;
|
|
||||||
//effectPacket.data().unknown_5 = 1;
|
|
||||||
//effectPacket.data().unknown_6 = 321;
|
|
||||||
//effectPacket.data().rotation = ( uint16_t ) ( 0x8000 * ( ( m_sourceActor->getPos().getR() + 3.1415926 ) ) / 3.1415926 );
|
|
||||||
//effectPacket.data().effectTargetId = m_sourceActor->getId();
|
|
||||||
//effectPacket.data().effects[4].unknown_1 = 17;
|
|
||||||
//effectPacket.data().effects[4].bonusPercent = 30;
|
|
||||||
//effectPacket.data().effects[4].param1 = m_id;
|
|
||||||
//effectPacket.data().effects[4].unknown_5 = 0x80;
|
|
||||||
//m_sourceActor->sendToInRangeSet( effectPacket, true );
|
|
||||||
|
|
||||||
scriptMgr.onStatusReceive( m_targetActor, m_id );
|
scriptMgr.onStatusReceive( m_targetActor, m_id );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,3 +139,13 @@ const std::string& Sapphire::StatusEffect::StatusEffect::getName() const
|
||||||
{
|
{
|
||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t Sapphire::StatusEffect::StatusEffect::getSlot() const
|
||||||
|
{
|
||||||
|
return m_slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sapphire::StatusEffect::StatusEffect::setSlot( uint8_t slot )
|
||||||
|
{
|
||||||
|
m_slot = slot;
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ public:
|
||||||
uint32_t getTickRate() const;
|
uint32_t getTickRate() const;
|
||||||
|
|
||||||
uint32_t getSrcActorId() const;
|
uint32_t getSrcActorId() const;
|
||||||
|
Entity::CharaPtr getSrcActor() const;
|
||||||
|
|
||||||
uint32_t getTargetActorId() const;
|
uint32_t getTargetActorId() const;
|
||||||
|
|
||||||
|
@ -47,6 +48,9 @@ public:
|
||||||
|
|
||||||
const std::string& getName() const;
|
const std::string& getName() const;
|
||||||
|
|
||||||
|
uint8_t getSlot() const;
|
||||||
|
void setSlot( uint8_t slot );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t m_id;
|
uint32_t m_id;
|
||||||
Entity::CharaPtr m_sourceActor;
|
Entity::CharaPtr m_sourceActor;
|
||||||
|
@ -57,6 +61,7 @@ private:
|
||||||
uint64_t m_lastTick;
|
uint64_t m_lastTick;
|
||||||
uint16_t m_param;
|
uint16_t m_param;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
|
uint8_t m_slot;
|
||||||
std::pair< uint8_t, uint32_t > m_currTickEffect;
|
std::pair< uint8_t, uint32_t > m_currTickEffect;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <WorldServer.h>
|
#include <WorldServer.h>
|
||||||
#include <Service.h>
|
#include <Service.h>
|
||||||
#include <Network/PacketWrappers/WarpPacket.h>
|
#include <Network/PacketWrappers/WarpPacket.h>
|
||||||
|
#include <StatusEffect/StatusEffect.h>
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
@ -39,15 +40,31 @@ void ActionIntegrityTask::execute()
|
||||||
if( inRangePlayers.empty() )
|
if( inRangePlayers.empty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
auto integrityPacket = makeZonePacket< FFXIVIpcActionIntegrity >( 0 );
|
||||||
|
auto& data = integrityPacket->data();
|
||||||
|
integrityPacket->setSourceActor( m_pTarget->getId() );
|
||||||
|
|
||||||
|
for( int i = 0; i < 4; ++i )
|
||||||
|
data.Status[ i ].Source = Common::INVALID_GAME_OBJECT_ID;
|
||||||
|
|
||||||
|
int statusIdx = 0;
|
||||||
for( auto& actionResult : m_results )
|
for( auto& actionResult : m_results )
|
||||||
{
|
{
|
||||||
if( actionResult && actionResult->getTarget() && actionResult->getTarget()->isAlive() )
|
if( actionResult && actionResult->getTarget() && actionResult->getTarget()->isAlive() )
|
||||||
actionResult->execute();
|
actionResult->execute();
|
||||||
|
|
||||||
|
if( actionResult->getCalcResultParam().Type == Common::CALC_RESULT_TYPE_SET_STATUS )
|
||||||
|
{
|
||||||
|
auto& status = data.Status[ statusIdx++ ];
|
||||||
|
auto pEffect = actionResult->getStatusEffect();
|
||||||
|
status.Source = pEffect->getSrcActorId();
|
||||||
|
status.Time = static_cast< float >( pEffect->getDuration() ) / 1000;
|
||||||
|
status.Id = static_cast< uint16_t >( pEffect->getId() );
|
||||||
|
status.Slot = static_cast< uint8_t >( pEffect->getSlot() );
|
||||||
|
status.SystemParam = static_cast< int16_t >( pEffect->getParam() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto integrityPacket = makeZonePacket< FFXIVIpcActionIntegrity >( 0 );
|
|
||||||
auto& data = integrityPacket->data();
|
|
||||||
integrityPacket->setSourceActor( m_pTarget->getId() );
|
|
||||||
data.Hp = m_pTarget->getHp();
|
data.Hp = m_pTarget->getHp();
|
||||||
data.HpMax = m_pTarget->getMaxHp();
|
data.HpMax = m_pTarget->getMaxHp();
|
||||||
data.Mp = m_pTarget->getMp();
|
data.Mp = m_pTarget->getMp();
|
||||||
|
@ -55,6 +72,9 @@ void ActionIntegrityTask::execute()
|
||||||
data.Tp = m_pTarget->getTp();
|
data.Tp = m_pTarget->getTp();
|
||||||
data.ResultId = m_resultId;
|
data.ResultId = m_resultId;
|
||||||
data.Target = m_pTarget->getId();
|
data.Target = m_pTarget->getId();
|
||||||
|
data.StatusCount = statusIdx;
|
||||||
|
data.ClassJob = static_cast< uint8_t >( m_pTarget->getClass() );
|
||||||
|
data.unknown_E0 = 0xE0;
|
||||||
|
|
||||||
server.queueForPlayers( inRangePlayers, integrityPacket );
|
server.queueForPlayers( inRangePlayers, integrityPacket );
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue