diff --git a/bin/config/settings_rest.xml b/bin/config/settings_rest.xml index af0c2fb9..35239671 100644 --- a/bin/config/settings_rest.xml +++ b/bin/config/settings_rest.xml @@ -6,7 +6,8 @@ 127.0.0.1 - C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv + + /opt/sapphire_3_15_0/bin/sqpack 127.0.0.1 @@ -16,10 +17,10 @@ 80 - 127.0.0.1 + localhost 3306 root - + viridis0! sapphire @@ -28,4 +29,4 @@ 255 - \ No newline at end of file + diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index ebf42d84..4ea14d78 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -1,7 +1,7 @@ if(UNIX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") -# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32") else() add_definitions(-D_WIN32_WINNT=0x601) add_definitions(-D_CRT_SECURE_NO_WARNINGS) diff --git a/src/servers/Server_Zone/Actor/Actor.cpp b/src/servers/Server_Zone/Actor/Actor.cpp index 02d9543d..6d3f87df 100644 --- a/src/servers/Server_Zone/Actor/Actor.cpp +++ b/src/servers/Server_Zone/Actor/Actor.cpp @@ -15,7 +15,6 @@ #include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket144.h" #include "src/servers/Server_Zone/Network/PacketWrappers/UpdateHpMpTpPacket.h" -#include "src/servers/Server_Zone/StatusEffect/StatusEffectContainer.h" #include "src/servers/Server_Zone/StatusEffect/StatusEffect.h" #include "src/servers/Server_Zone/Action/ActionCollision.h" #include "src/servers/Server_Zone/ServerZone.h" @@ -33,6 +32,11 @@ using namespace Core::Network::Packets::Server; Core::Entity::Actor::Actor() { + // initialize the free slot queue + for( uint8_t i = 0; i < MAX_STATUS_EFFECTS; i++ ) + { + m_statusEffectFreeSlotQueue.push( i ); + } } Core::Entity::Actor::~Actor() @@ -794,7 +798,30 @@ void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint16_t actionId, u /*! \param StatusEffectPtr to be applied to the actor */ void Core::Entity::Actor::addStatusEffect( StatusEffect::StatusEffectPtr pEffect ) { - m_pStatusEffectContainer->addStatusEffect( pEffect ); + int8_t nextSlot = getStatusEffectFreeSlot(); + // if there is no slot left, do not add the effect + if( nextSlot == -1 ) + return; + + pEffect->applyStatus(); + m_statusEffectMap[nextSlot] = pEffect; + + ZoneChannelPacket< Server::FFXIVIpcAddStatusEffect > statusEffectAdd( getId() ); + statusEffectAdd.data().actor_id = pEffect->getTargetActorId(); + statusEffectAdd.data().actor_id1 = pEffect->getSrcActorId(); + statusEffectAdd.data().current_hp = getHp(); + statusEffectAdd.data().current_mp = getMp(); + statusEffectAdd.data().current_tp = getTp(); + statusEffectAdd.data().duration = static_cast< float >( pEffect->getDuration() ) / 1000; + statusEffectAdd.data().effect_id = pEffect->getId(); + statusEffectAdd.data().effect_index = nextSlot; + statusEffectAdd.data().max_hp = getMaxHp(); + statusEffectAdd.data().max_mp = getMaxMp(); + statusEffectAdd.data().max_something = 1; + //statusEffectAdd.data().unknown2 = 28; + statusEffectAdd.data().param = pEffect->getParam(); + + sendToInRangeSet( statusEffectAdd, isPlayer() ); } /*! \param StatusEffectPtr to be applied to the actor */ @@ -809,7 +836,7 @@ void Core::Entity::Actor::addStatusEffectById( uint32_t id, int32_t duration, En /*! \param StatusEffectPtr to be applied to the actor */ void Core::Entity::Actor::addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Actor& pSource, uint16_t param ) { - if( !m_pStatusEffectContainer->hasStatusEffect( id ) ) + if( !hasStatusEffect( id ) ) { StatusEffect::StatusEffectPtr effect( new StatusEffect::StatusEffect( id, pSource.shared_from_this(), shared_from_this(), duration, 3000 ) ); @@ -818,17 +845,6 @@ void Core::Entity::Actor::addStatusEffectByIdIfNotExist( uint32_t id, int32_t du } } -/*! \param Status that should be removed, based on its ID. */ -void Core::Entity::Actor::removeSingleStatusEffectFromId( uint32_t id ) -{ - m_pStatusEffectContainer->removeSingleStatusEffectFromId( id ); -} - -Core::StatusEffect::StatusEffectContainerPtr Core::Entity::Actor::getStatusEffectContainer() const -{ - return m_pStatusEffectContainer; -} - float Core::Entity::Actor::getRotation() const { return m_rot; @@ -838,3 +854,154 @@ void Core::Entity::Actor::setRotation( float rot ) { m_rot = rot; } + +int8_t Core::Entity::Actor::getStatusEffectFreeSlot() +{ + int8_t freeEffectSlot = -1; + + if( m_statusEffectFreeSlotQueue.empty() ) + return freeEffectSlot; + + freeEffectSlot = m_statusEffectFreeSlotQueue.front(); + m_statusEffectFreeSlotQueue.pop(); + + return freeEffectSlot; +} + +void Core::Entity::Actor::statusEffectFreeSlot( uint8_t slotId ) +{ + m_statusEffectFreeSlotQueue.push( slotId ); +} + +void Core::Entity::Actor::removeSingleStatusEffectById( uint32_t id ) +{ + for( auto effectIt : m_statusEffectMap ) + { + if( effectIt.second->getId() == id ) + { + removeStatusEffect( effectIt.first ); + break; + } + } +} + +void Core::Entity::Actor::removeStatusEffect( uint8_t effectSlotId ) +{ + auto pEffectIt = m_statusEffectMap.find( effectSlotId ); + if( pEffectIt == m_statusEffectMap.end() ) + return; + + statusEffectFreeSlot( effectSlotId ); + + auto pEffect = pEffectIt->second; + pEffect->removeStatus(); + + sendToInRangeSet( ActorControlPacket142( getId(), StatusEffectLose, pEffect->getId() ), isPlayer() ); + + m_statusEffectMap.erase( effectSlotId ); + + sendStatusEffectUpdate(); +} + +std::map< uint8_t, Core::StatusEffect::StatusEffectPtr > Core::Entity::Actor::getStatusEffectMap() const +{ + return m_statusEffectMap; +} + +void Core::Entity::Actor::sendStatusEffectUpdate() +{ + uint64_t currentTimeMs = Util::getTimeMs(); + + ZoneChannelPacket< Server::FFXIVIpcStatusEffectList > statusEffectList( getId() ); + + statusEffectList.data().current_hp = getHp(); + statusEffectList.data().current_mp = getMp(); + statusEffectList.data().currentTp = getTp(); + statusEffectList.data().max_hp = getMaxHp(); + statusEffectList.data().max_mp = getMaxMp(); + uint8_t slot = 0; + for( auto effectIt : m_statusEffectMap ) + { + float timeLeft = static_cast< float >( effectIt.second->getDuration() - + ( currentTimeMs - effectIt.second->getStartTimeMs() ) ) / 1000; + statusEffectList.data().effect[slot].duration = timeLeft; + statusEffectList.data().effect[slot].effect_id = effectIt.second->getId(); + statusEffectList.data().effect[slot].sourceActorId = effectIt.second->getSrcActorId(); + slot++; + } + + sendToInRangeSet( statusEffectList, isPlayer() ); + +} + +void Core::Entity::Actor::updateStatusEffects() +{ + uint64_t currentTimeMs = Util::getTimeMs(); + + uint32_t thisTickDmg = 0; + uint32_t thisTickHeal = 0; + + for( auto effectIt : m_statusEffectMap ) + { + uint8_t effectIndex = effectIt.first; + auto effect = effectIt.second; + + uint64_t lastTick = effect->getLastTickMs(); + uint64_t startTime = effect->getStartTimeMs(); + uint32_t duration = effect->getDuration(); + uint32_t tickRate = effect->getTickRate(); + + if( ( currentTimeMs - startTime ) > duration ) + { + // remove status effect + removeStatusEffect( effectIndex ); + // break because removing invalidates iterators + break; + } + + if( ( currentTimeMs - lastTick ) > tickRate ) + { + 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( ActorControlPacket142( getId(), HPFloatingText, 0, static_cast< uint8_t >( ActionEffectType::Damage ), thisTickDmg ) ); + } + + if( thisTickHeal != 0 ) + { + heal( thisTickDmg ); + sendToInRangeSet( ActorControlPacket142( getId(), HPFloatingText, 0, static_cast< uint8_t >( ActionEffectType::Heal ), thisTickHeal ) ); + } +} + +bool Core::Entity::Actor::hasStatusEffect( uint32_t id ) +{ + if( m_statusEffectMap.find( id ) != m_statusEffectMap.end() ) + return true; + return false; +} diff --git a/src/servers/Server_Zone/Actor/Actor.h b/src/servers/Server_Zone/Actor/Actor.h index 6e14f8c0..6759d486 100644 --- a/src/servers/Server_Zone/Actor/Actor.h +++ b/src/servers/Server_Zone/Actor/Actor.h @@ -7,6 +7,7 @@ #include "src/servers/Server_Zone/Forwards.h" #include #include +#include namespace Core { namespace Entity { @@ -160,11 +161,15 @@ protected: uint64_t m_targetId; /*! Ptr to a queued action */ Action::ActionPtr m_pCurrentAction; - /*! Container for status effects */ - StatusEffect::StatusEffectContainerPtr m_pStatusEffectContainer; /*! Invincibility type */ Common::InvincibilityType m_invincibilityType; + /*! Status effects */ + const uint8_t MAX_STATUS_EFFECTS = 30; + std::queue< uint8_t > m_statusEffectFreeSlotQueue; + std::vector< std::pair< uint8_t, uint32_t> > m_statusEffectList; + std::map< uint8_t, StatusEffect::StatusEffectPtr > m_statusEffectMap; + public: Actor(); @@ -174,6 +179,30 @@ public: uint32_t getId() const; + /// Status effect functions + void addStatusEffect( StatusEffect::StatusEffectPtr pEffect ); + void removeStatusEffect( uint8_t effectSlotId ); + void removeSingleStatusEffectById( uint32_t id ); + void updateStatusEffects(); + + bool hasStatusEffect( uint32_t id ); + + int8_t getStatusEffectFreeSlot(); + void statusEffectFreeSlot( uint8_t slotId ); + + std::map< uint8_t, Core::StatusEffect::StatusEffectPtr > getStatusEffectMap() const; + + void sendStatusEffectUpdate(); + // add a status effect by id + void addStatusEffectById( uint32_t id, int32_t duration, Entity::Actor& pSource, uint16_t param = 0 ); + + // add a status effect by id if it doesn't exist + void addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Actor& pSource, uint16_t param = 0 ); + + // remove a status effect by id + void removeSingleStatusEffectFromId( uint32_t id ); + /// End Status Effect Functions + void setPosition( const Common::FFXIVARR_POSITION3& pos ); void setPosition( float x, float y, float z ); @@ -303,20 +332,6 @@ public: // set the current cell void setCell( Cell* pCell ); - // add a status effect - void addStatusEffect( StatusEffect::StatusEffectPtr pEffect ); - - // add a status effect by id - void addStatusEffectById( uint32_t id, int32_t duration, Entity::Actor& pSource, uint16_t param = 0 ); - - // add a status effect by id if it doesn't exist - void addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Actor& pSource, uint16_t param = 0 ); - - // remove a status effect by id - void removeSingleStatusEffectFromId( uint32_t id ); - - //get the status effect container - StatusEffect::StatusEffectContainerPtr getStatusEffectContainer() const; // TODO: Why did i even declare them publicly here?! std::set< ActorPtr > m_inRangeActors; diff --git a/src/servers/Server_Zone/Actor/BattleNpc.cpp b/src/servers/Server_Zone/Actor/BattleNpc.cpp index 0bd002f7..17160397 100644 --- a/src/servers/Server_Zone/Actor/BattleNpc.cpp +++ b/src/servers/Server_Zone/Actor/BattleNpc.cpp @@ -15,7 +15,6 @@ #include "src/servers/Server_Zone/Network/PacketWrappers/MoveActorPacket.h" #include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket142.h" #include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket143.h" -#include "src/servers/Server_Zone/StatusEffect/StatusEffectContainer.h" using namespace Core::Common; using namespace Core::Network::Packets; @@ -40,7 +39,7 @@ Core::Entity::BattleNpc::~BattleNpc() Core::Entity::BattleNpc::BattleNpc( uint16_t modelId, uint16_t nameid, const Common::FFXIVARR_POSITION3& spawnPos, uint16_t bnpcBaseId, uint32_t type, uint8_t level, uint8_t behaviour, - uint32_t mobType ) + uint32_t mobType ) : Actor() { BattleNpc::m_nextID++; m_id = BattleNpc::m_nextID; @@ -87,11 +86,6 @@ Core::Entity::BattleNpc::BattleNpc( uint16_t modelId, uint16_t nameid, const Com } -void Core::Entity::BattleNpc::initStatusEffectContainer() -{ - m_pStatusEffectContainer = StatusEffect::StatusEffectContainerPtr( new StatusEffect::StatusEffectContainer( shared_from_this() ) ); -} - // spawn this player for pTarget void Core::Entity::BattleNpc::spawn( Core::Entity::PlayerPtr pTarget ) { @@ -487,9 +481,7 @@ void Core::Entity::BattleNpc::update( int64_t currTime ) return; } - if ( !m_pStatusEffectContainer ) - initStatusEffectContainer(); - m_pStatusEffectContainer->update(); + updateStatusEffects(); float distance = Math::Util::distance( m_pos.x, m_pos.y, m_pos.z, m_posOrigin.x, m_posOrigin.y, m_posOrigin.z ); diff --git a/src/servers/Server_Zone/Actor/Player.cpp b/src/servers/Server_Zone/Actor/Player.cpp index 2caab4b3..4260e251 100644 --- a/src/servers/Server_Zone/Actor/Player.cpp +++ b/src/servers/Server_Zone/Actor/Player.cpp @@ -31,8 +31,6 @@ #include "src/servers/Server_Zone/Script/ScriptManager.h" -#include "src/servers/Server_Zone/StatusEffect/StatusEffectContainer.h" - #include "src/servers/Server_Zone/Inventory/Item.h" #include "src/servers/Server_Zone/Inventory/Inventory.h" @@ -57,6 +55,7 @@ using namespace Core::Network::Packets::Server; // player constructor Core::Entity::Player::Player() : + Actor(), m_lastWrite( 0 ), m_lastPing( 0 ), m_bIsLogin( false ), @@ -1045,7 +1044,7 @@ void Core::Entity::Player::update( int64_t currTime ) if( !isAlive() ) return; - m_pStatusEffectContainer->update(); + updateStatusEffects(); m_lastUpdate = currTime; diff --git a/src/servers/Server_Zone/Actor/PlayerSql.cpp b/src/servers/Server_Zone/Actor/PlayerSql.cpp index 46fdd8d8..26fb155f 100644 --- a/src/servers/Server_Zone/Actor/PlayerSql.cpp +++ b/src/servers/Server_Zone/Actor/PlayerSql.cpp @@ -26,7 +26,6 @@ #include "src/servers/Server_Zone/Network/GameConnection.h" #include "src/servers/Server_Zone/Network/PacketWrappers/InitUIPacket.h" -#include "src/servers/Server_Zone/StatusEffect/StatusEffectContainer.h" #include "src/servers/Server_Zone/Inventory/Inventory.h" #include @@ -211,8 +210,6 @@ bool Core::Entity::Player::load( uint32_t charId, Core::SessionPtr pSession ) initSpawnIdQueue(); - m_pStatusEffectContainer = StatusEffect::StatusEffectContainerPtr( new StatusEffect::StatusEffectContainer( shared_from_this() ) ); - if( !m_playerIdToSpawnIdMap.empty() ) m_playerIdToSpawnIdMap.clear(); @@ -508,4 +505,4 @@ void Core::Entity::Player::insertQuest( uint16_t questId, uint8_t index, uint8_t stmt->setInt( 11, 0 ); stmt->setInt( 12, 0 ); g_charaDb.execute( stmt ); -} \ No newline at end of file +} diff --git a/src/servers/Server_Zone/Network/Handlers/ActionHandler.cpp b/src/servers/Server_Zone/Network/Handlers/ActionHandler.cpp index 94aa4e71..5d3eef1d 100644 --- a/src/servers/Server_Zone/Network/Handlers/ActionHandler.cpp +++ b/src/servers/Server_Zone/Network/Handlers/ActionHandler.cpp @@ -110,7 +110,7 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in case 0x68: // Remove status (clicking it off) { // todo: check if status can be removed by client from exd - pPlayer->removeSingleStatusEffectFromId( static_cast< uint32_t >( param1 ) ); + pPlayer->removeSingleStatusEffectById( static_cast< uint32_t >( param1 ) ); break; } case 0x69: // Cancel cast diff --git a/src/servers/Server_Zone/Network/PacketWrappers/PlayerSpawnPacket.h b/src/servers/Server_Zone/Network/PacketWrappers/PlayerSpawnPacket.h index 859af3ad..07c16ec1 100644 --- a/src/servers/Server_Zone/Network/PacketWrappers/PlayerSpawnPacket.h +++ b/src/servers/Server_Zone/Network/PacketWrappers/PlayerSpawnPacket.h @@ -8,7 +8,6 @@ #include "src/servers/Server_Zone/Forwards.h" #include "src/servers/Server_Zone/Inventory/Inventory.h" #include "src/servers/Server_Zone/Inventory/Item.h" -#include "src/servers/Server_Zone/StatusEffect/StatusEffectContainer.h" #include "src/servers/Server_Zone/StatusEffect/StatusEffect.h" namespace Core { @@ -122,10 +121,11 @@ namespace Server { uint64_t currentTimeMs = Util::getTimeMs(); - for( auto const& effect : pPlayer->getStatusEffectContainer()->getEffectMap() ) + for( auto const& effect : pPlayer->getStatusEffectMap() ) { m_data.effect[effect.first].effect_id = effect.second->getId(); - m_data.effect[effect.first].duration = static_cast< float >( effect.second->getDuration() - ( currentTimeMs - effect.second->getStartTimeMs() ) ) / 1000; + m_data.effect[effect.first].duration = static_cast< float >( effect.second->getDuration() - + ( currentTimeMs - effect.second->getStartTimeMs() ) ) / 1000; m_data.effect[effect.first].sourceActorId = effect.second->getSrcActorId(); m_data.effect[effect.first].unknown1 = effect.second->getParam(); } @@ -138,4 +138,4 @@ namespace Server { } } -#endif /*_PlayerSpawn_H*/ \ No newline at end of file +#endif /*_PlayerSpawn_H*/ diff --git a/src/servers/Server_Zone/StatusEffect/StatusEffectContainer.cpp b/src/servers/Server_Zone/StatusEffect/StatusEffectContainer.cpp deleted file mode 100644 index 6c623abc..00000000 --- a/src/servers/Server_Zone/StatusEffect/StatusEffectContainer.cpp +++ /dev/null @@ -1,218 +0,0 @@ -#include -#include - -#include "src/servers/Server_Zone/Actor/Actor.h" -#include "StatusEffect.h" -#include "StatusEffectContainer.h" -#include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket142.h" -#include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket143.h" - - -using namespace Core::Common; -using namespace Core::Network::Packets; -using namespace Core::Network::Packets::Server; - -Core::StatusEffect::StatusEffectContainer::StatusEffectContainer( Entity::ActorPtr pOwner ) - : m_pOwner( pOwner ) -{ - // initialize the free slot queue - for( uint8_t i = 0; i < MAX_EFFECTS; i++ ) - { - m_freeEffectSlotQueue.push( i ); - } -} - -int8_t Core::StatusEffect::StatusEffectContainer::getFreeSlot() -{ - int8_t freeEffectSlot = -1; - - if( m_freeEffectSlotQueue.empty() ) - return freeEffectSlot; - - freeEffectSlot = m_freeEffectSlotQueue.front(); - m_freeEffectSlotQueue.pop(); - - return freeEffectSlot; -} - -void Core::StatusEffect::StatusEffectContainer::freeSlot( uint8_t slotId ) -{ - m_freeEffectSlotQueue.push( slotId ); -} - - -Core::StatusEffect::StatusEffectContainer::~StatusEffectContainer() -{ -} - - -void Core::StatusEffect::StatusEffectContainer::addStatusEffect( StatusEffectPtr pEffect ) -{ - int8_t nextSlot = getFreeSlot(); - // if there is no slot left, do not add the effect - if( nextSlot == -1 ) - return; - - pEffect->applyStatus(); - m_effectMap[nextSlot] = pEffect; - - ZoneChannelPacket< Server::FFXIVIpcAddStatusEffect > statusEffectAdd( m_pOwner->getId() ); - statusEffectAdd.data().actor_id = pEffect->getTargetActorId(); - statusEffectAdd.data().actor_id1 = pEffect->getSrcActorId(); - statusEffectAdd.data().current_hp = m_pOwner->getHp(); - statusEffectAdd.data().current_mp = m_pOwner->getMp(); - statusEffectAdd.data().current_tp = m_pOwner->getTp(); - statusEffectAdd.data().duration = static_cast< float >( pEffect->getDuration() ) / 1000; - statusEffectAdd.data().effect_id = pEffect->getId(); - statusEffectAdd.data().effect_index = nextSlot; - statusEffectAdd.data().max_hp = m_pOwner->getMaxHp(); - statusEffectAdd.data().max_mp = m_pOwner->getMaxMp(); - statusEffectAdd.data().max_something = 1; - //statusEffectAdd.data().unknown2 = 28; - statusEffectAdd.data().param = pEffect->getParam(); - - - bool sendToSelf = m_pOwner->isPlayer() ? true : false; - m_pOwner->sendToInRangeSet( statusEffectAdd, sendToSelf ); - -} - -void Core::StatusEffect::StatusEffectContainer::removeSingleStatusEffectFromId( uint32_t id ) -{ - for (auto effectIt : m_effectMap) - { - if (effectIt.second->getId() == id) - { - removeStatusEffect( effectIt.first ); - break; - } - } -} - -void Core::StatusEffect::StatusEffectContainer::removeStatusEffect( uint8_t effectSlotId ) -{ - auto pEffectIt = m_effectMap.find( effectSlotId ); - if( pEffectIt == m_effectMap.end() ) - return; - - freeSlot( effectSlotId ); - - auto pEffect = pEffectIt->second; - pEffect->removeStatus(); - - bool sendToSelf = m_pOwner->isPlayer() ? true : false; - m_pOwner->sendToInRangeSet( ActorControlPacket142( m_pOwner->getId(), StatusEffectLose, pEffect->getId() ), sendToSelf ); - - m_effectMap.erase( effectSlotId ); - - sendUpdate(); -} - -std::map< uint8_t, Core::StatusEffect::StatusEffectPtr > Core::StatusEffect::StatusEffectContainer::getEffectMap() const -{ - return m_effectMap; -} - -void Core::StatusEffect::StatusEffectContainer::sendUpdate() -{ - uint64_t currentTimeMs = Util::getTimeMs(); - - ZoneChannelPacket< Server::FFXIVIpcStatusEffectList > statusEffectList( m_pOwner->getId() ); - - statusEffectList.data().current_hp = m_pOwner->getHp(); - statusEffectList.data().current_mp = m_pOwner->getMp(); - statusEffectList.data().currentTp = m_pOwner->getTp(); - statusEffectList.data().max_hp = m_pOwner->getMaxHp(); - statusEffectList.data().max_mp = m_pOwner->getMaxMp(); - uint8_t slot = 0; - for( auto effectIt : m_effectMap ) - { - float timeLeft = static_cast< float >( effectIt.second->getDuration() - ( currentTimeMs - effectIt.second->getStartTimeMs() ) ) / 1000; - statusEffectList.data().effect[slot].duration = timeLeft; - statusEffectList.data().effect[slot].effect_id = effectIt.second->getId(); - statusEffectList.data().effect[slot].sourceActorId = effectIt.second->getSrcActorId(); - slot++; - } - - bool sendToSelf = m_pOwner->isPlayer(); - m_pOwner->sendToInRangeSet( statusEffectList, sendToSelf ); - -} - -void Core::StatusEffect::StatusEffectContainer::update() -{ - uint64_t currentTimeMs = Util::getTimeMs(); - - uint32_t thisTickDmg = 0; - uint32_t thisTickHeal = 0; - - for( auto effectIt : m_effectMap ) - { - uint8_t effectIndex = effectIt.first; - auto effect = effectIt.second; - - uint64_t lastTick = effect->getLastTickMs(); - uint64_t startTime = effect->getStartTimeMs(); - uint32_t duration = effect->getDuration(); - uint32_t tickRate = effect->getTickRate(); - - if( ( currentTimeMs - startTime ) > duration ) - { - // remove status effect - removeStatusEffect( effectIndex ); - // break because removing invalidates iterators - break; - } - - if( ( currentTimeMs - lastTick ) > tickRate ) - { - 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 ) - { - m_pOwner->takeDamage( thisTickDmg ); - m_pOwner->sendToInRangeSet( ActorControlPacket142( m_pOwner->getId(), HPFloatingText, 0, static_cast< uint8_t >( ActionEffectType::Damage ), thisTickDmg ) ); - } - - if( thisTickHeal != 0 ) - { - m_pOwner->heal( thisTickDmg ); - m_pOwner->sendToInRangeSet( ActorControlPacket142( m_pOwner->getId(), HPFloatingText, 0, static_cast< uint8_t >( ActionEffectType::Heal ), thisTickHeal ) ); - } -} - -bool Core::StatusEffect::StatusEffectContainer::hasStatusEffect( uint32_t id ) -{ - for( auto effectIt : m_effectMap ) - { - if( effectIt.second->getId() == id ) - { - return true; - } - } - - return false; -} \ No newline at end of file diff --git a/src/servers/Server_Zone/StatusEffect/StatusEffectContainer.h b/src/servers/Server_Zone/StatusEffect/StatusEffectContainer.h deleted file mode 100644 index 22a43aae..00000000 --- a/src/servers/Server_Zone/StatusEffect/StatusEffectContainer.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _STATUSEFFECTCONTAINER_H_ -#define _STATUSEFFECTCONTAINER_H_ - -#include - -#include -#include - -#include "src/servers/Server_Zone/Forwards.h" - -namespace Core -{ -namespace StatusEffect -{ - -class StatusEffectContainer -{ -public: - StatusEffectContainer( Entity::ActorPtr pOwner ); - ~StatusEffectContainer(); - - void addStatusEffect( StatusEffectPtr pEffect ); - void removeStatusEffect( uint8_t effectSlotId ); - void removeSingleStatusEffectFromId( uint32_t id ); - void update(); - - bool hasStatusEffect( uint32_t id ); - - int8_t getFreeSlot(); - void freeSlot( uint8_t slotId ); - - std::map< uint8_t, Core::StatusEffect::StatusEffectPtr > getEffectMap() const; - - void sendUpdate(); - - -private: - const uint8_t MAX_EFFECTS = 30; - - Entity::ActorPtr m_pOwner; - std::queue< uint8_t > m_freeEffectSlotQueue; - - std::vector< std::pair< uint8_t, uint32_t> > m_tickEffectList; - std::map< uint8_t, StatusEffectPtr > m_effectMap; -}; - -} -} -#endif diff --git a/src/servers/Server_Zone/Zone/Cell.cpp b/src/servers/Server_Zone/Zone/Cell.cpp index 08e886b3..7a598ae7 100644 --- a/src/servers/Server_Zone/Zone/Cell.cpp +++ b/src/servers/Server_Zone/Zone/Cell.cpp @@ -47,7 +47,6 @@ namespace Core { entry->setCurrentZone( m_pZone ); - entry->getAsBattleNpc()->initStatusEffectContainer(); m_pZone->pushActor( entry ); } @@ -170,4 +169,4 @@ namespace Core m_bUnloadPending = false; } -} \ No newline at end of file +}