Tick buffs for mobs

This commit is contained in:
gsemaj 2023-07-25 19:00:35 +00:00
parent 288a4a3da5
commit 464d18820b
6 changed files with 31 additions and 5 deletions

View File

@ -1,5 +1,7 @@
#include "Abilities.hpp" #include "Abilities.hpp"
#include "servers/CNShardServer.hpp"
#include "NPCManager.hpp" #include "NPCManager.hpp"
#include "PlayerManager.hpp" #include "PlayerManager.hpp"
#include "Buffs.hpp" #include "Buffs.hpp"
@ -55,7 +57,7 @@ static SkillResult handleSkillDamageNDebuff(SkillData* skill, int power, ICombat
duration = skill->durationTime[power]; duration = skill->durationTime[power];
strength = skill->values[0][power]; strength = skill->values[0][power];
BuffStack debuff = { BuffStack debuff = {
duration, // ticks (duration * 100) / MS_PER_COMBAT_TICK, // ticks
strength, // value strength, // value
source->getRef(), // source source->getRef(), // source
BuffClass::NANO, // buff class BuffClass::NANO, // buff class
@ -64,9 +66,10 @@ static SkillResult handleSkillDamageNDebuff(SkillData* skill, int power, ICombat
target->addBuff(timeBuffId, target->addBuff(timeBuffId,
[](EntityRef self, Buff* buff, int status, BuffStack* stack) { [](EntityRef self, Buff* buff, int status, BuffStack* stack) {
Buffs::timeBuffUpdate(self, buff, status, stack); Buffs::timeBuffUpdate(self, buff, status, stack);
if(status == ETBU_DEL) Buffs::timeBuffTimeout(self);
}, },
[](EntityRef self, Buff* buff, time_t currTime) { [](EntityRef self, Buff* buff, time_t currTime) {
// no-op //Buffs::timeBuffTick(self, buff);
}, },
&debuff); &debuff);
} }

View File

@ -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)); 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<ICombatant*>(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) { void Buffs::timeBuffTimeout(EntityRef self) {
if(self.kind != EntityKind::PLAYER && self.kind != EntityKind::COMBAT_NPC && self.kind != EntityKind::MOB) if(self.kind != EntityKind::PLAYER && self.kind != EntityKind::COMBAT_NPC && self.kind != EntityKind::MOB)
return; // not a combatant return; // not a combatant

View File

@ -86,5 +86,6 @@ public:
namespace Buffs { namespace Buffs {
void timeBuffUpdate(EntityRef self, Buff* buff, int status, BuffStack* stack); void timeBuffUpdate(EntityRef self, Buff* buff, int status, BuffStack* stack);
void timeBuffTick(EntityRef self, Buff* buff);
void timeBuffTimeout(EntityRef self); void timeBuffTimeout(EntityRef self);
} }

View File

@ -565,8 +565,17 @@ void MobAI::combatStep(CombatNPC* npc, time_t currTime) {
return; return;
// tick buffs // tick buffs
for(auto buffEntry : self->buffs) { auto it = npc->buffs.begin();
buffEntry.second->combatTick(currTime); 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 // skip attack if stunned or asleep

View File

@ -376,5 +376,5 @@ void NPCManager::init() {
REGISTER_SHARD_PACKET(P_CL2FE_REQ_NPC_UNSUMMON, npcUnsummonHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_NPC_UNSUMMON, npcUnsummonHandler);
REGISTER_SHARD_PACKET(P_CL2FE_REQ_BARKER, npcBarkHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_BARKER, npcBarkHandler);
REGISTER_SHARD_TIMER(step, 200); REGISTER_SHARD_TIMER(step, MS_PER_COMBAT_TICK);
} }

View File

@ -8,6 +8,7 @@
#define REGISTER_SHARD_PACKET(pactype, handlr) CNShardServer::ShardPackets[pactype] = handlr; #define REGISTER_SHARD_PACKET(pactype, handlr) CNShardServer::ShardPackets[pactype] = handlr;
#define REGISTER_SHARD_TIMER(handlr, delta) CNShardServer::Timers.push_back(TimerEvent(handlr, delta)); #define REGISTER_SHARD_TIMER(handlr, delta) CNShardServer::Timers.push_back(TimerEvent(handlr, delta));
#define MS_PER_PLAYER_TICK 500 #define MS_PER_PLAYER_TICK 500
#define MS_PER_COMBAT_TICK 200
class CNShardServer : public CNServer { class CNShardServer : public CNServer {
private: private: