mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-26 14:37:44 +00:00
cleanup action start behaviour, interrupt any unimplemented actions
This commit is contained in:
parent
b64049a94a
commit
4185ef5f38
4 changed files with 74 additions and 47 deletions
|
@ -95,13 +95,6 @@ void Sapphire::Action::Action::setInterrupted( Common::ActionInterruptType type
|
||||||
m_interruptType = type;
|
m_interruptType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sapphire::Action::Action::start()
|
|
||||||
{
|
|
||||||
m_startTime = Util::getTimeMs();
|
|
||||||
|
|
||||||
onStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t Sapphire::Action::Action::getCastTime() const
|
uint32_t Sapphire::Action::Action::getCastTime() const
|
||||||
{
|
{
|
||||||
return m_castTime;
|
return m_castTime;
|
||||||
|
@ -112,7 +105,7 @@ void Sapphire::Action::Action::setCastTime( uint32_t castTime )
|
||||||
m_castTime = castTime;
|
m_castTime = castTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sapphire::Action::Action::isCastedAction() const
|
bool Sapphire::Action::Action::hasCastTime() const
|
||||||
{
|
{
|
||||||
return m_castTime > 0;
|
return m_castTime > 0;
|
||||||
}
|
}
|
||||||
|
@ -130,7 +123,7 @@ bool Sapphire::Action::Action::update()
|
||||||
|
|
||||||
if( isInterrupted() )
|
if( isInterrupted() )
|
||||||
{
|
{
|
||||||
onInterrupt();
|
castInterrupt();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,26 +134,28 @@ bool Sapphire::Action::Action::update()
|
||||||
|
|
||||||
uint64_t currTime = Util::getTimeMs();
|
uint64_t currTime = Util::getTimeMs();
|
||||||
|
|
||||||
if( !isCastedAction() || std::difftime( currTime, m_startTime ) > m_castTime )
|
if( !hasCastTime() || std::difftime( currTime, m_startTime ) > m_castTime )
|
||||||
{
|
{
|
||||||
onFinish();
|
castFinish();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sapphire::Action::Action::onStart()
|
void Sapphire::Action::Action::castStart()
|
||||||
{
|
{
|
||||||
assert( m_pSource );
|
assert( m_pSource );
|
||||||
|
|
||||||
|
m_startTime = Util::getTimeMs();
|
||||||
|
|
||||||
auto player = m_pSource->getAsPlayer();
|
auto player = m_pSource->getAsPlayer();
|
||||||
if( player )
|
if( player )
|
||||||
{
|
{
|
||||||
player->sendDebug( "onStart()" );
|
player->sendDebug( "castStart()" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isCastedAction() )
|
if( hasCastTime() )
|
||||||
{
|
{
|
||||||
auto castPacket = makeZonePacket< Server::FFXIVIpcActorCast >( getId() );
|
auto castPacket = makeZonePacket< Server::FFXIVIpcActorCast >( getId() );
|
||||||
|
|
||||||
|
@ -180,10 +175,26 @@ void Sapphire::Action::Action::onStart()
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
|
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
|
||||||
pScriptMgr->onCastStart( *m_pSource, *this );
|
if( !pScriptMgr->onCastStart( *m_pSource, *this ) )
|
||||||
|
{
|
||||||
|
// script not implemented
|
||||||
|
castInterrupt();
|
||||||
|
|
||||||
|
if( player )
|
||||||
|
{
|
||||||
|
player->sendUrgent( "Action not implemented, missing script for actionId#{0}", getId() );
|
||||||
|
player->setCurrentAction( nullptr );
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// instantly finish cast if there's no cast time
|
||||||
|
if( !hasCastTime() )
|
||||||
|
castFinish();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sapphire::Action::Action::onInterrupt()
|
void Sapphire::Action::Action::castInterrupt()
|
||||||
{
|
{
|
||||||
assert( m_pSource );
|
assert( m_pSource );
|
||||||
|
|
||||||
|
@ -201,10 +212,10 @@ void Sapphire::Action::Action::onInterrupt()
|
||||||
//player->unsetStateFlag( PlayerStateFlag::Occupied1 );
|
//player->unsetStateFlag( PlayerStateFlag::Occupied1 );
|
||||||
player->unsetStateFlag( PlayerStateFlag::Casting );
|
player->unsetStateFlag( PlayerStateFlag::Casting );
|
||||||
|
|
||||||
player->sendDebug( "onInterrupt()" );
|
player->sendDebug( "castInterrupt()" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isCastedAction() )
|
if( hasCastTime() )
|
||||||
{
|
{
|
||||||
uint8_t interruptEffect = 0;
|
uint8_t interruptEffect = 0;
|
||||||
if( m_interruptType == ActionInterruptType::DamageInterrupt )
|
if( m_interruptType == ActionInterruptType::DamageInterrupt )
|
||||||
|
@ -222,16 +233,16 @@ void Sapphire::Action::Action::onInterrupt()
|
||||||
pScriptMgr->onCastInterrupt( *m_pSource, *this );
|
pScriptMgr->onCastInterrupt( *m_pSource, *this );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sapphire::Action::Action::onFinish()
|
void Sapphire::Action::Action::castFinish()
|
||||||
{
|
{
|
||||||
assert( m_pSource );
|
assert( m_pSource );
|
||||||
|
|
||||||
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
|
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
|
||||||
|
|
||||||
auto pPlayer = m_pSource->getAsPlayer();
|
auto pPlayer = m_pSource->getAsPlayer();
|
||||||
pPlayer->sendDebug( "onFinish()" );
|
pPlayer->sendDebug( "castFinish()" );
|
||||||
|
|
||||||
if( isCastedAction() )
|
if( hasCastTime() )
|
||||||
{
|
{
|
||||||
/*auto control = ActorControlPacket143( m_pTarget->getId(), ActorControlType::Unk7,
|
/*auto control = ActorControlPacket143( m_pTarget->getId(), ActorControlType::Unk7,
|
||||||
0x219, m_id, m_id, m_id, m_id );
|
0x219, m_id, m_id, m_id, m_id );
|
||||||
|
@ -286,6 +297,8 @@ void Sapphire::Action::Action::buildEffectPackets()
|
||||||
void Sapphire::Action::Action::damageTarget( uint32_t potency, Entity::Chara& chara,
|
void Sapphire::Action::Action::damageTarget( uint32_t potency, Entity::Chara& chara,
|
||||||
Common::ActionAspect aspect )
|
Common::ActionAspect aspect )
|
||||||
{
|
{
|
||||||
|
// todo: scale potency into damage from stats
|
||||||
|
|
||||||
Common::EffectEntry entry{};
|
Common::EffectEntry entry{};
|
||||||
|
|
||||||
// todo: handle cases where the action misses/is blocked?
|
// todo: handle cases where the action misses/is blocked?
|
||||||
|
@ -318,6 +331,8 @@ void Sapphire::Action::Action::damageTarget( uint32_t potency, Entity::Chara& ch
|
||||||
|
|
||||||
void Sapphire::Action::Action::healTarget( uint32_t potency, Entity::Chara& chara )
|
void Sapphire::Action::Action::healTarget( uint32_t potency, Entity::Chara& chara )
|
||||||
{
|
{
|
||||||
|
// todo: scale potency into healing from stats
|
||||||
|
|
||||||
Common::EffectEntry entry{};
|
Common::EffectEntry entry{};
|
||||||
|
|
||||||
entry.effectType = Common::ActionEffectType::Heal;
|
entry.effectType = Common::ActionEffectType::Heal;
|
||||||
|
|
|
@ -61,12 +61,7 @@ namespace Sapphire::Action
|
||||||
* @brief Tests whether the action is instantly usable or has a cast assoc'd with it
|
* @brief Tests whether the action is instantly usable or has a cast assoc'd with it
|
||||||
* @return true if action has a cast time
|
* @return true if action has a cast time
|
||||||
*/
|
*/
|
||||||
bool isCastedAction() const;
|
bool hasCastTime() const;
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief Starts the cast. Finishes it immediately if there is no cast time (weaponskills).
|
|
||||||
*/
|
|
||||||
void start();
|
|
||||||
|
|
||||||
void buildEffectPackets();
|
void buildEffectPackets();
|
||||||
|
|
||||||
|
@ -84,9 +79,12 @@ namespace Sapphire::Action
|
||||||
*/
|
*/
|
||||||
void healTarget( uint32_t potency, Entity::Chara& chara );
|
void healTarget( uint32_t potency, Entity::Chara& chara );
|
||||||
|
|
||||||
virtual void onStart();
|
/*!
|
||||||
virtual void onFinish();
|
* @brief Starts the cast. Finishes it immediately if there is no cast time (weaponskills).
|
||||||
virtual void onInterrupt();
|
*/
|
||||||
|
virtual void castStart();
|
||||||
|
virtual void castFinish();
|
||||||
|
virtual void castInterrupt();
|
||||||
|
|
||||||
// update action, if returns true, action is done and has to be removed from the actor
|
// update action, if returns true, action is done and has to be removed from the actor
|
||||||
virtual bool update();
|
virtual bool update();
|
||||||
|
|
|
@ -83,22 +83,20 @@ void World::Manager::ActionMgr::bootstrapAction( Entity::Player& player,
|
||||||
Data::Action& actionData )
|
Data::Action& actionData )
|
||||||
{
|
{
|
||||||
if( !canPlayerUseAction( player, *currentAction, actionData ) )
|
if( !canPlayerUseAction( player, *currentAction, actionData ) )
|
||||||
return;
|
|
||||||
|
|
||||||
// instantly cast and finish actions that have no cast time
|
|
||||||
// not worth adding it to the player
|
|
||||||
// todo: what do in cases of swiftcast/etc? script callback?
|
|
||||||
if( !currentAction->isCastedAction() )
|
|
||||||
{
|
{
|
||||||
currentAction->start();
|
// forcefully interrupt the action and reset the cooldown
|
||||||
currentAction->onFinish();
|
currentAction->castInterrupt();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, set the action on the player and start it
|
// if we have a cast time we want to associate the action with the player so update is called
|
||||||
|
if( currentAction->hasCastTime() )
|
||||||
|
{
|
||||||
player.setCurrentAction( currentAction );
|
player.setCurrentAction( currentAction );
|
||||||
currentAction->start();
|
}
|
||||||
|
|
||||||
|
// todo: what do in cases of swiftcast/etc? script callback?
|
||||||
|
currentAction->castStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::Manager::ActionMgr::canPlayerUseAction( Entity::Player& player,
|
bool World::Manager::ActionMgr::canPlayerUseAction( Entity::Player& player,
|
||||||
|
|
|
@ -303,6 +303,7 @@ bool Sapphire::Scripting::ScriptMgr::onBNpcKill( Entity::Player& player, uint16_
|
||||||
bool Sapphire::Scripting::ScriptMgr::onEObjHit( Sapphire::Entity::Player& player, uint64_t actorId )
|
bool Sapphire::Scripting::ScriptMgr::onEObjHit( Sapphire::Entity::Player& player, uint64_t actorId )
|
||||||
{
|
{
|
||||||
auto pEventMgr = framework()->get< World::Manager::EventMgr >();
|
auto pEventMgr = framework()->get< World::Manager::EventMgr >();
|
||||||
|
bool didCallScript = false;
|
||||||
|
|
||||||
for( size_t i = 0; i < 30; i++ )
|
for( size_t i = 0; i < 30; i++ )
|
||||||
{
|
{
|
||||||
|
@ -315,6 +316,7 @@ bool Sapphire::Scripting::ScriptMgr::onEObjHit( Sapphire::Entity::Player& player
|
||||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::EventScript >( questId );
|
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::EventScript >( questId );
|
||||||
if( script )
|
if( script )
|
||||||
{
|
{
|
||||||
|
didCallScript = true;
|
||||||
std::string objName = pEventMgr->getEventName( questId );
|
std::string objName = pEventMgr->getEventName( questId );
|
||||||
|
|
||||||
player.sendDebug( "Calling: {0}.onEObjHit actorId#{1}", objName, actorId );
|
player.sendDebug( "Calling: {0}.onEObjHit actorId#{1}", objName, actorId );
|
||||||
|
@ -323,7 +325,7 @@ bool Sapphire::Scripting::ScriptMgr::onEObjHit( Sapphire::Entity::Player& player
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return didCallScript;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sapphire::Scripting::ScriptMgr::onCastFinish( Entity::Chara& sourceActor, Action::Action& currentAction )
|
bool Sapphire::Scripting::ScriptMgr::onCastFinish( Entity::Chara& sourceActor, Action::Action& currentAction )
|
||||||
|
@ -331,8 +333,11 @@ bool Sapphire::Scripting::ScriptMgr::onCastFinish( Entity::Chara& sourceActor, A
|
||||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( currentAction.getId() );
|
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( currentAction.getId() );
|
||||||
|
|
||||||
if( script )
|
if( script )
|
||||||
|
{
|
||||||
script->onCastFinish( sourceActor, currentAction );
|
script->onCastFinish( sourceActor, currentAction );
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sapphire::Scripting::ScriptMgr::onCastInterrupt( Entity::Chara& sourceActor, Action::Action& currentAction )
|
bool Sapphire::Scripting::ScriptMgr::onCastInterrupt( Entity::Chara& sourceActor, Action::Action& currentAction )
|
||||||
|
@ -340,8 +345,11 @@ bool Sapphire::Scripting::ScriptMgr::onCastInterrupt( Entity::Chara& sourceActor
|
||||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( currentAction.getId() );
|
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( currentAction.getId() );
|
||||||
|
|
||||||
if( script )
|
if( script )
|
||||||
|
{
|
||||||
script->onCastInterrupt( sourceActor, currentAction );
|
script->onCastInterrupt( sourceActor, currentAction );
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sapphire::Scripting::ScriptMgr::onCastStart( Entity::Chara& sourceActor, Action::Action& currentAction )
|
bool Sapphire::Scripting::ScriptMgr::onCastStart( Entity::Chara& sourceActor, Action::Action& currentAction )
|
||||||
|
@ -349,8 +357,12 @@ bool Sapphire::Scripting::ScriptMgr::onCastStart( Entity::Chara& sourceActor, Ac
|
||||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( currentAction.getId() );
|
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( currentAction.getId() );
|
||||||
|
|
||||||
if( script )
|
if( script )
|
||||||
|
{
|
||||||
script->onCastStart( sourceActor, currentAction );
|
script->onCastStart( sourceActor, currentAction );
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sapphire::Scripting::ScriptMgr::onCharaHit( Entity::Chara& sourceActor, Entity::Chara& hitActor,
|
bool Sapphire::Scripting::ScriptMgr::onCharaHit( Entity::Chara& sourceActor, Entity::Chara& hitActor,
|
||||||
|
@ -359,8 +371,12 @@ bool Sapphire::Scripting::ScriptMgr::onCharaHit( Entity::Chara& sourceActor, Ent
|
||||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( currentAction.getId() );
|
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( currentAction.getId() );
|
||||||
|
|
||||||
if( script )
|
if( script )
|
||||||
|
{
|
||||||
script->onCharaHit( sourceActor, hitActor, currentAction );
|
script->onCharaHit( sourceActor, hitActor, currentAction );
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sapphire::Scripting::ScriptMgr::onStatusReceive( Entity::CharaPtr pActor, uint32_t effectId )
|
bool Sapphire::Scripting::ScriptMgr::onStatusReceive( Entity::CharaPtr pActor, uint32_t effectId )
|
||||||
|
|
Loading…
Add table
Reference in a new issue