Compare commits

..

2 Commits

Author SHA1 Message Date
gsemaj
9affe76587
Fix segv: Halt buff iteration if mob is dead 2023-08-13 13:59:28 -07:00
gsemaj
33fde8af69
Tighten parameter for removeBuff 2023-08-13 10:50:50 -07:00
5 changed files with 12 additions and 38 deletions

View File

@ -108,7 +108,6 @@ static SkillResult handleSkillBuff(SkillData* skill, int power, ICombatant* sour
ICombatant* combatant = dynamic_cast<ICombatant*>(self.getEntity());
combatant->takeDamage(buff->getLastSource(), 0); // aggro
}
Buffs::timeBuffUpdate(self, buff, status, stack);
if(drainType == SkillDrainType::ACTIVE && status == ETBU_DEL)
Buffs::timeBuffTimeout(self);
},

View File

@ -49,9 +49,9 @@ void Player::removeBuff(int buffId) {
}
}
void Player::removeBuff(int buffId, int buffClass) {
void Player::removeBuff(int buffId, BuffClass buffClass) {
if(hasBuff(buffId)) {
buffs[buffId]->clear((BuffClass)buffClass);
buffs[buffId]->clear(buffClass);
// buff might not be stale since another buff class might remain
if(buffs[buffId]->isStale()) {
delete buffs[buffId];
@ -203,9 +203,9 @@ void CombatNPC::removeBuff(int buffId) {
}
}
void CombatNPC::removeBuff(int buffId, int buffClass) {
void CombatNPC::removeBuff(int buffId, BuffClass buffClass) {
if(hasBuff(buffId)) {
buffs[buffId]->clear((BuffClass)buffClass);
buffs[buffId]->clear(buffClass);
// buff might not be stale since another buff class might remain
if(buffs[buffId]->isStale()) {
delete buffs[buffId];

View File

@ -47,7 +47,7 @@ public:
virtual bool addBuff(int, BuffCallback<int, BuffStack*>, BuffCallback<time_t>, BuffStack*) = 0;
virtual Buff* getBuff(int) = 0;
virtual void removeBuff(int) = 0;
virtual void removeBuff(int, int) = 0;
virtual void removeBuff(int, BuffClass) = 0;
virtual void clearBuffs(bool) = 0;
virtual bool hasBuff(int) = 0;
virtual int getCompositeCondition() = 0;
@ -125,7 +125,7 @@ struct CombatNPC : public BaseNPC, public ICombatant {
virtual bool addBuff(int buffId, BuffCallback<int, BuffStack*> onUpdate, BuffCallback<time_t> onTick, BuffStack* stack) override;
virtual Buff* getBuff(int buffId) override;
virtual void removeBuff(int buffId) override;
virtual void removeBuff(int buffId, int buffClass) override;
virtual void removeBuff(int buffId, BuffClass buffClass) override;
virtual void clearBuffs(bool force) override;
virtual bool hasBuff(int buffId) override;
virtual int getCompositeCondition() override;

View File

@ -441,32 +441,6 @@ static void useAbilities(Mob *mob, time_t currTime) {
return;
}
// TODO abiilities
static void drainMobHP(Mob *mob, int amount) {
size_t resplen = sizeof(sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK) + sizeof(sSkillResult_Damage);
assert(resplen < CN_PACKET_BUFFER_SIZE - 8);
uint8_t respbuf[CN_PACKET_BUFFER_SIZE];
memset(respbuf, 0, resplen);
sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK *pkt = (sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK*)respbuf;
sSkillResult_Damage *drain = (sSkillResult_Damage*)(respbuf + sizeof(sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK));
pkt->iID = mob->id;
pkt->eCT = 4; // mob
pkt->iTB_ID = ECSB_BOUNDINGBALL;
drain->eCT = 4;
drain->iID = mob->id;
drain->iDamage = amount;
drain->iHP = mob->hp -= amount;
NPCManager::sendToViewable(mob, (void*)&respbuf, P_FE2CL_CHAR_TIME_BUFF_TIME_TICK, resplen);
if (mob->hp <= 0)
mob->transition(AIState::DEAD, mob->target);
}
void MobAI::incNextMovement(Mob* mob, time_t currTime) {
if (currTime == 0)
currTime = getTime();
@ -558,6 +532,11 @@ void MobAI::combatStep(CombatNPC* npc, time_t currTime) {
while(it != npc->buffs.end()) {
Buff* buff = (*it).second;
buff->combatTick(currTime);
// if mob state changed, end the step
if(self->state != AIState::COMBAT)
return;
buff->tick(currTime);
if(buff->isStale()) {
// garbage collect
@ -567,10 +546,6 @@ void MobAI::combatStep(CombatNPC* npc, time_t currTime) {
else it++;
}
// if debuffs killed the mob, return early
if (self->hp <= 0)
return;
// skip attack if stunned or asleep
if (self->hasBuff(ECSB_STUN) || self->hasBuff(ECSB_MEZ)) {
self->skillStyle = -1; // in this case we also reset the any outlying abilities the mob might be winding up.

View File

@ -92,7 +92,7 @@ struct Player : public Entity, public ICombatant {
virtual bool addBuff(int buffId, BuffCallback<int, BuffStack*> onUpdate, BuffCallback<time_t> onTick, BuffStack* stack) override;
virtual Buff* getBuff(int buffId) override;
virtual void removeBuff(int buffId) override;
virtual void removeBuff(int buffId, int buffClass) override;
virtual void removeBuff(int buffId, BuffClass buffClass) override;
virtual void clearBuffs(bool force) override;
virtual bool hasBuff(int buffId) override;
virtual int getCompositeCondition() override;