diff --git a/src/Abilities.cpp b/src/Abilities.cpp index 63586a9..d1fa9a4 100644 --- a/src/Abilities.cpp +++ b/src/Abilities.cpp @@ -1,5 +1,7 @@ #include "Abilities.hpp" +#include "servers/CNShardServer.hpp" + #include "NPCManager.hpp" #include "PlayerManager.hpp" #include "Buffs.hpp" @@ -55,7 +57,7 @@ static SkillResult handleSkillDamageNDebuff(SkillData* skill, int power, ICombat duration = skill->durationTime[power]; strength = skill->values[0][power]; BuffStack debuff = { - duration, // ticks + (duration * 100) / MS_PER_COMBAT_TICK, // ticks strength, // value source->getRef(), // source BuffClass::NANO, // buff class @@ -64,9 +66,10 @@ static SkillResult handleSkillDamageNDebuff(SkillData* skill, int power, ICombat target->addBuff(timeBuffId, [](EntityRef self, Buff* buff, int status, BuffStack* stack) { Buffs::timeBuffUpdate(self, buff, status, stack); + if(status == ETBU_DEL) Buffs::timeBuffTimeout(self); }, [](EntityRef self, Buff* buff, time_t currTime) { - // no-op + //Buffs::timeBuffTick(self, buff); }, &debuff); } diff --git a/src/Buffs.cpp b/src/Buffs.cpp index 072001f..2b42e15 100644 --- a/src/Buffs.cpp +++ b/src/Buffs.cpp @@ -137,6 +137,18 @@ void Buffs::timeBuffUpdate(EntityRef self, Buff* buff, int status, BuffStack* st self.sock->sendPacket((void*)&pkt, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE)); } +void Buffs::timeBuffTick(EntityRef self, Buff* buff) { + if(self.kind != EntityKind::COMBAT_NPC && self.kind != EntityKind::MOB) + return; // not implemented + Entity* entity = self.getEntity(); + ICombatant* combatant = dynamic_cast(entity); + INITSTRUCT(sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK, pkt); + pkt.eCT = combatant->getCharType(); + pkt.iID = combatant->getID(); + pkt.iTB_ID = buff->id; + NPCManager::sendToViewable(entity, &pkt, P_FE2CL_CHAR_TIME_BUFF_TIME_TICK, sizeof(sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK)); +} + void Buffs::timeBuffTimeout(EntityRef self) { if(self.kind != EntityKind::PLAYER && self.kind != EntityKind::COMBAT_NPC && self.kind != EntityKind::MOB) return; // not a combatant diff --git a/src/Buffs.hpp b/src/Buffs.hpp index 3247143..95718af 100644 --- a/src/Buffs.hpp +++ b/src/Buffs.hpp @@ -86,5 +86,6 @@ public: namespace Buffs { void timeBuffUpdate(EntityRef self, Buff* buff, int status, BuffStack* stack); + void timeBuffTick(EntityRef self, Buff* buff); void timeBuffTimeout(EntityRef self); } diff --git a/src/MobAI.cpp b/src/MobAI.cpp index bcadb87..70a8d8e 100644 --- a/src/MobAI.cpp +++ b/src/MobAI.cpp @@ -565,8 +565,17 @@ void MobAI::combatStep(CombatNPC* npc, time_t currTime) { return; // tick buffs - for(auto buffEntry : self->buffs) { - buffEntry.second->combatTick(currTime); + auto it = npc->buffs.begin(); + while(it != npc->buffs.end()) { + Buff* buff = (*it).second; + buff->combatTick(currTime); + buff->tick(currTime); + if(buff->isStale()) { + // garbage collect + it = npc->buffs.erase(it); + delete buff; + } + else it++; } // skip attack if stunned or asleep diff --git a/src/NPCManager.cpp b/src/NPCManager.cpp index f1a5e13..cba6656 100644 --- a/src/NPCManager.cpp +++ b/src/NPCManager.cpp @@ -376,5 +376,5 @@ void NPCManager::init() { REGISTER_SHARD_PACKET(P_CL2FE_REQ_NPC_UNSUMMON, npcUnsummonHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_BARKER, npcBarkHandler); - REGISTER_SHARD_TIMER(step, 200); + REGISTER_SHARD_TIMER(step, MS_PER_COMBAT_TICK); } diff --git a/src/servers/CNShardServer.hpp b/src/servers/CNShardServer.hpp index c585428..7ed4e3f 100644 --- a/src/servers/CNShardServer.hpp +++ b/src/servers/CNShardServer.hpp @@ -8,6 +8,7 @@ #define REGISTER_SHARD_PACKET(pactype, handlr) CNShardServer::ShardPackets[pactype] = handlr; #define REGISTER_SHARD_TIMER(handlr, delta) CNShardServer::Timers.push_back(TimerEvent(handlr, delta)); #define MS_PER_PLAYER_TICK 500 +#define MS_PER_COMBAT_TICK 200 class CNShardServer : public CNServer { private: