1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-27 06:47:45 +00:00

add eobj action handling

This commit is contained in:
NotAdam 2019-02-10 22:13:47 +11:00
parent 7ccea66120
commit 2e9e127f56
7 changed files with 88 additions and 10 deletions

View file

@ -28,10 +28,11 @@ Sapphire::Action::Action::Action( Entity::CharaPtr caster, uint32_t actionId,
m_pFw( std::move( fw ) ),
m_id( actionId ),
m_startTime( 0 ),
m_interruptType( Common::ActionInterruptType::None )
m_interruptType( Common::ActionInterruptType::None ),
m_hasResidentTarget( false )
{
m_castTime = static_cast< uint32_t >( action->cast100ms * 100 );
m_cooldownTime = static_cast< uint16_t >( action->recast100ms * 100 );
m_recastTime = static_cast< uint16_t >( action->recast100ms * 100 );
m_cooldownGroup = action->cooldownGroup;
m_actionCost.fill( { Common::ActionCostType::None, 0 } );
@ -67,6 +68,17 @@ void Sapphire::Action::Action::setTargetChara( Sapphire::Entity::CharaPtr chara
m_targetId = chara->getId();
}
void Sapphire::Action::Action::setResidentTargetId( uint64_t targetId )
{
m_targetId = targetId;
m_hasResidentTarget = true;
}
bool Sapphire::Action::Action::hasResidentTarget() const
{
return m_hasResidentTarget;
}
Sapphire::Entity::CharaPtr Sapphire::Action::Action::getTargetChara() const
{
return m_pTarget;
@ -121,6 +133,11 @@ bool Sapphire::Action::Action::update()
return true;
}
if( !hasResidentTarget() )
{
// todo: check if the target is still in range
}
uint64_t currTime = Util::getTimeMs();
if( !isCastedAction() || std::difftime( currTime, m_startTime ) > m_castTime )
@ -136,6 +153,12 @@ void Sapphire::Action::Action::onStart()
{
assert( m_pSource );
auto player = m_pSource->getAsPlayer();
if( player )
{
player->sendDebug( "onStart()" );
}
if( isCastedAction() )
{
auto castPacket = makeZonePacket< Server::FFXIVIpcActorCast >( getId() );
@ -149,10 +172,9 @@ void Sapphire::Action::Action::onStart()
m_pSource->sendToInRangeSet( castPacket, true );
if( auto player = m_pSource->getAsPlayer() )
if( player )
{
player->setStateFlag( PlayerStateFlag::Casting );
player->sendDebug( "onStart()" );
}
}
}
@ -208,8 +230,16 @@ void Sapphire::Action::Action::onFinish()
0x219, m_id, m_id, m_id, m_id );
m_pSource->sendToInRangeSet( control, true );*/
}
if( !hasResidentTarget() )
{
pScriptMgr->onCastFinish( *pPlayer, m_pTarget, m_id );
}
else
{
pScriptMgr->onEObjHit( *pPlayer, m_targetId );
}
}
void Sapphire::Action::Action::buildEffectPacket()

View file

@ -37,6 +37,7 @@ namespace Sapphire::Action
Common::FFXIVARR_POSITION3 getPos() const;
void setTargetChara( Entity::CharaPtr chara );
void setResidentTargetId( uint64_t targetId );
Entity::CharaPtr getTargetChara() const;
Entity::CharaPtr getActionSource() const;
@ -46,6 +47,14 @@ namespace Sapphire::Action
uint32_t getCastTime() const;
void setCastTime( uint32_t castTime );
/*!
* @brief Checks if the action *may* target a resident instead of an actor
* This checks if m_pTarget is nullptr but m_targetId is set
*
* @return true if the target *may* be a resident and not an actor, otherwise false.
*/
bool hasResidentTarget() const;
const ActionCostArray& getCostArray() const;
/*!
@ -113,12 +122,13 @@ namespace Sapphire::Action
uint64_t m_startTime;
uint32_t m_castTime;
uint16_t m_cooldownTime;
uint16_t m_recastTime;
uint8_t m_cooldownGroup;
Entity::CharaPtr m_pSource;
Entity::CharaPtr m_pTarget;
uint64_t m_targetId;
bool m_hasResidentTarget;
Common::ActionInterruptType m_interruptType;

View file

@ -38,12 +38,16 @@ void World::Manager::ActionMgr::handleTargetedPlayerAction( Entity::Player& play
if( targetId != player.getId() )
{
auto target = player.lookupTargetById( targetId );
if( auto chara = target->getAsChara() )
if( !target )
{
// an eobj?
player.sendDebug( "Unable to find actor for targetId#{0}, passing through to event scripts...", targetId );
action->setResidentTargetId( targetId );
}
else if( auto chara = target->getAsChara() )
{
action->setTargetChara( chara );
}
else
{
// maybe an eobj? wat do?
}
}
bootstrapAction( player, action, *actionData );

View file

@ -141,6 +141,10 @@ namespace Sapphire::ScriptAPI
{
}
void EventScript::onEObjHit( Sapphire::Entity::Player& player, uint64_t actorId )
{
}
///////////////////////////////////////////////////////////////////
EventObjectScript::EventObjectScript( uint32_t eobjId ) :

View file

@ -180,6 +180,8 @@ namespace Sapphire::ScriptAPI
virtual void onEventHandlerTradeReturn( Sapphire::Entity::Player& player, uint32_t eventId, uint16_t subEvent, uint16_t param,
uint32_t catalogId );
virtual void onEObjHit( Sapphire::Entity::Player& player, uint64_t actorId );
};
/*!

View file

@ -299,6 +299,32 @@ bool Sapphire::Scripting::ScriptMgr::onBNpcKill( Entity::Player& player, uint16_
return true;
}
bool Sapphire::Scripting::ScriptMgr::onEObjHit( Sapphire::Entity::Player& player, uint64_t actorId )
{
auto pEventMgr = framework()->get< World::Manager::EventMgr >();
for( size_t i = 0; i < 30; i++ )
{
auto activeQuests = player.getQuestActive( static_cast< uint16_t >( i ) );
if( !activeQuests )
continue;
uint32_t questId = activeQuests->c.questId | Event::EventHandler::EventHandlerType::Quest << 16;
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::EventScript >( questId );
if( script )
{
std::string objName = pEventMgr->getEventName( questId );
player.sendDebug( "Calling: {0}.onEObjHit actorId#{1}", objName, actorId );
script->onEObjHit( player, actorId );
}
}
return true;
}
bool Sapphire::Scripting::ScriptMgr::onCastFinish( Entity::Player& player, Entity::CharaPtr pTarget, uint32_t actionId )
{
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( actionId );

View file

@ -70,6 +70,8 @@ namespace Sapphire::Scripting
bool onBNpcKill( Entity::Player& player, uint16_t nameId );
bool onEObjHit( Entity::Player& player, uint64_t actorId );
bool onCastFinish( Entity::Player& pPlayer, Entity::CharaPtr pTarget, uint32_t actionId );
bool onStatusReceive( Entity::CharaPtr pActor, uint32_t effectId );