mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-25 11:07:45 +00:00
allow scripts to interrupt actions and bug fixes
This commit is contained in:
parent
deebcd76c3
commit
5ff8965ed5
16 changed files with 58 additions and 21 deletions
|
@ -28,6 +28,7 @@ public:
|
|||
else
|
||||
{
|
||||
action.disableGenericHandler();
|
||||
action.interrupt();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
else
|
||||
{
|
||||
action.disableGenericHandler();
|
||||
action.interrupt();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void onStart( Sapphire::World::Action::Action& action ) override
|
||||
void onBeforePreCheck( Sapphire::World::Action::Action& action ) override
|
||||
{
|
||||
auto effectEntry = action.getSourceChara()->getStatusEffectById( STATUS_ID_FREECURE );
|
||||
if( effectEntry.second )
|
||||
|
|
|
@ -200,11 +200,6 @@ Common::ActionInterruptType Action::Action::getInterruptType() const
|
|||
return m_interruptType;
|
||||
}
|
||||
|
||||
void Action::Action::setInterrupted( Common::ActionInterruptType type )
|
||||
{
|
||||
m_interruptType = type;
|
||||
}
|
||||
|
||||
uint32_t Action::Action::getCastTime() const
|
||||
{
|
||||
return m_castTimeMs;
|
||||
|
@ -268,7 +263,6 @@ bool Action::Action::update()
|
|||
if( !m_pTarget->isAlive() )
|
||||
{
|
||||
// interrupt the cast if target died
|
||||
setInterrupted( Common::ActionInterruptType::RegularInterrupt );
|
||||
interrupt();
|
||||
return true;
|
||||
}
|
||||
|
@ -319,15 +313,23 @@ void Action::Action::start()
|
|||
player->queuePacket( actionStartPkt );
|
||||
}
|
||||
|
||||
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
|
||||
pScriptMgr->onStart( *this );
|
||||
|
||||
// instantly finish cast if there's no cast time
|
||||
if( !hasCastTime() )
|
||||
execute();
|
||||
}
|
||||
|
||||
void Action::Action::interrupt()
|
||||
void Action::Action::interrupt( ActionInterruptType type )
|
||||
{
|
||||
if( isInterrupted() )
|
||||
return;
|
||||
|
||||
assert( m_pSource );
|
||||
|
||||
m_interruptType = type;
|
||||
|
||||
// things that aren't players don't care about cooldowns and state flags
|
||||
if( m_pSource->isPlayer() )
|
||||
{
|
||||
|
@ -437,6 +439,9 @@ void Action::Action::buildEffects()
|
|||
|
||||
pScriptMgr->onExecute( *this );
|
||||
|
||||
if( isInterrupted() )
|
||||
return;
|
||||
|
||||
if( m_disableGenericHandler || !hasValidLutEntry() )
|
||||
{
|
||||
// send any effect packet added by script or an empty one just to play animation for other players
|
||||
|
@ -571,6 +576,12 @@ void Action::Action::buildEffects()
|
|||
|
||||
bool Action::Action::preCheck()
|
||||
{
|
||||
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
|
||||
pScriptMgr->onBeforePreCheck( *this );
|
||||
|
||||
if( isInterrupted() )
|
||||
return false;
|
||||
|
||||
if( auto player = m_pSource->getAsPlayer() )
|
||||
{
|
||||
if( !playerPreCheck( *player ) )
|
||||
|
|
|
@ -41,7 +41,6 @@ namespace Sapphire::World::Action
|
|||
|
||||
bool isInterrupted() const;
|
||||
Common::ActionInterruptType getInterruptType() const;
|
||||
void setInterrupted( Common::ActionInterruptType type );
|
||||
|
||||
uint32_t getCastTime() const;
|
||||
void setCastTime( uint32_t castTime );
|
||||
|
@ -154,7 +153,7 @@ namespace Sapphire::World::Action
|
|||
*
|
||||
* m_interruptType will have the reason why the action was interrupted (eg. damage, movement, ...)
|
||||
*/
|
||||
virtual void interrupt();
|
||||
virtual void interrupt( Common::ActionInterruptType type = Common::ActionInterruptType::RegularInterrupt );
|
||||
|
||||
/*!
|
||||
* @brief Called on each player update tick
|
||||
|
|
|
@ -92,11 +92,13 @@ void Action::EventAction::execute()
|
|||
|
||||
}
|
||||
|
||||
void Action::EventAction::interrupt()
|
||||
void Action::EventAction::interrupt( Common::ActionInterruptType type )
|
||||
{
|
||||
if( !m_pSource )
|
||||
return;
|
||||
|
||||
m_interruptType = type;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
|
||||
void execute() override;
|
||||
|
||||
void interrupt() override;
|
||||
void interrupt( Common::ActionInterruptType type = Common::ActionInterruptType::None) override;
|
||||
|
||||
private:
|
||||
uint32_t m_eventId;
|
||||
|
|
|
@ -51,7 +51,7 @@ void ItemAction::execute()
|
|||
}
|
||||
}
|
||||
|
||||
void ItemAction::interrupt()
|
||||
void ItemAction::interrupt( Common::ActionInterruptType type )
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Sapphire::World::Action
|
|||
|
||||
void execute() override;
|
||||
|
||||
void interrupt() override;
|
||||
void interrupt( Common::ActionInterruptType type = Common::ActionInterruptType::None ) override;
|
||||
|
||||
private:
|
||||
void handleVFXItem();
|
||||
|
|
|
@ -101,6 +101,14 @@ void World::Manager::ActionMgr::bootstrapAction( Entity::Player& player,
|
|||
Action::ActionPtr currentAction,
|
||||
Data::Action& actionData )
|
||||
{
|
||||
for( const auto& statusIt : player.getStatusEffectMap() )
|
||||
{
|
||||
statusIt.second->onBeforeActionStart( currentAction );
|
||||
}
|
||||
|
||||
if( currentAction->isInterrupted() )
|
||||
return;
|
||||
|
||||
if( !currentAction->preCheck() )
|
||||
{
|
||||
player.sendDebug( "preCheck failed" );
|
||||
|
@ -109,11 +117,6 @@ void World::Manager::ActionMgr::bootstrapAction( Entity::Player& player,
|
|||
return;
|
||||
}
|
||||
|
||||
for( const auto& statusIt : player.getStatusEffectMap() )
|
||||
{
|
||||
statusIt.second->onBeforeActionStart( currentAction );
|
||||
}
|
||||
|
||||
if( player.getCurrentAction() )
|
||||
{
|
||||
player.sendDebug( "Skill queued: {0}", currentAction->getId() );
|
||||
|
|
|
@ -140,7 +140,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( FrameworkPtr pFw,
|
|||
case ClientTriggerType::CastCancel: // Cancel cast
|
||||
{
|
||||
if( player.getCurrentAction() )
|
||||
player.getCurrentAction()->setInterrupted( Common::ActionInterruptType::RegularInterrupt );
|
||||
player.getCurrentAction()->interrupt();
|
||||
break;
|
||||
}
|
||||
case ClientTriggerType::Examine:
|
||||
|
|
|
@ -200,7 +200,7 @@ void Sapphire::Network::GameConnection::updatePositionHandler( FrameworkPtr pFw,
|
|||
player.setPos( updatePositionPacket.data().position );
|
||||
|
||||
if( ( player.getCurrentAction() != nullptr ) && bPosChanged )
|
||||
player.getCurrentAction()->setInterrupted( Common::ActionInterruptType::RegularInterrupt );
|
||||
player.getCurrentAction()->interrupt();
|
||||
|
||||
// if no one is in range, don't bother trying to send a position update
|
||||
if( !player.hasInRangeActor() )
|
||||
|
|
|
@ -88,6 +88,10 @@ namespace Sapphire::ScriptAPI
|
|||
{
|
||||
}
|
||||
|
||||
void ActionScript::onBeforePreCheck( Sapphire::World::Action::Action& action )
|
||||
{
|
||||
}
|
||||
|
||||
void ActionScript::onStart( Sapphire::World::Action::Action& action )
|
||||
{
|
||||
}
|
||||
|
|
|
@ -140,6 +140,8 @@ namespace Sapphire::ScriptAPI
|
|||
public:
|
||||
explicit ActionScript( uint32_t actionId );
|
||||
|
||||
virtual void onBeforePreCheck( Sapphire::World::Action::Action& action );
|
||||
|
||||
virtual void onStart( Sapphire::World::Action::Action& action );
|
||||
|
||||
virtual void onExecute( Sapphire::World::Action::Action& action );
|
||||
|
|
|
@ -329,6 +329,18 @@ bool Sapphire::Scripting::ScriptMgr::onEObjHit( Sapphire::Entity::Player& player
|
|||
return didCallScript;
|
||||
}
|
||||
|
||||
bool Sapphire::Scripting::ScriptMgr::onBeforePreCheck( World::Action::Action& action )
|
||||
{
|
||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( action.getId() );
|
||||
|
||||
if( script )
|
||||
{
|
||||
script->onBeforePreCheck( action );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Sapphire::Scripting::ScriptMgr::onExecute( World::Action::Action& action )
|
||||
{
|
||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( action.getId() );
|
||||
|
|
|
@ -72,6 +72,8 @@ namespace Sapphire::Scripting
|
|||
|
||||
bool onEObjHit( Entity::Player& player, uint64_t actorId, uint32_t actionId );
|
||||
|
||||
bool onBeforePreCheck( World::Action::Action& action );
|
||||
|
||||
bool onStart( World::Action::Action& action );
|
||||
|
||||
bool onInterrupt( World::Action::Action& action );
|
||||
|
|
Loading…
Add table
Reference in a new issue