1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-30 16:17:46 +00:00

Merge pull request #53 from amibu01/master

DoTs/HoTs, fixed status effects for players, more skill scripting and World ID parameter for lobby
This commit is contained in:
SapphireMordred 2017-08-15 11:48:15 +02:00 committed by GitHub
commit bed32e9cc9
24 changed files with 260 additions and 33 deletions

View file

@ -27,5 +27,7 @@
<Parameters> <Parameters>
<!-- Do not disconnect players without a session - this should be definitely disabled unless you are testing on a PS4 --> <!-- Do not disconnect players without a session - this should be definitely disabled unless you are testing on a PS4 -->
<AllowNoSessionConnect>false</AllowNoSessionConnect> <AllowNoSessionConnect>false</AllowNoSessionConnect>
<!-- The ID of the Sapphire world - this is what the game determines your datacenter with, check world.exh -->
<WorldID>67</WorldID>
</Parameters> </Parameters>
</Settings> </Settings>

View file

@ -224,3 +224,10 @@ GLOBAL CURRENCY_MGP = 0X0B
GLOBAL CURRENCY_TOMESTONELAW = 0X0C GLOBAL CURRENCY_TOMESTONELAW = 0X0C
GLOBAL CURRENCY_TOMESTONEESO = 0X0D GLOBAL CURRENCY_TOMESTONEESO = 0X0D
GLOBAL CURRENCY_TOMESTONELORE = 0X0E GLOBAL CURRENCY_TOMESTONELORE = 0X0E
////////////////////////////////////////////////////////////
// Skill handle types
////////////////////////////////////////////////////////////
GLOBAL STD_DAMAGE = 0X00
GLOBAL STD_HEAL = 0X01
GLOBAL STD_DOT = 0X02

View file

@ -0,0 +1,18 @@
// Skill Name: Sprint
// Skill ID: 3
class skillDef_120Def
{
def skillDef_120Def()
{
}
def onFinish( player, target )
{
player.handleScriptSkill( STD_HEAL, 120, 1000, 0, target );
}
};
GLOBAL skillDef_120 = skillDef_120Def();

View file

@ -0,0 +1,18 @@
// Skill Name: Sprint
// Skill ID: 3
class skillDef_121Def
{
def skillDef_121Def()
{
}
def onFinish( player, target )
{
target.addStatusEffectById(143, 20000, 0);
}
};
GLOBAL skillDef_121 = skillDef_121Def();

View file

@ -0,0 +1,18 @@
// Skill Name: Sprint
// Skill ID: 3
class skillDef_127Def
{
def skillDef_127Def()
{
}
def onFinish( player, target )
{
player.handleScriptSkill( STD_DAMAGE, 127, 1000, 0, target );
}
};
GLOBAL skillDef_127 = skillDef_127Def();

View file

@ -0,0 +1,19 @@
// Status Name: Wind
// Status ID: 143
class statusDef_143Def
{
def statusDef_143Def()
{
}
def onTick( actor, effect )
{
print("tick");
effect.registerTickEffect( 1, 30 );
}
};
GLOBAL statusDef_143 = statusDef_143Def();

View file

@ -545,6 +545,13 @@ namespace Core {
}; };
enum HandleSkillType : uint8_t
{
StdDamage,
StdHeal,
StdDot,
};
enum struct PlayerStateFlag : uint8_t enum struct PlayerStateFlag : uint8_t
{ {
NoCombat, NoCombat,
@ -695,6 +702,7 @@ namespace Core {
StatusEffectGain = 0x14, StatusEffectGain = 0x14,
StatusEffectLose = 0x15, StatusEffectLose = 0x15,
HPFloatingText = 0x17,
UpdateRestedExp = 0x018, UpdateRestedExp = 0x018,
Unk2 = 0x19, Unk2 = 0x19,

View file

@ -410,7 +410,7 @@ struct FFXIVIpcUpdateHpMpTp : FFXIVIpcBasePacket<UpdateHpMpTp>
/** /**
* Structural representation of the packet sent by the server * Structural representation of the packet sent by the server
* to update HP / MP / TP * for battle actions
*/ */
struct effectEntry struct effectEntry
{ {

View file

@ -104,7 +104,7 @@ void Core::Network::GameConnection::getCharList( FFXIVARR_PACKET_RAW& packet, ui
serverListPacket.data().seq = 1; serverListPacket.data().seq = 1;
serverListPacket.data().offset = 0; serverListPacket.data().offset = 0;
serverListPacket.data().numServers = 1; serverListPacket.data().numServers = 1;
serverListPacket.data().server[0].id = 1; serverListPacket.data().server[0].id = g_serverLobby.m_pConfig->getValue<uint16_t>( "Settings.Parameters.WorldID", 1 );
serverListPacket.data().server[0].index = 0; serverListPacket.data().server[0].index = 0;
serverListPacket.data().final = 1; serverListPacket.data().final = 1;
sprintf( serverListPacket.data().server[0].name, "Sapphire" ); sprintf( serverListPacket.data().server[0].name, "Sapphire" );
@ -141,7 +141,7 @@ void Core::Network::GameConnection::getCharList( FFXIVARR_PACKET_RAW& packet, ui
auto& charEntry = charList[charIndex]; auto& charEntry = charList[charIndex];
details.uniqueId = get<1>( charEntry ); details.uniqueId = get<1>( charEntry );
details.contentId = get<2>( charEntry ); details.contentId = get<2>( charEntry );
details.serverId = 1; details.serverId = g_serverLobby.m_pConfig->getValue<uint16_t>( "Settings.Parameters.WorldID", 1 );
details.index = charIndex; details.index = charIndex;
strcpy( details.charDetailJson, get<3>( charEntry ).c_str() ); strcpy( details.charDetailJson, get<3>( charEntry ).c_str() );
strcpy( details.nameChara, get<0>( charEntry ).c_str() ); strcpy( details.nameChara, get<0>( charEntry ).c_str() );

View file

@ -75,22 +75,7 @@ void Core::Action::ActionCast::onFinish()
pPlayer->unsetStateFlag( PlayerStateFlag::Casting ); pPlayer->unsetStateFlag( PlayerStateFlag::Casting );
pPlayer->sendStateFlags(); pPlayer->sendStateFlags();
GamePacketNew< FFXIVIpcEffect > effectPacket( pPlayer->getId() );
effectPacket.data().targetId = m_pTarget->getId();
effectPacket.data().actionAnimationId = m_id;
effectPacket.data().unknown_2 = 0;
// effectPacket.data().unknown_3 = 1;
effectPacket.data().actionTextId = m_id;
effectPacket.data().numEffects = 1;
effectPacket.data().rotation = Math::Util::floatToUInt16Rot( pPlayer->getRotation() );
effectPacket.data().effectTarget = m_pTarget->getId();
effectPacket.data().effects[0].param1 = 30;
effectPacket.data().effects[0].unknown_1 = 3;
effectPacket.data().effects[0].unknown_2 = 1;
effectPacket.data().effects[0].unknown_3 = 7;
pPlayer->sendToInRangeSet( effectPacket, true );
m_pTarget->takeDamage( 30 );
g_scriptMgr.onCastFinish( pPlayer, m_pTarget, m_id ); g_scriptMgr.onCastFinish( pPlayer, m_pTarget, m_id );
} }

View file

@ -337,6 +337,25 @@ void Core::Entity::Actor::takeDamage( uint32_t damage )
sendStatusUpdate( false ); sendStatusUpdate( false );
} }
/*!
Let an actor get healed and perform necessary steps
according to resulting hp, propagates new hp value to players
in range
\param amount of hp to be healed
*/
void Core::Entity::Actor::heal( uint32_t amount )
{
if( ( m_hp + amount ) > getMaxHp() )
{
m_hp = getMaxHp();
}
else
m_hp += amount;
sendStatusUpdate( false );
}
/*! /*!
Send an HpMpTp update to players in range ( and potentially to self ) 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 TODO: poor naming, should be changed. Status is not HP. Also should be virtual

View file

@ -245,6 +245,7 @@ public:
virtual uint8_t getLevel() const; virtual uint8_t getLevel() const;
virtual void sendStatusUpdate( bool toSelf = true ); virtual void sendStatusUpdate( bool toSelf = true );
virtual void takeDamage( uint32_t damage ); virtual void takeDamage( uint32_t damage );
virtual void heal( uint32_t amount );
virtual bool checkAction(); virtual bool checkAction();
virtual void update( int64_t currTime ) {}; virtual void update( int64_t currTime ) {};

View file

@ -15,6 +15,7 @@
#include "MoveActorPacket.h" #include "MoveActorPacket.h"
#include "ActorControlPacket142.h" #include "ActorControlPacket142.h"
#include "ActorControlPacket143.h" #include "ActorControlPacket143.h"
#include "StatusEffectContainer.h"
using namespace Core::Common; using namespace Core::Common;
using namespace Core::Network::Packets; using namespace Core::Network::Packets;
@ -84,6 +85,10 @@ Core::Entity::BattleNpc::BattleNpc( uint32_t modelId, uint32_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 )
@ -482,7 +487,7 @@ void Core::Entity::BattleNpc::update( int64_t currTime )
return; return;
} }
//m_pStatusEffectContainer->update(); 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 );

View file

@ -36,6 +36,8 @@ public:
// const Common::FFXIVARR_POSITION3& spawnPos, // const Common::FFXIVARR_POSITION3& spawnPos,
// uint32_t type = 2, uint32_t behaviour = 1, uint32_t mobType = 0 ); // uint32_t type = 2, uint32_t behaviour = 1, uint32_t mobType = 0 );
void initStatusEffectContainer();
// send spawn packets to pTarget // send spawn packets to pTarget
void spawn( PlayerPtr pTarget ) override; void spawn( PlayerPtr pTarget ) override;

View file

@ -46,6 +46,7 @@ namespace Core
{ {
entry->setCurrentZone( m_pZone ); entry->setCurrentZone( m_pZone );
entry->getAsBattleNpc()->initStatusEffectContainer();
m_pZone->pushActor( entry ); m_pZone->pushActor( entry );
} }

View file

@ -1499,3 +1499,62 @@ void Core::Entity::Player::autoAttack( ActorPtr pTarget )
pTarget->takeDamage(damage); pTarget->takeDamage(damage);
} }
void Core::Entity::Player::handleScriptSkill( uint32_t type, uint32_t actionId, uint64_t param1, uint64_t param2, Entity::Actor& pTarget )
{
sendDebug( std::to_string( pTarget.getId() ) );
sendDebug( "Handle script skill type: " + std::to_string( type ) );
switch( type )
{
case Core::Common::HandleSkillType::StdDamage:
{
sendDebug( "STD_DAMAGE" );
GamePacketNew< FFXIVIpcEffect > effectPacket( getId() );
effectPacket.data().targetId = pTarget.getId();
effectPacket.data().actionAnimationId = actionId;
effectPacket.data().unknown_2 = 0;
// effectPacket.data().unknown_3 = 1;
effectPacket.data().actionTextId = actionId;
effectPacket.data().numEffects = 1;
effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() );
effectPacket.data().effectTarget = pTarget.getId();
effectPacket.data().effects[0].param1 = param1;
effectPacket.data().effects[0].unknown_1 = 3;
effectPacket.data().effects[0].unknown_2 = 1;
effectPacket.data().effects[0].unknown_3 = 7;
sendToInRangeSet( effectPacket, true );
pTarget.takeDamage( param1 );
break;
}
case Core::Common::HandleSkillType::StdHeal:
{
sendDebug( "STD_HEAL" );
GamePacketNew< FFXIVIpcEffect > effectPacket( getId() );
effectPacket.data().targetId = pTarget.getId();
effectPacket.data().actionAnimationId = actionId;
effectPacket.data().unknown_2 = 0;
// effectPacket.data().unknown_3 = 1;
effectPacket.data().actionTextId = actionId;
effectPacket.data().numEffects = 1;
effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() );
effectPacket.data().effectTarget = pTarget.getId();
effectPacket.data().effects[0].param1 = param1;
effectPacket.data().effects[0].unknown_1 = 4;
effectPacket.data().effects[0].unknown_2 = 1;
effectPacket.data().effects[0].unknown_3 = 7;
sendToInRangeSet( effectPacket, true );
pTarget.heal( param1 );
break;
}
default:
break;
}
}

View file

@ -482,6 +482,8 @@ public:
void setAutoattack( bool mode ); void setAutoattack( bool mode );
bool isAutoattackOn() const; bool isAutoattackOn() const;
void handleScriptSkill( uint32_t type, uint32_t actionId, uint64_t param1, uint64_t param2, Entity::Actor& target );
private: private:
uint32_t m_lastWrite; uint32_t m_lastWrite;
uint32_t m_lastPing; uint32_t m_lastPing;

View file

@ -12,6 +12,7 @@
#include "Event.h" #include "Event.h"
#include "EventHelper.h" #include "EventHelper.h"
#include "ScriptManager.h" #include "ScriptManager.h"
#include "StatusEffect.h"
#include "ServerNoticePacket.h" #include "ServerNoticePacket.h"
@ -405,33 +406,39 @@ bool Core::Scripting::ScriptManager::onStatusReceive( Entity::ActorPtr pActor, u
auto obj = m_pChaiHandler->eval( "statusDef_" + std::to_string( effectId ) ); auto obj = m_pChaiHandler->eval( "statusDef_" + std::to_string( effectId ) );
std::string objName = "statusDef_" + std::to_string( effectId ); std::string objName = "statusDef_" + std::to_string( effectId );
if( pActor->isPlayer() )
pActor->getAsPlayer()->sendDebug( "Calling: " + objName + "." + eventName ); pActor->getAsPlayer()->sendDebug( "Calling: " + objName + "." + eventName );
auto fn = m_pChaiHandler->eval< std::function< void( chaiscript::Boxed_Value &, Entity::Actor&) > >( eventName ); auto fn = m_pChaiHandler->eval< std::function< void( chaiscript::Boxed_Value &, Entity::Actor&) > >( eventName );
fn( obj, *pActor ); fn( obj, *pActor );
} }
catch( std::exception& e ) catch( std::exception& e )
{ {
if( pActor->isPlayer() )
pActor->getAsPlayer()->sendUrgent( e.what() ); pActor->getAsPlayer()->sendUrgent( e.what() );
} }
return true; return true;
} }
bool Core::Scripting::ScriptManager::onStatusTick( Entity::ActorPtr pActor, uint32_t effectId ) bool Core::Scripting::ScriptManager::onStatusTick( Entity::ActorPtr pActor, Core::StatusEffect::StatusEffect& effect )
{ {
std::string eventName = "onTick"; std::string eventName = "onTick";
try try
{ {
auto obj = m_pChaiHandler->eval( "statusDef_" + std::to_string( effectId ) ); auto obj = m_pChaiHandler->eval( "statusDef_" + std::to_string( effect.getId() ) );
std::string objName = "statusDef_" + std::to_string( effectId ); std::string objName = "statusDef_" + std::to_string( effect.getId() );
if( pActor->isPlayer() )
pActor->getAsPlayer()->sendDebug( "Calling: " + objName + "." + eventName ); pActor->getAsPlayer()->sendDebug( "Calling: " + objName + "." + eventName );
auto fn = m_pChaiHandler->eval< std::function< void( chaiscript::Boxed_Value &, Entity::Actor& ) > >( eventName );
fn( obj, *pActor ); auto fn = m_pChaiHandler->eval< std::function< void( chaiscript::Boxed_Value &, Entity::Actor&, Core::StatusEffect::StatusEffect& ) > >( eventName );
fn( obj, *pActor, effect );
} }
catch( std::exception& e ) catch( std::exception& e )
{ {
if( pActor->isPlayer() )
pActor->getAsPlayer()->sendUrgent( e.what() ); pActor->getAsPlayer()->sendUrgent( e.what() );
} }
@ -447,12 +454,15 @@ bool Core::Scripting::ScriptManager::onStatusTimeOut( Entity::ActorPtr pActor, u
auto obj = m_pChaiHandler->eval( "statusDef_" + std::to_string( effectId ) ); auto obj = m_pChaiHandler->eval( "statusDef_" + std::to_string( effectId ) );
std::string objName = "statusDef_" + std::to_string( effectId ); std::string objName = "statusDef_" + std::to_string( effectId );
if( pActor->isPlayer() )
pActor->getAsPlayer()->sendDebug( "Calling: " + objName + "." + eventName ); pActor->getAsPlayer()->sendDebug( "Calling: " + objName + "." + eventName );
auto fn = m_pChaiHandler->eval< std::function< void( chaiscript::Boxed_Value &, Entity::Actor& ) > >( eventName ); auto fn = m_pChaiHandler->eval< std::function< void( chaiscript::Boxed_Value &, Entity::Actor& ) > >( eventName );
fn( obj, *pActor ); fn( obj, *pActor );
} }
catch( std::exception& e ) catch( std::exception& e )
{ {
if( pActor->isPlayer() )
pActor->getAsPlayer()->sendUrgent( e.what() ); pActor->getAsPlayer()->sendUrgent( e.what() );
} }

View file

@ -53,7 +53,7 @@ namespace Core
bool onCastFinish( Entity::PlayerPtr pPlayer, Entity::ActorPtr pTarget, uint32_t actionId ); bool onCastFinish( Entity::PlayerPtr pPlayer, Entity::ActorPtr pTarget, uint32_t actionId );
bool onStatusReceive( Entity::ActorPtr pActor, uint32_t effectId ); bool onStatusReceive( Entity::ActorPtr pActor, uint32_t effectId );
bool onStatusTick( Entity::ActorPtr pActor, uint32_t effectId ); bool onStatusTick( Entity::ActorPtr pActor, Core::StatusEffect::StatusEffect& effect );
bool onStatusTimeOut( Entity::ActorPtr pActor, uint32_t effectId ); bool onStatusTimeOut( Entity::ActorPtr pActor, uint32_t effectId );
bool onZoneInit( ZonePtr pZone ); bool onZoneInit( ZonePtr pZone );

View file

@ -35,6 +35,7 @@ int Core::Scripting::ScriptManager::init()
m_pChaiHandler->add( chaiscript::fun( &Entity::Actor::getTargetId ), "getTargetId" ); m_pChaiHandler->add( chaiscript::fun( &Entity::Actor::getTargetId ), "getTargetId" );
m_pChaiHandler->add( chaiscript::fun( &Entity::Actor::addStatusEffect ), "addStatusEffect" ); m_pChaiHandler->add( chaiscript::fun( &Entity::Actor::addStatusEffect ), "addStatusEffect" );
m_pChaiHandler->add( chaiscript::fun( &Entity::Actor::addStatusEffectById ), "addStatusEffectById" ); m_pChaiHandler->add( chaiscript::fun( &Entity::Actor::addStatusEffectById ), "addStatusEffectById" );
m_pChaiHandler->add( chaiscript::fun( &Entity::Actor::takeDamage ), "takeDamage" );
m_pChaiHandler->add( chaiscript::fun( &Entity::Player::forceZoneing ), "setZone" ); m_pChaiHandler->add( chaiscript::fun( &Entity::Player::forceZoneing ), "setZone" );
m_pChaiHandler->add( chaiscript::fun( &Entity::Player::getClassAsInt ), "getClass" ); m_pChaiHandler->add( chaiscript::fun( &Entity::Player::getClassAsInt ), "getClass" );
@ -65,6 +66,7 @@ int Core::Scripting::ScriptManager::init()
m_pChaiHandler->add( chaiscript::fun( &Entity::Player::getQuestSeq ), "questGetSeq" ); m_pChaiHandler->add( chaiscript::fun( &Entity::Player::getQuestSeq ), "questGetSeq" );
m_pChaiHandler->add( chaiscript::fun( &Entity::Player::hasQuest ), "hasQuest" ); m_pChaiHandler->add( chaiscript::fun( &Entity::Player::hasQuest ), "hasQuest" );
m_pChaiHandler->add( chaiscript::fun( &Entity::Player::getZoneId ), "getZoneId" ); m_pChaiHandler->add( chaiscript::fun( &Entity::Player::getZoneId ), "getZoneId" );
m_pChaiHandler->add( chaiscript::fun( &Entity::Player::handleScriptSkill ), "handleScriptSkill" );
m_pChaiHandler->add( chaiscript::fun( &Core::Event::mapEventActorToRealActor ), "mapActor" ); m_pChaiHandler->add( chaiscript::fun( &Core::Event::mapEventActorToRealActor ), "mapActor" );
@ -158,6 +160,8 @@ int Core::Scripting::ScriptManager::init()
m_pChaiHandler->add( chaiscript::user_type< Entity::BattleNpc >(), "BattleNpc" ); m_pChaiHandler->add( chaiscript::user_type< Entity::BattleNpc >(), "BattleNpc" );
m_pChaiHandler->add( chaiscript::user_type< StatusEffect::StatusEffect >(), "StatusEffect" ); m_pChaiHandler->add( chaiscript::user_type< StatusEffect::StatusEffect >(), "StatusEffect" );
m_pChaiHandler->add( chaiscript::fun( &StatusEffect::StatusEffect::registerTickEffect ), "registerTickEffect" );
m_pChaiHandler->add( chaiscript::user_type< Zone >(), "Zone" ); m_pChaiHandler->add( chaiscript::user_type< Zone >(), "Zone" );
m_pChaiHandler->add( chaiscript::fun( &Zone::getName ), "getName" ); m_pChaiHandler->add( chaiscript::fun( &Zone::getName ), "getName" );

View file

@ -50,11 +50,22 @@ Core::StatusEffect::StatusEffect::~StatusEffect()
{ {
} }
void Core::StatusEffect::StatusEffect::registerTickEffect( uint8_t type, uint32_t param )
{
m_currTickEffect = std::make_pair( type, param );
}
std::pair< uint8_t, uint32_t> Core::StatusEffect::StatusEffect::getTickEffect()
{
auto thisTick = m_currTickEffect;
m_currTickEffect = std::make_pair( 0, 0 );
return thisTick;
}
void Core::StatusEffect::StatusEffect::onTick() void Core::StatusEffect::StatusEffect::onTick()
{ {
m_lastTick = Util::getTimeMs(); m_lastTick = Util::getTimeMs();
g_scriptMgr.onStatusTick( m_targetActor, m_id ); g_scriptMgr.onStatusTick( m_targetActor, *this );
} }
uint32_t Core::StatusEffect::StatusEffect::getSrcActorId() const uint32_t Core::StatusEffect::StatusEffect::getSrcActorId() const

View file

@ -33,6 +33,8 @@ public:
uint16_t getParam() const; uint16_t getParam() const;
void setLastTick( uint64_t lastTick ); void setLastTick( uint64_t lastTick );
void setParam( uint16_t param ); void setParam( uint16_t param );
void registerTickEffect( uint8_t type, uint32_t param );
std::pair< uint8_t, uint32_t> getTickEffect();
const std::string& getName() const; const std::string& getName() const;
private: private:
@ -45,6 +47,7 @@ private:
uint64_t m_lastTick; uint64_t m_lastTick;
uint16_t m_param; uint16_t m_param;
std::string m_name; std::string m_name;
std::pair< uint8_t, uint32_t> m_currTickEffect;
}; };

View file

@ -125,6 +125,9 @@ void Core::StatusEffect::StatusEffectContainer::update()
{ {
uint64_t currentTimeMs = Util::getTimeMs(); uint64_t currentTimeMs = Util::getTimeMs();
uint64_t thisTickDmg = 0;
uint64_t thisTickHeal = 0;
for( auto effectIt : m_effectMap ) for( auto effectIt : m_effectMap )
{ {
uint8_t effectIndex = effectIt.first; uint8_t effectIndex = effectIt.first;
@ -147,7 +150,38 @@ void Core::StatusEffect::StatusEffectContainer::update()
{ {
effect->setLastTick( currentTimeMs ); effect->setLastTick( currentTimeMs );
effect->onTick(); 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, 3, thisTickDmg ) );
}
if( thisTickHeal != 0 )
{
m_pOwner->heal( thisTickDmg );
m_pOwner->sendToInRangeSet( ActorControlPacket142( m_pOwner->getId(), HPFloatingText, 0, 4, thisTickHeal ) );
}
} }

View file

@ -36,6 +36,7 @@ private:
std::queue< uint8_t > m_freeEffectSlotQueue; std::queue< uint8_t > m_freeEffectSlotQueue;
std::vector< StatusEffectPtr > m_effectList; std::vector< StatusEffectPtr > m_effectList;
std::vector< std::pair< uint8_t, uint32_t> > m_tickEffectList;
std::map< uint8_t, StatusEffectPtr > m_effectMap; std::map< uint8_t, StatusEffectPtr > m_effectMap;
}; };