diff --git a/src/common/Common.h b/src/common/Common.h index 0c43f9e6..b69a71d5 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -615,7 +615,12 @@ namespace Sapphire::Common Common::ActionEffectType effectType; Common::ActionHitSeverityType hitSeverity; uint8_t param; - int8_t bonusPercent; // shows an additional percentage in the battle log, will not change the damage number sent & shown + /*! + * @brief Shows an additional percentage in the battle log + * + * Has no effect on what is shown and stored in value + */ + int8_t bonusPercent; uint8_t valueMultiplier; // This multiplies whatever value is in the 'value' param by 10. Possibly a workaround for big numbers uint8_t flags; int16_t value; diff --git a/src/common/Network/CommonActorControl.h b/src/common/Network/CommonActorControl.h index 77daeef4..2cc3515f 100644 --- a/src/common/Network/CommonActorControl.h +++ b/src/common/Network/CommonActorControl.h @@ -17,10 +17,10 @@ enum ActorControlType : uint16_t { /*! Toggles weapon status -> Sheathed/UnSheathed \param param1 status 0|1 */ - ToggleWeapon = 0x00, + ToggleWeapon = 0x00, /*! Toggles Autoattack status on/off \param param1 status 0|1 */ - AutoAttack = 0x01, + AutoAttack = 0x01, SetStatus = 0x02, CastStart = 0x03, ToggleAggro = 0x04, @@ -35,7 +35,14 @@ enum ActorControlType : uint16_t DeathAnimation = 0x0E, CastInterrupt = 0x0F, - ActionStart = 0x11, + /*! + * @brief Sets the cooldown for an action + * + * @param param1 Seems to be always 1 from what I've seen, needs more research + * @param param2 The actionid to set the cooldown for + * @param param3 The time in milliseconds to apply the cooldown for, 0 resets the cooldown + */ + SetActionCooldown = 0x11, StatusEffectGain = 0x14, StatusEffectLose = 0x15, diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index 85a7d6ca..ab613811 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -30,7 +30,9 @@ Sapphire::Action::Action::Action( Entity::CharaPtr caster, uint32_t actionId, m_startTime( 0 ), m_bInterrupt( false ) { - m_castTime = static_cast< uint32_t >( action->cast100ms ) * 100; + m_castTime = static_cast< uint32_t >( action->cast100ms * 100 ); + m_cooldownTime = static_cast< uint16_t >( action->recast100ms * 100 ); + m_cooldownGroup = action->cooldownGroup; m_actionCost.fill( { Common::ActionCostType::None, 0 } ); @@ -121,11 +123,12 @@ bool Sapphire::Action::Action::update() uint64_t currTime = Util::getTimeMs(); - if( !isCastedAction() || ( currTime - m_startTime ) > m_castTime ) + if( !isCastedAction() || std::difftime( currTime, m_startTime ) > m_castTime ) { onFinish(); return true; } + return false; } @@ -155,11 +158,25 @@ void Sapphire::Action::Action::onInterrupt() { assert( m_pSource ); + // things that aren't players don't care about cooldowns and state flags + if( m_pSource->isPlayer() ) + { + auto player = m_pSource->getAsPlayer(); + + auto resetCooldownPkt = makeActorControl143( m_pSource->getId(), ActorControlType::SetActionCooldown, 1, getId(), 0 ); + player->queuePacket( resetCooldownPkt ); + + // todo: reset cooldown for actual player + + // reset state flag +// player->unsetStateFlag( PlayerStateFlag::Occupied1 ); + player->unsetStateFlag( PlayerStateFlag::Casting ); + + return; + } + if( isCastedAction() ) { - //m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 ); - m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting ); - auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 1, m_id, 0 ); // Note: When cast interrupt from taking too much damage, set the last value to 1. This enables the cast interrupt effect. Example: diff --git a/src/world/Action/Action.h b/src/world/Action/Action.h index 9fe5eaad..6c8a4731 100644 --- a/src/world/Action/Action.h +++ b/src/world/Action/Action.h @@ -113,6 +113,8 @@ namespace Sapphire::Action uint64_t m_startTime; uint32_t m_castTime; + uint16_t m_cooldownTime; + uint8_t m_cooldownGroup; Entity::CharaPtr m_pSource; Entity::CharaPtr m_pTarget;