From 60e701dbdd252d3e8f8464c54cbe2420dfbc11ba Mon Sep 17 00:00:00 2001 From: collett Date: Sun, 19 Jan 2020 21:20:01 +0900 Subject: [PATCH] enum/struct/packet updates, fix dot/hot tick, remove incorrect initial delay for player autoattacks. --- src/common/Common.h | 11 ++- src/common/Network/PacketDef/Ipcs.h | 2 +- .../Network/PacketDef/Zone/ServerZoneDef.h | 28 +++--- src/world/Action/Action.cpp | 4 +- src/world/Actor/BNpc.cpp | 1 + src/world/Actor/Chara.cpp | 90 ++++++++++--------- src/world/Actor/Chara.h | 2 +- src/world/Actor/Player.cpp | 3 - src/world/Actor/PlayerEvent.cpp | 2 +- .../Network/PacketWrappers/NpcSpawnPacket.h | 2 +- .../PacketWrappers/PlayerSpawnPacket.h | 2 +- 11 files changed, 73 insertions(+), 74 deletions(-) diff --git a/src/common/Common.h b/src/common/Common.h index 3777085c..543d5cd1 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -412,7 +412,7 @@ namespace Sapphire::Common struct StatusEffect { uint16_t effect_id; - uint16_t unknown1; + uint16_t param; float duration; uint32_t sourceActorId; }; @@ -591,9 +591,10 @@ namespace Sapphire::Common // DRGGauge3Eyes = 76, }; - enum class ActionType : int8_t + enum class AttackType : int8_t { - WeaponOverride = -1, // Needs more investigation (takes the damage type of the equipped weapon)? + //WeaponOverride = -1, // Needs more investigation (takes the damage type of the equipped weapon)? + Physical = -1, // seems to be the case Unknown_0 = 0, Slashing = 1, Piercing = 2, @@ -623,6 +624,8 @@ namespace Sapphire::Common TpGain = 13, GpGain = 14, ApplyStatusEffect = 15, + //ApplyStatusEffect2 = 16, // thin air uses this one but works fine with 15 wtf? + StatusNoEffect = 21, /*! * @brief Tells the client that it should show combo indicators on actions. * @@ -649,7 +652,9 @@ namespace Sapphire::Common enum class ActionEffectResultFlag : uint8_t { None = 0, + Absorbed = 0x04, EffectOnSource = 0x80, + Reflected = 0xA0, }; enum ItemActionType : uint16_t diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index 7bced52d..97dba6ba 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -160,7 +160,7 @@ namespace Sapphire::Network::Packets PlayerStateFlags = 0x02C6, // updated 5.18 PlayerClassInfo = 0x01B0, // updated 5.18 - ModelEquip = 0x0170, // updated 5.11 + ModelEquip = 0x02E6, // updated 5.18 Examine = 0x0366, // updated 5.18 CharaNameReq = 0x0116, // updated 5.18 diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 74bd02b2..8a06167b 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -422,7 +422,8 @@ namespace Sapphire::Network::Packets::Server uint16_t current_mp; uint16_t max_mp; uint16_t currentTp; - uint16_t unknown1; + uint8_t shieldPercentage; + uint8_t unknown1; Common::StatusEffect effect[30]; uint32_t padding; }; @@ -439,27 +440,18 @@ namespace Sapphire::Network::Packets::Server */ struct FFXIVIpcEffectResult : FFXIVIpcBasePacket< EffectResult > { - uint32_t unknown; + uint32_t globalSequence; uint32_t actor_id; - //uint8_t unknown1; - //uint8_t unknown2; - //uint16_t padding1; - //uint32_t current_hp; - //uint16_t current_mp; - //uint16_t current_tp; - //uint32_t max_hp; - //uint16_t max_mp; - //uint16_t max_something; uint32_t current_hp; uint32_t max_hp; uint16_t current_mp; - uint16_t unknown1; + uint16_t current_tp; uint16_t max_mp; - uint8_t unknown2; + uint8_t unknown1; uint8_t classId; - uint8_t unknown4; - uint8_t unkFlag; - uint16_t unknown6; + uint8_t shieldPercentage; + uint8_t entryCount; + uint16_t unknown2; struct StatusEntry { @@ -467,12 +459,12 @@ namespace Sapphire::Network::Packets::Server uint8_t unknown3; uint16_t id; uint16_t param; - uint16_t unknown5; // Sort this out (old right half of power/param property) + uint16_t unknown4; // Sort this out (old right half of power/param property) float duration; uint32_t sourceActorId; } statusEntries[4]; - uint32_t unknown7; + uint32_t unknown5; }; /** diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index 1f3de39a..9a89c249 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -565,7 +565,7 @@ bool Action::Action::playerPreCheck( Entity::Player& player ) return false; // npc actions/non player actions - if( m_actionData->classJob == -1 ) + if( m_actionData->classJob == -1 && !m_actionData->isRoleAction ) return false; if( player.getLevel() < m_actionData->classJobLevel ) @@ -574,7 +574,7 @@ bool Action::Action::playerPreCheck( Entity::Player& player ) auto currentClass = player.getClass(); auto actionClass = static_cast< Common::ClassJob >( m_actionData->classJob ); - if( actionClass != Common::ClassJob::Adventurer && currentClass != actionClass ) + if( actionClass != Common::ClassJob::Adventurer && currentClass != actionClass && !m_actionData->isRoleAction ) { // check if not a base class action auto exdData = m_pFw->get< Data::ExdDataGenerated >(); diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index ddb3f54b..b24d1053 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -396,6 +396,7 @@ void Sapphire::Entity::BNpc::deaggro( Sapphire::Entity::CharaPtr pChara ) void Sapphire::Entity::BNpc::onTick() { + Chara::onTick(); if( m_state == BNpcState::Retreat ) { regainHp(); diff --git a/src/world/Actor/Chara.cpp b/src/world/Actor/Chara.cpp index 97712dd8..6ecec118 100644 --- a/src/world/Actor/Chara.cpp +++ b/src/world/Actor/Chara.cpp @@ -44,6 +44,7 @@ Sapphire::Entity::Chara::Chara( ObjKind type, FrameworkPtr pFw ) : m_lastTickTime = 0; m_lastUpdate = 0; + m_lastAttack = Util::getTimeMs(); m_bonusStats.fill( 0 ); @@ -354,6 +355,8 @@ bool Sapphire::Entity::Chara::checkAction() void Sapphire::Entity::Chara::update( uint64_t tickCount ) { + updateStatusEffects(); + if( std::difftime( static_cast< time_t >( tickCount ), m_lastTickTime ) > 3000 ) { onTick(); @@ -532,16 +535,15 @@ void Sapphire::Entity::Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEf auto statusEffectAdd = makeZonePacket< FFXIVIpcEffectResult >( getId() ); + statusEffectAdd->data().globalSequence = getCurrentTerritory()->getNextEffectSequence(); statusEffectAdd->data().actor_id = pEffect->getTargetActorId(); statusEffectAdd->data().current_hp = getHp(); statusEffectAdd->data().current_mp = static_cast< uint16_t >( getMp() ); - //statusEffectAdd->data().current_tp = getTp(); + statusEffectAdd->data().current_tp = getTp(); statusEffectAdd->data().max_hp = getMaxHp(); statusEffectAdd->data().max_mp = static_cast< uint16_t >( getMaxMp() ); - //statusEffectAdd->data().max_something = 1; - //statusEffectAdd->data().unknown2 = 28; - statusEffectAdd->data().classId = static_cast< uint8_t >(getClass()); - statusEffectAdd->data().unkFlag = 1; + statusEffectAdd->data().classId = static_cast< uint8_t >( getClass() ); + statusEffectAdd->data().entryCount = 1; auto& status = statusEffectAdd->data().statusEntries[0]; @@ -681,9 +683,6 @@ void Sapphire::Entity::Chara::updateStatusEffects() { uint64_t currentTimeMs = Util::getTimeMs(); - uint32_t thisTickDmg = 0; - uint32_t thisTickHeal = 0; - for( auto effectIt : m_statusEffectMap ) { uint8_t effectIndex = effectIt.first; @@ -694,7 +693,7 @@ void Sapphire::Entity::Chara::updateStatusEffects() uint32_t duration = effect->getDuration(); uint32_t tickRate = effect->getTickRate(); - if( ( currentTimeMs - startTime ) > duration ) + if( duration > 0 && ( currentTimeMs - startTime ) > duration ) { // remove status effect removeStatusEffect( effectIndex ); @@ -706,41 +705,7 @@ void Sapphire::Entity::Chara::updateStatusEffects() { effect->setLastTick( currentTimeMs ); effect->onTick(); - - auto thisEffect = effect->getTickEffect(); - - switch( thisEffect.first ) - { - - case 1: - { - thisTickDmg += thisEffect.second; - break; - } - - case 2: - { - thisTickHeal += thisEffect.second; - break; - } - - } } - - } - - if( thisTickDmg != 0 ) - { - takeDamage( thisTickDmg ); - sendToInRangeSet( makeActorControl( getId(), HPFloatingText, 0, - static_cast< uint8_t >( ActionEffectType::Damage ), thisTickDmg ) ); - } - - if( thisTickHeal != 0 ) - { - heal( thisTickDmg ); - sendToInRangeSet( makeActorControl( getId(), HPFloatingText, 0, - static_cast< uint8_t >( ActionEffectType::Heal ), thisTickHeal ) ); } } @@ -944,3 +909,42 @@ uint32_t Sapphire::Entity::Chara::getStatValue( Sapphire::Common::BaseParam base return value + getBonusStat( baseParam ); } + +void Sapphire::Entity::Chara::onTick() +{ + uint32_t thisTickDmg = 0; + uint32_t thisTickHeal = 0; + + for( auto effectIt : m_statusEffectMap ) + { + auto thisEffect = effectIt.second->getTickEffect(); + switch( thisEffect.first ) + { + case 1: + { + thisTickDmg += thisEffect.second; + break; + } + + case 2: + { + thisTickHeal += thisEffect.second; + break; + } + } + } + + if( thisTickDmg != 0 ) + { + takeDamage( thisTickDmg ); + sendToInRangeSet( makeActorControl( getId(), HPFloatingText, 0, + static_cast< uint8_t >( ActionEffectType::Damage ), thisTickDmg ), true ); + } + + if( thisTickHeal != 0 ) + { + heal( thisTickHeal ); + sendToInRangeSet( makeActorControl( getId(), HPFloatingText, 0, + static_cast< uint8_t >( ActionEffectType::Heal ), thisTickHeal ), true ); + } +} \ No newline at end of file diff --git a/src/world/Actor/Chara.h b/src/world/Actor/Chara.h index 697f5a6e..f423507e 100644 --- a/src/world/Actor/Chara.h +++ b/src/world/Actor/Chara.h @@ -251,7 +251,7 @@ namespace Sapphire::Entity virtual void onActionFriendly( Chara& pSource ) {}; - virtual void onTick() {}; + virtual void onTick(); virtual void changeTarget( uint64_t targetId ); diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 39e64585..dc616600 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -306,7 +306,6 @@ void Sapphire::Entity::Player::calculateStats() void Sapphire::Entity::Player::setAutoattack( bool mode ) { m_bAutoattack = mode; - m_lastAttack = Util::getTimeMs(); } bool Sapphire::Entity::Player::isAutoattackOn() const @@ -1100,8 +1099,6 @@ void Sapphire::Entity::Player::update( uint64_t tickCount ) if( !isAlive() ) return; - updateStatusEffects(); - m_lastUpdate = tickCount; if( !checkAction() ) diff --git a/src/world/Actor/PlayerEvent.cpp b/src/world/Actor/PlayerEvent.cpp index 0303b4fb..08f830e4 100644 --- a/src/world/Actor/PlayerEvent.cpp +++ b/src/world/Actor/PlayerEvent.cpp @@ -370,7 +370,7 @@ void Sapphire::Entity::Player::onDeath() // TODO: slightly ugly here and way too static. Needs too be done properly void Sapphire::Entity::Player::onTick() { - + Chara::onTick(); // add 3 seconds to total play time m_playTime += 3; diff --git a/src/world/Network/PacketWrappers/NpcSpawnPacket.h b/src/world/Network/PacketWrappers/NpcSpawnPacket.h index 3cc99f89..0b9ab630 100644 --- a/src/world/Network/PacketWrappers/NpcSpawnPacket.h +++ b/src/world/Network/PacketWrappers/NpcSpawnPacket.h @@ -96,7 +96,7 @@ namespace Sapphire::Network::Packets::Server ( currentTimeMs - effect.second->getStartTimeMs() ) ) / 1000; m_data.effect[ effect.first ].sourceActorId = effect.second->getSrcActorId(); - m_data.effect[ effect.first ].unknown1 = effect.second->getParam(); + m_data.effect[ effect.first ].param = effect.second->getParam(); } }; diff --git a/src/world/Network/PacketWrappers/PlayerSpawnPacket.h b/src/world/Network/PacketWrappers/PlayerSpawnPacket.h index 4f384356..f20fdd7e 100644 --- a/src/world/Network/PacketWrappers/PlayerSpawnPacket.h +++ b/src/world/Network/PacketWrappers/PlayerSpawnPacket.h @@ -142,7 +142,7 @@ namespace Sapphire::Network::Packets::Server ( currentTimeMs - effect.second->getStartTimeMs() ) ) / 1000; m_data.effect[ effect.first ].sourceActorId = effect.second->getSrcActorId(); - m_data.effect[ effect.first ].unknown1 = effect.second->getParam(); + m_data.effect[ effect.first ].param = effect.second->getParam(); } };