mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-23 10:17:44 +00:00
Fix slot implementation and add functionality to replace a status effect
This commit is contained in:
parent
e442b735d3
commit
f2ab5d5304
7 changed files with 172 additions and 46 deletions
|
@ -9,6 +9,8 @@
|
|||
#include "Actor/Player.h"
|
||||
#include "StatusEffect/StatusEffect.h"
|
||||
|
||||
#include "Network/Util/PacketUtil.h"
|
||||
|
||||
using namespace Sapphire;
|
||||
using namespace Sapphire::Common;
|
||||
using namespace Sapphire::World::Action;
|
||||
|
@ -72,19 +74,21 @@ void ActionResult::applyStatusEffect( uint32_t id, int32_t duration, Entity::Cha
|
|||
m_result.Arg2 = param;
|
||||
m_result.Type = CalcResultType::TypeSetStatus;
|
||||
|
||||
m_bOverrideStatus = shouldOverride;
|
||||
m_bShouldOverride = shouldOverride;
|
||||
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, source.getAsChara(), m_target, duration, 3000 );
|
||||
m_pStatus->setParam( param );
|
||||
}
|
||||
|
||||
void ActionResult::applyStatusEffect( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param,
|
||||
const std::vector< StatusModifier >& modifiers, uint32_t flag, bool shouldOverride )
|
||||
const std::vector< StatusModifier >& modifiers, uint32_t flag, bool statusToSource, bool shouldOverride )
|
||||
{
|
||||
m_result.Value = static_cast< int16_t >( id );
|
||||
m_result.Arg2 = param;
|
||||
m_result.Type = CalcResultType::TypeSetStatus;
|
||||
m_result.Type = statusToSource ? CalcResultType::TypeSetStatusMe : CalcResultType::TypeSetStatus;
|
||||
if( statusToSource )
|
||||
m_result.Flag = static_cast< uint8_t >( ActionResultFlag::EffectOnSource );
|
||||
|
||||
m_bOverrideStatus = shouldOverride;
|
||||
m_bShouldOverride = shouldOverride;
|
||||
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, source.getAsChara(), m_target, duration, modifiers, flag, 3000 );
|
||||
m_pStatus->setParam( param );
|
||||
}
|
||||
|
@ -96,7 +100,7 @@ void ActionResult::applyStatusEffectSelf( uint32_t id, int32_t duration, uint8_t
|
|||
m_result.Type = CalcResultType::TypeSetStatusMe;
|
||||
m_result.Flag = static_cast< uint8_t >( ActionResultFlag::EffectOnSource );
|
||||
|
||||
m_bOverrideStatus = shouldOverride;
|
||||
m_bShouldOverride = shouldOverride;
|
||||
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, m_target, m_target, duration, 3000 );
|
||||
m_pStatus->setParam( param );
|
||||
}
|
||||
|
@ -109,11 +113,27 @@ void ActionResult::applyStatusEffectSelf( uint32_t id, int32_t duration, uint8_t
|
|||
m_result.Type = CalcResultType::TypeSetStatusMe;
|
||||
m_result.Flag = static_cast< uint8_t >( Common::ActionResultFlag::EffectOnSource );
|
||||
|
||||
m_bOverrideStatus = shouldOverride;
|
||||
m_bShouldOverride = shouldOverride;
|
||||
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, m_target, m_target, duration, modifiers, flag, 3000 );
|
||||
m_pStatus->setParam( param );
|
||||
}
|
||||
|
||||
void ActionResult::replaceStatusEffect( Sapphire::StatusEffect::StatusEffectPtr& pOldStatus, uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param,
|
||||
const std::vector< StatusModifier >& modifiers, uint32_t flag, bool statusToSource )
|
||||
{
|
||||
applyStatusEffect( id, duration, source, param, modifiers, flag, statusToSource, false );
|
||||
m_pOldStatus = std::move( pOldStatus );
|
||||
m_pStatus->setSlot( m_pOldStatus->getSlot() );
|
||||
}
|
||||
|
||||
void ActionResult::replaceStatusEffectSelf( Sapphire::StatusEffect::StatusEffectPtr& pOldStatus, uint32_t id, int32_t duration, uint8_t param,
|
||||
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag )
|
||||
{
|
||||
applyStatusEffectSelf( id, duration, param, modifiers, flag, false );
|
||||
m_pOldStatus = std::move( pOldStatus );
|
||||
m_pStatus->setSlot( m_pOldStatus->getSlot() );
|
||||
}
|
||||
|
||||
void ActionResult::mount( uint16_t mountId )
|
||||
{
|
||||
m_result.Value = static_cast< int16_t >( mountId );
|
||||
|
@ -161,7 +181,22 @@ void ActionResult::execute()
|
|||
case CalcResultType::TypeSetStatus:
|
||||
case CalcResultType::TypeSetStatusMe:
|
||||
{
|
||||
if( !m_bOverrideStatus )
|
||||
for( auto const& entry : m_target->getStatusEffectMap() )
|
||||
{
|
||||
auto statusEffect = entry.second;
|
||||
if( statusEffect->getId() == m_result.Value && m_bShouldOverride )
|
||||
{
|
||||
statusEffect->refresh( m_pStatus->getDuration() );
|
||||
m_pStatus->setSlot( statusEffect->getSlot() );
|
||||
|
||||
Network::Util::Packet::sendHudParam( *m_target );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_pOldStatus )
|
||||
m_target->replaceSingleStatusEffect( m_pOldStatus->getSlot(), m_pStatus );
|
||||
else if( !m_bShouldOverride )
|
||||
m_target->addStatusEffectByIdIfNotExist( m_pStatus );
|
||||
else
|
||||
m_target->addStatusEffectById( m_pStatus );
|
||||
|
@ -178,4 +213,4 @@ void ActionResult::execute()
|
|||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,10 +22,14 @@ namespace Sapphire::World::Action
|
|||
void comboSucceed();
|
||||
void applyStatusEffect( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param, bool shouldOverride );
|
||||
void applyStatusEffect( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param,
|
||||
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag, bool shouldOverride );
|
||||
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag, bool statusToSource, bool shouldOverride );
|
||||
void applyStatusEffectSelf( uint32_t id, int32_t duration, uint8_t param, bool shouldOverride );
|
||||
void applyStatusEffectSelf( uint32_t id, int32_t duration, uint8_t param, const std::vector< World::Action::StatusModifier >& modifiers,
|
||||
uint32_t flag, bool shouldOverride );
|
||||
void replaceStatusEffect( Sapphire::StatusEffect::StatusEffectPtr& pOldStatus, uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param,
|
||||
const std::vector< StatusModifier >& modifiers, uint32_t flag, bool statusToSource );
|
||||
void replaceStatusEffectSelf( Sapphire::StatusEffect::StatusEffectPtr& pOldStatus, uint32_t id, int32_t duration, uint8_t param,
|
||||
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag );
|
||||
void mount( uint16_t mountId );
|
||||
|
||||
Entity::CharaPtr getTarget() const;
|
||||
|
@ -40,8 +44,9 @@ namespace Sapphire::World::Action
|
|||
|
||||
Common::CalcResultParam m_result;
|
||||
|
||||
bool m_bOverrideStatus { false };
|
||||
bool m_bShouldOverride { false };
|
||||
Sapphire::StatusEffect::StatusEffectPtr m_pStatus;
|
||||
Sapphire::StatusEffect::StatusEffectPtr m_pOldStatus;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -94,10 +94,10 @@ void ActionResultBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t
|
|||
}
|
||||
|
||||
void ActionResultBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param,
|
||||
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag, bool shouldOverride )
|
||||
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag, bool statusToSource, bool shouldOverride )
|
||||
{
|
||||
ActionResultPtr nextResult = make_ActionResult( target );
|
||||
nextResult->applyStatusEffect( statusId, duration, *m_sourceChara, param, modifiers, flag, shouldOverride );
|
||||
nextResult->applyStatusEffect( statusId, duration, *m_sourceChara, param, modifiers, flag, statusToSource, shouldOverride );
|
||||
addResultToActor( target, nextResult );
|
||||
}
|
||||
|
||||
|
@ -116,6 +116,22 @@ void ActionResultBuilder::applyStatusEffectSelf( uint16_t statusId, uint32_t dur
|
|||
addResultToActor( m_sourceChara, nextResult );
|
||||
}
|
||||
|
||||
void ActionResultBuilder::replaceStatusEffect( Sapphire::StatusEffect::StatusEffectPtr& pOldStatus, Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param,
|
||||
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag, bool statusToSource )
|
||||
{
|
||||
ActionResultPtr nextResult = make_ActionResult( target );
|
||||
nextResult->replaceStatusEffect( pOldStatus, statusId, duration, *m_sourceChara, param, modifiers, flag, statusToSource );
|
||||
addResultToActor( target, nextResult );
|
||||
}
|
||||
|
||||
void ActionResultBuilder::replaceStatusEffectSelf( Sapphire::StatusEffect::StatusEffectPtr& pOldStatus, uint16_t statusId, uint32_t duration, uint8_t param,
|
||||
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag )
|
||||
{
|
||||
ActionResultPtr nextResult = make_ActionResult( m_sourceChara );
|
||||
nextResult->replaceStatusEffectSelf( pOldStatus, statusId, duration, param, modifiers, flag );
|
||||
addResultToActor( m_sourceChara, nextResult );
|
||||
}
|
||||
|
||||
void ActionResultBuilder::mount( Entity::CharaPtr& target, uint16_t mountId )
|
||||
{
|
||||
ActionResultPtr nextResult = make_ActionResult( target );
|
||||
|
|
|
@ -28,11 +28,14 @@ namespace Sapphire::World::Action
|
|||
|
||||
void applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param, bool shouldOverride = false );
|
||||
void applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param,
|
||||
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag = 0, bool shouldOverride = false );
|
||||
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag = 0, bool statusToSource = false, bool shouldOverride = false );
|
||||
void applyStatusEffectSelf( uint16_t statusId, uint32_t duration, uint8_t param, bool shouldOverride = false );
|
||||
void applyStatusEffectSelf( uint16_t statusId, uint32_t duration, uint8_t param, const std::vector< World::Action::StatusModifier >& modifiers,
|
||||
uint32_t flag = 0, bool shouldOverride = false );
|
||||
|
||||
void replaceStatusEffect( Sapphire::StatusEffect::StatusEffectPtr& pOldStatus, Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param,
|
||||
const std::vector< StatusModifier >& modifiers, uint32_t flag = 0, bool statusToSource = false );
|
||||
void replaceStatusEffectSelf( Sapphire::StatusEffect::StatusEffectPtr& pOldStatus, uint16_t statusId, uint32_t duration, uint8_t param,
|
||||
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag = 0 );
|
||||
void mount( Entity::CharaPtr& target, uint16_t mountId );
|
||||
|
||||
void sendActionResults( const std::vector< Entity::CharaPtr >& targetList );
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <Action/CommonAction.h>
|
||||
#include <Action/Action.h>
|
||||
#include <Actor/Player.h>
|
||||
#include <StatusEffect/StatusEffect.h>
|
||||
|
||||
using namespace Sapphire;
|
||||
using namespace Sapphire::World::Action;
|
||||
|
@ -29,6 +30,7 @@ void Warrior::onAction( Entity::Player& player, Action& action )
|
|||
|
||||
void Warrior::handleWrath( Entity::Player& player, Action& action )
|
||||
{
|
||||
Sapphire::StatusEffect::StatusEffectPtr oldStatus = nullptr;
|
||||
auto effectToApply = Wrath;
|
||||
auto parry = 2;
|
||||
auto asChara = player.getAsChara();
|
||||
|
@ -38,33 +40,45 @@ void Warrior::handleWrath( Entity::Player& player, Action& action )
|
|||
if( !pActionBuilder )
|
||||
return;
|
||||
|
||||
if( player.hasStatusEffect( Wrath ) )
|
||||
auto statusMap = player.getStatusEffectMap();
|
||||
|
||||
for( const auto& effectIt : statusMap )
|
||||
{
|
||||
player.replaceSingleStatusEffectById( Wrath );
|
||||
effectToApply = WrathII;
|
||||
parry += 2;
|
||||
}
|
||||
else if( player.hasStatusEffect( WrathII ) )
|
||||
{
|
||||
player.replaceSingleStatusEffectById( WrathII );
|
||||
effectToApply = WrathIII;
|
||||
parry += 2;
|
||||
}
|
||||
else if( player.hasStatusEffect( WrathIII ) )
|
||||
{
|
||||
player.replaceSingleStatusEffectById( WrathIII );
|
||||
effectToApply = WrathIV;
|
||||
parry += 2;
|
||||
}
|
||||
else if( player.hasStatusEffect( WrathIV ) )
|
||||
{
|
||||
player.replaceSingleStatusEffectById( WrathIV );
|
||||
effectToApply = Infuriated;
|
||||
parry += 2;
|
||||
if( effectIt.second->getId() == Wrath )
|
||||
{
|
||||
oldStatus = effectIt.second;
|
||||
effectToApply = WrathII;
|
||||
parry += 2;
|
||||
break;
|
||||
}
|
||||
else if( effectIt.second->getId() == WrathII )
|
||||
{
|
||||
oldStatus = effectIt.second;
|
||||
effectToApply = WrathIII;
|
||||
parry += 2;
|
||||
break;
|
||||
}
|
||||
else if( effectIt.second->getId() == WrathIII )
|
||||
{
|
||||
oldStatus = effectIt.second;
|
||||
effectToApply = WrathIV;
|
||||
parry += 2;
|
||||
break;
|
||||
}
|
||||
else if( effectIt.second->getId() == WrathIV )
|
||||
{
|
||||
oldStatus = effectIt.second;
|
||||
effectToApply = Infuriated;
|
||||
parry += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !player.hasStatusEffect( Infuriated ) )
|
||||
{
|
||||
pActionBuilder->applyStatusEffectSelf( effectToApply, 30000, 0, { StatusModifier{ Common::ParamModifier::ParryPercent, parry } }, 0, false );
|
||||
{
|
||||
if( oldStatus )
|
||||
pActionBuilder->replaceStatusEffectSelf( oldStatus, effectToApply, 30000, 0, { StatusModifier{ Common::ParamModifier::ParryPercent, parry } } );
|
||||
else
|
||||
pActionBuilder->applyStatusEffectSelf( effectToApply, 30000, 0, { StatusModifier{ Common::ParamModifier::ParryPercent, parry } } );
|
||||
}
|
||||
}
|
|
@ -521,18 +521,41 @@ int8_t Chara::getStatusEffectFreeSlot()
|
|||
{
|
||||
int8_t freeEffectSlot = -1;
|
||||
|
||||
if( m_statusEffectFreeSlotQueue.empty() )
|
||||
// if( m_statusEffectFreeSlotQueue.empty() )
|
||||
// return freeEffectSlot;
|
||||
|
||||
// freeEffectSlot = static_cast< int8_t >( m_statusEffectFreeSlotQueue.front() );
|
||||
// m_statusEffectFreeSlotQueue.pop();
|
||||
|
||||
if( m_statusEffectSlots.size() >= MAX_STATUS_EFFECTS )
|
||||
return freeEffectSlot;
|
||||
|
||||
freeEffectSlot = static_cast< int8_t >( m_statusEffectFreeSlotQueue.front() );
|
||||
m_statusEffectFreeSlotQueue.pop();
|
||||
if( m_statusEffectSlots.empty() )
|
||||
freeEffectSlot = 0;
|
||||
else
|
||||
freeEffectSlot = static_cast< int8_t >( *m_statusEffectSlots.rbegin() + 1 );
|
||||
|
||||
m_statusEffectSlots.insert( freeEffectSlot );
|
||||
|
||||
Logger::warn( "Slot id being added: {}", freeEffectSlot );
|
||||
|
||||
return freeEffectSlot;
|
||||
}
|
||||
|
||||
void Chara::statusEffectFreeSlot( uint8_t slotId )
|
||||
{
|
||||
m_statusEffectFreeSlotQueue.push( slotId );
|
||||
// m_statusEffectFreeSlotQueue.push( slotId );
|
||||
m_statusEffectSlots.erase( slotId );
|
||||
// std::set< uint8_t > shiftedSlots;
|
||||
}
|
||||
|
||||
void Chara::replaceSingleStatusEffect( uint32_t slotId, StatusEffect::StatusEffectPtr pStatus )
|
||||
{
|
||||
// removeStatusEffect( slotId, false );
|
||||
// addStatusEffect( pStatus );
|
||||
pStatus->setSlot( slotId );
|
||||
m_statusEffectMap[ slotId ] = pStatus;
|
||||
pStatus->applyStatus();
|
||||
}
|
||||
|
||||
void Chara::replaceSingleStatusEffectById( uint32_t id )
|
||||
|
@ -588,7 +611,7 @@ void Chara::removeStatusEffectByFlag( Common::StatusEffectFlag flag )
|
|||
}
|
||||
}
|
||||
|
||||
std::map< uint8_t, Sapphire::StatusEffect::StatusEffectPtr >::iterator Chara::removeStatusEffect( uint8_t effectSlotId, bool sendOrder )
|
||||
std::map< uint8_t, Sapphire::StatusEffect::StatusEffectPtr >::iterator Chara::removeStatusEffect( uint8_t effectSlotId, bool updateStatus )
|
||||
{
|
||||
auto pEffectIt = m_statusEffectMap.find( effectSlotId );
|
||||
if( pEffectIt == m_statusEffectMap.end() )
|
||||
|
@ -599,11 +622,38 @@ std::map< uint8_t, Sapphire::StatusEffect::StatusEffectPtr >::iterator Chara::re
|
|||
auto pEffect = pEffectIt->second;
|
||||
pEffect->removeStatus();
|
||||
|
||||
if( sendOrder )
|
||||
if( updateStatus )
|
||||
{
|
||||
Network::Util::Packet::sendActorControl( getInRangePlayerIds( isPlayer() ), getId(), StatusEffectLose, pEffect->getId() );
|
||||
Network::Util::Packet::sendHudParam( *this );
|
||||
}
|
||||
|
||||
auto it = m_statusEffectMap.erase( pEffectIt );
|
||||
Network::Util::Packet::sendHudParam( *this );
|
||||
|
||||
// for( const auto& effectIt : m_statusEffectMap )
|
||||
for( auto effectIt = it; effectIt != m_statusEffectMap.end(); )
|
||||
{
|
||||
// if( effectIt.first > effectSlotId )
|
||||
// {
|
||||
// if the status is *after* the one being removed, shift the slots down by one
|
||||
auto shifted_slot = effectIt->first - 1;
|
||||
auto node_slot = m_statusEffectSlots.extract( effectIt->first );
|
||||
node_slot.value() = shifted_slot;
|
||||
m_statusEffectSlots.insert( std::move( node_slot ) );
|
||||
|
||||
auto node_status = m_statusEffectMap.extract( effectIt->first );
|
||||
node_status.key() = shifted_slot;
|
||||
m_statusEffectMap.insert( std::move( node_status ) );
|
||||
|
||||
effectIt->second->setSlot( effectIt->second->getSlot() - 1 );
|
||||
|
||||
Logger::warn( "Shifted slot {} to slot: {}", effectSlotId, shifted_slot );
|
||||
++effectIt;
|
||||
// }
|
||||
}
|
||||
|
||||
Logger::warn( "Slot id being freed: {}", effectSlotId );
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ namespace Sapphire::Entity
|
|||
std::queue< uint8_t > m_statusEffectFreeSlotQueue;
|
||||
std::vector< std::pair< uint8_t, uint32_t > > m_statusEffectList;
|
||||
std::map< uint8_t, StatusEffect::StatusEffectPtr > m_statusEffectMap;
|
||||
std::set< uint8_t > m_statusEffectSlots;
|
||||
|
||||
/*! Detour Crowd AgentId */
|
||||
uint32_t m_agentId;
|
||||
|
@ -108,7 +109,9 @@ namespace Sapphire::Entity
|
|||
/// Status effect functions
|
||||
void addStatusEffect( StatusEffect::StatusEffectPtr pEffect );
|
||||
|
||||
std::map< uint8_t, StatusEffect::StatusEffectPtr >::iterator removeStatusEffect( uint8_t effectSlotId, bool sendOrder = true );
|
||||
std::map< uint8_t, StatusEffect::StatusEffectPtr >::iterator removeStatusEffect( uint8_t effectSlotId, bool updateStatus = true );
|
||||
|
||||
void replaceSingleStatusEffect( uint32_t slotId, StatusEffect::StatusEffectPtr pStatus );
|
||||
|
||||
void replaceSingleStatusEffectById( uint32_t id );
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue