From f0eb6d36a322b59bda7f851f44f5ba507409bc2d Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Fri, 25 Mar 2022 11:45:07 +0100 Subject: [PATCH 1/4] =?UTF-8?q?fix(Core/Handlers):=20Faction=20Change=20se?= =?UTF-8?q?rvice=20properly=20reset=20and=20give=20ne=E2=80=A6=20(#9729)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #7981 Fixes #8732 --- src/server/game/DataStores/DBCStores.cpp | 18 ++- src/server/game/DataStores/DBCStores.h | 2 + src/server/game/DungeonFinding/LFGMgr.h | 1 + src/server/game/Globals/ObjectMgr.cpp | 4 +- src/server/game/Handlers/CharacterHandler.cpp | 105 ++++++++++++++---- src/server/shared/DataStores/DBCStructure.h | 10 +- 6 files changed, 107 insertions(+), 33 deletions(-) diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index a276a9746..b9ff31654 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -20,6 +20,7 @@ #include "DBCFileLoader.h" #include "DBCfmt.h" #include "Errors.h" +#include "LFGMgr.h" #include "Log.h" #include "SharedDefines.h" #include "SpellMgr.h" @@ -510,7 +511,7 @@ void LoadDBCStores(const std::string& dataPath) for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) - sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID, entry->price); + sTaxiPathSetBySource[entry->from][entry->to] = entry; // Calculate path nodes count uint32 pathCount = sTaxiPathStore.GetNumRows(); @@ -559,7 +560,7 @@ void LoadDBCStores(const std::string& dataPath) for (TaxiPathSetForSource::const_iterator dest_i = src_i->second.begin(); dest_i != src_i->second.end(); ++dest_i) { // not spell path - if (dest_i->second.price || spellPaths.find(dest_i->second.ID) == spellPaths.end()) + if (dest_i->second->price || spellPaths.find(dest_i->second->ID) == spellPaths.end()) { ok = true; break; @@ -840,6 +841,19 @@ LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty) return nullptr; } +LFGDungeonEntry const* GetZoneLFGDungeonEntry(std::string const& zoneName, LocaleConstant locale) +{ + for (LFGDungeonEntry const* dungeon : sLFGDungeonStore) + { + if (dungeon->type == lfg::LFG_TYPE_ZONE && zoneName.find(dungeon->name[locale]) != std::string::npos) + { + return dungeon; + } + } + + return nullptr; +} + uint32 GetDefaultMapLight(uint32 mapId) { for (int32 i = sLightStore.GetNumRows(); i >= 0; --i) diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index b2913e309..046071e06 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -64,6 +64,8 @@ PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattlegroundB CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint8 class_, uint8 gender); LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty); +LFGDungeonEntry const* GetZoneLFGDungeonEntry(std::string const& zoneName, LocaleConstant locale); + uint32 GetDefaultMapLight(uint32 mapId); typedef std::unordered_multimap SkillRaceClassInfoMap; diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 8f1ef6777..2e0abf067 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -69,6 +69,7 @@ namespace lfg LFG_TYPE_NONE = 0, LFG_TYPE_DUNGEON = 1, LFG_TYPE_RAID = 2, + LFG_TYPE_ZONE = 4, LFG_TYPE_HEROIC = 5, LFG_TYPE_RANDOM = 6 }; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 427cb7c6a..e5e18746e 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -6435,8 +6435,8 @@ void ObjectMgr::GetTaxiPath(uint32 source, uint32 destination, uint32& path, uin return; } - cost = dest_i->second.price; - path = dest_i->second.ID; + cost = dest_i->second->price; + path = dest_i->second->ID; } uint32 ObjectMgr::GetTaxiMountDisplayId(uint32 id, TeamId teamId, bool allowed_alt_team /* = false */) diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index abd1f2b67..a9a8b78ad 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -33,6 +33,7 @@ #include "InstanceSaveMgr.h" #include "Language.h" #include "Log.h" +#include "MapMgr.h" #include "Metric.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" @@ -2174,33 +2175,97 @@ void WorldSession::HandleCharFactionOrRaceChangeCallback(std::shared_ptrFactionChange) { - // Delete all Flypaths - stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXI_PATH); - stmt->SetData(0, lowGuid); - trans->Append(stmt); - - if (level > 7) { - // Update Taxi path - // this doesn't seem to be 100% blizzlike... but it can't really be helped. - std::ostringstream taximaskstream; - uint32 numFullTaximasks = level / 7; + // Delete all Flypaths + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXI_PATH); + stmt->SetData(0, lowGuid); + trans->Append(stmt); - if (numFullTaximasks > 11) - numFullTaximasks = 11; + // Update Taxi path + TaxiMask newTaxiMask; + memset(newTaxiMask, 0, sizeof(newTaxiMask)); TaxiMask const& factionMask = newTeam == TEAM_HORDE ? sHordeTaxiNodesMask : sAllianceTaxiNodesMask; - for (uint8 i = 0; i < numFullTaximasks; ++i) + for (auto const& itr : sTaxiPathSetBySource) { - uint8 deathKnightExtraNode = (playerClass == CLASS_DEATH_KNIGHT) ? sDeathKnightTaxiNodesMask[i] : 0; - taximaskstream << uint32(factionMask[i] | deathKnightExtraNode) << ' '; + auto FillTaxiMask = [&](uint8 field, uint32 mask) + { + if (playerClass == CLASS_DEATH_KNIGHT) + { + newTaxiMask[field] |= uint32(mask | (sDeathKnightTaxiNodesMask[field] & mask)); + } + else + { + newTaxiMask[field] |= mask; + } + }; + + uint32 nodeId = itr.first; + uint8 field = (uint8)((nodeId - 1) / 32); + uint32 submask = 1 << ((nodeId - 1) % 32); + + if ((factionMask[field] & submask) == 0) + { + FillTaxiMask(field, 0); + continue; + } + + TaxiPathSetForSource const& taxiPaths = itr.second; + if (taxiPaths.empty()) + { + FillTaxiMask(field, 0); + continue; + } + + TaxiPathEntry const* taxiPath = taxiPaths.begin()->second; + if (!taxiPath) + { + FillTaxiMask(field, 0); + continue; + } + + TaxiPathNodeList const& taxiNodePaths = sTaxiPathNodesByPath[taxiPath->ID]; + if (taxiNodePaths.empty()) + { + FillTaxiMask(field, 0); + continue; + } + + TaxiPathNodeEntry const* pathNode = taxiNodePaths.front(); + if (!pathNode) + { + FillTaxiMask(field, 0); + continue; + } + + AreaTableEntry const* zone = sAreaTableStore.LookupEntry(sMapMgr->GetZoneId(PHASEMASK_NORMAL, pathNode->mapid, pathNode->x, pathNode->y, pathNode->z)); + if (!zone) + { + FillTaxiMask(field, 0); + continue; + } + + LFGDungeonEntry const* lfgDungeon = GetZoneLFGDungeonEntry(zone->area_name[GetSessionDbLocaleIndex()], GetSessionDbLocaleIndex()); + if (!lfgDungeon) + { + FillTaxiMask(field, 0); + continue; + } + + // Get level from LFGDungeonEntry because the one from AreaTableEntry is not valid + // If area level is too big, do not add new taxi + if (lfgDungeon->minlevel > level) + { + FillTaxiMask(field, 0); + continue; + } + + FillTaxiMask(field, submask); } - uint32 numEmptyTaximasks = 11 - numFullTaximasks; - for (uint8 i = 0; i < numEmptyTaximasks; ++i) - taximaskstream << "0 "; - - taximaskstream << '0'; + std::ostringstream taximaskstream; + for (uint8 i = 0; i < TaxiMaskSize; ++i) + taximaskstream << uint32(newTaxiMask[i]) << ' '; stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXIMASK); stmt->SetData(0, taximaskstream.str()); diff --git a/src/server/shared/DataStores/DBCStructure.h b/src/server/shared/DataStores/DBCStructure.h index 59b5f19e3..2bbc7c5bc 100644 --- a/src/server/shared/DataStores/DBCStructure.h +++ b/src/server/shared/DataStores/DBCStructure.h @@ -2159,15 +2159,7 @@ struct TalentSpellPos typedef std::map TalentSpellPosMap; -struct TaxiPathBySourceAndDestination -{ - TaxiPathBySourceAndDestination() = default; - TaxiPathBySourceAndDestination(uint32 _id, uint32 _price) : ID(_id), price(_price) {} - - uint32 ID{0}; - uint32 price{0}; -}; -typedef std::map TaxiPathSetForSource; +typedef std::map TaxiPathSetForSource; typedef std::map TaxiPathSetBySource; typedef std::vector TaxiPathNodeList; From c797cb0b930ecdee67e575611cb9afdda2691616 Mon Sep 17 00:00:00 2001 From: Grimgravy Date: Fri, 25 Mar 2022 08:44:25 -0300 Subject: [PATCH 2/4] fix(Scripts/Quest): improved Overwhelmed! (#10387) --- .../rev_1643290179356130100.sql | 64 +++ src/server/game/AI/CreatureAI.h | 3 + .../scripts/Northrend/zone_grizzly_hills.cpp | 443 ++++++++++++------ 3 files changed, 358 insertions(+), 152 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1643290179356130100.sql diff --git a/data/sql/updates/pending_db_world/rev_1643290179356130100.sql b/data/sql/updates/pending_db_world/rev_1643290179356130100.sql new file mode 100644 index 000000000..27956056a --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1643290179356130100.sql @@ -0,0 +1,64 @@ +INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1643290179356130100'); + +-- npc kneel +DELETE FROM `creature_addon` WHERE (`guid` IN (102453, 102454, 102455, 102457, 102458, 102459, 102462, 102463, 102464, 102466)); +INSERT INTO `creature_addon` (`guid`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES +(102453, 0, 0, 8, 257, 0, 0, NULL), +(102454, 0, 0, 8, 257, 0, 0, NULL), +(102455, 0, 0, 8, 257, 0, 0, NULL), +(102457, 0, 0, 8, 257, 0, 0, NULL), +(102458, 0, 0, 8, 257, 0, 0, NULL), +(102459, 0, 0, 8, 257, 0, 0, NULL), +(102462, 0, 0, 8, 257, 0, 0, NULL), +(102463, 0, 0, 8, 257, 0, 0, NULL), +(102464, 0, 0, 8, 257, 0, 0, NULL), +(102466, 0, 0, 8, 257, 0, 0, NULL); + +-- npc Wounded Skirmisher +DELETE FROM `creature` WHERE (`guid` IN (102453, 102454, 102455, 102456, 102457, 102458, 102459, 102460, 102461, 102462, 102463, 102464, 102466, 102467, 102469)); +INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`) VALUES +(102453, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4229.39, -2981.89, 283.151, 1.61792, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0), +(102454, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4134.07, -2897.23, 279.272, 5.12241, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0), +(102455, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4123.8, -2835.11, 284.196, 0.610865, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0), +(102456, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4000.98, -2847.93, 273.325, 6.03884, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0), +(102457, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4185.56, -2961.08, 283.319, 0.903392, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0), +(102458, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4017.75, -2835.31, 279.277, 1.47867, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0), +(102459, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4073.33, -2906.89, 278.332, 6.10865, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0), +(102460, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4085.95, -2846.31, 286.589, 2.94961, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0), +(102461, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4071.18, -2886.01, 281.6, 5.8294, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0), +(102462, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4074.98, -2940.5, 276.138, 4.22481, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0), +(102463, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4139.99, -3020.99, 285.459, 5.82814, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0), +(102464, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4166.57, -2964.73, 283.2, 2.63745, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0), +(102466, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4204.05, -3048.94, 280.839, 4.65053, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0), +(102467, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4057.32, -2822.2, 288.962, 3.4383, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0), +(102469, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4183.3, -2934.44, 283.114, 5.63741, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0); + +-- npc Skirmisher Corpse +DELETE FROM `creature` WHERE `guid`=91749; +INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`) VALUES +(91749, 27457, 0, 0, 571, 0, 0, 1, 1, 1, 4137.9, -3008.35, 285.667, 5.54491, 300, 0, 0, 4399, 0, 0, 0, 0, 0, '', 0); + +DELETE FROM `waypoint_data` WHERE `id`=274630; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(274630, 1, 4153.06, -2928.47, 282.58, 0, 0, 1, 0, 100, 0), +(274630, 2, 4184.53, -2909.76, 280.17, 0, 0, 1, 0, 100, 0); + +DELETE FROM `waypoint_data` WHERE `id`=274631; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(274631, 1, 4138.41, -2950.63, 282.92, 0, 0, 1, 0, 100, 0), +(274631, 2, 4153.06, -2928.47, 282.58, 0, 0, 1, 0, 100, 0), +(274631, 3, 4184.53, -2909.76, 280.17, 0, 0, 1, 0, 100, 0); + +DELETE FROM `waypoint_data` WHERE `id`=274632; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(274632, 1, 4184.53, -2909.76, 280.17, 0, 0, 1, 0, 100, 0); + +/* implementing both conditions */ + +DELETE FROM `spell_script_names` WHERE `spell_id`=48812 AND `ScriptName`='spell_renew_skirmisher'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(48812, 'spell_renew_skirmisher'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=17 AND `SourceGroup`=0 AND `SourceEntry`=48812; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(17,0,48812,0,0,31,1,3,27463,0,0,0,0,"","Heals a wounded skirmisher at Blue Sky Logging Ground."); diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index 55c65b16f..2f5880287 100644 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -21,6 +21,7 @@ #include "Common.h" #include "Creature.h" #include "UnitAI.h" +#include "EventMap.h" class WorldObject; class Unit; @@ -67,6 +68,8 @@ class CreatureAI : public UnitAI protected: Creature* const me; + EventMap events; + bool UpdateVictim(); bool UpdateVictimWithGaze(); diff --git a/src/server/scripts/Northrend/zone_grizzly_hills.cpp b/src/server/scripts/Northrend/zone_grizzly_hills.cpp index 9266a7ea8..1e0d546dd 100644 --- a/src/server/scripts/Northrend/zone_grizzly_hills.cpp +++ b/src/server/scripts/Northrend/zone_grizzly_hills.cpp @@ -25,37 +25,37 @@ #include "SpellInfo.h" #include "SpellScript.h" -// Theirs + // Theirs -/*###### -## Quest 12027: Mr. Floppy's Perilous Adventure -######*/ + /*###### + ## Quest 12027: Mr. Floppy's Perilous Adventure + ######*/ enum Floppy { // Creature - NPC_MRFLOPPY = 26589, - NPC_HUNGRY_WORG = 26586, - NPC_RAVENOUS_WORG = 26590, // RWORG - NPC_EMILY = 26588, + NPC_MRFLOPPY = 26589, + NPC_HUNGRY_WORG = 26586, + NPC_RAVENOUS_WORG = 26590, // RWORG + NPC_EMILY = 26588, // Quest - QUEST_PERILOUS_ADVENTURE = 12027, + QUEST_PERILOUS_ADVENTURE = 12027, // Spell - SPELL_MRFLOPPY = 47184, // vehicle aura + SPELL_MRFLOPPY = 47184, // vehicle aura // Text - SAY_WORGHAGGRO1 = 0, // Um... I think one of those wolves is back... - SAY_WORGHAGGRO2 = 1, // He's going for Mr. Floppy! - SAY_WORGRAGGRO3 = 2, // Oh, no! Look, it's another wolf, and it's a biiiiiig one! - SAY_WORGRAGGRO4 = 3, // He's gonna eat Mr. Floppy! You gotta help Mr. Floppy! You just gotta! - SAY_RANDOMAGGRO = 4, // There's a big meanie attacking Mr. Floppy! Help! - SAY_VICTORY1 = 5, // Let's get out of here before more wolves find us! - SAY_VICTORY2 = 6, // Don't go toward the light, Mr. Floppy! - SAY_VICTORY3 = 7, // Mr. Floppy, you're ok! Thank you so much for saving Mr. Floppy! - SAY_VICTORY4 = 8, // I think I see the camp! We're almost home, Mr. Floppy! Let's go! - TEXT_EMOTE_WP1 = 9, // Mr. Floppy revives - TEXT_EMOTE_AGGRO = 10, // The Ravenous Worg chomps down on Mr. Floppy - SAY_QUEST_ACCEPT = 11, // Are you ready, Mr. Floppy? Stay close to me and watch out for those wolves! - SAY_QUEST_COMPLETE = 12 // Thank you for helping me get back to the camp. Go tell Walter that I'm safe now! + SAY_WORGHAGGRO1 = 0, // Um... I think one of those wolves is back... + SAY_WORGHAGGRO2 = 1, // He's going for Mr. Floppy! + SAY_WORGRAGGRO3 = 2, // Oh, no! Look, it's another wolf, and it's a biiiiiig one! + SAY_WORGRAGGRO4 = 3, // He's gonna eat Mr. Floppy! You gotta help Mr. Floppy! You just gotta! + SAY_RANDOMAGGRO = 4, // There's a big meanie attacking Mr. Floppy! Help! + SAY_VICTORY1 = 5, // Let's get out of here before more wolves find us! + SAY_VICTORY2 = 6, // Don't go toward the light, Mr. Floppy! + SAY_VICTORY3 = 7, // Mr. Floppy, you're ok! Thank you so much for saving Mr. Floppy! + SAY_VICTORY4 = 8, // I think I see the camp! We're almost home, Mr. Floppy! Let's go! + TEXT_EMOTE_WP1 = 9, // Mr. Floppy revives + TEXT_EMOTE_AGGRO = 10, // The Ravenous Worg chomps down on Mr. Floppy + SAY_QUEST_ACCEPT = 11, // Are you ready, Mr. Floppy? Stay close to me and watch out for those wolves! + SAY_QUEST_COMPLETE = 12 // Thank you for helping me get back to the camp. Go tell Walter that I'm safe now! }; // emily @@ -84,102 +84,102 @@ public: switch (waypointId) { - case 9: - if (Creature* Mrfloppy = GetClosestCreatureWithEntry(me, NPC_MRFLOPPY, 100.0f)) - _mrfloppyGUID = Mrfloppy->GetGUID(); - break; - case 10: - if (ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) - { - Talk(SAY_WORGHAGGRO1); - if (Creature* worg = me->SummonCreature(NPC_HUNGRY_WORG, me->GetPositionX() + 5, me->GetPositionY() + 2, me->GetPositionZ() + 1, 3.229f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000)) - if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) - { - worg->SetReactState(REACT_AGGRESSIVE); - worg->GetAI()->AttackStart(Mrfloppy); - } - } - break; - case 11: - if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) - Mrfloppy->GetMotionMaster()->MoveFollow(me, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - break; - case 17: - if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) - Mrfloppy->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); - Talk(SAY_WORGRAGGRO3); - if (Creature* RWORG = me->SummonCreature(NPC_RAVENOUS_WORG, me->GetPositionX() + 10, me->GetPositionY() + 8, me->GetPositionZ() + 2, 3.229f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000)) - { - RWORG->SetReactState(REACT_PASSIVE); - RWORG->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - RWORG->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED); - _RavenousworgGUID = RWORG->GetGUID(); - } - break; - case 18: - if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) - { - if (Creature* RWORG = ObjectAccessor::GetCreature(*me, _RavenousworgGUID)) - RWORG->GetMotionMaster()->MovePoint(0, Mrfloppy->GetPositionX(), Mrfloppy->GetPositionY(), Mrfloppy->GetPositionZ()); - me->AddAura(SPELL_MRFLOPPY, Mrfloppy); - } - break; - case 19: - if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) - { - if (Mrfloppy->HasAura(SPELL_MRFLOPPY)) + case 9: + if (Creature* Mrfloppy = GetClosestCreatureWithEntry(me, NPC_MRFLOPPY, 100.0f)) + _mrfloppyGUID = Mrfloppy->GetGUID(); + break; + case 10: + if (ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) + { + Talk(SAY_WORGHAGGRO1); + if (Creature* worg = me->SummonCreature(NPC_HUNGRY_WORG, me->GetPositionX() + 5, me->GetPositionY() + 2, me->GetPositionZ() + 1, 3.229f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000)) + if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) { - if (Creature* RWORG = ObjectAccessor::GetCreature(*me, _RavenousworgGUID)) - Mrfloppy->EnterVehicle(RWORG); + worg->SetReactState(REACT_AGGRESSIVE); + worg->GetAI()->AttackStart(Mrfloppy); } - } - break; - case 20: + } + break; + case 11: + if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) + Mrfloppy->GetMotionMaster()->MoveFollow(me, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); + break; + case 17: + if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) + Mrfloppy->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); + Talk(SAY_WORGRAGGRO3); + if (Creature* RWORG = me->SummonCreature(NPC_RAVENOUS_WORG, me->GetPositionX() + 10, me->GetPositionY() + 8, me->GetPositionZ() + 2, 3.229f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000)) + { + RWORG->SetReactState(REACT_PASSIVE); + RWORG->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + RWORG->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED); + _RavenousworgGUID = RWORG->GetGUID(); + } + break; + case 18: + if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) + { if (Creature* RWORG = ObjectAccessor::GetCreature(*me, _RavenousworgGUID)) - RWORG->HandleEmoteCommand(34); - break; - case 21: - if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) + RWORG->GetMotionMaster()->MovePoint(0, Mrfloppy->GetPositionX(), Mrfloppy->GetPositionY(), Mrfloppy->GetPositionZ()); + me->AddAura(SPELL_MRFLOPPY, Mrfloppy); + } + break; + case 19: + if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) + { + if (Mrfloppy->HasAura(SPELL_MRFLOPPY)) { if (Creature* RWORG = ObjectAccessor::GetCreature(*me, _RavenousworgGUID)) - { - Unit::Kill(RWORG, Mrfloppy); - Mrfloppy->ExitVehicle(); - RWORG->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - RWORG->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED); - RWORG->AI()->AttackStart(player); - Talk(SAY_VICTORY2); - } + Mrfloppy->EnterVehicle(RWORG); } - break; - case 22: - if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) + } + break; + case 20: + if (Creature* RWORG = ObjectAccessor::GetCreature(*me, _RavenousworgGUID)) + RWORG->HandleEmoteCommand(34); + break; + case 21: + if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) + { + if (Creature* RWORG = ObjectAccessor::GetCreature(*me, _RavenousworgGUID)) { - if (Mrfloppy->isDead()) - { - me->GetMotionMaster()->MovePoint(0, Mrfloppy->GetPositionX(), Mrfloppy->GetPositionY(), Mrfloppy->GetPositionZ()); - Mrfloppy->setDeathState(ALIVE); - Mrfloppy->GetMotionMaster()->MoveFollow(me, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - Talk(SAY_VICTORY3); - } + Unit::Kill(RWORG, Mrfloppy); + Mrfloppy->ExitVehicle(); + RWORG->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + RWORG->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED); + RWORG->AI()->AttackStart(player); + Talk(SAY_VICTORY2); } - break; - case 24: - if (player) + } + break; + case 22: + if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) + { + if (Mrfloppy->isDead()) { - player->GroupEventHappens(QUEST_PERILOUS_ADVENTURE, me); - Talk(SAY_QUEST_COMPLETE, player); + me->GetMotionMaster()->MovePoint(0, Mrfloppy->GetPositionX(), Mrfloppy->GetPositionY(), Mrfloppy->GetPositionZ()); + Mrfloppy->setDeathState(ALIVE); + Mrfloppy->GetMotionMaster()->MoveFollow(me, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); + Talk(SAY_VICTORY3); } - me->SetWalk(false); - break; - case 25: - Talk(SAY_VICTORY4); - break; - case 27: - me->DisappearAndDie(); - if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) - Mrfloppy->DisappearAndDie(); - break; + } + break; + case 24: + if (player) + { + player->GroupEventHappens(QUEST_PERILOUS_ADVENTURE, me); + Talk(SAY_QUEST_COMPLETE, player); + } + me->SetWalk(false); + break; + case 25: + Talk(SAY_VICTORY4); + break; + case 27: + me->DisappearAndDie(); + if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID)) + Mrfloppy->DisappearAndDie(); + break; } } @@ -506,66 +506,204 @@ enum Skirmisher { // Quest QUEST_OVERWHELMED = 12288, + // Spell SPELL_RENEW_SKIRMISHER = 48812, SPELL_KILL_CREDIT = 48813, + SPELL_CLEAVE = 15496, + SPELL_HAMSTRING = 9080, + SPELL_MORTAL_STRIKE = 32736, + // Text - SAY_RANDOM = 0 + SAY_RANDOM = 0, + + // EVENT + EVENT_WOUNDED_MOVE = 1, + EVENT_CLEAVE = 2, + EVENT_HAMSTRING = 3, + EVENT_MORTAL_STRIKE = 4, + + // Waypoints + WOUNDED_MOVE_1 = 274630, + WOUNDED_MOVE_2 = 274631, + WOUNDED_MOVE_3 = 274632 }; -class npc_wounded_skirmisher : public CreatureScript +struct npc_wounded_skirmisher : public CreatureAI { public: - npc_wounded_skirmisher() : CreatureScript("npc_wounded_skirmisher") { } - - struct npc_wounded_skirmisherAI : public ScriptedAI + npc_wounded_skirmisher(Creature* creature) : CreatureAI(creature) { - npc_wounded_skirmisherAI(Creature* creature) : ScriptedAI(creature) { } + Initialize(); + } - void Reset() override - { - _despawnTimer = 5000; - _playerGUID.Clear(); - } + void Initialize() + { + me->SetReactState(REACT_DEFENSIVE); + } - void MovementInform(uint32, uint32 id) override - { - if (id == 1) - me->DespawnOrUnsummon(_despawnTimer); - } + void Reset() override + { + Initialize(); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } - void SpellHit(Unit* caster, SpellInfo const* spell) override + void EnterCombat(Unit* /*who*/) override + { + events.ScheduleEvent(EVENT_CLEAVE, urand(1000, 7000)); + events.ScheduleEvent(EVENT_HAMSTRING, urand(5000, 12000)); + events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(5000, 10000)); + } + + void SpellHit(Unit* caster, SpellInfo const* spell) override + { + Player* playerCaster = caster->ToPlayer(); + if (!playerCaster) + return; + + if (spell->Id == SPELL_RENEW_SKIRMISHER && playerCaster->GetQuestStatus(QUEST_OVERWHELMED) == QUEST_STATUS_INCOMPLETE) { - if (spell->Id == SPELL_RENEW_SKIRMISHER && caster->GetTypeId() == TYPEID_PLAYER - && caster->ToPlayer()->GetQuestStatus(QUEST_OVERWHELMED) == QUEST_STATUS_INCOMPLETE) + me->SetFacingToObject(caster); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + Talk(SAY_RANDOM, caster); + DoCast(caster, SPELL_KILL_CREDIT); + + if (!me->IsStandState()) { - DoCast(caster, SPELL_KILL_CREDIT); - Talk(SAY_RANDOM, caster); - if (me->IsStandState()) - me->GetMotionMaster()->MovePoint(1, me->GetPositionX() + 7, me->GetPositionY() + 7, me->GetPositionZ()); - else - { - me->SetStandState(UNIT_STAND_STATE_STAND); - me->DespawnOrUnsummon(_despawnTimer); - } + me->SetStandState(UNIT_STAND_STATE_STAND); + me->HandleEmoteCommand(EMOTE_ONESHOT_CHEER); + events.ScheduleEvent(EVENT_WOUNDED_MOVE, 3000); } } + } - void UpdateAI(uint32 /*diff*/) override - { - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - private: - ObjectGuid _playerGUID; - uint32 _despawnTimer; - }; - - CreatureAI* GetAI(Creature* creature) const override + void UpdateAI(uint32 diff) override { - return new npc_wounded_skirmisherAI(creature); + events.Update(diff); + + switch (events.ExecuteEvent()) + { + case EVENT_WOUNDED_MOVE: + if (me->GetPositionY() == -2835.11f) + { + me->GetMotionMaster()->MovePath(WOUNDED_MOVE_1, false); + me->DespawnOrUnsummon(20000); + } + if (me->GetPositionY() == -2981.89f) + { + me->GetMotionMaster()->MovePath(WOUNDED_MOVE_3, false); + me->DespawnOrUnsummon(18000); + } + if (me->GetPositionY() == -2934.44f) + { + me->GetMotionMaster()->MovePath(WOUNDED_MOVE_3, false); + me->DespawnOrUnsummon(9000); + } + if (me->GetPositionY() == -3020.99f) + { + me->GetMotionMaster()->MovePath(WOUNDED_MOVE_1, false); + me->DespawnOrUnsummon(22000); + } + if (me->GetPositionY() == -2964.73f) + { + me->GetMotionMaster()->MovePath(WOUNDED_MOVE_2, false); + me->DespawnOrUnsummon(15000); + } + if (me->GetPositionY() == -2940.50f) + { + me->GetMotionMaster()->MovePath(WOUNDED_MOVE_1, false); + me->DespawnOrUnsummon(20000); + } + if (me->GetPositionY() == -2847.93f) + { + me->GetMotionMaster()->MovePath(WOUNDED_MOVE_1, false); + me->DespawnOrUnsummon(30000); + } + if (me->GetPositionY() == -2835.31f) + { + me->GetMotionMaster()->MovePath(WOUNDED_MOVE_1, false); + me->DespawnOrUnsummon(27000); + } + if (me->GetPositionY() == -2822.20f) + { + me->GetMotionMaster()->MovePath(WOUNDED_MOVE_1, false); + me->DespawnOrUnsummon(25000); + } + if (me->GetPositionY() == -2846.31f) + { + me->GetMotionMaster()->MovePath(WOUNDED_MOVE_1, false); + me->DespawnOrUnsummon(21000); + } + if (me->GetPositionY() == -2897.23f) + { + me->GetMotionMaster()->MovePath(WOUNDED_MOVE_3, false); + me->DespawnOrUnsummon(15000); + } + if (me->GetPositionY() == -2886.01f) + { + me->GetMotionMaster()->MovePath(WOUNDED_MOVE_3, false); + me->DespawnOrUnsummon(25000); + } + if (me->GetPositionY() == -2906.89f) + { + me->GetMotionMaster()->MovePath(WOUNDED_MOVE_3, false); + me->DespawnOrUnsummon(25000); + } + if (me->GetPositionY() == -3048.94f) + { + me->GetMotionMaster()->MovePath(WOUNDED_MOVE_2, false); + me->DespawnOrUnsummon(30000); + } + if (me->GetPositionY() == -2961.08f) + { + me->GetMotionMaster()->MovePath(WOUNDED_MOVE_2, false); + me->DespawnOrUnsummon(25000); + } + break; + case EVENT_CLEAVE: + me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false); + events.RepeatEvent(urand(7000, 15000)); + break; + case EVENT_HAMSTRING: + me->CastSpell(me->GetVictim(), SPELL_HAMSTRING, false); + events.RepeatEvent(urand(9000, 15000)); + break; + case EVENT_MORTAL_STRIKE: + me->CastSpell(me->GetVictim(), SPELL_MORTAL_STRIKE, false); + events.RepeatEvent(urand(10000, 15000)); + break; + } + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } +}; + +enum renewskirmisher +{ + NPC_WOUNDED_SKIRMISHER = 27463 +}; + +class spell_renew_skirmisher : public SpellScript +{ +public: + PrepareSpellScript(spell_renew_skirmisher); + + SpellCastResult CheckRequirement() + { + if (Unit* caster = GetCaster()) + if (Creature* wounded = caster->FindNearestCreature(NPC_WOUNDED_SKIRMISHER, 5.0f)) + if (!wounded->IsInCombat()) + return SPELL_CAST_OK; + + return SPELL_FAILED_CASTER_AURASTATE; + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_renew_skirmisher::CheckRequirement); } }; @@ -1163,7 +1301,8 @@ void AddSC_grizzly_hills() new npc_outhouse_bunny(); new npc_tallhorn_stag(); new npc_amberpine_woodsman(); - new npc_wounded_skirmisher(); + RegisterCreatureAI(npc_wounded_skirmisher); + RegisterSpellScript(spell_renew_skirmisher); new npc_venture_co_straggler(); new npc_lake_frog(); new spell_shredder_delivery(); From 89ba502bfc09ae5e8d217d7beb9494c5673c1af4 Mon Sep 17 00:00:00 2001 From: AzerothCoreBot Date: Fri, 25 Mar 2022 11:46:10 +0000 Subject: [PATCH 3/4] chore(DB): import pending files Referenced commit(s): c797cb0b930ecdee67e575611cb9afdda2691616 --- .../2022_03_25_00.sql} | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) rename data/sql/updates/{pending_db_world/rev_1643290179356130100.sql => db_world/2022_03_25_00.sql} (86%) diff --git a/data/sql/updates/pending_db_world/rev_1643290179356130100.sql b/data/sql/updates/db_world/2022_03_25_00.sql similarity index 86% rename from data/sql/updates/pending_db_world/rev_1643290179356130100.sql rename to data/sql/updates/db_world/2022_03_25_00.sql index 27956056a..6866734e8 100644 --- a/data/sql/updates/pending_db_world/rev_1643290179356130100.sql +++ b/data/sql/updates/db_world/2022_03_25_00.sql @@ -1,3 +1,19 @@ +-- DB update 2022_03_23_03 -> 2022_03_25_00 +DROP PROCEDURE IF EXISTS `updateDb`; +DELIMITER // +CREATE PROCEDURE updateDb () +proc:BEGIN DECLARE OK VARCHAR(100) DEFAULT 'FALSE'; +SELECT COUNT(*) INTO @COLEXISTS +FROM information_schema.COLUMNS +WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'version_db_world' AND COLUMN_NAME = '2022_03_23_03'; +IF @COLEXISTS = 0 THEN LEAVE proc; END IF; +START TRANSACTION; +ALTER TABLE version_db_world CHANGE COLUMN 2022_03_23_03 2022_03_25_00 bit; +SELECT sql_rev INTO OK FROM version_db_world WHERE sql_rev = '1643290179356130100'; IF OK <> 'FALSE' THEN LEAVE proc; END IF; +-- +-- START UPDATING QUERIES +-- + INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1643290179356130100'); -- npc kneel @@ -62,3 +78,13 @@ INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=17 AND `SourceGroup`=0 AND `SourceEntry`=48812; INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES (17,0,48812,0,0,31,1,3,27463,0,0,0,0,"","Heals a wounded skirmisher at Blue Sky Logging Ground."); + +-- +-- END UPDATING QUERIES +-- +UPDATE version_db_world SET date = '2022_03_25_00' WHERE sql_rev = '1643290179356130100'; +COMMIT; +END // +DELIMITER ; +CALL updateDb(); +DROP PROCEDURE IF EXISTS `updateDb`; From 606c5dc7a8e22ac893a5fe81e82603e22d419b16 Mon Sep 17 00:00:00 2001 From: acidmanifesto Date: Fri, 25 Mar 2022 10:13:03 -0400 Subject: [PATCH 4/4] Fix (core) Death Comes from high Client Crash Fix (#11136) This fixes the client side crash while flying as the EYE OF ACHERUS, apparrently if the player lacks the visual spell on his character the client would crash. This is something I just want NOT ABLE to identify in debugger, however, true story also by the way, @TheDdraig made a suggestion while being both stone and highly intoxicate that he came up with the insane nonsensible approach that actually solved the issue 100%. Co-Authored-By: TheDdraig <62179779+TheDdraig@users.noreply.github.com> Co-authored-by: TheDdraig <62179779+TheDdraig@users.noreply.github.com> --- .../scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp index ccd1a49a7..965c537c2 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp @@ -111,6 +111,10 @@ public: break; case EVENT_LAUNCH: { + if (Player* player = me->GetCharmerOrOwnerPlayerOrPlayerItself()) + { + player->AddAura(SPELL_EYE_OF_ACHERUS_VISUAL, player); + } me->SetSpeed(MOVE_FLIGHT, 5.0f, true); const Position EYE_DESTINATION_1 = { me->GetPositionX() - 40.0f, me->GetPositionY(), me->GetPositionZ() + 10.0f, 0.0f }; @@ -118,6 +122,10 @@ public: me->GetMotionMaster()->MovePoint(EYE_POINT_DESTINATION_1, EYE_DESTINATION_1); me->GetMotionMaster()->MovePoint(EYE_POINT_DESTINATION_2, EYE_DESTINATION_2); + if (Player* player = me->GetCharmerOrOwnerPlayerOrPlayerItself()) + { + player->RemoveAura(SPELL_EYE_OF_ACHERUS_VISUAL); + } break; } case EVENT_REGAIN_CONTROL: