mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-25 14:07:46 +00:00
Converted autoattacks to the action system
This commit is contained in:
parent
7c4a053bea
commit
5cc7b0c87b
15 changed files with 93 additions and 100 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"7": {
|
||||
"name": "Attack",
|
||||
"potency": 0,
|
||||
"potency": 110,
|
||||
"comboPotency": 0,
|
||||
"flankPotency": 0,
|
||||
"frontPotency": 0,
|
||||
|
@ -16,7 +16,7 @@
|
|||
},
|
||||
"8": {
|
||||
"name": "Shot",
|
||||
"potency": 0,
|
||||
"potency": 100,
|
||||
"comboPotency": 0,
|
||||
"flankPotency": 0,
|
||||
"frontPotency": 0,
|
||||
|
|
|
@ -333,9 +333,11 @@ void Action::Action::start()
|
|||
// 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 );
|
||||
|
||||
player->setRecastGroup( m_cooldownGroup, static_cast< float >( m_castTimeMs ) / 1000.f );
|
||||
|
||||
server().queueForPlayer( player->getCharacterId(), actionStartPkt );
|
||||
if( player )
|
||||
{
|
||||
player->setRecastGroup( m_cooldownGroup, static_cast< float >( m_castTimeMs ) / 1000.f );
|
||||
server().queueForPlayer( player->getCharacterId(), actionStartPkt );
|
||||
}
|
||||
|
||||
onStart();
|
||||
|
||||
|
@ -369,7 +371,6 @@ void Action::Action::onStart()
|
|||
void Action::Action::interrupt()
|
||||
{
|
||||
assert( m_pSource );
|
||||
|
||||
// things that aren't players don't care about cooldowns and state flags
|
||||
if( m_pSource->isPlayer() )
|
||||
{
|
||||
|
@ -409,7 +410,6 @@ void Action::Action::onInterrupt()
|
|||
void Action::Action::execute()
|
||||
{
|
||||
assert( m_pSource );
|
||||
|
||||
// subtract costs first, if somehow the caster stops meeting those requirements cancel the cast
|
||||
if( !consumeResources() )
|
||||
{
|
||||
|
@ -464,6 +464,10 @@ std::pair< uint32_t, Common::ActionHitSeverityType > Action::Action::calcDamage(
|
|||
wepDmg = item->getMagicalDmg();
|
||||
else
|
||||
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 );
|
||||
|
@ -574,7 +578,6 @@ void Action::Action::buildActionResults()
|
|||
shouldRestoreMP = false;
|
||||
}
|
||||
}
|
||||
|
||||
m_actionResultBuilder->sendActionResults( m_hitActors );
|
||||
|
||||
// TODO: disabled, reset kills our queued actions
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <Manager/PlayerMgr.h>
|
||||
#include <Manager/TaskMgr.h>
|
||||
#include <Manager/MgrUtil.h>
|
||||
#include <Manager/ActionMgr.h>
|
||||
#include <Script/ScriptMgr.h>
|
||||
#include <Task/RemoveBNpcTask.h>
|
||||
#include <Task/FadeBNpcTask.h>
|
||||
|
@ -643,6 +644,8 @@ void BNpc::update( uint64_t tickCount )
|
|||
if( !pNaviProvider )
|
||||
return;
|
||||
|
||||
checkAction();
|
||||
|
||||
switch( m_state )
|
||||
{
|
||||
case BNpcState::Dead:
|
||||
|
@ -803,7 +806,7 @@ void BNpc::restHp()
|
|||
m_hp = getMaxHp();
|
||||
}
|
||||
|
||||
sendHudParam();
|
||||
Network::Util::Packet::sendHudParam( *this );
|
||||
}
|
||||
|
||||
void BNpc::onActionHostile( CharaPtr pSource )
|
||||
|
@ -963,6 +966,8 @@ void BNpc::autoAttack( CharaPtr pTarget )
|
|||
{
|
||||
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
|
||||
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();
|
||||
|
||||
|
@ -972,26 +977,7 @@ void BNpc::autoAttack( CharaPtr pTarget )
|
|||
pTarget->onActionHostile( getAsChara() );
|
||||
m_lastAttack = tick;
|
||||
srand( static_cast< uint32_t >( tick ) );
|
||||
|
||||
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 ) );
|
||||
actionMgr.handleTargetedAction( *this, 7, exdData.getRow< Excel::Action >( 7 ), pTarget->getId(), 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -285,6 +285,16 @@ void Chara::die()
|
|||
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
|
||||
position
|
||||
|
@ -426,18 +436,6 @@ void Chara::restoreMP( uint32_t 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 */
|
||||
Action::ActionPtr Chara::getCurrentAction() const
|
||||
{
|
||||
|
|
|
@ -203,6 +203,10 @@ namespace Sapphire::Entity
|
|||
|
||||
void die();
|
||||
|
||||
uint64_t getLastAttack() const;
|
||||
|
||||
void setLastAttack( uint64_t tickCount );
|
||||
|
||||
Common::ActorStatus getStatus() const;
|
||||
|
||||
void setStatus( Common::ActorStatus status );
|
||||
|
@ -223,8 +227,6 @@ namespace Sapphire::Entity
|
|||
|
||||
virtual uint8_t getLevel() const;
|
||||
|
||||
virtual void sendHudParam();
|
||||
|
||||
virtual void takeDamage( uint32_t damage );
|
||||
|
||||
virtual void heal( uint32_t amount );
|
||||
|
|
|
@ -923,16 +923,6 @@ void Player::update( uint64_t 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 )
|
||||
{
|
||||
auto spawnId = m_actorSpawnIndexAllocator.freeUsedSpawnIndex( actorId );
|
||||
|
@ -1295,9 +1285,9 @@ void Player::autoAttack( CharaPtr pTarget )
|
|||
auto& RNGMgr = Common::Service< World::Manager::RNGMgr >::ref();
|
||||
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 );
|
||||
|
||||
|
@ -1320,7 +1310,7 @@ void Player::autoAttack( CharaPtr pTarget )
|
|||
|
||||
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 ) );
|
||||
}
|
||||
|
||||
|
|
|
@ -83,12 +83,6 @@ namespace Sapphire::Entity
|
|||
/*! Event called on every session iteration */
|
||||
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
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/*! load data for currently active quests */
|
||||
|
|
|
@ -59,13 +59,13 @@ void ActionMgr::handleItemManipulationAction( Entity::Player& player, uint32_t a
|
|||
action->start();
|
||||
}
|
||||
|
||||
void ActionMgr::handleTargetedPlayerAction( Entity::Player& player, uint32_t actionId,
|
||||
Excel::ExcelStructPtr< Excel::Action > actionData, uint64_t targetId, uint16_t requestId )
|
||||
void ActionMgr::handleTargetedAction( Entity::Chara& src, uint32_t actionId,
|
||||
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->setPos( player.getPos() );
|
||||
action->setPos( src.getPos() );
|
||||
|
||||
if( !action->init() )
|
||||
return;
|
||||
|
@ -77,7 +77,7 @@ void ActionMgr::handleTargetedPlayerAction( Entity::Player& player, uint32_t act
|
|||
return;
|
||||
}
|
||||
|
||||
bootstrapAction( player, action, actionData );
|
||||
bootstrapAction( src, action, actionData );
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
void ActionMgr::bootstrapAction( Entity::Player& player, Action::ActionPtr currentAction,
|
||||
void ActionMgr::bootstrapAction( Entity::Chara& src, Action::ActionPtr currentAction,
|
||||
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() );
|
||||
player.setQueuedAction( currentAction );
|
||||
if( src.isPlayer() )
|
||||
{
|
||||
auto& player = *src.getAsPlayer();
|
||||
PlayerMgr::sendDebug( player, "Skill queued: {0}", currentAction->getId() );
|
||||
player.setQueuedAction( currentAction );
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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 );
|
||||
src.setCurrentAction( currentAction );
|
||||
|
||||
// todo: what do in cases of swiftcast/etc? script callback?
|
||||
currentAction->start();
|
||||
player.setLastAttack( Common::Util::getTimeMs() );
|
||||
src.setLastAttack( Common::Util::getTimeMs() );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 handleTargetedPlayerAction( Entity::Player& player, uint32_t actionId,
|
||||
std::shared_ptr< Excel::ExcelStruct< Excel::Action > > actionData, uint64_t targetId, uint16_t requestId );
|
||||
void handleTargetedAction( Entity::Chara& chara, uint32_t actionId,
|
||||
std::shared_ptr< Excel::ExcelStruct< Excel::Action > > actionData, uint64_t targetId, uint16_t requestId );
|
||||
void handlePlacedPlayerAction( Entity::Player& player, uint32_t actionId,
|
||||
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 );
|
||||
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
|
||||
void handleItemActionVFX( Entity::Player& player, uint32_t itemId, uint16_t vfxId );
|
||||
|
|
|
@ -52,7 +52,7 @@ void Sapphire::Network::GameConnection::actionRequest( const Packets::FFXIVARR_P
|
|||
if( category == Common::ActionCategory::ItemManipulation )
|
||||
actionMgr.handleItemManipulationAction( player, actionId, action, requestId );
|
||||
else
|
||||
actionMgr.handleTargetedPlayerAction( player, actionId, action, targetId, requestId );
|
||||
actionMgr.handleTargetedAction( player, actionId, action, targetId, requestId );
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,8 +71,12 @@ void Util::Packet::sendBaseParams( Entity::Player& player )
|
|||
|
||||
void Util::Packet::sendHudParam( Entity::Chara& source )
|
||||
{
|
||||
auto hudParamPacket = makeHudParam( source );
|
||||
server().queueForPlayers( source.getInRangePlayerIds( source.isPlayer() ), hudParamPacket );
|
||||
if( source.isPlayer() )
|
||||
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 )
|
||||
|
|
|
@ -204,27 +204,35 @@ void Sapphire::World::Session::sendReplayInfo()
|
|||
PlayerMgr::sendDebug( *getPlayer(), message );
|
||||
}
|
||||
|
||||
void Sapphire::World::Session::processOutQueue()
|
||||
{
|
||||
if( !m_pZoneConnection )
|
||||
return;
|
||||
|
||||
m_pZoneConnection->processOutQueue();
|
||||
}
|
||||
|
||||
void Sapphire::World::Session::update()
|
||||
{
|
||||
if( m_isReplaying )
|
||||
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();
|
||||
|
||||
// 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();
|
||||
updateLastSqlTime();
|
||||
m_pPlayer->updateSql();
|
||||
}
|
||||
|
||||
m_pZoneConnection->processOutQueue();
|
||||
|
||||
if( m_pChatConnection )
|
||||
{
|
||||
m_pChatConnection->processInQueue();
|
||||
|
|
|
@ -47,6 +47,8 @@ namespace Sapphire::World
|
|||
|
||||
void update();
|
||||
|
||||
void processOutQueue();
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
Entity::PlayerPtr getPlayer() const;
|
||||
|
|
|
@ -49,9 +49,6 @@ void ActionIntegrityTask::execute()
|
|||
int statusIdx = 0;
|
||||
for( auto& actionResult : m_results )
|
||||
{
|
||||
if( actionResult && actionResult->getTarget() && actionResult->getTarget()->isAlive() )
|
||||
actionResult->execute();
|
||||
|
||||
if( actionResult->getCalcResultParam().Type == Common::CALC_RESULT_TYPE_SET_STATUS )
|
||||
{
|
||||
auto& status = data.Status[ statusIdx++ ];
|
||||
|
@ -62,6 +59,9 @@ void ActionIntegrityTask::execute()
|
|||
status.Slot = static_cast< uint8_t >( pEffect->getSlot() );
|
||||
status.SystemParam = static_cast< int16_t >( pEffect->getParam() );
|
||||
}
|
||||
|
||||
if( actionResult && actionResult->getTarget() )
|
||||
actionResult->execute();
|
||||
}
|
||||
|
||||
data.Hp = m_pTarget->getHp();
|
||||
|
|
|
@ -386,20 +386,21 @@ void WorldServer::mainLoop()
|
|||
{
|
||||
auto tickCount = Common::Util::getTimeMs();
|
||||
|
||||
auto currTime = Common::Util::getTimeSeconds();
|
||||
taskMgr.update( tickCount );
|
||||
updateSessions( currTime );
|
||||
|
||||
if( tickCount - m_lastServerTick < 300 )
|
||||
{
|
||||
std::this_thread::sleep_for( std::chrono::milliseconds( 50 ) );
|
||||
std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
|
||||
continue;
|
||||
}
|
||||
m_lastServerTick = tickCount;
|
||||
|
||||
auto currTime = Common::Util::getTimeSeconds();
|
||||
|
||||
taskMgr.update( tickCount );
|
||||
terriMgr.updateTerritoryInstances( tickCount );
|
||||
scriptMgr.update();
|
||||
contentFinder.update();
|
||||
updateSessions( currTime );
|
||||
|
||||
|
||||
DbKeepAlive( currTime );
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue