diff --git a/zone/aggro.cpp b/zone/aggro.cpp index 746a14dca..2f1355f86 100644 --- a/zone/aggro.cpp +++ b/zone/aggro.cpp @@ -1436,7 +1436,7 @@ void Mob::ClearFeignMemory() { while (remembered_feigned_mobid != feign_memory_list.end()) { Mob* remembered_mob = entity_list.GetMob(*remembered_feigned_mobid); - if (remembered_mob->IsClient() && remembered_mob != nullptr) { //Still in zone + if (remembered_mob && remembered_mob->IsClient()) { //Still in zone remembered_mob->CastToClient()->RemoveXTarget(this, false); } ++remembered_feigned_mobid; diff --git a/zone/attack.cpp b/zone/attack.cpp index c0f7f3cc3..36f3bc397 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -2835,8 +2835,9 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy if (emote_id) { oos->CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::KilledNPC, emote_id); } - - killer_mob->TrySpellOnKill(killed_level, spell); + if (killer_mob) { + killer_mob->TrySpellOnKill(killed_level, spell); + } } } diff --git a/zone/aura.cpp b/zone/aura.cpp index 14ca590f2..1f693ab04 100644 --- a/zone/aura.cpp +++ b/zone/aura.cpp @@ -963,6 +963,10 @@ bool ZoneDatabase::GetAuraEntry(uint16 spell_id, AuraRecord &record) void Mob::AddAura(Aura *aura, AuraRecord &record) { + if (!aura) { + return; + } + LogAura( "aura owner [{}] spawn_id [{}] aura_name [{}]", GetCleanName(), @@ -971,7 +975,6 @@ void Mob::AddAura(Aura *aura, AuraRecord &record) ); // this is called only when it's safe - assert(aura != nullptr); strn0cpy(aura_mgr.auras[aura_mgr.count].name, aura->GetCleanName(), 64); aura_mgr.auras[aura_mgr.count].spawn_id = aura->GetID(); aura_mgr.auras[aura_mgr.count].aura = aura; @@ -998,6 +1001,10 @@ void Mob::AddAura(Aura *aura, AuraRecord &record) void Mob::AddTrap(Aura *aura, AuraRecord &record) { + if (!aura) { + return; + } + LogAura( "aura owner [{}] spawn_id [{}] aura_name [{}]", GetCleanName(), @@ -1006,7 +1013,6 @@ void Mob::AddTrap(Aura *aura, AuraRecord &record) ); // this is called only when it's safe - assert(aura != nullptr); strn0cpy(trap_mgr.auras[trap_mgr.count].name, aura->GetCleanName(), 64); trap_mgr.auras[trap_mgr.count].spawn_id = aura->GetID(); trap_mgr.auras[trap_mgr.count].aura = aura; diff --git a/zone/bot.cpp b/zone/bot.cpp index eab55d45f..ac43f01ed 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -4637,7 +4637,9 @@ void Bot::Damage(Mob *from, int64 damage, uint16 spell_id, EQ::skills::SkillType int64 healed = GetActSpellHealing(spell_id, damage); LogCombatDetail("Applying lifetap heal of [{}] to [{}]", healed, GetCleanName()); HealDamage(healed); - entity_list.FilteredMessageClose(this, true, RuleI(Range, SpellMessages), Chat::Emote, FilterSocials, "%s beams a smile at %s", GetCleanName(), from->GetCleanName() ); + if (from) { + entity_list.FilteredMessageClose(this, true, RuleI(Range, SpellMessages), Chat::Emote, FilterSocials, "%s beams a smile at %s", GetCleanName(), from->GetCleanName()); + } } CommonDamage(from, damage, spell_id, attack_skill, avoidable, buffslot, iBuffTic, special); @@ -8552,22 +8554,25 @@ std::vector Bot::GetApplySpellList( if (apply_type == ApplySpellType::Raid && IsRaidGrouped()) { auto* r = GetRaid(); - auto group_id = r->GetGroup(GetCleanName()); - if (r && EQ::ValueWithin(group_id, 0, (MAX_RAID_GROUPS - 1))) { - for (const auto& m : r->members) { - if (m.is_bot) { - continue; - } - if (m.member && m.member->IsClient() && (!is_raid_group_only || r->GetGroup(m.member) == group_id)) { - l.push_back(m.member); - - if (allow_pets && m.member->HasPet()) { - l.push_back(m.member->GetPet()); + if (r) { + auto group_id = r->GetGroup(GetCleanName()); + if (EQ::ValueWithin(group_id, 0, (MAX_RAID_GROUPS - 1))) { + for (const auto& m: r->members) { + if (m.is_bot) { + continue; } + if (m.member && m.member->IsClient() && + (!is_raid_group_only || r->GetGroup(m.member) == group_id)) { + l.push_back(m.member); - const auto& sbl = entity_list.GetBotListByCharacterID(m.member->CharacterID()); - for (const auto& b : sbl) { - l.push_back(b); + if (allow_pets && m.member->HasPet()) { + l.push_back(m.member->GetPet()); + } + + const auto& sbl = entity_list.GetBotListByCharacterID(m.member->CharacterID()); + for (const auto& b: sbl) { + l.push_back(b); + } } } } diff --git a/zone/botspellsai.cpp b/zone/botspellsai.cpp index f5158fe35..085632e1f 100644 --- a/zone/botspellsai.cpp +++ b/zone/botspellsai.cpp @@ -1888,11 +1888,15 @@ bool Bot::AIHealRotation(Mob* tar, bool useFastHeals) { std::list Bot::GetBotSpellsForSpellEffect(Bot* botCaster, int spellEffect) { std::list result; + if (!botCaster) { + return result; + } + if (auto bot_owner = botCaster->GetBotOwner(); !bot_owner) { return result; } - if (botCaster && botCaster->AI_HasSpells()) { + if (botCaster->AI_HasSpells()) { std::vector botSpellList = botCaster->AIBot_spells; for (int i = botSpellList.size() - 1; i >= 0; i--) { @@ -1919,11 +1923,15 @@ std::list Bot::GetBotSpellsForSpellEffect(Bot* botCaster, int spellEff std::list Bot::GetBotSpellsForSpellEffectAndTargetType(Bot* botCaster, int spellEffect, SpellTargetType targetType) { std::list result; + if (!botCaster) { + return result; + } + if (auto bot_owner = botCaster->GetBotOwner(); !bot_owner) { return result; } - if (botCaster && botCaster->AI_HasSpells()) { + if (botCaster->AI_HasSpells()) { std::vector botSpellList = botCaster->AIBot_spells; for (int i = botSpellList.size() - 1; i >= 0; i--) { @@ -1955,11 +1963,15 @@ std::list Bot::GetBotSpellsForSpellEffectAndTargetType(Bot* botCaster, std::list Bot::GetBotSpellsBySpellType(Bot* botCaster, uint32 spellType) { std::list result; + if (!botCaster) { + return result; + } + if (auto bot_owner = botCaster->GetBotOwner(); !bot_owner) { return result; } - if (botCaster && botCaster->AI_HasSpells()) { + if (botCaster->AI_HasSpells()) { std::vector botSpellList = botCaster->AIBot_spells; for (int i = botSpellList.size() - 1; i >= 0; i--) { @@ -2694,21 +2706,22 @@ BotSpell Bot::GetBestBotSpellForResistDebuff(Bot* botCaster, Mob *tar) { result.SpellIndex = 0; result.ManaCost = 0; - if (!tar) + if (!tar || !botCaster) { return result; + } int level_mod = (tar->GetLevel() - botCaster->GetLevel())* (tar->GetLevel() - botCaster->GetLevel()) / 2; - if (tar->GetLevel() - botCaster->GetLevel() < 0) - { + if (tar->GetLevel() - botCaster->GetLevel() < 0) { level_mod = -level_mod; } + bool needsMagicResistDebuff = (tar->GetMR() + level_mod) > 100; bool needsColdResistDebuff = (tar->GetCR() + level_mod) > 100; bool needsFireResistDebuff = (tar->GetFR() + level_mod) > 100; bool needsPoisonResistDebuff = (tar->GetPR() + level_mod) > 100; bool needsDiseaseResistDebuff = (tar->GetDR() + level_mod) > 100; - if (botCaster && botCaster->AI_HasSpells()) { + if (botCaster->AI_HasSpells()) { std::vector botSpellList = botCaster->AIBot_spells; for (int i = botSpellList.size() - 1; i >= 0; i--) { diff --git a/zone/client.cpp b/zone/client.cpp index ad75a0b7c..0c52a329b 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -7470,15 +7470,17 @@ const char* Client::GetClassPlural(Client* client) { void Client::SendWebLink(const char *website) { - size_t len = strlen(website) + 1; - if(website != 0 && len > 1) - { - auto outapp = new EQApplicationPacket(OP_Weblink, sizeof(Weblink_Struct) + len); - Weblink_Struct *wl = (Weblink_Struct*)outapp->pBuffer; - memcpy(wl->weblink, website, len); - wl->weblink[len] = '\0'; + if (website) { + size_t len = strlen(website) + 1; + if (len > 1) + { + auto outapp = new EQApplicationPacket(OP_Weblink, sizeof(Weblink_Struct) + len); + Weblink_Struct* wl = (Weblink_Struct*)outapp->pBuffer; + memcpy(wl->weblink, website, len); + wl->weblink[len] = '\0'; - FastQueuePacket(&outapp); + FastQueuePacket(&outapp); + } } } @@ -11734,20 +11736,22 @@ std::vector Client::GetApplySpellList( if (apply_type == ApplySpellType::Raid && IsRaidGrouped()) { auto* r = GetRaid(); - auto group_id = r->GetGroup(this); - if (r && EQ::ValueWithin(group_id, 0, (MAX_RAID_GROUPS - 1))) { - for (const auto& m : r->members) { - if (m.member && m.member->IsClient() && (!is_raid_group_only || r->GetGroup(m.member) == group_id)) { - l.push_back(m.member); + if (r) { + auto group_id = r->GetGroup(this); + if (EQ::ValueWithin(group_id, 0, (MAX_RAID_GROUPS - 1))) { + for (const auto& m : r->members) { + if (m.member && m.member->IsClient() && (!is_raid_group_only || r->GetGroup(m.member) == group_id)) { + l.push_back(m.member); - if (allow_pets && m.member->HasPet()) { - l.push_back(m.member->GetPet()); - } + if (allow_pets && m.member->HasPet()) { + l.push_back(m.member->GetPet()); + } - if (allow_bots) { - const auto& sbl = entity_list.GetBotListByCharacterID(m.member->CharacterID()); - for (const auto& b : sbl) { - l.push_back(b); + if (allow_bots) { + const auto& sbl = entity_list.GetBotListByCharacterID(m.member->CharacterID()); + for (const auto& b : sbl) { + l.push_back(b); + } } } } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 6bf2f5c1a..facc39ad7 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -11775,13 +11775,13 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app) Bot* player_to_invite = nullptr; if (RuleB(Bots, Enabled) && entity_list.GetBotByBotName(raid_command_packet->player_name)) { - Bot* player_to_invite = entity_list.GetBotByBotName(raid_command_packet->player_name); - Group* player_to_invite_group = player_to_invite->GetGroup(); - if (!player_to_invite) { break; } + Bot* player_to_invite = entity_list.GetBotByBotName(raid_command_packet->player_name); + Group* player_to_invite_group = player_to_invite->GetGroup(); + if (player_to_invite_group && player_to_invite_group->IsGroupMember(this)) { MessageString(Chat::Red, ALREADY_IN_PARTY); break; diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 53a41bfe7..329be9457 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -1145,6 +1145,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app) const auto* item = inst->GetItem(); if ( + item && RuleB(Character, RestrictSpellScribing) && !item->IsEquipable(GetRace(), GetClass()) ) { diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 114766c36..4a1827d6f 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -520,8 +520,6 @@ bool PerlembParser::SpellHasQuestSub(uint32 spell_id, QuestEventID evt) bool PerlembParser::ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt) { - std::stringstream package_name; - package_name << "qst_item_" << itm->GetID(); if (!perl) { return false; @@ -535,6 +533,9 @@ bool PerlembParser::ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt) return false; } + std::stringstream package_name; + package_name << "qst_item_" << itm->GetID(); + const char *subname = QuestEventSubroutines[evt]; auto iter = item_quest_status_.find(itm->GetID()); diff --git a/zone/groups.cpp b/zone/groups.cpp index 9a609f648..ed3b9083e 100644 --- a/zone/groups.cpp +++ b/zone/groups.cpp @@ -298,7 +298,7 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte } //put existing group member(s) into the new member's list - if(InZone && newmember->IsClient()) + if(InZone && newmember && newmember->IsClient()) { if(IsLeader(members[i])) { @@ -307,13 +307,13 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte else { strcpy(newmember->CastToClient()->GetPP().groupMembers[x], members[i]->GetCleanName()); - x++; + ++x; } } } } - if(InZone) + if(InZone && newmember) { //put new member in his own list. newmember->SetGrouped(true); @@ -2499,4 +2499,4 @@ bool Group::IsLeader(const char* name) { } return false; -} \ No newline at end of file +} diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index e5452921d..5a67f3a9f 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -483,20 +483,22 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center, Mob *skip, bool skip_mezzed while (iterator != list.end()) { struct_HateList *cur = (*iterator); - if (cur->entity_on_hatelist == skip) { - ++iterator; - continue; - } + if (cur) { + if (cur->entity_on_hatelist == skip) { + ++iterator; + continue; + } - if (skip_mezzed && cur->entity_on_hatelist->IsMezzed()) { - ++iterator; - continue; - } + if (skip_mezzed && cur->entity_on_hatelist->IsMezzed()) { + ++iterator; + continue; + } - if (cur->entity_on_hatelist != nullptr && ((cur->stored_hate_amount > hate) || cur->is_entity_frenzy)) - { - top_hate = cur->entity_on_hatelist; - hate = cur->stored_hate_amount; + if (cur->entity_on_hatelist != nullptr && ((cur->stored_hate_amount > hate) || cur->is_entity_frenzy)) + { + top_hate = cur->entity_on_hatelist; + hate = cur->stored_hate_amount; + } } ++iterator; } @@ -516,24 +518,27 @@ Mob *HateList::GetEntWithMostHateOnList(bool skip_mezzed){ while (iterator != list.end()) { struct_HateList *cur = (*iterator); - LogHateDetail( - "Looping GetEntWithMostHateOnList1 [{}] cur [{}] hate [{}] calc [{}]", - cur->entity_on_hatelist->GetMobDescription(), - cur->stored_hate_amount, - hate, - (cur->stored_hate_amount > hate) - ); - if (cur && cur->entity_on_hatelist != nullptr && (cur->stored_hate_amount > hate)) - { + if (cur) { LogHateDetail( - "Looping GetEntWithMostHateOnList2 [{}]", - cur->entity_on_hatelist->GetMobDescription() + "Looping GetEntWithMostHateOnList1 [{}] cur [{}] hate [{}] calc [{}]", + cur->entity_on_hatelist->GetMobDescription(), + cur->stored_hate_amount, + hate, + (cur->stored_hate_amount > hate) ); - if (!skip_mezzed || !cur->entity_on_hatelist->IsMezzed()) { - top = cur->entity_on_hatelist; - hate = cur->stored_hate_amount; + if (cur->entity_on_hatelist != nullptr && (cur->stored_hate_amount > hate)) + { + LogHateDetail( + "Looping GetEntWithMostHateOnList2 [{}]", + cur->entity_on_hatelist->GetMobDescription() + ); + + if (!skip_mezzed || !cur->entity_on_hatelist->IsMezzed()) { + top = cur->entity_on_hatelist; + hate = cur->stored_hate_amount; + } } } ++iterator; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index f71b34fce..9d966d3d5 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -717,12 +717,15 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, EQ::ItemInstance* inst = database.CreateItem(item, charges); auto timestamps = database.GetItemRecastTimestamps(CharacterID()); - const auto* d = inst->GetItem(); - if (d->RecastDelay) { - if (d->RecastType != RECAST_TYPE_UNLINKED_ITEM) { - inst->SetRecastTimestamp(timestamps.count(d->RecastType) ? timestamps.at(d->RecastType) : 0); - } else { - inst->SetRecastTimestamp(timestamps.count(d->ID) ? timestamps.at(d->ID) : 0); + if (inst) { + const auto* d = inst->GetItem(); + if (d->RecastDelay) { + if (d->RecastType != RECAST_TYPE_UNLINKED_ITEM) { + inst->SetRecastTimestamp(timestamps.count(d->RecastType) ? timestamps.at(d->RecastType) : 0); + } + else { + inst->SetRecastTimestamp(timestamps.count(d->ID) ? timestamps.at(d->ID) : 0); + } } } @@ -2043,8 +2046,8 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { } if ((srcbagid && srcbag->GetItem()->BagType == EQ::item::BagTypeTradersSatchel) || (dstbagid && dstbag->GetItem()->BagType == EQ::item::BagTypeTradersSatchel) || - (srcitemid && src_inst->GetItem()->BagType == EQ::item::BagTypeTradersSatchel) || - (dstitemid && dst_inst->GetItem()->BagType == EQ::item::BagTypeTradersSatchel)) { + (srcitemid && src_inst && src_inst->GetItem()->BagType == EQ::item::BagTypeTradersSatchel) || + (dstitemid && dst_inst && dst_inst->GetItem()->BagType == EQ::item::BagTypeTradersSatchel)) { Trader_EndTrader(); Message(Chat::Red,"You cannot move your Trader Satchels, or items inside them, while Trading."); } diff --git a/zone/merc.cpp b/zone/merc.cpp index e6634d8e6..f27091f7c 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -3261,6 +3261,10 @@ MercSpell Merc::GetBestMercSpellForTargetedAENuke(Merc* caster, Mob* tar) { result.proc_chance = 0; result.time_cancast = 0; + if (!caster) { + return result; + } + switch(caster->GetStance()) { case EQ::constants::stanceBurnAE: @@ -3272,28 +3276,26 @@ MercSpell Merc::GetBestMercSpellForTargetedAENuke(Merc* caster, Mob* tar) { break; } - if(caster) { - std::list mercSpellList = GetMercSpellsBySpellType(caster, SpellType_Nuke); + std::list mercSpellList = GetMercSpellsBySpellType(caster, SpellType_Nuke); - for (auto mercSpellListItr = mercSpellList.begin(); mercSpellListItr != mercSpellList.end(); - ++mercSpellListItr) { - // Assuming all the spells have been loaded into this list by level and in descending order - if(IsAENukeSpell(mercSpellListItr->spellid) && !IsAERainNukeSpell(mercSpellListItr->spellid) - && !IsPBAENukeSpell(mercSpellListItr->spellid) && CheckSpellRecastTimers(caster, mercSpellListItr->spellid)) { - uint8 numTargets = 0; - if(CheckAENuke(caster, tar, mercSpellListItr->spellid, numTargets)) { - if(numTargets >= numTargetsCheck && zone->random.Roll(castChance)) { - result.spellid = mercSpellListItr->spellid; - result.stance = mercSpellListItr->stance; - result.type = mercSpellListItr->type; - result.slot = mercSpellListItr->slot; - result.proc_chance = mercSpellListItr->proc_chance; - result.time_cancast = mercSpellListItr->time_cancast; - } + for (auto mercSpellListItr = mercSpellList.begin(); mercSpellListItr != mercSpellList.end(); + ++mercSpellListItr) { + // Assuming all the spells have been loaded into this list by level and in descending order + if(IsAENukeSpell(mercSpellListItr->spellid) && !IsAERainNukeSpell(mercSpellListItr->spellid) + && !IsPBAENukeSpell(mercSpellListItr->spellid) && CheckSpellRecastTimers(caster, mercSpellListItr->spellid)) { + uint8 numTargets = 0; + if(CheckAENuke(caster, tar, mercSpellListItr->spellid, numTargets)) { + if(numTargets >= numTargetsCheck && zone->random.Roll(castChance)) { + result.spellid = mercSpellListItr->spellid; + result.stance = mercSpellListItr->stance; + result.type = mercSpellListItr->type; + result.slot = mercSpellListItr->slot; + result.proc_chance = mercSpellListItr->proc_chance; + result.time_cancast = mercSpellListItr->time_cancast; } + } - break; - } + break; } } @@ -3313,6 +3315,10 @@ MercSpell Merc::GetBestMercSpellForPBAENuke(Merc* caster, Mob* tar) { result.proc_chance = 0; result.time_cancast = 0; + if (!caster) { + return result; + } + switch(caster->GetStance()) { case EQ::constants::stanceBurnAE: @@ -3324,27 +3330,25 @@ MercSpell Merc::GetBestMercSpellForPBAENuke(Merc* caster, Mob* tar) { break; } - if(caster) { - std::list mercSpellList = GetMercSpellsBySpellType(caster, SpellType_Nuke); + std::list mercSpellList = GetMercSpellsBySpellType(caster, SpellType_Nuke); - for (auto mercSpellListItr = mercSpellList.begin(); mercSpellListItr != mercSpellList.end(); - ++mercSpellListItr) { - // Assuming all the spells have been loaded into this list by level and in descending order - if(IsPBAENukeSpell(mercSpellListItr->spellid) && CheckSpellRecastTimers(caster, mercSpellListItr->spellid)) { - uint8 numTargets = 0; - if(CheckAENuke(caster, caster, mercSpellListItr->spellid, numTargets)) { - if(numTargets >= numTargetsCheck && zone->random.Roll(castChance)) { - result.spellid = mercSpellListItr->spellid; - result.stance = mercSpellListItr->stance; - result.type = mercSpellListItr->type; - result.slot = mercSpellListItr->slot; - result.proc_chance = mercSpellListItr->proc_chance; - result.time_cancast = mercSpellListItr->time_cancast; - } + for (auto mercSpellListItr = mercSpellList.begin(); mercSpellListItr != mercSpellList.end(); + ++mercSpellListItr) { + // Assuming all the spells have been loaded into this list by level and in descending order + if(IsPBAENukeSpell(mercSpellListItr->spellid) && CheckSpellRecastTimers(caster, mercSpellListItr->spellid)) { + uint8 numTargets = 0; + if(CheckAENuke(caster, caster, mercSpellListItr->spellid, numTargets)) { + if(numTargets >= numTargetsCheck && zone->random.Roll(castChance)) { + result.spellid = mercSpellListItr->spellid; + result.stance = mercSpellListItr->stance; + result.type = mercSpellListItr->type; + result.slot = mercSpellListItr->slot; + result.proc_chance = mercSpellListItr->proc_chance; + result.time_cancast = mercSpellListItr->time_cancast; } - - break; } + + break; } } @@ -3364,6 +3368,10 @@ MercSpell Merc::GetBestMercSpellForAERainNuke(Merc* caster, Mob* tar) { result.proc_chance = 0; result.time_cancast = 0; + if (!caster) { + return result; + } + switch(caster->GetStance()) { case EQ::constants::stanceBurnAE: @@ -3375,27 +3383,25 @@ MercSpell Merc::GetBestMercSpellForAERainNuke(Merc* caster, Mob* tar) { break; } - if(caster) { - std::list mercSpellList = GetMercSpellsBySpellType(caster, SpellType_Nuke); + std::list mercSpellList = GetMercSpellsBySpellType(caster, SpellType_Nuke); - for (auto mercSpellListItr = mercSpellList.begin(); mercSpellListItr != mercSpellList.end(); - ++mercSpellListItr) { - // Assuming all the spells have been loaded into this list by level and in descending order - if(IsAERainNukeSpell(mercSpellListItr->spellid) && zone->random.Roll(castChance) && CheckSpellRecastTimers(caster, mercSpellListItr->spellid)) { - uint8 numTargets = 0; - if(CheckAENuke(caster, tar, mercSpellListItr->spellid, numTargets)) { - if(numTargets >= numTargetsCheck) { - result.spellid = mercSpellListItr->spellid; - result.stance = mercSpellListItr->stance; - result.type = mercSpellListItr->type; - result.slot = mercSpellListItr->slot; - result.proc_chance = mercSpellListItr->proc_chance; - result.time_cancast = mercSpellListItr->time_cancast; - } + for (auto mercSpellListItr = mercSpellList.begin(); mercSpellListItr != mercSpellList.end(); + ++mercSpellListItr) { + // Assuming all the spells have been loaded into this list by level and in descending order + if(IsAERainNukeSpell(mercSpellListItr->spellid) && zone->random.Roll(castChance) && CheckSpellRecastTimers(caster, mercSpellListItr->spellid)) { + uint8 numTargets = 0; + if(CheckAENuke(caster, tar, mercSpellListItr->spellid, numTargets)) { + if(numTargets >= numTargetsCheck) { + result.spellid = mercSpellListItr->spellid; + result.stance = mercSpellListItr->stance; + result.type = mercSpellListItr->type; + result.slot = mercSpellListItr->slot; + result.proc_chance = mercSpellListItr->proc_chance; + result.time_cancast = mercSpellListItr->time_cancast; } - - break; } + + break; } } @@ -4302,7 +4308,12 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id, if(merc_template) { //TODO: Maybe add a way of updating client merc stats in a seperate function? like, for example, on leveling up. - const NPCType* npc_type_to_copy = content_db.GetMercType(merc_template->MercNPCID, merc_template->RaceID, c->GetLevel()); + + const NPCType* npc_type_to_copy = nullptr; + if (c) { + const NPCType* npc_type_to_copy = content_db.GetMercType(merc_template->MercNPCID, merc_template->RaceID, c->GetLevel()); + } + if(npc_type_to_copy != nullptr) { //This is actually a very terrible method of assigning stats, and should be changed at some point. See the comment in merc's deconstructor. diff --git a/zone/mob.cpp b/zone/mob.cpp index 8045807f8..56bb8d843 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -5109,6 +5109,10 @@ void Mob::TarGlobal(const char *varname, const char *value, const char *duration void Mob::DelGlobal(const char *varname) { + if (!zone) { + return; + } + int qgZoneid=zone->GetZoneID(); int qgCharid=0; int qgNpcid=0; @@ -5129,22 +5133,19 @@ void Mob::DelGlobal(const char *varname) { database.QueryDatabase(query); - if(zone) - { - auto pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct)); - ServerQGlobalDelete_Struct *qgu = (ServerQGlobalDelete_Struct*)pack->pBuffer; + auto pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct)); + ServerQGlobalDelete_Struct *qgu = (ServerQGlobalDelete_Struct*)pack->pBuffer; - qgu->npc_id = qgNpcid; - qgu->char_id = qgCharid; - qgu->zone_id = qgZoneid; - strcpy(qgu->name, varname); + qgu->npc_id = qgNpcid; + qgu->char_id = qgCharid; + qgu->zone_id = qgZoneid; + strcpy(qgu->name, varname); - entity_list.DeleteQGlobal(std::string((char*)qgu->name), qgu->npc_id, qgu->char_id, qgu->zone_id); - zone->DeleteQGlobal(std::string((char*)qgu->name), qgu->npc_id, qgu->char_id, qgu->zone_id); + entity_list.DeleteQGlobal(std::string((char*)qgu->name), qgu->npc_id, qgu->char_id, qgu->zone_id); + zone->DeleteQGlobal(std::string((char*)qgu->name), qgu->npc_id, qgu->char_id, qgu->zone_id); - worldserver.SendPacket(pack); - safe_delete(pack); - } + worldserver.SendPacket(pack); + safe_delete(pack); } // Inserts global variable into quest_globals table diff --git a/zone/pets.cpp b/zone/pets.cpp index 8c5018518..e5575b7a5 100644 --- a/zone/pets.cpp +++ b/zone/pets.cpp @@ -445,7 +445,7 @@ Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 po GiveNPCTypeData(type_data); typeofpet = type; petpower = power; - SetOwnerID(owner->GetID()); + SetOwnerID(owner ? owner->GetID() : 0); SetPetSpellID(spell_id); // All pets start at false on newer clients. The client diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index 5c98fcd9a..5a8309a1d 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -150,7 +150,7 @@ bool Spawn2::Process() { //grab our spawn group SpawnGroup *spawn_group = zone->spawn_group_list.GetSpawnGroup(spawngroup_id_); - if (NPCPointerValid() && (spawn_group->despawn == 0 || condition_id != 0)) { + if (NPCPointerValid() && (spawn_group && spawn_group->despawn == 0 || condition_id != 0)) { return true; } diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index e7d1a4cc5..ebb0d07ac 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -147,9 +147,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if (spells[spell_id].hit_number > 0) { int numhit = spells[spell_id].hit_number; - - numhit += numhit * caster->GetFocusEffect(focusFcLimitUse, spell_id) / 100; - numhit += caster->GetFocusEffect(focusIncreaseNumHits, spell_id); + if (caster) { + numhit += numhit * caster->GetFocusEffect(focusFcLimitUse, spell_id) / 100; + numhit += caster->GetFocusEffect(focusIncreaseNumHits, spell_id); + } buffs[buffslot].hit_number = numhit; } @@ -262,7 +263,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove // SE_CurrentHP is calculated at first tick if its a dot/buff if (buffslot >= 0) { //This is here so dots with hit counters tic down on initial cast. - if (effect_value < 0) { + if (caster && effect_value < 0) { caster->GetActDoTDamage(spell_id, effect_value, this, false); } break; @@ -1766,7 +1767,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove gid = r->GetGroup(caster->GetName()); if(gid < 11) { - if(r->GetGroup(TargetClient->GetName()) != gid) { + if (TargetClient && r->GetGroup(TargetClient->GetName()) != gid) { Message(Chat::Red, "Your target must be a group member for this spell."); break; } @@ -1817,7 +1818,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove { if (IsClient()) { Client* client_target = CastToClient(); - if (client_target->IsGrouped()) { + if (client_target && client_target->IsGrouped()) { Group* group = client_target->GetGroup(); if (!group->IsGroupMember(caster)) { if (caster != this) { @@ -1830,7 +1831,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove Raid *raid = caster->GetRaid(); uint32 group_id = raid->GetGroup(caster->GetName()); if (group_id > 0 && group_id < MAX_RAID_GROUPS) { - if (raid->GetGroup(client_target->GetName()) != group_id) { + if (client_target && raid->GetGroup(client_target->GetName()) != group_id) { caster->MessageString(Chat::Red, SUMMON_ONLY_GROUP_CORPSE); break; } @@ -2963,10 +2964,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if (caster && !caster->IsClient()) break; - if (zone->random.Roll(spells[spell_id].base_value[i])) { + if (caster && zone->random.Roll(spells[spell_id].base_value[i])) { uint32 best_spell_id = caster->CastToClient()->GetHighestScribedSpellinSpellGroup(spells[spell_id].limit_value[i]); - if (caster && IsValidSpell(best_spell_id)) + if (IsValidSpell(best_spell_id)) caster->SpellFinished(best_spell_id, this, EQ::spells::CastingSlot::Item, 0, -1, spells[best_spell_id].resist_difficulty); } break; diff --git a/zone/trap.cpp b/zone/trap.cpp index 947a325e5..56c98fe84 100644 --- a/zone/trap.cpp +++ b/zone/trap.cpp @@ -209,8 +209,7 @@ void Trap::Trigger(Mob* trigger) { entity_list.MessageClose(trigger,false,100,13,"%s",message.c_str()); } - if(trigger->IsClient()) - { + if (trigger && trigger->IsClient()) { auto outapp = new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct)); CombatDamage_Struct* a = (CombatDamage_Struct*)outapp->pBuffer; int64 dmg = zone->random.Int(effectvalue, effectvalue2); @@ -226,8 +225,7 @@ void Trap::Trigger(Mob* trigger) } } - if (trigger && trigger->IsClient()) - { + if (trigger && trigger->IsClient()) { trigger->CastToClient()->trapid = trap_id; charid = trigger->CastToClient()->CharacterID(); } diff --git a/zone/zone.cpp b/zone/zone.cpp index 85c08b7d7..8db742d31 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -2027,13 +2027,12 @@ ZonePoint* Zone::GetClosestZonePoint(const glm::vec3& location, uint32 to, Clien // if we have a water map and it says we're in a zoneline, lets assume it's just a really big zone line // this shouldn't open up any exploits since those situations are detected later on - if ((zone->HasWaterMap() && !zone->watermap->InZoneLine(glm::vec3(client->GetPosition()))) || (!zone->HasWaterMap() && closest_dist > 400.0f && closest_dist < max_distance2)) + if ((client && zone->HasWaterMap() && !zone->watermap->InZoneLine(glm::vec3(client->GetPosition()))) || (!zone->HasWaterMap() && closest_dist > 400.0f && closest_dist < max_distance2)) { - if (client) { - if (!client->cheat_manager.GetExemptStatus(Port)) { - client->cheat_manager.CheatDetected(MQZoneUnknownDest, location); - } + if (!client->cheat_manager.GetExemptStatus(Port)) { + client->cheat_manager.CheatDetected(MQZoneUnknownDest, location); } + LogInfo("WARNING: Closest zone point for zone id [{}] is [{}], you might need to update your zone_points table if you dont arrive at the right spot", to, closest_dist); LogInfo(". [{}]", to_string(location).c_str()); }