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

Converted autoattacks to the action system

This commit is contained in:
Mordred 2023-03-11 20:52:52 +01:00
parent 7c4a053bea
commit 5cc7b0c87b
15 changed files with 93 additions and 100 deletions

View file

@ -1,7 +1,7 @@
{ {
"7": { "7": {
"name": "Attack", "name": "Attack",
"potency": 0, "potency": 110,
"comboPotency": 0, "comboPotency": 0,
"flankPotency": 0, "flankPotency": 0,
"frontPotency": 0, "frontPotency": 0,
@ -16,7 +16,7 @@
}, },
"8": { "8": {
"name": "Shot", "name": "Shot",
"potency": 0, "potency": 100,
"comboPotency": 0, "comboPotency": 0,
"flankPotency": 0, "flankPotency": 0,
"frontPotency": 0, "frontPotency": 0,

View file

@ -333,9 +333,11 @@ void Action::Action::start()
// todo: m_recastTimeMs needs to be adjusted for player sks/sps // todo: m_recastTimeMs needs to be adjusted for player sks/sps
auto actionStartPkt = makeActorControlSelf( m_pSource->getId(), ActorControlType::ActionStart, m_cooldownGroup, getId(), m_recastTimeMs / 10 ); auto actionStartPkt = makeActorControlSelf( m_pSource->getId(), ActorControlType::ActionStart, m_cooldownGroup, getId(), m_recastTimeMs / 10 );
player->setRecastGroup( m_cooldownGroup, static_cast< float >( m_castTimeMs ) / 1000.f ); if( player )
{
server().queueForPlayer( player->getCharacterId(), actionStartPkt ); player->setRecastGroup( m_cooldownGroup, static_cast< float >( m_castTimeMs ) / 1000.f );
server().queueForPlayer( player->getCharacterId(), actionStartPkt );
}
onStart(); onStart();
@ -369,7 +371,6 @@ void Action::Action::onStart()
void Action::Action::interrupt() void Action::Action::interrupt()
{ {
assert( m_pSource ); assert( m_pSource );
// things that aren't players don't care about cooldowns and state flags // things that aren't players don't care about cooldowns and state flags
if( m_pSource->isPlayer() ) if( m_pSource->isPlayer() )
{ {
@ -409,7 +410,6 @@ void Action::Action::onInterrupt()
void Action::Action::execute() void Action::Action::execute()
{ {
assert( m_pSource ); assert( m_pSource );
// subtract costs first, if somehow the caster stops meeting those requirements cancel the cast // subtract costs first, if somehow the caster stops meeting those requirements cancel the cast
if( !consumeResources() ) if( !consumeResources() )
{ {
@ -464,6 +464,10 @@ std::pair< uint32_t, Common::ActionHitSeverityType > Action::Action::calcDamage(
wepDmg = item->getMagicalDmg(); wepDmg = item->getMagicalDmg();
else else
wepDmg = item->getPhysicalDmg(); wepDmg = item->getPhysicalDmg();
// is auto attack
if( getId() == 7 || getId() == 8 )
return Math::CalcStats::calcAutoAttackDamage( *m_pSource->getAsPlayer() );
} }
return Math::CalcStats::calcActionDamage( *m_pSource, potency, wepDmg ); return Math::CalcStats::calcActionDamage( *m_pSource, potency, wepDmg );
@ -574,7 +578,6 @@ void Action::Action::buildActionResults()
shouldRestoreMP = false; shouldRestoreMP = false;
} }
} }
m_actionResultBuilder->sendActionResults( m_hitActors ); m_actionResultBuilder->sendActionResults( m_hitActors );
// TODO: disabled, reset kills our queued actions // TODO: disabled, reset kills our queued actions

View file

@ -36,6 +36,7 @@
#include <Manager/PlayerMgr.h> #include <Manager/PlayerMgr.h>
#include <Manager/TaskMgr.h> #include <Manager/TaskMgr.h>
#include <Manager/MgrUtil.h> #include <Manager/MgrUtil.h>
#include <Manager/ActionMgr.h>
#include <Script/ScriptMgr.h> #include <Script/ScriptMgr.h>
#include <Task/RemoveBNpcTask.h> #include <Task/RemoveBNpcTask.h>
#include <Task/FadeBNpcTask.h> #include <Task/FadeBNpcTask.h>
@ -643,6 +644,8 @@ void BNpc::update( uint64_t tickCount )
if( !pNaviProvider ) if( !pNaviProvider )
return; return;
checkAction();
switch( m_state ) switch( m_state )
{ {
case BNpcState::Dead: case BNpcState::Dead:
@ -803,7 +806,7 @@ void BNpc::restHp()
m_hp = getMaxHp(); m_hp = getMaxHp();
} }
sendHudParam(); Network::Util::Packet::sendHudParam( *this );
} }
void BNpc::onActionHostile( CharaPtr pSource ) void BNpc::onActionHostile( CharaPtr pSource )
@ -963,6 +966,8 @@ void BNpc::autoAttack( CharaPtr pTarget )
{ {
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref(); auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
auto pZone = teriMgr.getTerritoryByGuId( getTerritoryId() ); auto pZone = teriMgr.getTerritoryByGuId( getTerritoryId() );
auto& actionMgr = Common::Service< World::Manager::ActionMgr >::ref();
auto& exdData = Common::Service< Data::ExdData >::ref();
uint64_t tick = Util::getTimeMs(); uint64_t tick = Util::getTimeMs();
@ -972,26 +977,7 @@ void BNpc::autoAttack( CharaPtr pTarget )
pTarget->onActionHostile( getAsChara() ); pTarget->onActionHostile( getAsChara() );
m_lastAttack = tick; m_lastAttack = tick;
srand( static_cast< uint32_t >( tick ) ); srand( static_cast< uint32_t >( tick ) );
actionMgr.handleTargetedAction( *this, 7, exdData.getRow< Excel::Action >( 7 ), pTarget->getId(), 0 );
auto damage = Math::CalcStats::calcAutoAttackDamage( *this );
//damage.first = 1;
auto effectPacket = std::make_shared< EffectPacket1 >( getId(), pTarget->getId(), 7 );
effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) );
Common::CalcResultParam effectEntry{};
effectEntry.Value = static_cast< int16_t >( damage.first );
effectEntry.Type = ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP;
effectEntry.Arg0 = 3;
effectEntry.Arg1 = 7;
auto resultId = pZone->getNextActionResultId();
effectPacket->setResultId( resultId );
effectPacket->addTargetEffect( effectEntry );
server().queueForPlayers( getInRangePlayerIds(), effectPacket );
pTarget->takeDamage( static_cast< uint16_t >( damage.first ) );
auto& taskMgr = Common::Service< World::Manager::TaskMgr >::ref();
//taskMgr.queueTask( Sapphire::World::makeActionIntegrityTask( resultId, pTarget, 500 ) );
} }
} }

View file

@ -285,6 +285,16 @@ void Chara::die()
Network::Util::Packet::sendActorControl( getInRangePlayerIds( selfNeedsUpdate ), getId(), DeathAnimation ); Network::Util::Packet::sendActorControl( getInRangePlayerIds( selfNeedsUpdate ), getId(), DeathAnimation );
} }
uint64_t Chara::getLastAttack() const
{
return m_lastAttack;
}
void Chara::setLastAttack( uint64_t tickCount )
{
m_lastAttack = tickCount;
}
/*! /*!
Calculates and sets the rotation to look towards a specified Calculates and sets the rotation to look towards a specified
position position
@ -426,18 +436,6 @@ void Chara::restoreMP( uint32_t amount )
m_mp += amount; m_mp += amount;
} }
/*!
Send an HpMpTp update to players in range ( and potentially to self )
TODO: poor naming, should be changed. Status is not HP. Also should be virtual
so players can have their own version and we can abolish the param.
\param true if the update should also be sent to the actor ( player ) himself
*/
void Chara::sendHudParam()
{
Network::Util::Packet::sendHudParam( *this );
}
/*! \return ActionPtr of the currently registered action, or nullptr */ /*! \return ActionPtr of the currently registered action, or nullptr */
Action::ActionPtr Chara::getCurrentAction() const Action::ActionPtr Chara::getCurrentAction() const
{ {

View file

@ -203,6 +203,10 @@ namespace Sapphire::Entity
void die(); void die();
uint64_t getLastAttack() const;
void setLastAttack( uint64_t tickCount );
Common::ActorStatus getStatus() const; Common::ActorStatus getStatus() const;
void setStatus( Common::ActorStatus status ); void setStatus( Common::ActorStatus status );
@ -223,8 +227,6 @@ namespace Sapphire::Entity
virtual uint8_t getLevel() const; virtual uint8_t getLevel() const;
virtual void sendHudParam();
virtual void takeDamage( uint32_t damage ); virtual void takeDamage( uint32_t damage );
virtual void heal( uint32_t amount ); virtual void heal( uint32_t amount );

View file

@ -923,16 +923,6 @@ void Player::update( uint64_t tickCount )
Chara::update( tickCount ); Chara::update( tickCount );
} }
uint64_t Player::getLastAttack() const
{
return m_lastAttack;
}
void Player::setLastAttack( uint64_t tickCount )
{
m_lastAttack = tickCount;
}
void Player::freePlayerSpawnId( uint32_t actorId ) void Player::freePlayerSpawnId( uint32_t actorId )
{ {
auto spawnId = m_actorSpawnIndexAllocator.freeUsedSpawnIndex( actorId ); auto spawnId = m_actorSpawnIndexAllocator.freeUsedSpawnIndex( actorId );
@ -1295,9 +1285,9 @@ void Player::autoAttack( CharaPtr pTarget )
auto& RNGMgr = Common::Service< World::Manager::RNGMgr >::ref(); auto& RNGMgr = Common::Service< World::Manager::RNGMgr >::ref();
auto variation = static_cast< uint32_t >( RNGMgr.getRandGenerator< float >( 0, 3 ).next() ); auto variation = static_cast< uint32_t >( RNGMgr.getRandGenerator< float >( 0, 3 ).next() );
//actionMgr.handleTargetedPlayerAction( *this, 7, exdData.getRow< Excel::Action >( 7 ), pTarget->getId(), 0 ); actionMgr.handleTargetedAction( *this, 7, exdData.getRow< Excel::Action >( 7 ), pTarget->getId(), 0 );
auto damage = Math::CalcStats::calcAutoAttackDamage( *this ); /* auto damage = Math::CalcStats::calcAutoAttackDamage( *this );
auto effectPacket = std::make_shared< EffectPacket1 >( getId(), pTarget->getId(), 7 ); auto effectPacket = std::make_shared< EffectPacket1 >( getId(), pTarget->getId(), 7 );
@ -1320,7 +1310,7 @@ void Player::autoAttack( CharaPtr pTarget )
pTarget->takeDamage( static_cast< uint32_t >( damage.first ) ); pTarget->takeDamage( static_cast< uint32_t >( damage.first ) );
auto& taskMgr = Common::Service< TaskMgr >::ref(); auto& taskMgr = Common::Service< TaskMgr >::ref();*/
//taskMgr.queueTask( Sapphire::World::makeActionIntegrityTask( resultId, pTarget, 500 ) ); //taskMgr.queueTask( Sapphire::World::makeActionIntegrityTask( resultId, pTarget, 500 ) );
} }

View file

@ -83,12 +83,6 @@ namespace Sapphire::Entity
/*! Event called on every session iteration */ /*! Event called on every session iteration */
void update( uint64_t tickCount ) override; void update( uint64_t tickCount ) override;
/*! get last attack tick for player */
uint64_t getLastAttack() const;
/*! set last attack tick for player */
void setLastAttack( uint64_t tickCount );
// Quest // Quest
////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////
/*! load data for currently active quests */ /*! load data for currently active quests */

View file

@ -59,13 +59,13 @@ void ActionMgr::handleItemManipulationAction( Entity::Player& player, uint32_t a
action->start(); action->start();
} }
void ActionMgr::handleTargetedPlayerAction( Entity::Player& player, uint32_t actionId, void ActionMgr::handleTargetedAction( Entity::Chara& src, uint32_t actionId,
Excel::ExcelStructPtr< Excel::Action > actionData, uint64_t targetId, uint16_t requestId ) Excel::ExcelStructPtr< Excel::Action > actionData, uint64_t targetId, uint16_t requestId )
{ {
auto action = Action::make_Action( player.getAsPlayer(), actionId, requestId, actionData ); auto action = Action::make_Action( src.getAsChara(), actionId, requestId, actionData );
action->setTargetId( targetId ); action->setTargetId( targetId );
action->setPos( player.getPos() ); action->setPos( src.getPos() );
if( !action->init() ) if( !action->init() )
return; return;
@ -77,7 +77,7 @@ void ActionMgr::handleTargetedPlayerAction( Entity::Player& player, uint32_t act
return; return;
} }
bootstrapAction( player, action, actionData ); bootstrapAction( src, action, actionData );
} }
void ActionMgr::handleItemAction( Sapphire::Entity::Player& player, uint32_t itemId, void ActionMgr::handleItemAction( Sapphire::Entity::Player& player, uint32_t itemId,
@ -124,7 +124,7 @@ void ActionMgr::handleMountAction( Entity::Player& player, uint16_t mountId,
bootstrapAction( player, action, actionData ); bootstrapAction( player, action, actionData );
} }
void ActionMgr::bootstrapAction( Entity::Player& player, Action::ActionPtr currentAction, void ActionMgr::bootstrapAction( Entity::Chara& src, Action::ActionPtr currentAction,
Excel::ExcelStructPtr< Excel::Action > actionData ) Excel::ExcelStructPtr< Excel::Action > actionData )
{ {
/* /*
@ -137,20 +137,25 @@ void ActionMgr::bootstrapAction( Entity::Player& player, Action::ActionPtr curre
} }
*/ */
if( player.getCurrentAction() ) if( src.getCurrentAction() )
{ {
PlayerMgr::sendDebug( player, "Skill queued: {0}", currentAction->getId() ); if( src.isPlayer() )
player.setQueuedAction( currentAction ); {
auto& player = *src.getAsPlayer();
PlayerMgr::sendDebug( player, "Skill queued: {0}", currentAction->getId() );
player.setQueuedAction( currentAction );
}
} }
else else
{ {
// if we have a cast time we want to associate the action with the player so update is called // if we have a cast time we want to associate the action with the player so update is called
if( currentAction->hasCastTime() ) if( currentAction->hasCastTime() )
player.setCurrentAction( currentAction ); src.setCurrentAction( currentAction );
// todo: what do in cases of swiftcast/etc? script callback? // todo: what do in cases of swiftcast/etc? script callback?
currentAction->start(); currentAction->start();
player.setLastAttack( Common::Util::getTimeMs() ); src.setLastAttack( Common::Util::getTimeMs() );
} }
} }

View file

@ -24,8 +24,8 @@ namespace Sapphire::World::Manager
void handleItemManipulationAction( Entity::Player& player, uint32_t actionId, Excel::ExcelStructPtr< Excel::Action > actionData, uint16_t sequence ); void handleItemManipulationAction( Entity::Player& player, uint32_t actionId, Excel::ExcelStructPtr< Excel::Action > actionData, uint16_t sequence );
void handleTargetedPlayerAction( Entity::Player& player, uint32_t actionId, void handleTargetedAction( Entity::Chara& chara, uint32_t actionId,
std::shared_ptr< Excel::ExcelStruct< Excel::Action > > actionData, uint64_t targetId, uint16_t requestId ); std::shared_ptr< Excel::ExcelStruct< Excel::Action > > actionData, uint64_t targetId, uint16_t requestId );
void handlePlacedPlayerAction( Entity::Player& player, uint32_t actionId, void handlePlacedPlayerAction( Entity::Player& player, uint32_t actionId,
std::shared_ptr< Excel::ExcelStruct< Excel::Action > > actionData, Common::FFXIVARR_POSITION3 pos, uint16_t sequence ); std::shared_ptr< Excel::ExcelStruct< Excel::Action > > actionData, Common::FFXIVARR_POSITION3 pos, uint16_t sequence );
@ -40,7 +40,7 @@ namespace Sapphire::World::Manager
bool actionHasCastTime( uint32_t actionId ); bool actionHasCastTime( uint32_t actionId );
private: private:
void bootstrapAction( Entity::Player& player, Action::ActionPtr currentAction, std::shared_ptr< Excel::ExcelStruct< Excel::Action > > actionData ); void bootstrapAction( Entity::Chara& src, Action::ActionPtr currentAction, std::shared_ptr< Excel::ExcelStruct< Excel::Action > > actionData );
// item action handlers // item action handlers
void handleItemActionVFX( Entity::Player& player, uint32_t itemId, uint16_t vfxId ); void handleItemActionVFX( Entity::Player& player, uint32_t itemId, uint16_t vfxId );

View file

@ -52,7 +52,7 @@ void Sapphire::Network::GameConnection::actionRequest( const Packets::FFXIVARR_P
if( category == Common::ActionCategory::ItemManipulation ) if( category == Common::ActionCategory::ItemManipulation )
actionMgr.handleItemManipulationAction( player, actionId, action, requestId ); actionMgr.handleItemManipulationAction( player, actionId, action, requestId );
else else
actionMgr.handleTargetedPlayerAction( player, actionId, action, targetId, requestId ); actionMgr.handleTargetedAction( player, actionId, action, targetId, requestId );
break; break;
} }

View file

@ -71,8 +71,12 @@ void Util::Packet::sendBaseParams( Entity::Player& player )
void Util::Packet::sendHudParam( Entity::Chara& source ) void Util::Packet::sendHudParam( Entity::Chara& source )
{ {
auto hudParamPacket = makeHudParam( source ); if( source.isPlayer() )
server().queueForPlayers( source.getInRangePlayerIds( source.isPlayer() ), hudParamPacket ); server().queueForPlayers( source.getInRangePlayerIds( true ), makeHudParam( *source.getAsPlayer() ) );
else if( source.isBattleNpc() )
server().queueForPlayers( source.getInRangePlayerIds( false ), makeHudParam( *source.getAsBNpc() ) );
else
server().queueForPlayers( source.getInRangePlayerIds( false ), makeHudParam( source ) );
} }
void Util::Packet::sendStatusUpdate( Entity::Player& player ) void Util::Packet::sendStatusUpdate( Entity::Player& player )

View file

@ -204,27 +204,35 @@ void Sapphire::World::Session::sendReplayInfo()
PlayerMgr::sendDebug( *getPlayer(), message ); PlayerMgr::sendDebug( *getPlayer(), message );
} }
void Sapphire::World::Session::processOutQueue()
{
if( !m_pZoneConnection )
return;
m_pZoneConnection->processOutQueue();
}
void Sapphire::World::Session::update() void Sapphire::World::Session::update()
{ {
if( m_isReplaying ) if( m_isReplaying )
processReplay(); processReplay();
if( m_pZoneConnection ) if( !m_pZoneConnection )
return;
m_pZoneConnection->processInQueue();
// SESSION LOGIC
m_pPlayer->update( Common::Util::getTimeMs() );
if( Common::Util::getTimeSeconds() - static_cast< uint32_t >( getLastSqlTime() ) > 10 )
{ {
m_pZoneConnection->processInQueue(); updateLastSqlTime();
m_pPlayer->updateSql();
// SESSION LOGIC
m_pPlayer->update( Common::Util::getTimeMs() );
if( Common::Util::getTimeSeconds() - static_cast< uint32_t >( getLastSqlTime() ) > 10 )
{
updateLastSqlTime();
m_pPlayer->updateSql();
}
m_pZoneConnection->processOutQueue();
} }
m_pZoneConnection->processOutQueue();
if( m_pChatConnection ) if( m_pChatConnection )
{ {
m_pChatConnection->processInQueue(); m_pChatConnection->processInQueue();

View file

@ -47,6 +47,8 @@ namespace Sapphire::World
void update(); void update();
void processOutQueue();
bool isValid() const; bool isValid() const;
Entity::PlayerPtr getPlayer() const; Entity::PlayerPtr getPlayer() const;

View file

@ -49,9 +49,6 @@ void ActionIntegrityTask::execute()
int statusIdx = 0; int statusIdx = 0;
for( auto& actionResult : m_results ) for( auto& actionResult : m_results )
{ {
if( actionResult && actionResult->getTarget() && actionResult->getTarget()->isAlive() )
actionResult->execute();
if( actionResult->getCalcResultParam().Type == Common::CALC_RESULT_TYPE_SET_STATUS ) if( actionResult->getCalcResultParam().Type == Common::CALC_RESULT_TYPE_SET_STATUS )
{ {
auto& status = data.Status[ statusIdx++ ]; auto& status = data.Status[ statusIdx++ ];
@ -62,6 +59,9 @@ void ActionIntegrityTask::execute()
status.Slot = static_cast< uint8_t >( pEffect->getSlot() ); status.Slot = static_cast< uint8_t >( pEffect->getSlot() );
status.SystemParam = static_cast< int16_t >( pEffect->getParam() ); status.SystemParam = static_cast< int16_t >( pEffect->getParam() );
} }
if( actionResult && actionResult->getTarget() )
actionResult->execute();
} }
data.Hp = m_pTarget->getHp(); data.Hp = m_pTarget->getHp();

View file

@ -386,20 +386,21 @@ void WorldServer::mainLoop()
{ {
auto tickCount = Common::Util::getTimeMs(); auto tickCount = Common::Util::getTimeMs();
auto currTime = Common::Util::getTimeSeconds();
taskMgr.update( tickCount );
updateSessions( currTime );
if( tickCount - m_lastServerTick < 300 ) if( tickCount - m_lastServerTick < 300 )
{ {
std::this_thread::sleep_for( std::chrono::milliseconds( 50 ) ); std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
continue; continue;
} }
m_lastServerTick = tickCount; m_lastServerTick = tickCount;
auto currTime = Common::Util::getTimeSeconds();
taskMgr.update( tickCount );
terriMgr.updateTerritoryInstances( tickCount ); terriMgr.updateTerritoryInstances( tickCount );
scriptMgr.update(); scriptMgr.update();
contentFinder.update(); contentFinder.update();
updateSessions( currTime );
DbKeepAlive( currTime ); DbKeepAlive( currTime );
} }