From af49c0bd105d244afc169df15d14e5401cb4e362 Mon Sep 17 00:00:00 2001 From: fusion32 Date: Fri, 12 Sep 2025 02:28:35 -0300 Subject: fix crash when a summon would attack before despawning (#28) --- src/crmain.cc | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/crmain.cc b/src/crmain.cc index f2f13ac..15c72b8 100644 --- a/src/crmain.cc +++ b/src/crmain.cc @@ -457,12 +457,12 @@ int TCreature::Damage(TCreature *Attacker, int Damage, int DamageType){ return 0; } - if(this->Type == PLAYER){ - if(this->Connection != NULL && Attacker != NULL){ + if(Attacker != NULL && this->Type == PLAYER){ + if(this->Connection != NULL){ SendMarkCreature(this->Connection, Attacker->ID, COLOR_BLACK); } - if(Attacker != NULL && Attacker->Type == PLAYER + if(Attacker->Type == PLAYER && DamageType != DAMAGE_POISON_PERIODIC && DamageType != DAMAGE_FIRE_PERIODIC && DamageType != DAMAGE_ENERGY_PERIODIC){ @@ -479,7 +479,15 @@ int TCreature::Damage(TCreature *Attacker, int Damage, int DamageType){ uint32 MasterID = Attacker->GetMaster(); if(MasterID != 0){ - Responsible = GetCreature(MasterID); + // NOTE(fusion): This is very subtle but we could hit a case where the + // master logs out or dies but the summon has a ToDoAttack queued, in + // which case it would try to attack before checking whether it should + // despawn in `TMonster::IdleStimulus`, causing `Responsible` to be NULL + // even though `Attacker` is not. + TCreature *Master = GetCreature(MasterID); + if(Master != NULL){ + Responsible = Master; + } } Attacker->BlockLogout(60, this->Type == PLAYER); @@ -653,8 +661,8 @@ int TCreature::Damage(TCreature *Attacker, int Damage, int DamageType){ } this->Skills[SKILL_HITPOINTS]->Change(-Damage); - if(Responsible != NULL){ - ASSERT(Attacker != NULL); + if(Attacker != NULL){ + ASSERT(Responsible != NULL); if(Responsible == Attacker){ this->Combat.AddDamageToCombatList(Attacker->ID, Damage); }else{ -- cgit v1.2.3