mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-23 10:17:44 +00:00
Merge cf5fbc2620
into bf3368224a
This commit is contained in:
commit
71ecd9eb6e
9 changed files with 97 additions and 37 deletions
|
@ -350,7 +350,7 @@ void Action::Action::start()
|
|||
onStart();
|
||||
|
||||
// instantly finish cast if there's no cast time
|
||||
if( !hasCastTime() )
|
||||
if( !hasCastTime() && !isInterrupted() )
|
||||
execute();
|
||||
}
|
||||
|
||||
|
@ -379,6 +379,8 @@ void Action::Action::onStart()
|
|||
void Action::Action::interrupt()
|
||||
{
|
||||
assert( m_pSource );
|
||||
if( m_interruptType == ActionInterruptType::None )
|
||||
m_interruptType = ActionInterruptType::RegularInterrupt;
|
||||
// things that aren't players don't care about cooldowns and state flags
|
||||
if( m_pSource->isPlayer() )
|
||||
{
|
||||
|
@ -522,6 +524,7 @@ void Action::Action::buildActionResults()
|
|||
|
||||
if( !m_enableGenericHandler || !hasLutEntry || m_hitActors.empty() )
|
||||
{
|
||||
scriptMgr.onAfterBuildEffect( *this );
|
||||
// send any effect packet added by script or an empty one just to play animation for other players
|
||||
m_actionResultBuilder->sendActionResults( {} );
|
||||
return;
|
||||
|
@ -592,7 +595,7 @@ void Action::Action::buildActionResults()
|
|||
}
|
||||
|
||||
// If we hit an enemy
|
||||
if( !m_hitActors.empty() && getHitChara()->getObjKind() != m_pSource->getObjKind() )
|
||||
if( !m_hitActors.empty() && getHitChara()->isHostile( *m_pSource ) )
|
||||
{
|
||||
m_pSource->removeStatusEffectByFlag( Common::StatusEffectFlag::RemoveOnSuccessfulHit );
|
||||
}
|
||||
|
@ -600,6 +603,8 @@ void Action::Action::buildActionResults()
|
|||
handleJobAction();
|
||||
handleStatusEffects();
|
||||
|
||||
scriptMgr.onAfterBuildEffect( *this );
|
||||
|
||||
m_actionResultBuilder->sendActionResults( m_hitActors );
|
||||
|
||||
// TODO: disabled, reset kills our queued actions
|
||||
|
@ -667,7 +672,6 @@ bool Action::Action::preCheck()
|
|||
|
||||
bool Action::Action::playerPreCheck( Entity::Player& player )
|
||||
{
|
||||
// lol
|
||||
if( !player.isAlive() )
|
||||
return false;
|
||||
|
||||
|
@ -675,27 +679,27 @@ bool Action::Action::playerPreCheck( Entity::Player& player )
|
|||
//if( m_actionData->data().UseClassJob == -1 /* dunno what this is in old data && !m_actionData->data().isRoleAction*/ )
|
||||
// return false;
|
||||
|
||||
if( player.getLevel() < m_actionData->data().UseClassJob )
|
||||
return false;
|
||||
//if( player.getLevel() < m_actionData->data().UseClassJob )
|
||||
// return false;
|
||||
|
||||
auto currentClass = player.getClass();
|
||||
auto actionClass = static_cast< Common::ClassJob >( m_actionData->data().UseClassJob );
|
||||
//auto currentClass = player.getClass();
|
||||
//auto actionClass = static_cast< Common::ClassJob >( m_actionData->data().UseClassJob );
|
||||
|
||||
if( actionClass != Common::ClassJob::Adventurer && currentClass != actionClass /* dunno what this is in old data && !m_actionData->data().isRoleAction*/ )
|
||||
{
|
||||
//if( actionClass != Common::ClassJob::Adventurer && currentClass != actionClass /* dunno what this is in old data && !m_actionData->data().isRoleAction*/ )
|
||||
//{
|
||||
// check if not a base class action
|
||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
//auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
|
||||
auto classJob = exdData.getRow< Excel::ClassJob >( static_cast< uint8_t >( currentClass ) );
|
||||
if( !classJob )
|
||||
return false;
|
||||
//auto classJob = exdData.getRow< Excel::ClassJob >( static_cast< uint8_t >( currentClass ) );
|
||||
//if( !classJob )
|
||||
// return false;
|
||||
|
||||
if( classJob->data().MainClass != m_actionData->data().UseClassJob )
|
||||
return false;
|
||||
}
|
||||
//if( classJob->data().MainClass != m_actionData->data().UseClassJob )
|
||||
// return false;
|
||||
//}
|
||||
|
||||
if( !m_actionData->data().SelectMyself && getTargetId() == m_pSource->getId() )
|
||||
return false;
|
||||
//if( !m_actionData->data().SelectMyself && getTargetId() == m_pSource->getId() )
|
||||
// return false;
|
||||
|
||||
// todo: does this need to check for party/alliance stuff or it's just same type?
|
||||
// todo: m_pTarget doesn't exist at this stage because we only fill it when we snapshot targets
|
||||
|
@ -885,6 +889,9 @@ void Action::Action::addDefaultActorFilters()
|
|||
|
||||
bool Action::Action::preFilterActor( Entity::GameObject& actor ) const
|
||||
{
|
||||
if( m_castType == Common::CastType::SingleTarget ) // client filters any single target action by itself
|
||||
return true;
|
||||
|
||||
auto kind = actor.getObjKind();
|
||||
auto chara = actor.getAsChara();
|
||||
|
||||
|
@ -892,20 +899,15 @@ bool Action::Action::preFilterActor( Entity::GameObject& actor ) const
|
|||
if( kind != ObjKind::BattleNpc && kind != ObjKind::Player )
|
||||
return false;
|
||||
|
||||
// todo: evaluate other actions that can hit condition (eg. sprint)
|
||||
/* if( !m_canTargetSelf && chara->getId() == m_pSource->getId() )
|
||||
return false;*/
|
||||
|
||||
if( ( m_lutEntry.potency > 0 || m_lutEntry.curePotency > 0 ) && !chara->isAlive() ) // !m_canTargetDead not working for aoe
|
||||
return false;
|
||||
|
||||
if( m_lutEntry.potency > 0 && m_pSource->getObjKind() == chara->getObjKind() ) // !m_canTargetFriendly not working for aoe
|
||||
return false;
|
||||
|
||||
if( ( m_lutEntry.potency == 0 && m_lutEntry.curePotency > 0 ) && m_pSource->getObjKind() != chara->getObjKind() ) // !m_canTargetHostile not working for aoe
|
||||
return false;
|
||||
// for any non-targeted aoe action m_canTargetSelf is always true and no other info is available
|
||||
|
||||
if( chara->isAlive() && ( m_lutEntry.curePotency > 0 || m_canTargetFriendly ) && m_pSource->isFriendly( *chara ) )
|
||||
return true;
|
||||
|
||||
if( chara->isAlive() && ( m_lutEntry.potency > 0 || m_canTargetHostile ) > 0 && m_pSource->isHostile( *chara ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector< Entity::CharaPtr >& Action::Action::getHitCharas()
|
||||
|
|
|
@ -833,8 +833,21 @@ bool Chara::isFacingTarget( const Chara& other, float threshold )
|
|||
return dot >= threshold;
|
||||
}
|
||||
|
||||
bool Sapphire::Entity::Chara::isHostile( const Chara& chara )
|
||||
{
|
||||
return m_objKind != chara.getObjKind();
|
||||
}
|
||||
|
||||
bool Sapphire::Entity::Chara::isFriendly( const Chara& chara )
|
||||
{
|
||||
return m_objKind == chara.getObjKind();
|
||||
}
|
||||
|
||||
void Chara::onTick()
|
||||
{
|
||||
if ( !isAlive() )
|
||||
return;
|
||||
|
||||
uint32_t thisTickDmg = 0;
|
||||
uint32_t thisTickHeal = 0;
|
||||
|
||||
|
|
|
@ -229,8 +229,12 @@ namespace Sapphire::Entity
|
|||
|
||||
virtual void onDamageTaken( Chara& pSource ) {};
|
||||
|
||||
virtual bool isHostile( const Chara& chara );
|
||||
|
||||
virtual void onActionHostile( CharaPtr pSource ) {};
|
||||
|
||||
virtual bool isFriendly( const Chara& chara );
|
||||
|
||||
virtual void onActionFriendly( Chara& pSource ) {};
|
||||
|
||||
virtual void onTick();
|
||||
|
|
|
@ -121,15 +121,18 @@ void ActionMgr::handleMountAction( Entity::Player& player, uint16_t mountId,
|
|||
void ActionMgr::bootstrapAction( Entity::Chara& src, Action::ActionPtr currentAction,
|
||||
Excel::ExcelStructPtr< Excel::Action > actionData )
|
||||
{
|
||||
/*
|
||||
//TODO: need to be fixed
|
||||
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
||||
scriptMgr.onBeforeBootstrap( *currentAction );
|
||||
if( currentAction->isInterrupted() )
|
||||
return;
|
||||
|
||||
// re-enable this call but disable most of the old unfixed checks as scripts can override it with special checks.
|
||||
if( !currentAction->preCheck() )
|
||||
{
|
||||
// forcefully interrupt the action and reset the cooldown
|
||||
currentAction->interrupt();
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
if( src.getCurrentAction() )
|
||||
{
|
||||
|
|
|
@ -90,9 +90,6 @@ void Sapphire::Network::GameConnection::actionRequest( const Packets::FFXIVARR_P
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Sapphire::Network::GameConnection::selectGroundActionRequest( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player )
|
||||
|
|
|
@ -77,6 +77,10 @@ namespace Sapphire::ScriptAPI
|
|||
{
|
||||
}
|
||||
|
||||
void ActionScript::onBeforeBootstrap( Sapphire::World::Action::Action& action )
|
||||
{
|
||||
}
|
||||
|
||||
void ActionScript::onStart( Sapphire::World::Action::Action& action )
|
||||
{
|
||||
}
|
||||
|
@ -89,6 +93,10 @@ namespace Sapphire::ScriptAPI
|
|||
{
|
||||
}
|
||||
|
||||
void ActionScript::onAfterBuildEffect( Sapphire::World::Action::Action& action )
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
EventScript::EventScript( uint32_t eventId ) : ScriptObject( eventId, typeid( EventScript ).hash_code() )
|
||||
|
|
|
@ -133,12 +133,16 @@ namespace Sapphire::ScriptAPI
|
|||
public:
|
||||
explicit ActionScript( uint32_t actionId );
|
||||
|
||||
virtual void onBeforeBootstrap( Sapphire::World::Action::Action& action );
|
||||
|
||||
virtual void onStart( Sapphire::World::Action::Action& action );
|
||||
|
||||
virtual void onExecute( Sapphire::World::Action::Action& action );
|
||||
|
||||
virtual void onInterrupt( Sapphire::World::Action::Action& action );
|
||||
|
||||
virtual void onAfterBuildEffect( Sapphire::World::Action::Action& action );
|
||||
|
||||
World::Manager::WarpMgr& warpMgr()
|
||||
{
|
||||
return Common::Service< World::Manager::WarpMgr >::ref();
|
||||
|
|
|
@ -598,6 +598,18 @@ bool Sapphire::Scripting::ScriptMgr::onExecute( World::Action::Action& action )
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Sapphire::Scripting::ScriptMgr::onAfterBuildEffect( World::Action::Action& action )
|
||||
{
|
||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( action.getId() );
|
||||
|
||||
if( script )
|
||||
{
|
||||
script->onAfterBuildEffect( action );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Sapphire::Scripting::ScriptMgr::onInterrupt( World::Action::Action& action )
|
||||
{
|
||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( action.getId() );
|
||||
|
@ -610,6 +622,19 @@ bool Sapphire::Scripting::ScriptMgr::onInterrupt( World::Action::Action& action
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Sapphire::Scripting::ScriptMgr::onBeforeBootstrap( World::Action::Action& action )
|
||||
{
|
||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( action.getId() );
|
||||
|
||||
if( script )
|
||||
{
|
||||
script->onBeforeBootstrap( action );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Sapphire::Scripting::ScriptMgr::onStart( World::Action::Action& action )
|
||||
{
|
||||
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( action.getId() );
|
||||
|
|
|
@ -78,12 +78,16 @@ namespace Sapphire::Scripting
|
|||
|
||||
bool onEObjHit( Entity::Player& player, uint64_t actorId, uint32_t actionId );
|
||||
|
||||
bool onBeforeBootstrap( World::Action::Action& action );
|
||||
|
||||
bool onStart( World::Action::Action& action );
|
||||
|
||||
bool onInterrupt( World::Action::Action& action );
|
||||
|
||||
bool onExecute( World::Action::Action& action );
|
||||
|
||||
bool onAfterBuildEffect( World::Action::Action& action );
|
||||
|
||||
bool onStatusReceive( Entity::CharaPtr pActor, uint32_t effectId );
|
||||
|
||||
bool onStatusTick( Entity::CharaPtr pActor, Sapphire::StatusEffect::StatusEffect& effect );
|
||||
|
|
Loading…
Add table
Reference in a new issue