From 7f05e209947347a32d70cce706cb2bd38f6161a4 Mon Sep 17 00:00:00 2001 From: Kargatum Date: Sun, 16 Jan 2022 05:08:54 +0700 Subject: [PATCH] fix(Core/Pets): fix crash at pet resurrect (#10120) --- src/server/game/Entities/Pet/Pet.cpp | 37 +- src/server/game/Entities/Player/Player.cpp | 392 ++++++++++++------ src/server/game/Entities/Player/Player.h | 5 + src/server/game/Spells/Spell.cpp | 11 - src/server/scripts/Commands/cs_npc.cpp | 42 +- src/server/scripts/Commands/cs_pet.cpp | 38 +- .../EasternKingdoms/zone_elwynn_forest.cpp | 1 - src/server/scripts/World/go_scripts.cpp | 1 - 8 files changed, 301 insertions(+), 226 deletions(-) diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index a0f0c9e39..acc86d073 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -342,24 +342,6 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c SetReactState(petInfo->ReactState); SetCanModifyStats(true); - if (getPetType() == SUMMON_PET && !current) //all (?) summon pets come with full health when called, but not when they are current - { - SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); - //SetHealth(GetMaxHealth()); - } - else - { - uint32 savedhealth = petInfo->Health; - uint32 savedmana = petInfo->Mana; - if (!savedhealth && getPetType() == HUNTER_PET) - setDeathState(JUST_DIED); - else - { - SetHealth(savedhealth > GetMaxHealth() ? GetMaxHealth() : savedhealth); - SetPower(POWER_MANA, savedmana > GetMaxPower(POWER_MANA) ? GetMaxPower(POWER_MANA) : savedmana); - } - } - // set current pet as current // 0=current // 1..MAX_PET_STABLES in stable slot @@ -426,7 +408,8 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c owner->ToPlayer()->SetLastPetNumber(petInfo->PetNumber); owner->GetSession()->AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(std::make_shared(ownerid, petInfo->PetNumber))) - .AfterComplete([this, owner, session = owner->GetSession(), isTemporarySummon, current, lastSaveTime = petInfo->LastSaveTime](SQLQueryHolderBase const& holder) + .AfterComplete([this, owner, session = owner->GetSession(), isTemporarySummon, current, lastSaveTime = petInfo->LastSaveTime, savedhealth = petInfo->Health, savedmana = petInfo->Mana] + (SQLQueryHolderBase const& holder) { if (session->GetPlayer() != owner || owner->GetPet() != this) return; @@ -475,6 +458,22 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c } } + if (getPetType() == SUMMON_PET && !current) //all (?) summon pets come with full health when called, but not when they are current + { + SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); + SetFullHealth(); + } + else + { + if (!savedhealth && getPetType() == HUNTER_PET) + setDeathState(JUST_DIED); + else + { + SetHealth(savedhealth > GetMaxHealth() ? GetMaxHealth() : savedhealth); + SetPower(POWER_MANA, savedmana > GetMaxPower(POWER_MANA) ? GetMaxPower(POWER_MANA) : savedmana); + } + } + // must be after SetMinion (owner guid check) //LoadTemplateImmunities(); //LoadMechanicTemplateImmunity(); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 2e7c0bb53..3f3726f31 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -8667,6 +8667,136 @@ Pet* Player::GetPet() const return nullptr; } +Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration /*= 0s*/) +{ + PetStable& petStable = GetOrInitPetStable(); + + Pet* pet = new Pet(this, petType); + + if (petType == SUMMON_PET && pet->LoadPetFromDB(this, entry, 0, false)) + { + // Remove Demonic Sacrifice auras (known pet) + Unit::AuraEffectList const& auraClassScripts = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + for (Unit::AuraEffectList::const_iterator itr = auraClassScripts.begin(); itr != auraClassScripts.end();) + { + if ((*itr)->GetMiscValue() == 2228) + { + RemoveAurasDueToSpell((*itr)->GetId()); + itr = auraClassScripts.begin(); + } + else + ++itr; + } + + if (duration > 0s) + pet->SetDuration(duration); + + // Generate a new name for the newly summoned ghoul + if (pet->IsPetGhoul()) + { + std::string new_name = sObjectMgr->GeneratePetName(entry); + if (!new_name.empty()) + pet->SetName(new_name); + } + + return nullptr; + } + + // petentry == 0 for hunter "call pet" (current pet summoned if any) + if (!entry) + { + delete pet; + return nullptr; + } + + pet->Relocate(x, y, z, ang); + if (!pet->IsPositionValid()) + { + LOG_ERROR("misc", "Player::SummonPet: Pet (%s, Entry: %d) not summoned. Suggested coordinates aren't valid (X: %f Y: %f)", pet->GetGUID().ToString().c_str(), pet->GetEntry(), pet->GetPositionX(), pet->GetPositionY()); + delete pet; + return nullptr; + } + + Map* map = GetMap(); + uint32 pet_number = sObjectMgr->GeneratePetNumber(); + if (!pet->Create(map->GenerateLowGuid(), map, GetPhaseMask(), entry, pet_number)) + { + LOG_ERROR("misc", "Player::SummonPet: No such creature entry %u", entry); + delete pet; + return nullptr; + } + + if (petType == SUMMON_PET && petStable.CurrentPet) + RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT); + + pet->SetCreatorGUID(GetGUID()); + pet->SetFaction(GetFaction()); + pet->setPowerType(POWER_MANA); + pet->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); + pet->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + pet->InitStatsForLevel(getLevel()); + + SetMinion(pet, true); + + switch (petType) + { + case SUMMON_PET: + { + if (pet->GetCreatureTemplate()->type == CREATURE_TYPE_DEMON || pet->GetCreatureTemplate()->type == CREATURE_TYPE_UNDEAD) + pet->GetCharmInfo()->SetPetNumber(pet_number, true); // Show pet details tab (Shift+P) only for demons & undead + else + pet->GetCharmInfo()->SetPetNumber(pet_number, false); + + pet->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048); + pet->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0); + pet->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000); + pet->SetFullHealth(); + pet->SetPower(POWER_MANA, pet->GetMaxPower(POWER_MANA)); + pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(nullptr))); // cast can't be helped in this case + break; + } + default: + break; + } + + map->AddToMap(pet->ToCreature(), true); + + ASSERT(!petStable.CurrentPet && (petType != HUNTER_PET || !petStable.GetUnslottedHunterPet())); + pet->FillPetInfo(&petStable.CurrentPet.emplace()); + + if (petType == SUMMON_PET) + { + pet->InitPetCreateSpells(); + pet->InitTalentForLevel(); + pet->SavePetToDB(PET_SAVE_AS_CURRENT); + PetSpellInitialize(); + + // Remove Demonic Sacrifice auras (known pet) + Unit::AuraEffectList const& auraClassScripts = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + for (Unit::AuraEffectList::const_iterator itr = auraClassScripts.begin(); itr != auraClassScripts.end();) + { + if ((*itr)->GetMiscValue() == 2228) + { + RemoveAurasDueToSpell((*itr)->GetId()); + itr = auraClassScripts.begin(); + } + else + ++itr; + } + } + + if (duration > 0s) + pet->SetDuration(duration); + + if (NeedSendSpectatorData() && pet->GetCreatureTemplate()->family) + { + ArenaSpectator::SendCommand_UInt32Value(FindMap(), GetGUID(), "PHP", (uint32)pet->GetHealthPct()); + ArenaSpectator::SendCommand_UInt32Value(FindMap(), GetGUID(), "PET", pet->GetCreatureTemplate()->family); + } + + return pet; +} + void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent) { if (!pet) @@ -8782,6 +8912,138 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent) } } +bool Player::CanPetResurrect() +{ + PetStable* const petStable = GetPetStable(); + if (!petStable) + { + // No pets + return false; + } + + auto const& currectPet = petStable->CurrentPet; + auto const& unslottedHunterPet = petStable->GetUnslottedHunterPet(); + + if (!currectPet && !unslottedHunterPet) + { + // No pets + return false; + } + + // Check current pet + if (currectPet && !currectPet->Health) + { + return true; + } + + // Check dismiss/unslotted hunter pet + if (unslottedHunterPet && !unslottedHunterPet->Health) + { + return true; + } + + return false; +} + +bool Player::IsExistPet() +{ + PetStable* const petStable = GetPetStable(); + return petStable && (petStable->CurrentPet || petStable->GetUnslottedHunterPet()); +} + +Pet* Player::CreatePet(Creature* creatureTarget, uint32 spellID /*= 0*/) +{ + if (IsExistPet()) + { + return nullptr; + } + + if (!creatureTarget || creatureTarget->IsPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER) + { + return nullptr; + } + + CreatureTemplate const* creatrueTemplate = sObjectMgr->GetCreatureTemplate(creatureTarget->GetEntry()); + if (!creatrueTemplate->family) + { + // Creatures with family 0 crashes the server + return nullptr; + } + + // Everything looks OK, create new pet + Pet* pet = CreateTamedPetFrom(creatureTarget, spellID); + if (!pet) + { + return nullptr; + } + + // "kill" original creature + creatureTarget->DespawnOrUnsummon(); + + // calculate proper level + uint8 level = (creatureTarget->getLevel() < (getLevel() - 5)) ? (getLevel() - 5) : getLevel(); + + // prepare visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1); + + // add to world + pet->GetMap()->AddToMap(pet->ToCreature()); + + // visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL, level); + + // caster have pet now + SetMinion(pet, true); + + pet->InitTalentForLevel(); + + pet->SavePetToDB(PET_SAVE_AS_CURRENT); + PetSpellInitialize(); + + return pet; +} + +Pet* Player::CreatePet(uint32 creatureEntry, uint32 spellID /*= 0*/) +{ + if (IsExistPet()) + { + return nullptr; + } + + CreatureTemplate const* creatrueTemplate = sObjectMgr->GetCreatureTemplate(creatureEntry); + if (!creatrueTemplate->family) + { + // Creatures with family 0 crashes the server + return nullptr; + } + + // Everything looks OK, create new pet + Pet* pet = CreateTamedPetFrom(creatureEntry, spellID); + if (!pet) + { + return nullptr; + } + + // prepare visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL, getLevel() - 1); + + // add to world + pet->GetMap()->AddToMap(pet->ToCreature()); + + // visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL, getLevel()); + + // caster have pet now + SetMinion(pet, true); + + pet->InitTalentForLevel(); + + pet->SavePetToDB(PET_SAVE_AS_CURRENT); + PetSpellInitialize(); + + return pet; +} + void Player::StopCastingCharm() { Unit* charm = GetCharm(); @@ -15180,136 +15442,6 @@ Guild* Player::GetGuild() const return guildId ? sGuildMgr->GetGuildById(guildId) : nullptr; } -Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration /*= 0s*/) -{ - PetStable& petStable = GetOrInitPetStable(); - - Pet* pet = new Pet(this, petType); - - if (petType == SUMMON_PET && pet->LoadPetFromDB(this, entry, 0, false)) - { - // Remove Demonic Sacrifice auras (known pet) - Unit::AuraEffectList const& auraClassScripts = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); - for (Unit::AuraEffectList::const_iterator itr = auraClassScripts.begin(); itr != auraClassScripts.end();) - { - if ((*itr)->GetMiscValue() == 2228) - { - RemoveAurasDueToSpell((*itr)->GetId()); - itr = auraClassScripts.begin(); - } - else - ++itr; - } - - if (duration > 0s) - pet->SetDuration(duration); - - // Generate a new name for the newly summoned ghoul - if (pet->IsPetGhoul()) - { - std::string new_name = sObjectMgr->GeneratePetName(entry); - if (!new_name.empty()) - pet->SetName(new_name); - } - - return nullptr; - } - - // petentry == 0 for hunter "call pet" (current pet summoned if any) - if (!entry) - { - delete pet; - return nullptr; - } - - pet->Relocate(x, y, z, ang); - if (!pet->IsPositionValid()) - { - LOG_ERROR("misc", "Player::SummonPet: Pet (%s, Entry: %d) not summoned. Suggested coordinates aren't valid (X: %f Y: %f)", pet->GetGUID().ToString().c_str(), pet->GetEntry(), pet->GetPositionX(), pet->GetPositionY()); - delete pet; - return nullptr; - } - - Map* map = GetMap(); - uint32 pet_number = sObjectMgr->GeneratePetNumber(); - if (!pet->Create(map->GenerateLowGuid(), map, GetPhaseMask(), entry, pet_number)) - { - LOG_ERROR("misc", "Player::SummonPet: No such creature entry %u", entry); - delete pet; - return nullptr; - } - - if (petType == SUMMON_PET && petStable.CurrentPet) - RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT); - - pet->SetCreatorGUID(GetGUID()); - pet->SetFaction(GetFaction()); - pet->setPowerType(POWER_MANA); - pet->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); - pet->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - pet->InitStatsForLevel(getLevel()); - - SetMinion(pet, true); - - switch (petType) - { - case SUMMON_PET: - { - if (pet->GetCreatureTemplate()->type == CREATURE_TYPE_DEMON || pet->GetCreatureTemplate()->type == CREATURE_TYPE_UNDEAD) - pet->GetCharmInfo()->SetPetNumber(pet_number, true); // Show pet details tab (Shift+P) only for demons & undead - else - pet->GetCharmInfo()->SetPetNumber(pet_number, false); - - pet->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048); - pet->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0); - pet->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000); - pet->SetFullHealth(); - pet->SetPower(POWER_MANA, pet->GetMaxPower(POWER_MANA)); - pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(nullptr))); // cast can't be helped in this case - break; - } - default: - break; - } - - map->AddToMap(pet->ToCreature(), true); - - ASSERT(!petStable.CurrentPet && (petType != HUNTER_PET || !petStable.GetUnslottedHunterPet())); - pet->FillPetInfo(&petStable.CurrentPet.emplace()); - - if (petType == SUMMON_PET) - { - pet->InitPetCreateSpells(); - pet->InitTalentForLevel(); - pet->SavePetToDB(PET_SAVE_AS_CURRENT); - PetSpellInitialize(); - - // Remove Demonic Sacrifice auras (known pet) - Unit::AuraEffectList const& auraClassScripts = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); - for (Unit::AuraEffectList::const_iterator itr = auraClassScripts.begin(); itr != auraClassScripts.end();) - { - if ((*itr)->GetMiscValue() == 2228) - { - RemoveAurasDueToSpell((*itr)->GetId()); - itr = auraClassScripts.begin(); - } - else - ++itr; - } - } - - if (duration > 0s) - pet->SetDuration(duration); - - if (NeedSendSpectatorData() && pet->GetCreatureTemplate()->family) - { - ArenaSpectator::SendCommand_UInt32Value(FindMap(), GetGUID(), "PHP", (uint32)pet->GetHealthPct()); - ArenaSpectator::SendCommand_UInt32Value(FindMap(), GetGUID(), "PET", pet->GetCreatureTemplate()->family); - } - - return pet; -} - uint32 Player::GetSpec(int8 spec) { uint32 mostTalentTabId = 0; diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 322430256..0cc8b4c19 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1173,6 +1173,11 @@ public: [[nodiscard]] Pet* GetPet() const; Pet* SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration = 0s); void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false); + bool CanPetResurrect(); + bool IsExistPet(); + Pet* CreatePet(Creature* creatureTarget, uint32 spellID = 0); + Pet* CreatePet(uint32 creatureEntry, uint32 spellID = 0); + [[nodiscard]] uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn /// Handles said message in regular chat based on declared language and in config pre-defined Range. diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index f3df928ab..89efcf26e 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5932,17 +5932,6 @@ SpellCastResult Spell::CheckCast(bool strict) if (pet && pet->IsAlive()) return SPELL_FAILED_ALREADY_HAVE_SUMMON; - Player* player = unitCaster->ToPlayer(); - if (player) - { - // Check pet before resurrect - auto [petStable, petSlot] = Pet::GetLoadPetInfo(*player->GetPetStable(), 0, 0, false); - if (!petStable) - { - return SPELL_FAILED_NO_PET; - } - } - break; } // This is generic summon effect diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index b8a767f82..3b8347e31 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -1157,10 +1157,10 @@ public: Player* player = handler->GetSession()->GetPlayer(); - if (player->GetPetGUID()) + if (player->IsExistPet()) { - handler->SendSysMessage (LANG_YOU_ALREADY_HAVE_PET); - handler->SetSentErrorMessage (true); + handler->SendSysMessage(LANG_YOU_ALREADY_HAVE_PET); + handler->SetSentErrorMessage(true); return false; } @@ -1168,46 +1168,18 @@ public: if (!cInfo->IsTameable(player->CanTameExoticPets())) { - handler->PSendSysMessage (LANG_CREATURE_NON_TAMEABLE, cInfo->Entry); + handler->PSendSysMessage(LANG_CREATURE_NON_TAMEABLE, cInfo->Entry); handler->SetSentErrorMessage (true); return false; } - // Everything looks OK, create new pet - Pet* pet = player->CreateTamedPetFrom(creatureTarget); - if (!pet) + if (!player->CreatePet(creatureTarget)) { - handler->PSendSysMessage (LANG_CREATURE_NON_TAMEABLE, cInfo->Entry); - handler->SetSentErrorMessage (true); + handler->PSendSysMessage(LANG_CREATURE_NON_TAMEABLE, cInfo->Entry); + handler->SetSentErrorMessage(true); return false; } - // place pet before player - float x, y, z; - player->GetClosePoint (x, y, z, creatureTarget->GetObjectSize(), CONTACT_DISTANCE); - pet->Relocate(x, y, z, M_PI - player->GetOrientation()); - - // set pet to defensive mode by default (some classes can't control controlled pets in fact). - pet->SetReactState(REACT_DEFENSIVE); - - // calculate proper level - uint8 level = (creatureTarget->getLevel() < (player->getLevel() - 5)) ? (player->getLevel() - 5) : creatureTarget->getLevel(); - - // prepare visual effect for levelup - pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1); - - // add to world - pet->GetMap()->AddToMap(pet->ToCreature()); - - // visual effect for levelup - pet->SetUInt32Value(UNIT_FIELD_LEVEL, level); - - // caster have pet now - player->SetMinion(pet, true); - - pet->SavePetToDB(PET_SAVE_AS_CURRENT); - player->PetSpellInitialize(); - return true; } diff --git a/src/server/scripts/Commands/cs_pet.cpp b/src/server/scripts/Commands/cs_pet.cpp index c4995bd47..0863eec74 100644 --- a/src/server/scripts/Commands/cs_pet.cpp +++ b/src/server/scripts/Commands/cs_pet.cpp @@ -66,44 +66,24 @@ public: // Creatures with family 0 crashes the server if (!creatrueTemplate->family) { - handler->PSendSysMessage("This creature cannot be tamed. (family id: 0)."); + handler->PSendSysMessage(LANG_CREATURE_NON_TAMEABLE, creatrueTemplate->Entry); handler->SetSentErrorMessage(true); return false; } - PetStable const* petStable = player->GetPetStable(); - - if (petStable && (petStable->CurrentPet || petStable->GetUnslottedHunterPet())) + if (player->IsExistPet()) { - handler->PSendSysMessage("You already have a pet"); + handler->SendSysMessage(LANG_YOU_ALREADY_HAVE_PET); handler->SetSentErrorMessage(true); return false; } - // Everything looks OK, create new pet - Pet* pet = player->CreateTamedPetFrom(creatureTarget); - - // "kill" original creature - creatureTarget->DespawnOrUnsummon(); - - uint8 level = (creatureTarget->getLevel() < (player->getLevel() - 5)) ? (player->getLevel() - 5) : player->getLevel(); - - // prepare visual effect for levelup - pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1); - - // add to world - pet->GetMap()->AddToMap(pet->ToCreature()); - - // visual effect for levelup - pet->SetUInt32Value(UNIT_FIELD_LEVEL, level); - - // caster have pet now - player->SetMinion(pet, true); - - pet->InitTalentForLevel(); - - pet->SavePetToDB(PET_SAVE_AS_CURRENT); - player->PetSpellInitialize(); + if (!player->CreatePet(creatureTarget)) + { + handler->PSendSysMessage(LANG_CREATURE_NON_TAMEABLE, creatrueTemplate->Entry); + handler->SetSentErrorMessage(true); + return false; + } return true; } diff --git a/src/server/scripts/EasternKingdoms/zone_elwynn_forest.cpp b/src/server/scripts/EasternKingdoms/zone_elwynn_forest.cpp index b56b07057..35c3874ba 100644 --- a/src/server/scripts/EasternKingdoms/zone_elwynn_forest.cpp +++ b/src/server/scripts/EasternKingdoms/zone_elwynn_forest.cpp @@ -517,4 +517,3 @@ void AddSC_elwynn_forest() RegisterCreatureAI(npc_supervisor_raelen); RegisterCreatureAI(npc_eastvale_peasent); } - diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp index 62fd168d6..8ac5ce997 100644 --- a/src/server/scripts/World/go_scripts.cpp +++ b/src/server/scripts/World/go_scripts.cpp @@ -1998,4 +1998,3 @@ void AddSC_go_scripts() new go_veil_skith_cage(); new go_bells(); } -