1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-26 06:27:45 +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;
}
void Sapphire::Action::Action::start()
{
m_startTime = Util::getTimeMs();
onStart();
}
uint32_t Sapphire::Action::Action::getCastTime() const
{
return m_castTime;
@ -112,7 +105,7 @@ void Sapphire::Action::Action::setCastTime( uint32_t castTime )
m_castTime = castTime;
}
bool Sapphire::Action::Action::isCastedAction() const
bool Sapphire::Action::Action::hasCastTime() const
{
return m_castTime > 0;
}
@ -130,7 +123,7 @@ bool Sapphire::Action::Action::update()
if( isInterrupted() )
{
onInterrupt();
castInterrupt();
return true;
}
@ -141,26 +134,28 @@ bool Sapphire::Action::Action::update()
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 false;
}
void Sapphire::Action::Action::onStart()
void Sapphire::Action::Action::castStart()
{
assert( m_pSource );
m_startTime = Util::getTimeMs();
auto player = m_pSource->getAsPlayer();
if( player )
{
player->sendDebug( "onStart()" );
player->sendDebug( "castStart()" );
}
if( isCastedAction() )
if( hasCastTime() )
{
auto castPacket = makeZonePacket< Server::FFXIVIpcActorCast >( getId() );
@ -180,10 +175,26 @@ void Sapphire::Action::Action::onStart()
}
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 );
@ -201,10 +212,10 @@ void Sapphire::Action::Action::onInterrupt()
//player->unsetStateFlag( PlayerStateFlag::Occupied1 );
player->unsetStateFlag( PlayerStateFlag::Casting );
player->sendDebug( "onInterrupt()" );
player->sendDebug( "castInterrupt()" );
}
if( isCastedAction() )
if( hasCastTime() )
{
uint8_t interruptEffect = 0;
if( m_interruptType == ActionInterruptType::DamageInterrupt )
@ -222,16 +233,16 @@ void Sapphire::Action::Action::onInterrupt()
pScriptMgr->onCastInterrupt( *m_pSource, *this );
}
void Sapphire::Action::Action::onFinish()
void Sapphire::Action::Action::castFinish()
{
assert( m_pSource );
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
auto pPlayer = m_pSource->getAsPlayer();
pPlayer->sendDebug( "onFinish()" );
pPlayer->sendDebug( "castFinish()" );
if( isCastedAction() )
if( hasCastTime() )
{
/*auto control = ActorControlPacket143( m_pTarget->getId(), ActorControlType::Unk7,
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,
Common::ActionAspect aspect )
{
// todo: scale potency into damage from stats
Common::EffectEntry entry{};
// 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 )
{
// todo: scale potency into healing from stats
Common::EffectEntry entry{};
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
* @return true if action has a cast time
*/
bool isCastedAction() const;
/*!
* @brief Starts the cast. Finishes it immediately if there is no cast time (weaponskills).
*/
void start();
bool hasCastTime() const;
void buildEffectPackets();
@ -84,9 +79,12 @@ namespace Sapphire::Action
*/
void healTarget( uint32_t potency, Entity::Chara& chara );
virtual void onStart();
virtual void onFinish();
virtual void onInterrupt();
/*!
* @brief Starts the cast. Finishes it immediately if there is no cast time (weaponskills).
*/
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
virtual bool update();

View file

@ -83,22 +83,20 @@ void World::Manager::ActionMgr::bootstrapAction( Entity::Player& player,
Data::Action& 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();
currentAction->onFinish();
// forcefully interrupt the action and reset the cooldown
currentAction->castInterrupt();
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 );
currentAction->start();
}
// todo: what do in cases of swiftcast/etc? script callback?
currentAction->castStart();
}
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 )
{
auto pEventMgr = framework()->get< World::Manager::EventMgr >();
bool didCallScript = false;
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 );
if( script )
{
didCallScript = true;
std::string objName = pEventMgr->getEventName( questId );
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 )
@ -331,8 +333,11 @@ bool Sapphire::Scripting::ScriptMgr::onCastFinish( Entity::Chara& sourceActor, A
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( currentAction.getId() );
if( script )
{
script->onCastFinish( sourceActor, currentAction );
return true;
}
return false;
}
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() );
if( script )
{
script->onCastInterrupt( sourceActor, currentAction );
return true;
}
return false;
}
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() );
if( script )
{
script->onCastStart( sourceActor, currentAction );
return true;
}
return false;
}
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() );
if( script )
{
script->onCharaHit( sourceActor, hitActor, currentAction );
return true;
}
return false;
}
bool Sapphire::Scripting::ScriptMgr::onStatusReceive( Entity::CharaPtr pActor, uint32_t effectId )