Fix potential crashes in Mob::SpellEffect

This commit is contained in:
Michael Cook (mackal) 2016-08-13 16:45:32 -04:00
parent f06a9b3dce
commit 8ce2921e3d

View File

@ -357,8 +357,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
break; break;
int32 val = 0; int32 val = 0;
val = 7500*effect_value; val = 7500 * effect_value;
val = caster->GetActSpellHealing(spell_id, val, this); if (caster)
val = caster->GetActSpellHealing(spell_id, val, this);
if (val > 0) if (val > 0)
HealDamage(val, caster); HealDamage(val, caster);
@ -377,12 +378,14 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
snprintf(effect_desc, _EDLEN, "Current Mana: %+i", effect_value); snprintf(effect_desc, _EDLEN, "Current Mana: %+i", effect_value);
#endif #endif
SetMana(GetMana() + effect_value); SetMana(GetMana() + effect_value);
caster->SetMana(caster->GetMana() + std::abs(effect_value)); if (caster)
caster->SetMana(caster->GetMana() + std::abs(effect_value));
if (effect_value < 0) if (effect_value < 0)
TryTriggerOnValueAmount(false, true); TryTriggerOnValueAmount(false, true);
#ifdef SPELL_EFFECT_SPAM #ifdef SPELL_EFFECT_SPAM
caster->Message(0, "You have gained %+i mana!", effect_value); if (caster)
caster->Message(0, "You have gained %+i mana!", effect_value);
#endif #endif
} }
} }
@ -534,7 +537,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
} }
} }
if (effect == SE_GateCastersBindpoint && caster->IsClient()) if (effect == SE_GateCastersBindpoint && caster && caster->IsClient())
{ // Teleport Bind uses caster's bind point { // Teleport Bind uses caster's bind point
int index = spells[spell_id].base[i] - 1; int index = spells[spell_id].base[i] - 1;
if (index < 0 || index > 4) if (index < 0 || index > 4)
@ -650,7 +653,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
//Added client messages to give some indication this effect is active. //Added client messages to give some indication this effect is active.
// Is there a message generated? Too disgusted by raids. // Is there a message generated? Too disgusted by raids.
uint32 time = spell.base[i] * 10 * 1000; uint32 time = spell.base[i] * 10 * 1000;
if (caster->IsClient()) { if (caster && caster->IsClient()) {
if (caster->IsGrouped()) { if (caster->IsGrouped()) {
auto group = caster->GetGroup(); auto group = caster->GetGroup();
for (int i = 0; i < 6; ++i) for (int i = 0; i < 6; ++i)
@ -697,7 +700,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
((GetLevel() > max_level) && caster && (!caster->IsNPC() || ((GetLevel() > max_level) && caster && (!caster->IsNPC() ||
(caster->IsNPC() && !RuleB(Spells, NPCIgnoreBaseImmunity)))))) (caster->IsNPC() && !RuleB(Spells, NPCIgnoreBaseImmunity))))))
{ {
caster->Message_StringID(MT_SpellFailure, IMMUNE_STUN); if (caster)
caster->Message_StringID(MT_SpellFailure, IMMUNE_STUN);
} else { } else {
int stun_resist = itembonuses.StunResist+spellbonuses.StunResist; int stun_resist = itembonuses.StunResist+spellbonuses.StunResist;
if (IsClient()) if (IsClient())
@ -706,7 +710,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
if (stun_resist <= 0 || zone->random.Int(0,99) >= stun_resist) { if (stun_resist <= 0 || zone->random.Int(0,99) >= stun_resist) {
Log.Out(Logs::Detail, Logs::Combat, "Stunned. We had %d percent resist chance.", stun_resist); Log.Out(Logs::Detail, Logs::Combat, "Stunned. We had %d percent resist chance.", stun_resist);
if (caster->IsClient()) if (caster && caster->IsClient())
effect_value += effect_value*caster->GetFocusEffect(focusFcStunTimeMod, spell_id)/100; effect_value += effect_value*caster->GetFocusEffect(focusFcStunTimeMod, spell_id)/100;
Stun(effect_value); Stun(effect_value);
@ -918,11 +922,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
cd->meleepush_xy = action->sequence; cd->meleepush_xy = action->sequence;
CastToClient()->QueuePacket(action_packet); CastToClient()->QueuePacket(action_packet);
if(caster->IsClient() && caster != this) if(caster && caster->IsClient() && caster != this)
caster->CastToClient()->QueuePacket(action_packet); caster->CastToClient()->QueuePacket(action_packet);
CastToClient()->QueuePacket(message_packet); CastToClient()->QueuePacket(message_packet);
if(caster->IsClient() && caster != this) if(caster && caster->IsClient() && caster != this)
caster->CastToClient()->QueuePacket(message_packet); caster->CastToClient()->QueuePacket(message_packet);
CastToClient()->SetBindPoint(spells[spell_id].base[i] - 1); CastToClient()->SetBindPoint(spells[spell_id].base[i] - 1);
@ -1033,7 +1037,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
if(zone->random.Roll(effect_value)) if(zone->random.Roll(effect_value))
Gate(spells[spell_id].base2[i] - 1); Gate(spells[spell_id].base2[i] - 1);
else else if (caster)
caster->Message_StringID(MT_SpellFailure,GATE_FAIL); caster->Message_StringID(MT_SpellFailure,GATE_FAIL);
} }
break; break;
@ -1045,7 +1049,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
snprintf(effect_desc, _EDLEN, "Cancel Magic: %d", effect_value); snprintf(effect_desc, _EDLEN, "Cancel Magic: %d", effect_value);
#endif #endif
if(GetSpecialAbility(UNDISPELLABLE)){ if(GetSpecialAbility(UNDISPELLABLE)){
caster->Message_StringID(MT_SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name); if (caster)
caster->Message_StringID(MT_SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name);
break; break;
} }
@ -1055,7 +1060,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
spells[buffs[slot].spellid].dispel_flag == 0 && spells[buffs[slot].spellid].dispel_flag == 0 &&
!IsDiscipline(buffs[slot].spellid)) !IsDiscipline(buffs[slot].spellid))
{ {
if (TryDispel(caster->GetLevel(),buffs[slot].casterlevel, effect_value)){ if (caster && TryDispel(caster->GetLevel(),buffs[slot].casterlevel, effect_value)){
BuffFadeBySlot(slot); BuffFadeBySlot(slot);
slot = buff_count; slot = buff_count;
} }
@ -1070,7 +1075,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
snprintf(effect_desc, _EDLEN, "Dispel Detrimental: %d", effect_value); snprintf(effect_desc, _EDLEN, "Dispel Detrimental: %d", effect_value);
#endif #endif
if(GetSpecialAbility(UNDISPELLABLE)){ if(GetSpecialAbility(UNDISPELLABLE)){
caster->Message_StringID(MT_SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name); if (caster)
caster->Message_StringID(MT_SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name);
break; break;
} }
@ -1080,7 +1086,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
IsDetrimentalSpell(buffs[slot].spellid) && IsDetrimentalSpell(buffs[slot].spellid) &&
spells[buffs[slot].spellid].dispel_flag == 0) spells[buffs[slot].spellid].dispel_flag == 0)
{ {
if (TryDispel(caster->GetLevel(),buffs[slot].casterlevel, effect_value)){ if (caster && TryDispel(caster->GetLevel(),buffs[slot].casterlevel, effect_value)){
BuffFadeBySlot(slot); BuffFadeBySlot(slot);
slot = buff_count; slot = buff_count;
} }
@ -1095,7 +1101,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
snprintf(effect_desc, _EDLEN, "Dispel Beneficial: %d", effect_value); snprintf(effect_desc, _EDLEN, "Dispel Beneficial: %d", effect_value);
#endif #endif
if(GetSpecialAbility(UNDISPELLABLE)){ if(GetSpecialAbility(UNDISPELLABLE)){
caster->Message_StringID(MT_SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name); if (caster)
caster->Message_StringID(MT_SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name);
break; break;
} }
@ -1105,7 +1112,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
IsBeneficialSpell(buffs[slot].spellid) && IsBeneficialSpell(buffs[slot].spellid) &&
spells[buffs[slot].spellid].dispel_flag == 0) spells[buffs[slot].spellid].dispel_flag == 0)
{ {
if (TryDispel(caster->GetLevel(),buffs[slot].casterlevel, effect_value)){ if (caster && TryDispel(caster->GetLevel(),buffs[slot].casterlevel, effect_value)){
BuffFadeBySlot(slot); BuffFadeBySlot(slot);
slot = buff_count; slot = buff_count;
} }
@ -1122,7 +1129,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
if (buffs[slot].spellid != SPELL_UNKNOWN && if (buffs[slot].spellid != SPELL_UNKNOWN &&
IsDetrimentalSpell(buffs[slot].spellid)) IsDetrimentalSpell(buffs[slot].spellid))
{ {
if (TryDispel(caster->GetLevel(),buffs[slot].casterlevel, effect_value)){ if (caster && TryDispel(caster->GetLevel(),buffs[slot].casterlevel, effect_value)){
BuffFadeBySlot(slot); BuffFadeBySlot(slot);
} }
} }
@ -1511,7 +1518,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
((GetLevel() > max_level) ((GetLevel() > max_level)
&& caster && (!caster->IsNPC() || (caster->IsNPC() && !RuleB(Spells, NPCIgnoreBaseImmunity))))) && caster && (!caster->IsNPC() || (caster->IsNPC() && !RuleB(Spells, NPCIgnoreBaseImmunity)))))
{ {
caster->Message_StringID(MT_Shout, IMMUNE_STUN); if (caster)
caster->Message_StringID(MT_Shout, IMMUNE_STUN);
} }
else else
{ {
@ -1728,7 +1736,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
break; break;
} }
} }
else { else if (client) {
Raid *r = entity_list.GetRaidByClient(caster->CastToClient()); Raid *r = entity_list.GetRaidByClient(caster->CastToClient());
if(r) if(r)
{ {
@ -1768,7 +1776,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
Message_StringID(4, CORPSE_CANT_SENSE); Message_StringID(4, CORPSE_CANT_SENSE);
} }
} }
else else if (caster)
caster->Message_StringID(MT_SpellFailure, SPELL_LEVEL_REQ); caster->Message_StringID(MT_SpellFailure, SPELL_LEVEL_REQ);
} }
else { else {
@ -2115,7 +2123,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#ifdef SPELL_EFFECT_SPAM #ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Sacrifice"); snprintf(effect_desc, _EDLEN, "Sacrifice");
#endif #endif
if(!IsClient() || !caster->IsClient()){ if(!caster || !IsClient() || !caster->IsClient()){
break; break;
} }
CastToClient()->SacrificeConfirm(caster->CastToClient()); CastToClient()->SacrificeConfirm(caster->CastToClient());
@ -2124,12 +2132,15 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
case SE_SummonPC: case SE_SummonPC:
{ {
if(IsClient()){ if (!caster)
CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), caster->GetX(), caster->GetY(), caster->GetZ(), caster->GetHeading(), 2, SummonPC); break;
if (IsClient()) {
CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), caster->GetX(),
caster->GetY(), caster->GetZ(), caster->GetHeading(), 2,
SummonPC);
Message(15, "You have been summoned!"); Message(15, "You have been summoned!");
entity_list.ClearAggro(this); entity_list.ClearAggro(this);
} } else
else
caster->Message(13, "This spell can only be cast on players."); caster->Message(13, "This spell can only be cast on players.");
break; break;
@ -2176,6 +2187,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
case SE_TemporaryPets: //Dook- swarms and wards: case SE_TemporaryPets: //Dook- swarms and wards:
{ {
if (!caster)
break;
// this makes necro epic 1.5/2.0 proc work properly // this makes necro epic 1.5/2.0 proc work properly
if((spell_id != 6882) && (spell_id != 6884)) // Chaotic Jester/Steadfast Servant if((spell_id != 6882) && (spell_id != 6884)) // Chaotic Jester/Steadfast Servant
{ {
@ -2271,6 +2284,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
*/ */
int16 focus = 0; int16 focus = 0;
int ReuseTime = spells[spell_id].recast_time + spells[spell_id].recovery_time; int ReuseTime = spells[spell_id].recast_time + spells[spell_id].recovery_time;
if (!caster)
break;
focus = caster->GetFocusEffect(focusFcBaseEffects, spell_id); focus = caster->GetFocusEffect(focusFcBaseEffects, spell_id);
@ -2294,7 +2309,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
snprintf(effect_desc, _EDLEN, "Wake The Dead"); snprintf(effect_desc, _EDLEN, "Wake The Dead");
#endif #endif
//meh dupe issue with npc casting this //meh dupe issue with npc casting this
if(caster->IsClient()){ if(caster && caster->IsClient()){
int dur = spells[spell_id].max[i]; int dur = spells[spell_id].max[i];
if (!dur) if (!dur)
dur = 60; dur = 60;
@ -2659,7 +2674,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
case SE_Taunt: case SE_Taunt:
{ {
if (IsNPC()){ if (caster && IsNPC()){
caster->Taunt(this->CastToNPC(), false, static_cast<float>(spell.base[i]), true, spell.base2[i]); caster->Taunt(this->CastToNPC(), false, static_cast<float>(spell.base[i]), true, spell.base2[i]);
} }
break; break;