mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-25 19:17:45 +00:00
Action data update.
All values are parsed from ffxiv act plugin at https://github.com/ravahn/FFXIV_ACT_Plugin
This commit is contained in:
parent
6eaa4c407f
commit
761b6cc94d
13 changed files with 2185 additions and 1585 deletions
|
@ -13,14 +13,14 @@ public:
|
|||
|
||||
void onExecute( Sapphire::World::Action::Action& action ) override
|
||||
{
|
||||
/*
|
||||
auto sourceChara = action.getSourceChara();
|
||||
|
||||
if( !sourceChara->isPlayer() )
|
||||
return;
|
||||
|
||||
action.getEffectbuilder()->applyStatusEffect( sourceChara, 50, 30 );
|
||||
|
||||
sourceChara->getAsPlayer()->addStatusEffectByIdIfNotExist( 50, 20000, *sourceChara, 30 );
|
||||
action.getEffectbuilder()->applyStatusEffect( sourceChara, sourceChara, 50, 20000, 30 );
|
||||
*/
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -468,19 +468,21 @@ void Action::Action::buildEffects()
|
|||
return;
|
||||
}
|
||||
|
||||
if( !hasLutEntry || m_hitActors.empty() ) // this is just "if ( weCanNotUseGenericActionHandler )" in case we start to expand it.
|
||||
if( !hasLutEntry ) // this is just "if ( weCanNotUseGenericActionHandler )" in case we start to expand it.
|
||||
{
|
||||
// send any effect packet added by script or an empty one just to play animation for other players
|
||||
m_effectBuilder->buildAndSendPackets();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// we have a valid lut entry
|
||||
if( auto player = getSourceChara()->getAsPlayer() )
|
||||
{
|
||||
player->sendDebug( "Hit target: pot: {} (c: {}, f: {}, r: {}), heal pot: {}, mpp: {}",
|
||||
m_lutEntry.potency, m_lutEntry.comboPotency, m_lutEntry.flankPotency, m_lutEntry.rearPotency,
|
||||
m_lutEntry.curePotency, m_lutEntry.restoreMPPercentage );
|
||||
player->sendDebug( "dpot: {} (dcpot: {}, ddpot: {}), hpot: {}, shpot: {}, ss: {}, ts: {}, gmp: {}, gjob: {}",
|
||||
m_lutEntry.damagePotency, m_lutEntry.damageComboPotency, m_lutEntry.damageDirectionalPotency,
|
||||
m_lutEntry.healPotency, m_lutEntry.selfHealPotency,
|
||||
m_lutEntry.selfStatus, m_lutEntry.targetStatus,
|
||||
m_lutEntry.gainMPPercentage, m_lutEntry.gainJobResource );
|
||||
}
|
||||
|
||||
// when aoe, these effects are in the target whatever is hit first
|
||||
|
@ -489,9 +491,9 @@ void Action::Action::buildEffects()
|
|||
|
||||
for( auto& actor : m_hitActors )
|
||||
{
|
||||
if( m_lutEntry.potency > 0 )
|
||||
if( m_lutEntry.damagePotency > 0 )
|
||||
{
|
||||
auto dmg = calcDamage( isCorrectCombo() ? m_lutEntry.comboPotency : m_lutEntry.potency );
|
||||
auto dmg = calcDamage( isCorrectCombo() ? m_lutEntry.damageComboPotency : m_lutEntry.damagePotency );
|
||||
m_effectBuilder->damage( actor, actor, dmg.first, dmg.second );
|
||||
|
||||
if( dmg.first > 0 )
|
||||
|
@ -505,15 +507,15 @@ void Action::Action::buildEffects()
|
|||
|
||||
if( !isComboAction() || isCorrectCombo() )
|
||||
{
|
||||
if( m_lutEntry.curePotency > 0 ) // actions with self heal
|
||||
if( m_lutEntry.selfHealPotency > 0 ) // actions with self heal
|
||||
{
|
||||
auto heal = calcHealing( m_lutEntry.curePotency );
|
||||
auto heal = calcHealing( m_lutEntry.selfHealPotency );
|
||||
m_effectBuilder->heal( actor, m_pSource, heal.first, heal.second, Common::ActionEffectResultFlag::EffectOnSource );
|
||||
}
|
||||
|
||||
if( m_lutEntry.restoreMPPercentage > 0 && shouldRestoreMP )
|
||||
if( m_lutEntry.gainMPPercentage > 0 && shouldRestoreMP )
|
||||
{
|
||||
m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100, Common::ActionEffectResultFlag::EffectOnSource );
|
||||
m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.gainMPPercentage / 100, Common::ActionEffectResultFlag::EffectOnSource );
|
||||
shouldRestoreMP = false;
|
||||
}
|
||||
|
||||
|
@ -523,24 +525,34 @@ void Action::Action::buildEffects()
|
|||
}
|
||||
}
|
||||
}
|
||||
else if( m_lutEntry.curePotency > 0 )
|
||||
else if( m_lutEntry.healPotency > 0 )
|
||||
{
|
||||
auto heal = calcHealing( m_lutEntry.curePotency );
|
||||
auto heal = calcHealing( m_lutEntry.healPotency );
|
||||
m_effectBuilder->heal( actor, actor, heal.first, heal.second );
|
||||
|
||||
if( m_lutEntry.restoreMPPercentage > 0 && shouldRestoreMP )
|
||||
if( m_lutEntry.gainMPPercentage > 0 && shouldRestoreMP )
|
||||
{
|
||||
m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100, Common::ActionEffectResultFlag::EffectOnSource );
|
||||
m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.gainMPPercentage / 100, Common::ActionEffectResultFlag::EffectOnSource );
|
||||
shouldRestoreMP = false;
|
||||
}
|
||||
}
|
||||
else if( m_lutEntry.restoreMPPercentage > 0 && shouldRestoreMP )
|
||||
else if( m_lutEntry.gainMPPercentage > 0 && shouldRestoreMP )
|
||||
{
|
||||
m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100, Common::ActionEffectResultFlag::EffectOnSource );
|
||||
m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.gainMPPercentage / 100, Common::ActionEffectResultFlag::EffectOnSource );
|
||||
shouldRestoreMP = false;
|
||||
}
|
||||
|
||||
if( m_lutEntry.targetStatus != 0 )
|
||||
{
|
||||
m_effectBuilder->applyStatusEffect( actor, m_pSource, m_lutEntry.targetStatus, m_lutEntry.targetStatusDuration, m_lutEntry.targetStatusParam );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_lutEntry.selfStatus != 0 )
|
||||
{
|
||||
m_effectBuilder->applyStatusEffect( m_pSource, m_pSource, m_lutEntry.selfStatus, m_lutEntry.selfStatusDuration, m_lutEntry.selfStatusParam );
|
||||
}
|
||||
|
||||
m_effectBuilder->buildAndSendPackets();
|
||||
|
||||
// at this point we're done with it and no longer need it
|
||||
|
@ -565,7 +577,7 @@ bool Action::Action::playerPreCheck( Entity::Player& player )
|
|||
return false;
|
||||
|
||||
// npc actions/non player actions
|
||||
if( m_actionData->classJob == -1 )
|
||||
if( m_actionData->classJob == -1 && !m_actionData->isRoleAction )
|
||||
return false;
|
||||
|
||||
if( player.getLevel() < m_actionData->classJobLevel )
|
||||
|
@ -574,7 +586,7 @@ bool Action::Action::playerPreCheck( Entity::Player& player )
|
|||
auto currentClass = player.getClass();
|
||||
auto actionClass = static_cast< Common::ClassJob >( m_actionData->classJob );
|
||||
|
||||
if( actionClass != Common::ClassJob::Adventurer && currentClass != actionClass )
|
||||
if( actionClass != Common::ClassJob::Adventurer && currentClass != actionClass && !m_actionData->isRoleAction )
|
||||
{
|
||||
// check if not a base class action
|
||||
auto exdData = m_pFw->get< Data::ExdDataGenerated >();
|
||||
|
@ -777,18 +789,18 @@ bool Action::Action::preFilterActor( Sapphire::Entity::Actor& actor ) const
|
|||
if( kind != ObjKind::BattleNpc && kind != ObjKind::Player )
|
||||
return false;
|
||||
|
||||
if( !m_canTargetSelf && chara->getId() == m_pSource->getId() )
|
||||
if( m_lutEntry.damagePotency > 0 && chara->getId() == m_pSource->getId() ) // !m_canTargetSelf
|
||||
return false;
|
||||
|
||||
if( ( m_lutEntry.potency > 0 || m_lutEntry.curePotency > 0 ) && !chara->isAlive() ) // !m_canTargetDead not working for aoe
|
||||
if( ( m_lutEntry.damagePotency > 0 || m_lutEntry.healPotency > 0 ) && !chara->isAlive() ) // !m_canTargetDead not working for aoe
|
||||
return false;
|
||||
|
||||
if( m_lutEntry.potency > 0 && m_pSource->getObjKind() == chara->getObjKind() ) // !m_canTargetFriendly not working for aoe
|
||||
if( m_lutEntry.damagePotency > 0 && m_pSource->getObjKind() == chara->getObjKind() ) // !m_canTargetFriendly not working for aoe
|
||||
return false;
|
||||
|
||||
if( ( m_lutEntry.potency == 0 && m_lutEntry.curePotency > 0 ) && m_pSource->getObjKind() != chara->getObjKind() ) // !m_canTargetHostile not working for aoe
|
||||
if( ( m_lutEntry.damagePotency == 0 && m_lutEntry.healPotency > 0 ) && m_pSource->getObjKind() != chara->getObjKind() ) // !m_canTargetHostile not working for aoe
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -809,8 +821,8 @@ Sapphire::Entity::CharaPtr Action::Action::getHitChara()
|
|||
|
||||
bool Action::Action::hasValidLutEntry() const
|
||||
{
|
||||
return m_lutEntry.potency != 0 || m_lutEntry.comboPotency != 0 || m_lutEntry.flankPotency != 0 || m_lutEntry.frontPotency != 0 ||
|
||||
m_lutEntry.rearPotency != 0 || m_lutEntry.curePotency != 0 || m_lutEntry.restoreMPPercentage != 0;
|
||||
return m_lutEntry.damagePotency != 0 || m_lutEntry.healPotency != 0 || m_lutEntry.selfHealPotency != 0 || m_lutEntry.selfStatus != 0 ||
|
||||
m_lutEntry.targetStatus != 0 || m_lutEntry.gainMPPercentage != 0 || m_lutEntry.gainJobResource != 0;
|
||||
}
|
||||
|
||||
Action::EffectBuilderPtr Action::Action::getEffectbuilder()
|
||||
|
|
|
@ -12,9 +12,9 @@ bool ActionLut::validEntryExists( uint16_t actionId )
|
|||
|
||||
const auto& entry = it->second;
|
||||
|
||||
// if all of the fields are 0, it's not 'valid' due to parse error or no useful data in the tooltip
|
||||
return entry.potency != 0 || entry.comboPotency != 0 || entry.flankPotency != 0 || entry.frontPotency != 0 ||
|
||||
entry.rearPotency != 0 || entry.curePotency != 0;
|
||||
// if all of these fields are 0, it's not 'valid' due to parse error or no useful data
|
||||
return entry.damagePotency != 0 || entry.healPotency != 0 || entry.selfHealPotency != 0 || entry.selfStatus != 0 ||
|
||||
entry.targetStatus != 0 || entry.gainMPPercentage != 0 || entry.gainJobResource != 0;
|
||||
}
|
||||
|
||||
const ActionEntry& ActionLut::getEntry( uint16_t actionId )
|
||||
|
|
|
@ -7,13 +7,19 @@ namespace Sapphire::World::Action
|
|||
{
|
||||
struct ActionEntry
|
||||
{
|
||||
uint16_t potency;
|
||||
uint16_t comboPotency;
|
||||
uint16_t flankPotency;
|
||||
uint16_t frontPotency;
|
||||
uint16_t rearPotency;
|
||||
uint16_t curePotency;
|
||||
uint16_t restoreMPPercentage;
|
||||
uint16_t damagePotency;
|
||||
uint16_t damageComboPotency;
|
||||
uint16_t damageDirectionalPotency;
|
||||
uint16_t healPotency;
|
||||
uint16_t selfHealPotency;
|
||||
uint16_t selfStatus;
|
||||
uint16_t selfStatusDuration;
|
||||
uint16_t selfStatusParam;
|
||||
uint16_t targetStatus;
|
||||
uint16_t targetStatusDuration;
|
||||
uint16_t targetStatusParam;
|
||||
uint16_t gainMPPercentage;
|
||||
uint16_t gainJobResource;
|
||||
};
|
||||
|
||||
class ActionLut
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -51,43 +51,43 @@ void EffectBuilder::moveToResultList( Entity::CharaPtr& chara, EffectResultPtr r
|
|||
|
||||
void EffectBuilder::heal( Entity::CharaPtr& effectTarget, Entity::CharaPtr& healingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag )
|
||||
{
|
||||
EffectResultPtr nextResult = make_EffectResult( healingTarget, getResultDelayMs() );
|
||||
EffectResultPtr nextResult = make_EffectResult( healingTarget, nullptr, getResultDelayMs() );
|
||||
nextResult->heal( amount, severity, flag );
|
||||
moveToResultList( effectTarget, nextResult );
|
||||
}
|
||||
|
||||
void EffectBuilder::restoreMP( Entity::CharaPtr& target, Entity::CharaPtr& restoringTarget, uint32_t amount, Common::ActionEffectResultFlag flag )
|
||||
{
|
||||
EffectResultPtr nextResult = make_EffectResult( restoringTarget, getResultDelayMs() ); // restore mp source actor
|
||||
EffectResultPtr nextResult = make_EffectResult( restoringTarget, nullptr, getResultDelayMs() ); // restore mp source actor
|
||||
nextResult->restoreMP( amount, flag );
|
||||
moveToResultList( target, nextResult );
|
||||
}
|
||||
|
||||
void EffectBuilder::damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag )
|
||||
{
|
||||
EffectResultPtr nextResult = make_EffectResult( damagingTarget, getResultDelayMs() );
|
||||
EffectResultPtr nextResult = make_EffectResult( damagingTarget, nullptr, getResultDelayMs() );
|
||||
nextResult->damage( amount, severity, flag );
|
||||
moveToResultList( effectTarget, nextResult );
|
||||
}
|
||||
|
||||
void EffectBuilder::startCombo( Entity::CharaPtr& target, uint16_t actionId )
|
||||
{
|
||||
EffectResultPtr nextResult = make_EffectResult( target, 0 );
|
||||
EffectResultPtr nextResult = make_EffectResult( target, nullptr, 0 );
|
||||
nextResult->startCombo( actionId );
|
||||
moveToResultList( target, nextResult );
|
||||
}
|
||||
|
||||
void EffectBuilder::comboSucceed( Entity::CharaPtr& target )
|
||||
{
|
||||
EffectResultPtr nextResult = make_EffectResult( target, 0 );
|
||||
EffectResultPtr nextResult = make_EffectResult( target, nullptr, 0 );
|
||||
nextResult->comboSucceed();
|
||||
moveToResultList( target, nextResult );
|
||||
}
|
||||
|
||||
void EffectBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint8_t param )
|
||||
void EffectBuilder::applyStatusEffect( Entity::CharaPtr& target, Entity::CharaPtr& source, uint16_t statusId, uint32_t duration, uint8_t param )
|
||||
{
|
||||
EffectResultPtr nextResult = make_EffectResult( target, 0 );
|
||||
nextResult->applyStatusEffect( statusId, param );
|
||||
EffectResultPtr nextResult = make_EffectResult( target, source, 0 );
|
||||
nextResult->applyStatusEffect( statusId, duration, param );
|
||||
moveToResultList( target, nextResult );
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Sapphire::World::Action
|
|||
|
||||
void comboSucceed( Entity::CharaPtr& target );
|
||||
|
||||
void applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint8_t param );
|
||||
void applyStatusEffect( Entity::CharaPtr& target, Entity::CharaPtr& source, uint16_t statusId, uint32_t duration, uint8_t param );
|
||||
|
||||
void buildAndSendPackets();
|
||||
|
||||
|
|
|
@ -8,10 +8,12 @@ using namespace Sapphire;
|
|||
using namespace Sapphire::World::Action;
|
||||
|
||||
|
||||
EffectResult::EffectResult( Entity::CharaPtr target, uint64_t runAfter ) :
|
||||
EffectResult::EffectResult( Entity::CharaPtr target, Entity::CharaPtr source, uint64_t runAfter ) :
|
||||
m_target( std::move( target ) ),
|
||||
m_source( std::move( source ) ),
|
||||
m_delayMs( runAfter ),
|
||||
m_value( 0 ),
|
||||
m_value2( 0 ),
|
||||
m_param0( 0 ),
|
||||
m_param1( 0 ),
|
||||
m_type( Common::ActionEffectType::Nothing ),
|
||||
|
@ -21,6 +23,11 @@ EffectResult::EffectResult( Entity::CharaPtr target, uint64_t runAfter ) :
|
|||
|
||||
}
|
||||
|
||||
Entity::CharaPtr EffectResult::getSource() const
|
||||
{
|
||||
return m_source;
|
||||
}
|
||||
|
||||
Entity::CharaPtr EffectResult::getTarget() const
|
||||
{
|
||||
return m_target;
|
||||
|
@ -76,9 +83,10 @@ void EffectResult::comboSucceed()
|
|||
m_type = Common::ActionEffectType::ComboSucceed;
|
||||
}
|
||||
|
||||
void EffectResult::applyStatusEffect( uint16_t statusId, uint8_t param )
|
||||
void EffectResult::applyStatusEffect( uint16_t statusId, uint32_t duration, uint8_t param )
|
||||
{
|
||||
m_value = statusId;
|
||||
m_value2 = duration;
|
||||
m_param2 = param;
|
||||
|
||||
m_type = Common::ActionEffectType::ApplyStatusEffect;
|
||||
|
@ -121,6 +129,12 @@ void EffectResult::execute()
|
|||
break;
|
||||
}
|
||||
|
||||
case Common::ActionEffectType::ApplyStatusEffect:
|
||||
{
|
||||
m_target->addStatusEffectById( m_value, m_value2, *m_source, m_param2 );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -13,15 +13,16 @@ namespace Sapphire::World::Action
|
|||
class EffectResult
|
||||
{
|
||||
public:
|
||||
explicit EffectResult( Entity::CharaPtr target, uint64_t delayMs );
|
||||
explicit EffectResult( Entity::CharaPtr target, Entity::CharaPtr source, uint64_t delayMs );
|
||||
|
||||
void damage( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
||||
void heal( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
||||
void restoreMP( uint32_t amount, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
||||
void startCombo( uint16_t actionId );
|
||||
void comboSucceed();
|
||||
void applyStatusEffect( uint16_t statusId, uint8_t param );
|
||||
void applyStatusEffect( uint16_t statusId, uint32_t duration, uint8_t param );
|
||||
|
||||
Entity::CharaPtr getSource() const;
|
||||
Entity::CharaPtr getTarget() const;
|
||||
|
||||
uint32_t getValue() const;
|
||||
|
@ -35,6 +36,7 @@ namespace Sapphire::World::Action
|
|||
private:
|
||||
uint64_t m_delayMs;
|
||||
|
||||
Entity::CharaPtr m_source;
|
||||
Entity::CharaPtr m_target;
|
||||
|
||||
Common::ActionEffectType m_type;
|
||||
|
@ -44,6 +46,7 @@ namespace Sapphire::World::Action
|
|||
uint8_t m_param2;
|
||||
|
||||
uint32_t m_value;
|
||||
uint32_t m_value2;
|
||||
Common::ActionEffectResultFlag m_flag;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -354,6 +354,8 @@ bool Sapphire::Entity::Chara::checkAction()
|
|||
|
||||
void Sapphire::Entity::Chara::update( uint64_t tickCount )
|
||||
{
|
||||
updateStatusEffects();
|
||||
|
||||
if( std::difftime( static_cast< time_t >( tickCount ), m_lastTickTime ) > 3000 )
|
||||
{
|
||||
onTick();
|
||||
|
@ -557,6 +559,9 @@ void Sapphire::Entity::Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEf
|
|||
/*! \param StatusEffectPtr to be applied to the actor */
|
||||
void Sapphire::Entity::Chara::addStatusEffectById( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param )
|
||||
{
|
||||
if( hasStatusEffect( id ) ) // todo: check if we want to refresh it or discard and keep the old one
|
||||
removeSingleStatusEffectById( id, false );
|
||||
|
||||
auto effect = StatusEffect::make_StatusEffect( id, source.getAsChara(), getAsChara(), duration, 3000, m_pFw );
|
||||
effect->setParam( param );
|
||||
addStatusEffect( effect );
|
||||
|
@ -593,19 +598,19 @@ void Sapphire::Entity::Chara::statusEffectFreeSlot( uint8_t slotId )
|
|||
m_statusEffectFreeSlotQueue.push( slotId );
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Chara::removeSingleStatusEffectById( uint32_t id )
|
||||
void Sapphire::Entity::Chara::removeSingleStatusEffectById( uint32_t id, bool sendPacket )
|
||||
{
|
||||
for( auto effectIt : m_statusEffectMap )
|
||||
{
|
||||
if( effectIt.second->getId() == id )
|
||||
{
|
||||
removeStatusEffect( effectIt.first );
|
||||
removeStatusEffect( effectIt.first, sendPacket );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Chara::removeStatusEffect( uint8_t effectSlotId )
|
||||
void Sapphire::Entity::Chara::removeStatusEffect( uint8_t effectSlotId, bool sendPacket )
|
||||
{
|
||||
auto pEffectIt = m_statusEffectMap.find( effectSlotId );
|
||||
if( pEffectIt == m_statusEffectMap.end() )
|
||||
|
@ -616,7 +621,8 @@ void Sapphire::Entity::Chara::removeStatusEffect( uint8_t effectSlotId )
|
|||
auto pEffect = pEffectIt->second;
|
||||
pEffect->removeStatus();
|
||||
|
||||
sendToInRangeSet( makeActorControl( getId(), StatusEffectLose, pEffect->getId() ), isPlayer() );
|
||||
if( sendPacket )
|
||||
sendToInRangeSet( makeActorControl( getId(), StatusEffectLose, pEffect->getId() ), isPlayer() );
|
||||
|
||||
m_statusEffectMap.erase( effectSlotId );
|
||||
|
||||
|
@ -694,10 +700,10 @@ void Sapphire::Entity::Chara::updateStatusEffects()
|
|||
uint32_t duration = effect->getDuration();
|
||||
uint32_t tickRate = effect->getTickRate();
|
||||
|
||||
if( ( currentTimeMs - startTime ) > duration )
|
||||
if( duration > 0 && ( currentTimeMs - startTime ) > duration )
|
||||
{
|
||||
// remove status effect
|
||||
removeStatusEffect( effectIndex );
|
||||
removeStatusEffect( effectIndex, true );
|
||||
// break because removing invalidates iterators
|
||||
break;
|
||||
}
|
||||
|
@ -746,7 +752,15 @@ void Sapphire::Entity::Chara::updateStatusEffects()
|
|||
|
||||
bool Sapphire::Entity::Chara::hasStatusEffect( uint32_t id )
|
||||
{
|
||||
return m_statusEffectMap.find( id ) != m_statusEffectMap.end();
|
||||
//return m_statusEffectMap.find( id ) != m_statusEffectMap.end();
|
||||
for( auto effectIt : m_statusEffectMap )
|
||||
{
|
||||
if( effectIt.second->getId() == id )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t Sapphire::Entity::Chara::getLastUpdateTime() const
|
||||
|
|
|
@ -146,9 +146,9 @@ namespace Sapphire::Entity
|
|||
/// Status effect functions
|
||||
void addStatusEffect( StatusEffect::StatusEffectPtr pEffect );
|
||||
|
||||
void removeStatusEffect( uint8_t effectSlotId );
|
||||
void removeStatusEffect( uint8_t effectSlotId, bool sendPacket );
|
||||
|
||||
void removeSingleStatusEffectById( uint32_t id );
|
||||
void removeSingleStatusEffectById( uint32_t id, bool sendPacket );
|
||||
|
||||
void updateStatusEffects();
|
||||
|
||||
|
|
|
@ -1100,8 +1100,6 @@ void Sapphire::Entity::Player::update( uint64_t tickCount )
|
|||
if( !isAlive() )
|
||||
return;
|
||||
|
||||
updateStatusEffects();
|
||||
|
||||
m_lastUpdate = tickCount;
|
||||
|
||||
if( !checkAction() )
|
||||
|
|
|
@ -134,7 +134,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( FrameworkPtr pFw,
|
|||
case ClientTriggerType::RemoveStatusEffect: // Remove status (clicking it off)
|
||||
{
|
||||
// todo: check if status can be removed by client from exd
|
||||
player.removeSingleStatusEffectById( static_cast< uint32_t >( param1 ) );
|
||||
player.removeSingleStatusEffectById( static_cast< uint32_t >( param1 ), true );
|
||||
break;
|
||||
}
|
||||
case ClientTriggerType::CastCancel: // Cancel cast
|
||||
|
|
Loading…
Add table
Reference in a new issue