mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-25 14:07:46 +00:00
Removed statusEffectContainer, now directly part of Actor
This commit is contained in:
parent
65e90edb1b
commit
55c49b0bc4
12 changed files with 229 additions and 326 deletions
|
@ -6,7 +6,8 @@
|
||||||
<!-- Ip the lobby server listens on -->
|
<!-- Ip the lobby server listens on -->
|
||||||
<ListenIp>127.0.0.1</ListenIp>
|
<ListenIp>127.0.0.1</ListenIp>
|
||||||
<!-- Path of FFXIV dat files -->
|
<!-- Path of FFXIV dat files -->
|
||||||
<DataPath>C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv</DataPath>
|
<!-- <DataPath>C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv</DataPath> -->
|
||||||
|
<DataPath>/opt/sapphire_3_15_0/bin/sqpack</DataPath>
|
||||||
<!-- IP of the lobby server -->
|
<!-- IP of the lobby server -->
|
||||||
<LobbyHost>127.0.0.1</LobbyHost>
|
<LobbyHost>127.0.0.1</LobbyHost>
|
||||||
<!-- IP of the frontier server -->
|
<!-- IP of the frontier server -->
|
||||||
|
@ -16,10 +17,10 @@
|
||||||
<!-- Web server port -->
|
<!-- Web server port -->
|
||||||
<HttpPort>80</HttpPort>
|
<HttpPort>80</HttpPort>
|
||||||
<Mysql>
|
<Mysql>
|
||||||
<Host>127.0.0.1</Host>
|
<Host>localhost</Host>
|
||||||
<Port>3306</Port>
|
<Port>3306</Port>
|
||||||
<Username>root</Username>
|
<Username>root</Username>
|
||||||
<Pass></Pass>
|
<Pass>viridis0!</Pass>
|
||||||
<Database>sapphire</Database>
|
<Database>sapphire</Database>
|
||||||
</Mysql>
|
</Mysql>
|
||||||
</General>
|
</General>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
|
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()
|
else()
|
||||||
add_definitions(-D_WIN32_WINNT=0x601)
|
add_definitions(-D_WIN32_WINNT=0x601)
|
||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket144.h"
|
#include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket144.h"
|
||||||
#include "src/servers/Server_Zone/Network/PacketWrappers/UpdateHpMpTpPacket.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/StatusEffect/StatusEffect.h"
|
||||||
#include "src/servers/Server_Zone/Action/ActionCollision.h"
|
#include "src/servers/Server_Zone/Action/ActionCollision.h"
|
||||||
#include "src/servers/Server_Zone/ServerZone.h"
|
#include "src/servers/Server_Zone/ServerZone.h"
|
||||||
|
@ -33,6 +32,11 @@ using namespace Core::Network::Packets::Server;
|
||||||
|
|
||||||
Core::Entity::Actor::Actor()
|
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()
|
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 */
|
/*! \param StatusEffectPtr to be applied to the actor */
|
||||||
void Core::Entity::Actor::addStatusEffect( StatusEffect::StatusEffectPtr pEffect )
|
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 */
|
/*! \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 */
|
/*! \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 )
|
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(),
|
StatusEffect::StatusEffectPtr effect( new StatusEffect::StatusEffect( id, pSource.shared_from_this(),
|
||||||
shared_from_this(), duration, 3000 ) );
|
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
|
float Core::Entity::Actor::getRotation() const
|
||||||
{
|
{
|
||||||
return m_rot;
|
return m_rot;
|
||||||
|
@ -838,3 +854,154 @@ void Core::Entity::Actor::setRotation( float rot )
|
||||||
{
|
{
|
||||||
m_rot = 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;
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "src/servers/Server_Zone/Forwards.h"
|
#include "src/servers/Server_Zone/Forwards.h"
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
namespace Entity {
|
namespace Entity {
|
||||||
|
@ -160,11 +161,15 @@ protected:
|
||||||
uint64_t m_targetId;
|
uint64_t m_targetId;
|
||||||
/*! Ptr to a queued action */
|
/*! Ptr to a queued action */
|
||||||
Action::ActionPtr m_pCurrentAction;
|
Action::ActionPtr m_pCurrentAction;
|
||||||
/*! Container for status effects */
|
|
||||||
StatusEffect::StatusEffectContainerPtr m_pStatusEffectContainer;
|
|
||||||
/*! Invincibility type */
|
/*! Invincibility type */
|
||||||
Common::InvincibilityType m_invincibilityType;
|
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:
|
public:
|
||||||
Actor();
|
Actor();
|
||||||
|
|
||||||
|
@ -174,6 +179,30 @@ public:
|
||||||
|
|
||||||
uint32_t getId() const;
|
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( const Common::FFXIVARR_POSITION3& pos );
|
||||||
void setPosition( float x, float y, float z );
|
void setPosition( float x, float y, float z );
|
||||||
|
|
||||||
|
@ -303,20 +332,6 @@ public:
|
||||||
// set the current cell
|
// set the current cell
|
||||||
void setCell( Cell* pCell );
|
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?!
|
// TODO: Why did i even declare them publicly here?!
|
||||||
std::set< ActorPtr > m_inRangeActors;
|
std::set< ActorPtr > m_inRangeActors;
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "src/servers/Server_Zone/Network/PacketWrappers/MoveActorPacket.h"
|
#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/ActorControlPacket142.h"
|
||||||
#include "src/servers/Server_Zone/Network/PacketWrappers/ActorControlPacket143.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::Common;
|
||||||
using namespace Core::Network::Packets;
|
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,
|
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,
|
uint16_t bnpcBaseId, uint32_t type, uint8_t level, uint8_t behaviour,
|
||||||
uint32_t mobType )
|
uint32_t mobType ) : Actor()
|
||||||
{
|
{
|
||||||
BattleNpc::m_nextID++;
|
BattleNpc::m_nextID++;
|
||||||
m_id = 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
|
// spawn this player for pTarget
|
||||||
void Core::Entity::BattleNpc::spawn( Core::Entity::PlayerPtr pTarget )
|
void Core::Entity::BattleNpc::spawn( Core::Entity::PlayerPtr pTarget )
|
||||||
{
|
{
|
||||||
|
@ -487,9 +481,7 @@ void Core::Entity::BattleNpc::update( int64_t currTime )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !m_pStatusEffectContainer )
|
updateStatusEffects();
|
||||||
initStatusEffectContainer();
|
|
||||||
m_pStatusEffectContainer->update();
|
|
||||||
float distance = Math::Util::distance( m_pos.x, m_pos.y, m_pos.z,
|
float distance = Math::Util::distance( m_pos.x, m_pos.y, m_pos.z,
|
||||||
m_posOrigin.x, m_posOrigin.y, m_posOrigin.z );
|
m_posOrigin.x, m_posOrigin.y, m_posOrigin.z );
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,6 @@
|
||||||
|
|
||||||
#include "src/servers/Server_Zone/Script/ScriptManager.h"
|
#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/Item.h"
|
||||||
|
|
||||||
#include "src/servers/Server_Zone/Inventory/Inventory.h"
|
#include "src/servers/Server_Zone/Inventory/Inventory.h"
|
||||||
|
@ -57,6 +55,7 @@ using namespace Core::Network::Packets::Server;
|
||||||
|
|
||||||
// player constructor
|
// player constructor
|
||||||
Core::Entity::Player::Player() :
|
Core::Entity::Player::Player() :
|
||||||
|
Actor(),
|
||||||
m_lastWrite( 0 ),
|
m_lastWrite( 0 ),
|
||||||
m_lastPing( 0 ),
|
m_lastPing( 0 ),
|
||||||
m_bIsLogin( false ),
|
m_bIsLogin( false ),
|
||||||
|
@ -1045,7 +1044,7 @@ void Core::Entity::Player::update( int64_t currTime )
|
||||||
if( !isAlive() )
|
if( !isAlive() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_pStatusEffectContainer->update();
|
updateStatusEffects();
|
||||||
|
|
||||||
m_lastUpdate = currTime;
|
m_lastUpdate = currTime;
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
|
|
||||||
#include "src/servers/Server_Zone/Network/GameConnection.h"
|
#include "src/servers/Server_Zone/Network/GameConnection.h"
|
||||||
#include "src/servers/Server_Zone/Network/PacketWrappers/InitUIPacket.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 "src/servers/Server_Zone/Inventory/Inventory.h"
|
||||||
|
|
||||||
#include <Server_Common/Database/DatabaseDef.h>
|
#include <Server_Common/Database/DatabaseDef.h>
|
||||||
|
@ -211,8 +210,6 @@ bool Core::Entity::Player::load( uint32_t charId, Core::SessionPtr pSession )
|
||||||
|
|
||||||
initSpawnIdQueue();
|
initSpawnIdQueue();
|
||||||
|
|
||||||
m_pStatusEffectContainer = StatusEffect::StatusEffectContainerPtr( new StatusEffect::StatusEffectContainer( shared_from_this() ) );
|
|
||||||
|
|
||||||
if( !m_playerIdToSpawnIdMap.empty() )
|
if( !m_playerIdToSpawnIdMap.empty() )
|
||||||
m_playerIdToSpawnIdMap.clear();
|
m_playerIdToSpawnIdMap.clear();
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in
|
||||||
case 0x68: // Remove status (clicking it off)
|
case 0x68: // Remove status (clicking it off)
|
||||||
{
|
{
|
||||||
// todo: check if status can be removed by client from exd
|
// 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;
|
break;
|
||||||
}
|
}
|
||||||
case 0x69: // Cancel cast
|
case 0x69: // Cancel cast
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include "src/servers/Server_Zone/Forwards.h"
|
#include "src/servers/Server_Zone/Forwards.h"
|
||||||
#include "src/servers/Server_Zone/Inventory/Inventory.h"
|
#include "src/servers/Server_Zone/Inventory/Inventory.h"
|
||||||
#include "src/servers/Server_Zone/Inventory/Item.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"
|
#include "src/servers/Server_Zone/StatusEffect/StatusEffect.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
@ -122,10 +121,11 @@ namespace Server {
|
||||||
|
|
||||||
uint64_t currentTimeMs = Util::getTimeMs();
|
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].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].sourceActorId = effect.second->getSrcActorId();
|
||||||
m_data.effect[effect.first].unknown1 = effect.second->getParam();
|
m_data.effect[effect.first].unknown1 = effect.second->getParam();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,218 +0,0 @@
|
||||||
#include <src/servers/Server_Common/Util/Util.h>
|
|
||||||
#include <src/servers/Server_Common/Network/PacketDef/Zone/ServerZoneDef.h>
|
|
||||||
|
|
||||||
#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;
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
#ifndef _STATUSEFFECTCONTAINER_H_
|
|
||||||
#define _STATUSEFFECTCONTAINER_H_
|
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
|
|
||||||
#include <queue>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#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
|
|
|
@ -47,7 +47,6 @@ namespace Core
|
||||||
{
|
{
|
||||||
|
|
||||||
entry->setCurrentZone( m_pZone );
|
entry->setCurrentZone( m_pZone );
|
||||||
entry->getAsBattleNpc()->initStatusEffectContainer();
|
|
||||||
m_pZone->pushActor( entry );
|
m_pZone->pushActor( entry );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue