1
Fork 0
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:
NotAdam 2019-02-11 00:40:00 +11:00
parent b64049a94a
commit 4185ef5f38
4 changed files with 74 additions and 47 deletions

View file

@ -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;

View file

@ -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();

View file

@ -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,

View file

@ -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 )