Merge branch 'master' into Playerbot

This commit is contained in:
Yunfan Li
2024-07-07 13:32:00 +08:00
87 changed files with 1928 additions and 1062 deletions

View File

@@ -223,7 +223,7 @@ public:
static bool HandleReloadBattlegroundTemplate(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Battleground Templates...");
LOG_INFO("server.loading", "Reloading Battleground Templates...");
sBattlegroundMgr->LoadBattlegroundTemplates();
handler->SendGlobalGMSysMessage("DB table `battleground_template` reloaded.");
return true;
@@ -247,7 +247,7 @@ public:
static bool HandleReloadAllLootCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Loot Tables...");
LOG_INFO("server.loading", "Reloading Loot Tables...");
LoadLootTables();
handler->SendGlobalGMSysMessage("DB tables `*_loot_template` reloaded.");
sConditionMgr->LoadConditions(true);
@@ -271,7 +271,7 @@ public:
HandleReloadQuestTemplateCommand(handler);
HandleReloadLocalesQuestGreetingCommand(handler);
LOG_INFO("server.loading", "Re-Loading Quests Relations...");
LOG_INFO("server.loading", "Reloading Quests Relations...");
sObjectMgr->LoadQuestStartersAndEnders();
handler->SendGlobalGMSysMessage("DB tables `*_queststarter` and `*_questender` reloaded.");
return true;
@@ -285,7 +285,7 @@ public:
return false;
}
LOG_INFO("server.loading", "Re-Loading Scripts...");
LOG_INFO("server.loading", "Reloading Scripts...");
HandleReloadEventScriptsCommand(handler);
HandleReloadSpellScriptsCommand(handler);
handler->SendGlobalGMSysMessage("DB tables `*_scripts` reloaded.");
@@ -346,7 +346,7 @@ public:
static bool HandleReloadConfigCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading config settings...");
LOG_INFO("server.loading", "Reloading config settings...");
sWorld->LoadConfigSettings(true);
sMapMgr->InitializeVisibilityDistanceInfo();
handler->SendGlobalGMSysMessage("World config settings reloaded.");
@@ -355,7 +355,7 @@ public:
static bool HandleReloadDungeonAccessCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Dungeon Access Requirement definitions...");
LOG_INFO("server.loading", "Reloading Dungeon Access Requirement definitions...");
sObjectMgr->LoadAccessRequirements();
handler->SendGlobalGMSysMessage("DB tables `dungeon_access_template` AND `dungeon_access_requirements` reloaded.");
return true;
@@ -363,7 +363,7 @@ public:
static bool HandleReloadAchievementCriteriaDataCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Additional Achievement Criteria Data...");
LOG_INFO("server.loading", "Reloading Additional Achievement Criteria Data...");
sAchievementMgr->LoadAchievementCriteriaData();
handler->SendGlobalGMSysMessage("DB table `achievement_criteria_data` reloaded.");
return true;
@@ -371,7 +371,7 @@ public:
static bool HandleReloadAchievementRewardCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Achievement Reward Data...");
LOG_INFO("server.loading", "Reloading Achievement Reward Data...");
sAchievementMgr->LoadRewards();
handler->SendGlobalGMSysMessage("DB table `achievement_reward` reloaded.");
return true;
@@ -379,7 +379,7 @@ public:
static bool HandleReloadAreaTriggerTavernCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Tavern Area Triggers...");
LOG_INFO("server.loading", "Reloading Tavern Area Triggers...");
sObjectMgr->LoadTavernAreaTriggers();
handler->SendGlobalGMSysMessage("DB table `areatrigger_tavern` reloaded.");
return true;
@@ -387,7 +387,7 @@ public:
static bool HandleReloadAreaTriggerCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Area Trigger definitions...");
LOG_INFO("server.loading", "Reloading Area Trigger definitions...");
sObjectMgr->LoadAreaTriggers();
handler->SendGlobalGMSysMessage("DB table `areatrigger` reloaded.");
return true;
@@ -395,7 +395,7 @@ public:
static bool HandleReloadAreaTriggerTeleportCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Area Trigger teleport definitions...");
LOG_INFO("server.loading", "Reloading Area Trigger teleport definitions...");
sObjectMgr->LoadAreaTriggerTeleports();
handler->SendGlobalGMSysMessage("DB table `areatrigger_teleport` reloaded.");
return true;
@@ -403,7 +403,7 @@ public:
static bool HandleReloadAutobroadcastCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Autobroadcasts...");
LOG_INFO("server.loading", "Reloading Autobroadcasts...");
sAutobroadcastMgr->LoadAutobroadcasts();
handler->SendGlobalGMSysMessage("DB table `autobroadcast` reloaded.");
return true;
@@ -411,7 +411,7 @@ public:
static bool HandleReloadMotdCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Motd...");
LOG_INFO("server.loading", "Reloading Motd...");
sMotdMgr->LoadMotd();
handler->SendGlobalGMSysMessage("DB table `motd` reloaded.");
handler->SendGlobalSysMessage(sMotdMgr->GetMotd());
@@ -420,7 +420,7 @@ public:
static bool HandleReloadBroadcastTextCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Broadcast texts...");
LOG_INFO("server.loading", "Reloading Broadcast texts...");
sObjectMgr->LoadBroadcastTexts();
sObjectMgr->LoadBroadcastTextLocales();
handler->SendGlobalGMSysMessage("DB table `broadcast_text` reloaded.");
@@ -440,7 +440,7 @@ public:
static bool HandleReloadOnKillReputationCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading creature award reputation definitions...");
LOG_INFO("server.loading", "Reloading creature award reputation definitions...");
sObjectMgr->LoadReputationOnKill();
handler->SendGlobalGMSysMessage("DB table `creature_onkill_reputation` reloaded.");
return true;
@@ -510,7 +510,7 @@ public:
static bool HandleReloadGossipMenuCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading `gossip_menu` Table!");
LOG_INFO("server.loading", "Reloading `gossip_menu` Table!");
sObjectMgr->LoadGossipMenu();
handler->SendGlobalGMSysMessage("DB table `gossip_menu` reloaded.");
sConditionMgr->LoadConditions(true);
@@ -519,7 +519,7 @@ public:
static bool HandleReloadGossipMenuOptionCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading `gossip_menu_option` Table!");
LOG_INFO("server.loading", "Reloading `gossip_menu_option` Table!");
sObjectMgr->LoadGossipMenuItems();
handler->SendGlobalGMSysMessage("DB table `gossip_menu_option` reloaded.");
sConditionMgr->LoadConditions(true);
@@ -544,7 +544,7 @@ public:
static bool HandleReloadQuestAreaTriggersCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Quest Area Triggers...");
LOG_INFO("server.loading", "Reloading Quest Area Triggers...");
sObjectMgr->LoadQuestAreaTriggers();
handler->SendGlobalGMSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded.");
return true;
@@ -552,7 +552,7 @@ public:
static bool HandleReloadQuestGreetingCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Quest Greeting ...");
LOG_INFO("server.loading", "Reloading Quest Greeting ...");
sObjectMgr->LoadQuestGreetings();
handler->SendGlobalGMSysMessage("DB table `quest_greeting` reloaded.");
return true;
@@ -560,7 +560,7 @@ public:
static bool HandleReloadLocalesQuestGreetingCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Quest Greeting locales...");
LOG_INFO("server.loading", "Reloading Quest Greeting locales...");
sObjectMgr->LoadQuestGreetingsLocales();
handler->SendGlobalGMSysMessage("DB table `quest_greeting_locale` reloaded.");
return true;
@@ -568,12 +568,12 @@ public:
static bool HandleReloadQuestTemplateCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Quest Templates...");
LOG_INFO("server.loading", "Reloading Quest Templates...");
sObjectMgr->LoadQuests();
handler->SendGlobalGMSysMessage("DB table `quest_template` (quest definitions) reloaded.");
/// dependent also from `gameobject` but this table not reloaded anyway
LOG_INFO("server.loading", "Re-Loading GameObjects for quests...");
LOG_INFO("server.loading", "Reloading GameObjects for quests...");
sObjectMgr->LoadGameObjectForQuests();
handler->SendGlobalGMSysMessage("Data GameObjects for quests reloaded.");
return true;
@@ -581,7 +581,7 @@ public:
static bool HandleReloadLootTemplatesCreatureCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Loot Tables... (`creature_loot_template`)");
LOG_INFO("server.loading", "Reloading Loot Tables... (`creature_loot_template`)");
LoadLootTemplates_Creature();
LootTemplates_Creature.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `creature_loot_template` reloaded.");
@@ -591,7 +591,7 @@ public:
static bool HandleReloadCreatureMovementOverrideCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Creature movement overrides...");
LOG_INFO("server.loading", "Reloading Creature movement overrides...");
sObjectMgr->LoadCreatureMovementOverrides();
handler->SendGlobalGMSysMessage("DB table `creature_movement_override` reloaded.");
return true;
@@ -599,7 +599,7 @@ public:
static bool HandleReloadLootTemplatesDisenchantCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Loot Tables... (`disenchant_loot_template`)");
LOG_INFO("server.loading", "Reloading Loot Tables... (`disenchant_loot_template`)");
LoadLootTemplates_Disenchant();
LootTemplates_Disenchant.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `disenchant_loot_template` reloaded.");
@@ -609,7 +609,7 @@ public:
static bool HandleReloadLootTemplatesFishingCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Loot Tables... (`fishing_loot_template`)");
LOG_INFO("server.loading", "Reloading Loot Tables... (`fishing_loot_template`)");
LoadLootTemplates_Fishing();
LootTemplates_Fishing.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `fishing_loot_template` reloaded.");
@@ -619,7 +619,7 @@ public:
static bool HandleReloadLootTemplatesGameobjectCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Loot Tables... (`gameobject_loot_template`)");
LOG_INFO("server.loading", "Reloading Loot Tables... (`gameobject_loot_template`)");
LoadLootTemplates_Gameobject();
LootTemplates_Gameobject.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `gameobject_loot_template` reloaded.");
@@ -629,7 +629,7 @@ public:
static bool HandleReloadLootTemplatesItemCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Loot Tables... (`item_loot_template`)");
LOG_INFO("server.loading", "Reloading Loot Tables... (`item_loot_template`)");
LoadLootTemplates_Item();
LootTemplates_Item.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `item_loot_template` reloaded.");
@@ -639,7 +639,7 @@ public:
static bool HandleReloadLootTemplatesMillingCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Loot Tables... (`milling_loot_template`)");
LOG_INFO("server.loading", "Reloading Loot Tables... (`milling_loot_template`)");
LoadLootTemplates_Milling();
LootTemplates_Milling.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `milling_loot_template` reloaded.");
@@ -649,7 +649,7 @@ public:
static bool HandleReloadLootTemplatesPickpocketingCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Loot Tables... (`pickpocketing_loot_template`)");
LOG_INFO("server.loading", "Reloading Loot Tables... (`pickpocketing_loot_template`)");
LoadLootTemplates_Pickpocketing();
LootTemplates_Pickpocketing.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `pickpocketing_loot_template` reloaded.");
@@ -659,7 +659,7 @@ public:
static bool HandleReloadLootTemplatesProspectingCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Loot Tables... (`prospecting_loot_template`)");
LOG_INFO("server.loading", "Reloading Loot Tables... (`prospecting_loot_template`)");
LoadLootTemplates_Prospecting();
LootTemplates_Prospecting.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `prospecting_loot_template` reloaded.");
@@ -669,7 +669,7 @@ public:
static bool HandleReloadLootTemplatesMailCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Loot Tables... (`mail_loot_template`)");
LOG_INFO("server.loading", "Reloading Loot Tables... (`mail_loot_template`)");
LoadLootTemplates_Mail();
LootTemplates_Mail.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `mail_loot_template` reloaded.");
@@ -679,7 +679,7 @@ public:
static bool HandleReloadLootTemplatesReferenceCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Loot Tables... (`reference_loot_template`)");
LOG_INFO("server.loading", "Reloading Loot Tables... (`reference_loot_template`)");
LoadLootTemplates_Reference();
handler->SendGlobalGMSysMessage("DB table `reference_loot_template` reloaded.");
sConditionMgr->LoadConditions(true);
@@ -688,7 +688,7 @@ public:
static bool HandleReloadLootTemplatesSkinningCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Loot Tables... (`skinning_loot_template`)");
LOG_INFO("server.loading", "Reloading Loot Tables... (`skinning_loot_template`)");
LoadLootTemplates_Skinning();
LootTemplates_Skinning.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `skinning_loot_template` reloaded.");
@@ -698,7 +698,7 @@ public:
static bool HandleReloadLootTemplatesSpellCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Loot Tables... (`spell_loot_template`)");
LOG_INFO("server.loading", "Reloading Loot Tables... (`spell_loot_template`)");
LoadLootTemplates_Spell();
LootTemplates_Spell.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `spell_loot_template` reloaded.");
@@ -708,7 +708,7 @@ public:
static bool HandleReloadLootTemplatesPlayerCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Loot Tables... (`player_loot_template`)");
LOG_INFO("server.loading", "Reloading Loot Tables... (`player_loot_template`)");
LoadLootTemplates_Player();
LootTemplates_Player.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `player_loot_template` reloaded.");
@@ -718,7 +718,7 @@ public:
static bool HandleReloadAcoreStringCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading acore_string Table!");
LOG_INFO("server.loading", "Reloading acore_string Table!");
sObjectMgr->LoadAcoreStrings();
handler->SendGlobalGMSysMessage("DB table `acore_string` reloaded.");
return true;
@@ -732,7 +732,7 @@ public:
return false;
}
LOG_INFO("server.loading", "Re-Loading warden_action Table!");
LOG_INFO("server.loading", "Reloading warden_action Table!");
sWardenCheckMgr->LoadWardenOverrides();
handler->SendGlobalGMSysMessage("DB table `warden_action` reloaded.");
return true;
@@ -740,7 +740,7 @@ public:
static bool HandleReloadNpcTrainerCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading `npc_trainer` Table!");
LOG_INFO("server.loading", "Reloading `npc_trainer` Table!");
sObjectMgr->LoadTrainerSpell();
handler->SendGlobalGMSysMessage("DB table `npc_trainer` reloaded.");
return true;
@@ -748,7 +748,7 @@ public:
static bool HandleReloadNpcVendorCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading `npc_vendor` Table!");
LOG_INFO("server.loading", "Reloading `npc_vendor` Table!");
sObjectMgr->LoadVendors();
handler->SendGlobalGMSysMessage("DB table `npc_vendor` reloaded.");
return true;
@@ -756,7 +756,7 @@ public:
static bool HandleReloadPointsOfInterestCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading `points_of_interest` Table!");
LOG_INFO("server.loading", "Reloading `points_of_interest` Table!");
sObjectMgr->LoadPointsOfInterest();
handler->SendGlobalGMSysMessage("DB table `points_of_interest` reloaded.");
return true;
@@ -764,7 +764,7 @@ public:
static bool HandleReloadQuestPOICommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Quest POI ..." );
LOG_INFO("server.loading", "Reloading Quest POI ..." );
sObjectMgr->LoadQuestPOI();
handler->SendGlobalGMSysMessage("DB Table `quest_poi` and `quest_poi_points` reloaded.");
return true;
@@ -772,7 +772,7 @@ public:
static bool HandleReloadSpellClickSpellsCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading `npc_spellclick_spells` Table!");
LOG_INFO("server.loading", "Reloading `npc_spellclick_spells` Table!");
sObjectMgr->LoadNPCSpellClickSpells();
handler->SendGlobalGMSysMessage("DB table `npc_spellclick_spells` reloaded.");
return true;
@@ -780,7 +780,7 @@ public:
static bool HandleReloadReservedNameCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Reserved Names!");
LOG_INFO("server.loading", "Reloading Reserved Names!");
sObjectMgr->LoadReservedPlayerNamesDB();
sObjectMgr->LoadReservedPlayerNamesDBC(); // Needed because we clear the store in LoadReservedPlayerNamesDB()
handler->SendGlobalGMSysMessage("Reserved Names reloaded.");
@@ -789,7 +789,7 @@ public:
static bool HandleReloadProfanityNameCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Profanity Names!");
LOG_INFO("server.loading", "Reloading Profanity Names!");
sObjectMgr->LoadProfanityNamesFromDB();
sObjectMgr->LoadProfanityNamesFromDBC(); // Needed because we clear the store in LoadProfanityNamesFromDB()
handler->SendGlobalGMSysMessage("Profanity Names reloaded.");
@@ -798,7 +798,7 @@ public:
static bool HandleReloadReputationRewardRateCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading `reputation_reward_rate` Table!" );
LOG_INFO("server.loading", "Reloading `reputation_reward_rate` Table!" );
sObjectMgr->LoadReputationRewardRate();
handler->SendGlobalSysMessage("DB table `reputation_reward_rate` reloaded.");
return true;
@@ -806,7 +806,7 @@ public:
static bool HandleReloadReputationSpilloverTemplateCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading `reputation_spillover_template` Table!" );
LOG_INFO("server.loading", "Reloading `reputation_spillover_template` Table!" );
sObjectMgr->LoadReputationSpilloverTemplate();
handler->SendGlobalSysMessage("DB table `reputation_spillover_template` reloaded.");
return true;
@@ -814,7 +814,7 @@ public:
static bool HandleReloadSkillDiscoveryTemplateCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Skill Discovery Table...");
LOG_INFO("server.loading", "Reloading Skill Discovery Table...");
LoadSkillDiscoveryTable();
handler->SendGlobalGMSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded.");
return true;
@@ -823,7 +823,7 @@ public:
static bool HandleReloadSkillPerfectItemTemplateCommand(ChatHandler* handler)
{
// latched onto HandleReloadSkillExtraItemTemplateCommand as it's part of that table group (and i don't want to chance all the command IDs)
LOG_INFO("server.loading", "Re-Loading Skill Perfection Data Table...");
LOG_INFO("server.loading", "Reloading Skill Perfection Data Table...");
LoadSkillPerfectItemTable();
handler->SendGlobalGMSysMessage("DB table `skill_perfect_item_template` (perfect item procs when crafting) reloaded.");
return true;
@@ -831,7 +831,7 @@ public:
static bool HandleReloadSkillExtraItemTemplateCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Skill Extra Item Table...");
LOG_INFO("server.loading", "Reloading Skill Extra Item Table...");
LoadSkillExtraItemTable();
handler->SendGlobalGMSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
return HandleReloadSkillPerfectItemTemplateCommand(handler);
@@ -839,7 +839,7 @@ public:
static bool HandleReloadSkillFishingBaseLevelCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Skill Fishing base level requirements...");
LOG_INFO("server.loading", "Reloading Skill Fishing base level requirements...");
sObjectMgr->LoadFishingBaseSkillLevel();
handler->SendGlobalGMSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded.");
return true;
@@ -847,7 +847,7 @@ public:
static bool HandleReloadSpellAreaCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading SpellArea Data...");
LOG_INFO("server.loading", "Reloading SpellArea Data...");
sSpellMgr->LoadSpellAreas();
handler->SendGlobalGMSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded.");
return true;
@@ -855,7 +855,7 @@ public:
static bool HandleReloadSpellRequiredCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Spell Required Data... ");
LOG_INFO("server.loading", "Reloading Spell Required Data... ");
sSpellMgr->LoadSpellRequired();
handler->SendGlobalGMSysMessage("DB table `spell_required` reloaded.");
return true;
@@ -863,7 +863,7 @@ public:
static bool HandleReloadSpellGroupsCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Spell Groups...");
LOG_INFO("server.loading", "Reloading Spell Groups...");
sSpellMgr->LoadSpellGroups();
handler->SendGlobalGMSysMessage("DB table `spell_group` (spell groups) reloaded.");
return true;
@@ -871,7 +871,7 @@ public:
static bool HandleReloadSpellLinkedSpellCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Spell Linked Spells...");
LOG_INFO("server.loading", "Reloading Spell Linked Spells...");
sSpellMgr->LoadSpellLinked();
handler->SendGlobalGMSysMessage("DB table `spell_linked_spell` reloaded.");
return true;
@@ -879,7 +879,7 @@ public:
static bool HandleReloadSpellProcEventCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Spell Proc Event conditions...");
LOG_INFO("server.loading", "Reloading Spell Proc Event conditions...");
sSpellMgr->LoadSpellProcEvents();
handler->SendGlobalGMSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded.");
return true;
@@ -887,7 +887,7 @@ public:
static bool HandleReloadSpellProcsCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Spell Proc conditions and data...");
LOG_INFO("server.loading", "Reloading Spell Proc conditions and data...");
sSpellMgr->LoadSpellProcs();
handler->SendGlobalGMSysMessage("DB table `spell_proc` (spell proc conditions and data) reloaded.");
return true;
@@ -895,7 +895,7 @@ public:
static bool HandleReloadSpellBonusesCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Spell Bonus Data...");
LOG_INFO("server.loading", "Reloading Spell Bonus Data...");
sSpellMgr->LoadSpellBonuses();
handler->SendGlobalGMSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
return true;
@@ -903,7 +903,7 @@ public:
static bool HandleReloadSpellTargetPositionCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Spell target coordinates...");
LOG_INFO("server.loading", "Reloading Spell target coordinates...");
sSpellMgr->LoadSpellTargetPositions();
handler->SendGlobalGMSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded.");
return true;
@@ -911,7 +911,7 @@ public:
static bool HandleReloadSpellThreatsCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Aggro Spells Definitions...");
LOG_INFO("server.loading", "Reloading Aggro Spells Definitions...");
sSpellMgr->LoadSpellThreats();
handler->SendGlobalGMSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded.");
return true;
@@ -919,7 +919,7 @@ public:
static bool HandleReloadSpellGroupStackRulesCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Spell Group Stack Rules...");
LOG_INFO("server.loading", "Reloading Spell Group Stack Rules...");
sSpellMgr->LoadSpellGroupStackRules();
handler->SendGlobalGMSysMessage("DB table `spell_group_stack_rules` (spell stacking definitions) reloaded.");
return true;
@@ -927,7 +927,7 @@ public:
static bool HandleReloadSpellPetAurasCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Spell pet auras...");
LOG_INFO("server.loading", "Reloading Spell pet auras...");
sSpellMgr->LoadSpellPetAuras();
handler->SendGlobalGMSysMessage("DB table `spell_pet_auras` reloaded.");
return true;
@@ -935,7 +935,7 @@ public:
static bool HandleReloadPageTextsCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Page Texts...");
LOG_INFO("server.loading", "Reloading Page Texts...");
sObjectMgr->LoadPageTexts();
handler->SendGlobalGMSysMessage("DB table `page_texts` reloaded.");
handler->SendGlobalGMSysMessage("You need to delete your client cache or change the cache number in config in order for your players see the changes.");
@@ -944,7 +944,7 @@ public:
static bool HandleReloadItemEnchantementsCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Item Random Enchantments Table...");
LOG_INFO("server.loading", "Reloading Item Random Enchantments Table...");
LoadRandomEnchantmentsTable();
handler->SendGlobalGMSysMessage("DB table `item_enchantment_template` reloaded.");
return true;
@@ -952,7 +952,7 @@ public:
static bool HandleReloadItemSetNamesCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Item set names...");
LOG_INFO("server.loading", "Reloading Item set names...");
sObjectMgr->LoadItemSetNames();
handler->SendGlobalGMSysMessage("DB table `item_set_names` reloaded.");
return true;
@@ -966,7 +966,7 @@ public:
return false;
}
LOG_INFO("server.loading", "Re-Loading Scripts from `event_scripts`...");
LOG_INFO("server.loading", "Reloading Scripts from `event_scripts`...");
sObjectMgr->LoadEventScripts();
@@ -983,7 +983,7 @@ public:
return false;
}
LOG_INFO("server.loading", "Re-Loading Scripts from `waypoint_scripts`...");
LOG_INFO("server.loading", "Reloading Scripts from `waypoint_scripts`...");
sObjectMgr->LoadWaypointScripts();
@@ -994,7 +994,7 @@ public:
static bool HandleReloadWpCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Waypoints data from 'waypoints_data'");
LOG_INFO("server.loading", "Reloading Waypoints data from 'waypoints_data'");
sWaypointMgr->Load();
handler->SendGlobalGMSysMessage("DB Table 'waypoint_data' reloaded.");
@@ -1009,7 +1009,7 @@ public:
return false;
}
LOG_INFO("server.loading", "Re-Loading Scripts from `spell_scripts`...");
LOG_INFO("server.loading", "Reloading Scripts from `spell_scripts`...");
sObjectMgr->LoadSpellScripts();
@@ -1020,7 +1020,7 @@ public:
static bool HandleReloadGameGraveyardZoneCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Graveyard-zone links...");
LOG_INFO("server.loading", "Reloading Graveyard-zone links...");
sGraveyard->LoadGraveyardZones();
@@ -1031,7 +1031,7 @@ public:
static bool HandleReloadGameTeleCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Game Tele coordinates...");
LOG_INFO("server.loading", "Reloading Game Tele coordinates...");
sObjectMgr->LoadGameTele();
@@ -1042,7 +1042,7 @@ public:
static bool HandleReloadDisablesCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading disables table...");
LOG_INFO("server.loading", "Reloading disables table...");
DisableMgr::LoadDisables();
LOG_INFO("server.loading", "Checking quest disables...");
DisableMgr::CheckQuestDisables();
@@ -1052,7 +1052,7 @@ public:
static bool HandleReloadLocalesAchievementRewardCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Achievement Reward Data Locale...");
LOG_INFO("server.loading", "Reloading Achievement Reward Data Locale...");
sAchievementMgr->LoadRewardLocales();
handler->SendGlobalGMSysMessage("DB table `achievement_reward_locale` reloaded.");
return true;
@@ -1060,7 +1060,7 @@ public:
static bool HandleReloadLfgRewardsCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading lfg dungeon rewards...");
LOG_INFO("server.loading", "Reloading lfg dungeon rewards...");
sLFGMgr->LoadRewards();
handler->SendGlobalGMSysMessage("DB table `lfg_dungeon_rewards` reloaded.");
return true;
@@ -1068,7 +1068,7 @@ public:
static bool HandleReloadLocalesCreatureCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Creature Template Locale...");
LOG_INFO("server.loading", "Reloading Creature Template Locale...");
sObjectMgr->LoadCreatureLocales();
handler->SendGlobalGMSysMessage("DB table `creature_template_locale` reloaded.");
return true;
@@ -1076,7 +1076,7 @@ public:
static bool HandleReloadLocalesCreatureTextCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Creature Texts Locale...");
LOG_INFO("server.loading", "Reloading Creature Texts Locale...");
sCreatureTextMgr->LoadCreatureTextLocales();
handler->SendGlobalGMSysMessage("DB table `creature_text_locale` reloaded.");
return true;
@@ -1084,7 +1084,7 @@ public:
static bool HandleReloadLocalesGameobjectCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Gameobject Template Locale ... ");
LOG_INFO("server.loading", "Reloading Gameobject Template Locale ... ");
sObjectMgr->LoadGameObjectLocales();
handler->SendGlobalGMSysMessage("DB table `gameobject_template_locale` reloaded.");
return true;
@@ -1092,7 +1092,7 @@ public:
static bool HandleReloadLocalesGossipMenuOptionCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Gossip Menu Option Locale ... ");
LOG_INFO("server.loading", "Reloading Gossip Menu Option Locale ... ");
sObjectMgr->LoadGossipMenuItemsLocales();
handler->SendGlobalGMSysMessage("DB table `gossip_menu_option_locale` reloaded.");
return true;
@@ -1100,7 +1100,7 @@ public:
static bool HandleReloadLocalesItemCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Item Template Locale ... ");
LOG_INFO("server.loading", "Reloading Item Template Locale ... ");
sObjectMgr->LoadItemLocales();
handler->SendGlobalGMSysMessage("DB table `item_template_locale` reloaded.");
return true;
@@ -1108,7 +1108,7 @@ public:
static bool HandleReloadLocalesItemSetNameCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Item set name Locale... ");
LOG_INFO("server.loading", "Reloading Item set name Locale... ");
sObjectMgr->LoadItemSetNameLocales();
handler->SendGlobalGMSysMessage("DB table `item_set_name_locale` reloaded.");
return true;
@@ -1116,7 +1116,7 @@ public:
static bool HandleReloadLocalesNpcTextCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading NPC Text Locale ... ");
LOG_INFO("server.loading", "Reloading NPC Text Locale ... ");
sObjectMgr->LoadNpcTextLocales();
handler->SendGlobalGMSysMessage("DB table `npc_text_locale` reloaded.");
return true;
@@ -1124,7 +1124,7 @@ public:
static bool HandleReloadLocalesPageTextCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Page Text Locale ... ");
LOG_INFO("server.loading", "Reloading Page Text Locale ... ");
sObjectMgr->LoadPageTextLocales();
handler->SendGlobalGMSysMessage("DB table `page_text_locale` reloaded.");
handler->SendGlobalGMSysMessage("You need to delete your client cache or change the cache number in config in order for your players see the changes.");
@@ -1133,7 +1133,7 @@ public:
static bool HandleReloadLocalesPointsOfInterestCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Points Of Interest Locale ... ");
LOG_INFO("server.loading", "Reloading Points Of Interest Locale ... ");
sObjectMgr->LoadPointOfInterestLocales();
handler->SendGlobalGMSysMessage("DB table `points_of_interest_locale` reloaded.");
return true;
@@ -1141,7 +1141,7 @@ public:
static bool HandleReloadLocalesQuestCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Locales Quest ... ");
LOG_INFO("server.loading", "Reloading Locales Quest ... ");
sObjectMgr->LoadQuestLocales();
handler->SendGlobalGMSysMessage("DB table `quest_template_locale` reloaded.");
return true;
@@ -1149,7 +1149,7 @@ public:
static bool HandleReloadLocalesQuestOfferRewardCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Quest Offer Reward Locale... ");
LOG_INFO("server.loading", "Reloading Quest Offer Reward Locale... ");
sObjectMgr->LoadQuestOfferRewardLocale();
handler->SendGlobalGMSysMessage("DB table `quest_offer_reward_locale` reloaded.");
return true;
@@ -1157,7 +1157,7 @@ public:
static bool HandleReloadLocalesQuestRequestItemsCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Quest Request Item Locale... ");
LOG_INFO("server.loading", "Reloading Quest Request Item Locale... ");
sObjectMgr->LoadQuestRequestItemsLocale();
handler->SendGlobalGMSysMessage("DB table `quest_request_item_locale` reloaded.");
return true;
@@ -1165,7 +1165,7 @@ public:
static bool HandleReloadMailLevelRewardCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Player level dependent mail rewards...");
LOG_INFO("server.loading", "Reloading Player level dependent mail rewards...");
sObjectMgr->LoadMailLevelRewards();
handler->SendGlobalGMSysMessage("DB table `mail_level_reward` reloaded.");
return true;
@@ -1173,7 +1173,7 @@ public:
static bool HandleReloadMailServerTemplateCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading `server_mail_template` table");
LOG_INFO("server.loading", "Reloading `server_mail_template` table");
sObjectMgr->LoadMailServerTemplates();
handler->SendGlobalGMSysMessage("DB table `server_mail_template` reloaded.");
return true;
@@ -1182,7 +1182,7 @@ public:
static bool HandleReloadAuctionsCommand(ChatHandler* handler)
{
///- Reload dynamic data tables from the database
LOG_INFO("server.loading", "Re-Loading Auctions...");
LOG_INFO("server.loading", "Reloading Auctions...");
sAuctionMgr->LoadAuctionItems();
sAuctionMgr->LoadAuctions();
handler->SendGlobalGMSysMessage("Auctions reloaded.");
@@ -1191,7 +1191,7 @@ public:
static bool HandleReloadConditions(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Conditions...");
LOG_INFO("server.loading", "Reloading Conditions...");
sConditionMgr->LoadConditions(true);
handler->SendGlobalGMSysMessage("Conditions reloaded.");
return true;
@@ -1199,7 +1199,7 @@ public:
static bool HandleReloadCreatureText(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Creature Texts...");
LOG_INFO("server.loading", "Reloading Creature Texts...");
sCreatureTextMgr->LoadCreatureTexts();
handler->SendGlobalGMSysMessage("Creature Texts reloaded.");
return true;
@@ -1207,7 +1207,7 @@ public:
static bool HandleReloadSmartScripts(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Smart Scripts...");
LOG_INFO("server.loading", "Reloading Smart Scripts...");
sSmartScriptMgr->LoadSmartAIFromDB();
handler->SendGlobalGMSysMessage("Smart Scripts reloaded.");
return true;

View File

@@ -244,23 +244,17 @@ public:
handler->PSendSysMessage("LoginDatabase queue size: %zu", LoginDatabase.QueueSize());
handler->PSendSysMessage("CharacterDatabase queue size: %zu", CharacterDatabase.QueueSize());
handler->PSendSysMessage("WorldDatabase queue size: %zu", WorldDatabase.QueueSize());
if (Acore::Module::GetEnableModulesList().empty())
handler->SendSysMessage("No modules enabled");
else
handler->SendSysMessage("> List enable modules:");
#ifdef MOD_PLAYERBOTS
handler->PSendSysMessage("PlayerbotsDatabase queue size: %zu", PlayerbotsDatabase.QueueSize());
#endif
if (Acore::Module::GetEnableModulesList().empty())
handler->SendSysMessage("No modules enabled");
handler->SendSysMessage("No modules are enabled");
else
handler->SendSysMessage("> List enable modules:");
handler->SendSysMessage("List of enabled modules:");
for (auto const& modName : Acore::Module::GetEnableModulesList())
{
handler->SendSysMessage(Acore::StringFormatFmt("- {}", modName));
handler->SendSysMessage(Acore::StringFormatFmt("|- {}", modName));
}
return true;
@@ -283,9 +277,9 @@ public:
handler->PSendSysMessage("Connection peak: %u.", connPeak);
handler->PSendSysMessage(LANG_UPTIME, secsToTimeString(GameTime::GetUptime().count()).c_str());
handler->PSendSysMessage("Update time diff: %ums. Last %d diffs summary:", sWorldUpdateTime.GetLastUpdateTime(), sWorldUpdateTime.GetDatasetSize());
handler->PSendSysMessage("- Mean: %ums", sWorldUpdateTime.GetAverageUpdateTime());
handler->PSendSysMessage("- Median: %ums", sWorldUpdateTime.GetPercentile(50));
handler->PSendSysMessage("- Percentiles (95, 99, max): %ums, %ums, %ums",
handler->PSendSysMessage("|- Mean: %ums", sWorldUpdateTime.GetAverageUpdateTime());
handler->PSendSysMessage("|- Median: %ums", sWorldUpdateTime.GetPercentile(50));
handler->PSendSysMessage("|- Percentiles (95, 99, max): %ums, %ums, %ums",
sWorldUpdateTime.GetPercentile(95),
sWorldUpdateTime.GetPercentile(99),
sWorldUpdateTime.GetPercentile(100));

View File

@@ -73,7 +73,11 @@ enum Spells
SPELL_SHADOW_PYRO = 29978,
SPELL_ATIESH_VISUAL = 31796
SPELL_ATIESH_VISUAL = 31796,
SPELL_CURSE_OF_TONGUE_RANK1 = 1714,
SPELL_CURSE_OF_TONGUE_RANK2 = 11719,
SPELL_MIND_NUMBING_POISON = 5760
};
enum Creatures
@@ -100,6 +104,8 @@ enum Misc
Position const roomCenter = {-11158.f, -1920.f};
std::vector<uint32> immuneSpells = { SPELL_CURSE_OF_TONGUE_RANK1, SPELL_CURSE_OF_TONGUE_RANK2, SPELL_MIND_NUMBING_POISON };
struct boss_shade_of_aran : public BossAI
{
boss_shade_of_aran(Creature* creature) : BossAI(creature, DATA_ARAN), _atieshReaction(false) { }
@@ -118,6 +124,9 @@ struct boss_shade_of_aran : public BossAI
_drinking = false;
_hasDrunk = false;
for (int i = 0; i < immuneSpells.size(); i++)
me->ApplySpellImmune(0, IMMUNITY_ID, immuneSpells[i], true);
if (GameObject* libraryDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR)))
{
libraryDoor->SetGoState(GO_STATE_ACTIVE);

View File

@@ -46,19 +46,6 @@ enum Spells
SPELL_DEAFENINGROAR = 42398
};
// Trash Waves
float NalorakkWay[8][3] =
{
{ 18.569f, 1414.512f, 11.42f}, // waypoint 1
{-17.264f, 1419.551f, 12.62f},
{-52.642f, 1419.357f, 27.31f}, // waypoint 2
{-69.908f, 1419.721f, 27.31f},
{-79.929f, 1395.958f, 27.31f},
{-80.072f, 1374.555f, 40.87f}, // waypoint 3
{-80.072f, 1314.398f, 40.87f},
{-80.072f, 1295.775f, 48.60f} // waypoint 4
};
enum Talks
{
SAY_WAVE1 = 0,
@@ -74,399 +61,300 @@ enum Talks
SAY_KILL_TWO,
SAY_DEATH,
SAY_NALORAKK_EVENT1, // Not implemented
SAY_NALORAKK_EVENT2 // Not implemented
SAY_NALORAKK_EVENT2, // Not implemented
SAY_RUN_AWAY,
EMOTE_BEAR
};
class boss_nalorakk : public CreatureScript
enum Phases
{
public:
boss_nalorakk()
: CreatureScript("boss_nalorakk")
PHASE_SEND_GUARDS_1 = 0,
PHASE_SEND_GUARDS_2 = 1,
PHASE_SEND_GUARDS_3 = 2,
PHASE_SEND_GUARDS_4 = 3,
PHASE_SEND_GUARDS_5 = 4,
PHASE_START_COMBAT = 5
};
enum NalorakkGroups
{
GROUP_CHECK_DEAD = 1,
GROUP_MOVE = 2,
GROUP_BERSERK = 3,
GROUP_HUMAN = 4,
GROUP_BEAR = 5
};
struct boss_nalorakk : public BossAI
{
boss_nalorakk(Creature* creature) : BossAI(creature, DATA_NALORAKKEVENT)
{
_ranIntro = false;
_active = true;
creature->SetReactState(REACT_PASSIVE);
me->SetImmuneToAll(true);
}
struct boss_nalorakkAI : public ScriptedAI
void Reset() override
{
boss_nalorakkAI(Creature* creature) : ScriptedAI(creature)
BossAI::Reset();
_waveList.clear();
_introScheduler.CancelAll();
if (_bearForm)
{
MoveEvent = true;
MovePhase = 0;
instance = creature->GetInstanceScript();
me->RemoveAurasDueToSpell(SPELL_BEARFORM);
_bearForm = false;
}
InstanceScript* instance;
uint32 BrutalSwipe_Timer;
uint32 Mangle_Timer;
uint32 Surge_Timer;
uint32 LaceratingSlash_Timer;
uint32 RendFlesh_Timer;
uint32 DeafeningRoar_Timer;
uint32 ShapeShift_Timer;
uint32 Berserk_Timer;
bool inBearForm;
bool MoveEvent;
bool inMove;
uint32 MovePhase;
uint32 waitTimer;
void Reset() override
if (_ranIntro)
{
if (MoveEvent)
{
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
inMove = false;
waitTimer = 0;
me->SetSpeed(MOVE_RUN, 2);
me->SetWalk(false);
ResetMobs();
}
else
{
(*me).GetMotionMaster()->MovePoint(0, NalorakkWay[7][0], NalorakkWay[7][1], NalorakkWay[7][2]);
}
_phase = PHASE_START_COMBAT;
me->SetReactState(REACT_AGGRESSIVE);
_active = false;
if (instance)
{
instance->SetData(DATA_NALORAKKEVENT, NOT_STARTED);
}
Surge_Timer = urand(15000, 20000);
BrutalSwipe_Timer = urand(7000, 12000);
Mangle_Timer = urand(10000, 15000);
ShapeShift_Timer = urand(45000, 50000);
Berserk_Timer = 600000;
inBearForm = false;
// me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122); /// @todo find the correct equipment id
}
}
void ResetMobs()
void MoveInLineOfSight(Unit* who) override
{
if (who->IsPlayer() && _phase < PHASE_START_COMBAT && _active)
{
std::list<Creature*> templist;
float x, y, z;
me->GetPosition(x, y, z);
_active = false;
switch (_phase)
{
CellCoord pair(Acore::ComputeCellCoord(x, y));
Cell cell(pair);
cell.SetNoCreate();
Acore::AllFriendlyCreaturesInGrid check(me);
Acore::CreatureListSearcher<Acore::AllFriendlyCreaturesInGrid> searcher(me, templist, check);
TypeContainerVisitor<Acore::CreatureListSearcher<Acore::AllFriendlyCreaturesInGrid>, GridTypeMapContainer> cSearcher(searcher);
cell.Visit(pair, cSearcher, *(me->GetMap()), *me, me->GetGridActivationRange());
}
if (templist.empty())
return;
for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end(); ++i)
if ((*i) && me->GetGUID() != (*i)->GetGUID() && me->IsWithinDistInMap((*i), 25))
(*i)->AI()->Reset();
}
void SendAttacker(Unit* target)
{
std::list<Creature*> templist;
float x, y, z;
me->GetPosition(x, y, z);
{
CellCoord pair(Acore::ComputeCellCoord(x, y));
Cell cell(pair);
cell.SetNoCreate();
Acore::AllFriendlyCreaturesInGrid check(me);
Acore::CreatureListSearcher<Acore::AllFriendlyCreaturesInGrid> searcher(me, templist, check);
TypeContainerVisitor<Acore::CreatureListSearcher<Acore::AllFriendlyCreaturesInGrid>, GridTypeMapContainer> cSearcher(searcher);
cell.Visit(pair, cSearcher, *(me->GetMap()), *me, me->GetGridActivationRange());
}
if (templist.empty())
return;
for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end(); ++i)
{
if ((*i) && me->IsWithinDistInMap((*i), 25))
{
(*i)->SetNoCallAssistance(true);
(*i)->AI()->AttackStart(target);
}
}
}
void AttackStart(Unit* who) override
{
if (!MoveEvent)
ScriptedAI::AttackStart(who);
}
void MoveInLineOfSight(Unit* who) override
{
if (!MoveEvent)
{
ScriptedAI::MoveInLineOfSight(who);
}
else
{
if (me->IsHostileTo(who))
{
if (!inMove)
case PHASE_SEND_GUARDS_1:
me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_AXE_THROWER);
me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_TRIBESMAN);
GroupedAttack(_waveList);
Talk(SAY_WAVE1);
_introScheduler.Schedule(5s, GROUP_CHECK_DEAD, [this](TaskContext context)
{
switch (MovePhase)
if (CheckFullyDeadGroup(_waveList))
{
case 0:
if (me->IsWithinDistInMap(who, 50))
if (_phase == PHASE_SEND_GUARDS_1)
{
_introScheduler.CancelGroup(GROUP_CHECK_DEAD);
_waveList.clear();
me->GetMotionMaster()->MovePath(me->GetEntry()*100+1, false);
Talk(SAY_RUN_AWAY);
_introScheduler.Schedule(5s, [this](TaskContext)
{
Talk(SAY_WAVE1);
(*me).GetMotionMaster()->MovePoint(1, NalorakkWay[1][0], NalorakkWay[1][1], NalorakkWay[1][2]);
MovePhase ++;
inMove = true;
SendAttacker(who);
}
break;
case 2:
if (me->IsWithinDistInMap(who, 40))
{
Talk(SAY_WAVE2);
(*me).GetMotionMaster()->MovePoint(3, NalorakkWay[3][0], NalorakkWay[3][1], NalorakkWay[3][2]);
MovePhase ++;
inMove = true;
SendAttacker(who);
}
break;
case 5:
if (me->IsWithinDistInMap(who, 40))
{
Talk(SAY_WAVE3);
(*me).GetMotionMaster()->MovePoint(6, NalorakkWay[6][0], NalorakkWay[6][1], NalorakkWay[6][2]);
MovePhase ++;
inMove = true;
SendAttacker(who);
}
break;
case 7:
if (me->IsWithinDistInMap(who, 50))
{
SendAttacker(who);
Talk(SAY_WAVE4);
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
MoveEvent = false;
}
break;
me->SetFacingTo(6.25f);
_active = true;
});
_phase = PHASE_SEND_GUARDS_2;
}
}
}
}
}
}
void JustEngagedWith(Unit* /*who*/) override
{
if (instance)
instance->SetData(DATA_NALORAKKEVENT, IN_PROGRESS);
Talk(SAY_AGGRO);
DoZoneInCombat();
}
void JustDied(Unit* /*killer*/) override
{
ResetMobs();
if (instance)
instance->SetData(DATA_NALORAKKEVENT, DONE);
Talk(SAY_DEATH);
}
void KilledUnit(Unit* /*victim*/) override
{
switch (urand(0, 1))
{
case 0:
Talk(SAY_KILL_ONE);
context.Repeat(5s);
});
break;
case 1:
Talk(SAY_KILL_TWO);
break;
}
}
void MovementInform(uint32 type, uint32 id) override
{
if (MoveEvent)
{
if (type != POINT_MOTION_TYPE)
return;
if (!inMove)
return;
if (MovePhase != id)
return;
switch (MovePhase)
{
case 2:
me->SetOrientation(3.1415f * 2);
inMove = false;
return;
case 1:
case 3:
case 4:
case 6:
MovePhase ++;
waitTimer = 1;
inMove = true;
return;
case 5:
me->SetOrientation(3.1415f * 0.5f);
inMove = false;
return;
case 7:
me->SetOrientation(3.1415f * 0.5f);
inMove = false;
return;
}
}
}
void UpdateAI(uint32 diff) override
{
if (waitTimer && inMove)
{
if (waitTimer <= diff)
{
(*me).GetMotionMaster()->MovementExpired();
(*me).GetMotionMaster()->MovePoint(MovePhase, NalorakkWay[MovePhase][0], NalorakkWay[MovePhase][1], NalorakkWay[MovePhase][2]);
waitTimer = 0;
}
else waitTimer -= diff;
}
if (!UpdateVictim())
return;
if (Berserk_Timer <= diff)
{
DoCast(me, SPELL_BERSERK, true);
Talk(SAY_BERSERK);
Berserk_Timer = 600000;
}
else Berserk_Timer -= diff;
if (ShapeShift_Timer <= diff)
{
if (inBearForm)
{
// me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122);
Talk(SAY_SHIFTEDTOTROLL);
me->RemoveAurasDueToSpell(SPELL_BEARFORM);
Surge_Timer = urand(15000, 20000);
BrutalSwipe_Timer = urand(7000, 12000);
Mangle_Timer = urand(10000, 15000);
ShapeShift_Timer = urand(45000, 50000);
inBearForm = false;
}
else
{
// me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0);
Talk(SAY_SHIFTEDTOBEAR);
DoCast(me, SPELL_BEARFORM, true);
LaceratingSlash_Timer = 2000; // dur 18s
RendFlesh_Timer = 3000; // dur 5s
DeafeningRoar_Timer = urand(5000, 10000); // dur 2s
ShapeShift_Timer = urand(20000, 25000); // dur 30s
inBearForm = true;
}
}
else ShapeShift_Timer -= diff;
if (!inBearForm)
{
if (BrutalSwipe_Timer <= diff)
{
DoCastVictim(SPELL_BRUTALSWIPE);
BrutalSwipe_Timer = urand(7000, 12000);
}
else BrutalSwipe_Timer -= diff;
if (Mangle_Timer <= diff)
{
if (me->GetVictim() && !me->GetVictim()->HasAura(SPELL_MANGLEEFFECT))
case PHASE_SEND_GUARDS_2:
me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_AXE_THROWER);
me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_TRIBESMAN);
me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_MEDICINE_MAN);
GroupedAttack(_waveList);
Talk(SAY_WAVE2);
_introScheduler.Schedule(5s, GROUP_CHECK_DEAD, [this](TaskContext context)
{
DoCastVictim(SPELL_MANGLE);
Mangle_Timer = 1000;
}
else Mangle_Timer = urand(10000, 15000);
}
else Mangle_Timer -= diff;
if (CheckFullyDeadGroup(_waveList))
{
if (_phase == PHASE_SEND_GUARDS_2)
{
_introScheduler.CancelGroup(GROUP_CHECK_DEAD);
_waveList.clear();
Talk(SAY_RUN_AWAY);
me->GetMotionMaster()->MovePath(me->GetEntry()*100+2, false);
_introScheduler.Schedule(6s, [this](TaskContext)
{
me->SetFacingTo(1.54f);
_active = true;
});
_phase = PHASE_SEND_GUARDS_3;
}
if (Surge_Timer <= diff)
{
Talk(SAY_SURGE);
Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 45, true);
if (target)
DoCast(target, SPELL_SURGE);
Surge_Timer = urand(15000, 20000);
}
else Surge_Timer -= diff;
}
context.Repeat(5s);
});
break;
case PHASE_SEND_GUARDS_3:
me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_WARBRINGER);
GroupedAttack(_waveList);
Talk(SAY_WAVE3);
_introScheduler.Schedule(5s, GROUP_CHECK_DEAD, [this](TaskContext context)
{
if (CheckFullyDeadGroup(_waveList))
{
if (_phase == PHASE_SEND_GUARDS_3)
{
_introScheduler.CancelGroup(GROUP_CHECK_DEAD);
_waveList.clear();
Talk(SAY_RUN_AWAY);
me->GetMotionMaster()->MovePath(me->GetEntry()*100+3, false);
_introScheduler.Schedule(6s, [this](TaskContext)
{
me->SetFacingTo(1.54f);
_active = true;
});
_phase = PHASE_SEND_GUARDS_4;
}
}
context.Repeat(5s);
});
break;
case PHASE_SEND_GUARDS_4:
me->GetCreaturesWithEntryInRange(_waveList, 25.0f, NPC_AMANISHI_WARBRINGER);
me->GetCreaturesWithEntryInRange(_waveList, 25.0f, NPC_AMANISHI_MEDICINE_MAN);
GroupedAttack(_waveList);
Talk(SAY_WAVE4);
_introScheduler.Schedule(5s, GROUP_CHECK_DEAD, [this](TaskContext context)
{
if (CheckFullyDeadGroup(_waveList))
{
if (_phase == PHASE_SEND_GUARDS_4)
{
_introScheduler.CancelGroup(GROUP_CHECK_DEAD);
me->SetHomePosition(me->GetPosition());
me->SetImmuneToAll(false);
me->SetReactState(REACT_AGGRESSIVE);
me->SetInCombatWithZone();
_waveList.clear();
_phase = PHASE_START_COMBAT;
_ranIntro = true;
}
}
context.Repeat(5s);
});
break;
}
}
BossAI::MoveInLineOfSight(who);
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
Talk(SAY_AGGRO);
scheduler.Schedule(15s, 20s, GROUP_HUMAN, [this](TaskContext context)
{
Talk(SAY_SURGE);
DoCastRandomTarget(SPELL_SURGE, 0, 45.0f, false, false, false);
context.Repeat();
}).Schedule(7s, 12s, GROUP_HUMAN, [this](TaskContext context)
{
DoCastVictim(SPELL_BRUTALSWIPE);
context.Repeat();
}).Schedule(10s, 15s, GROUP_HUMAN, [this](TaskContext context)
{
if (!me->GetVictim()->HasAura(SPELL_MANGLEEFFECT))
{
DoCastVictim(SPELL_MANGLE);
context.Repeat(1s);
}
else
{
if (LaceratingSlash_Timer <= diff)
{
DoCastVictim(SPELL_LACERATINGSLASH);
LaceratingSlash_Timer = urand(18000, 23000);
}
else LaceratingSlash_Timer -= diff;
if (RendFlesh_Timer <= diff)
{
DoCastVictim(SPELL_RENDFLESH);
RendFlesh_Timer = urand(5000, 10000);
}
else RendFlesh_Timer -= diff;
if (DeafeningRoar_Timer <= diff)
{
DoCastVictim(SPELL_DEAFENINGROAR);
DeafeningRoar_Timer = urand(15000, 20000);
}
else DeafeningRoar_Timer -= diff;
context.Repeat();
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetZulAmanAI<boss_nalorakkAI>(creature);
}).Schedule(10min, GROUP_BERSERK, [this](TaskContext)
{
Talk(SAY_BERSERK);
DoCastSelf(SPELL_BERSERK, true);
}).Schedule(45s, 50s, GROUP_HUMAN, [this](TaskContext)
{
ShapeShift(_bearForm);
});
}
void ShapeShift(bool currentlyInBearForm)
{
if (currentlyInBearForm)
{
Talk(SAY_SHIFTEDTOTROLL);
me->RemoveAurasDueToSpell(SPELL_BEARFORM);
scheduler.CancelGroup(GROUP_BEAR);
_bearForm = false;
scheduler.Schedule(15s, 20s, GROUP_HUMAN, [this](TaskContext context)
{
Talk(SAY_SURGE);
DoCastRandomTarget(SPELL_SURGE, 0, 45.0f, false, false, false);
context.Repeat();
}).Schedule(7s, 12s, GROUP_HUMAN, [this](TaskContext context)
{
DoCastVictim(SPELL_BRUTALSWIPE);
context.Repeat();
}).Schedule(10s, 15s, GROUP_HUMAN, [this](TaskContext context)
{
DoCastVictim(SPELL_MANGLE);
context.Repeat();
}).Schedule(10min, GROUP_BERSERK, [this](TaskContext)
{
Talk(SAY_BERSERK);
DoCastSelf(SPELL_BERSERK, true);
}).Schedule(45s, 50s, GROUP_HUMAN, [this](TaskContext)
{
ShapeShift(_bearForm);
});
}
else
{
Talk(SAY_SHIFTEDTOBEAR);
Talk(EMOTE_BEAR);
DoCastSelf(SPELL_BEARFORM, true);
scheduler.CancelGroup(GROUP_HUMAN);
_bearForm = true;
scheduler.Schedule(2s, GROUP_BEAR, [this](TaskContext context)
{
DoCastVictim(SPELL_LACERATINGSLASH);
context.Repeat(18s, 23s);
}).Schedule(3s, GROUP_BEAR, [this](TaskContext context)
{
DoCastVictim(SPELL_RENDFLESH);
context.Repeat(5s, 10s);
}).Schedule(5s, 10s, GROUP_BEAR, [this](TaskContext context)
{
DoCastSelf(SPELL_DEAFENINGROAR);
context.Repeat(15s, 20s);
}).Schedule(25s, 30s, GROUP_BEAR, [this](TaskContext context)
{
ShapeShift(_bearForm);
context.Repeat();
});
}
}
void GroupedAttack(std::list<Creature* > attackerList)
{
for (Creature* attacker : attackerList)
{
attacker->SetInCombatWithZone();
}
}
void UpdateAI(uint32 diff) override
{
_introScheduler.Update(diff);
BossAI::UpdateAI(diff);
}
bool CheckFullyDeadGroup(std::list<Creature* > groupToCheck)
{
for (Creature* member : groupToCheck)
{
if (member->IsAlive())
{
return false;
}
}
return true;
}
private:
uint8 _phase;
bool _ranIntro;
bool _active;
bool _bearForm;
TaskScheduler _introScheduler;
std::list<Creature *> _waveList;
};
void AddSC_boss_nalorakk()
{
new boss_nalorakk();
RegisterZulAmanCreatureAI(boss_nalorakk);
}

View File

@@ -57,8 +57,8 @@ Position const HarrisonJonesLoc = {120.687f, 1674.0f, 42.0217f, 1.59044f};
ObjectData const creatureData[] =
{
{ NPC_SPIRIT_LYNX, DATA_SPIRIT_LYNX },
{ 0, 0 }
{ NPC_SPIRIT_LYNX, DATA_SPIRIT_LYNX },
{ 0, 0 }
};
ObjectData const gameObjectData[] =

View File

@@ -46,7 +46,11 @@ enum CreatureIds
NPC_HEXLORD = 24239,
NPC_HALAZZI = 23577,
NPC_NALORAKK = 23576,
NPC_SPIRIT_LYNX = 24143
NPC_SPIRIT_LYNX = 24143,
NPC_AMANISHI_WARBRINGER = 23580,
NPC_AMANISHI_TRIBESMAN = 23582,
NPC_AMANISHI_MEDICINE_MAN = 23581,
NPC_AMANISHI_AXE_THROWER = 23542
};
enum GameobjectIds

View File

@@ -18,6 +18,7 @@
#include "CreatureScript.h"
#include "Player.h"
#include "ScriptedCreature.h"
#include "SpellAuraEffects.h"
#include "SpellAuras.h"
#include "SpellScript.h"
#include "SpellScriptLoader.h"
@@ -51,6 +52,7 @@ enum ArchiSpells
SPELL_DOOMFIRE_STRIKE = 31903, //summons two creatures
SPELL_DOOMFIRE_SPAWN = 32074,
SPELL_DOOMFIRE = 31945,
SPELL_DOOMFIRE_DOT = 31969,
SPELL_SOUL_CHARGE_YELLOW = 32045,
SPELL_SOUL_CHARGE_GREEN = 32051,
SPELL_SOUL_CHARGE_RED = 32052,
@@ -143,35 +145,37 @@ struct npc_doomfire_spirit : public ScriptedAI
{
npc_doomfire_spirit(Creature* creature) : ScriptedAI(creature){ }
float const turnConstant = 0.785402f;
float fAngle = urand(0, M_PI * 2);
void Reset() override
{
scheduler.CancelAll();
ScheduleTimedEvent(0s, [&] {
me->GetMotionMaster()->MovePoint(NEAR_POINT, DoomfireMovement(me->GetPosition()));
}, 1500ms);
float nextOrientation = Position::NormalizeOrientation(me->GetOrientation() + irand(-1, 1) * turnConstant);
Position pos = GetFirstRandomAngleCollisionPosition(8.f, nextOrientation); // both orientation and distance verified with sniffs
me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), nextOrientation);
}, 1600ms);
fAngle = urand(0, M_PI * 2);
}
Position DoomfireMovement(Position mePos)
Position GetFirstRandomAngleCollisionPosition(float dist, float angle)
{
float angle = mePos.GetOrientation();
float distance = 100.0f;
float newAngle = angle + ((rand() % 181) - 90) * M_PI / 180;
float x = mePos.GetPositionX() + distance * cos(newAngle);
float y = mePos.GetPositionY() + distance * sin(newAngle);
Position targetPos = Position(x, y, me->GetPositionZ());
return targetPos;
Position pos;
for (uint32 i = 0; i < 10; ++i)
{
pos = me->WorldObject::GetFirstCollisionPosition(dist, angle);
if (me->GetDistance(pos) > dist * 0.8f) // if at least 80% distance, good enough
break;
angle += (M_PI / 5); // else try slightly different angle
}
return pos;
}
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff);
if (!UpdateVictim())
return;
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
};
@@ -313,7 +317,7 @@ struct boss_archimonde : public BossAI
DoCastVictim(SPELL_RED_SKY_EFFECT);
DoCastVictim(SPELL_HAND_OF_DEATH);
}, 3s);
scheduler.Schedule(25s, 35s, GROUP_FEAR, [this](TaskContext context)
scheduler.Schedule(40s, GROUP_FEAR, [this](TaskContext context)
{
DoCastAOE(SPELL_FEAR);
context.Repeat(42s);
@@ -381,11 +385,6 @@ struct boss_archimonde : public BossAI
summoned->CastSpell(summoned, SPELL_DOOMFIRE_SPAWN);
summoned->CastSpell(summoned, SPELL_DOOMFIRE, true, 0, 0, me->GetGUID());
}
else if (summoned->GetEntry() == CREATURE_DOOMFIRE_SPIRIT)
{
Position randomPosition = summoned->GetRandomNearPosition(40.0f);
summoned->GetMotionMaster()->MovePoint(0, randomPosition);
}
else
{
summoned->SetFaction(me->GetFaction()); //remove?
@@ -487,10 +486,38 @@ class spell_air_burst : public SpellScript
}
};
class spell_doomfire : public AuraScript
{
PrepareAuraScript(spell_doomfire);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_DOOMFIRE_DOT });
}
void PeriodicTick(AuraEffect const* aurEff)
{
Unit* target = GetTarget();
if (!target)
return;
int32 bp = GetSpellInfo()->Effects[EFFECT_1].CalcValue();
float tickCoef = (static_cast<float>(aurEff->GetTickNumber() - 1) / aurEff->GetTotalTicks()); // Tick moved back to ensure proper damage on each tick
int32 damage = bp - (bp*tickCoef);
SpellCastResult result = target->CastCustomSpell(target, SPELL_DOOMFIRE_DOT, &damage, &damage, &damage, true, nullptr, nullptr, target->GetGUID());
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_doomfire::PeriodicTick, EFFECT_ALL, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
void AddSC_boss_archimonde()
{
RegisterSpellScript(spell_red_sky_effect);
RegisterSpellScript(spell_air_burst);
RegisterSpellScript(spell_doomfire);
RegisterHyjalAI(boss_archimonde);
RegisterHyjalAI(npc_ancient_wisp);
RegisterHyjalAI(npc_doomfire_spirit);

View File

@@ -7,36 +7,53 @@
namespace Razuvious {
enum RazuviousSays
enum Says
{
RAZUVIOUS_SAY_AGGRO = 0,
RAZUVIOUS_SAY_SLAY = 1,
RAZUVIOUS_SAY_TAUNTED = 2,
RAZUVIOUS_SAY_DEATH = 3
SAY_AGGRO = 0,
SAY_SLAY = 1,
SAY_TAUNTED = 2,
SAY_DEATH = 3,
SAY_PATHETIC = 4,
SAY_TARGET_DUMMY = 5,
SAY_DEATH_KNIGHT_UNDERSTUDY = 0,
};
enum RazuviousSpells
enum Spells
{
SPELL_UNBALANCING_STRIKE = 26613,
SPELL_DISRUPTING_SHOUT_10 = 55543,
SPELL_DISRUPTING_SHOUT_25 = 29107,
SPELL_JAGGED_KNIFE = 55550,
SPELL_HOPELESS = 29125,
RAZUVIOUS_SPELL_TAUNT = 29060
SPELL_TAUNT = 29060
};
enum RazuviousEvents
enum Events
{
EVENT_UNBALANCING_STRIKE = 1,
EVENT_DISRUPTING_SHOUT = 2,
EVENT_JAGGED_KNIFE = 3
};
enum RazuviousMisc
enum NPCs
{
NPC_DEATH_KNIGHT_UNDERSTUDY = 16803,
NPC_RAZUVIOUS = 16061
NPC_TARGET_DUMMY = 16211,
};
enum Actions
{
ACTION_FACE_ME = 0,
ACTION_TALK = 1,
ACTION_EMOTE = 2,
ACTION_SALUTE = 3,
ACTION_BACK_TO_TRAINING = 4,
};
enum Misc
{
GROUP_OOC_RP = 0,
POINT_DEATH_KNIGHT = 0,
};
class boss_razuvious : public CreatureScript
@@ -82,13 +99,106 @@ public:
summons.DespawnAll();
events.Reset();
SpawnHelpers();
ScheduleRP();
}
void ScheduleInteractWithDeathKnight()
{
if (_rpBuddyGUID)
if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
me->SetFacingToObject(understudy);
scheduler.Schedule(2s, GROUP_OOC_RP, [this](TaskContext /*context*/)
{
if (roll_chance_i(75))
{
bool longText = roll_chance_i(50);
Talk(longText ? SAY_TARGET_DUMMY : SAY_PATHETIC);
scheduler.Schedule(4s, GROUP_OOC_RP, [this](TaskContext /*context*/)
{
if (_rpBuddyGUID)
if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
understudy->AI()->DoAction(ACTION_TALK);
});
if (longText)
scheduler.DelayGroup(GROUP_OOC_RP, 5s);
}
else
{
me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
scheduler.Schedule(4s, GROUP_OOC_RP, [this](TaskContext /*context*/)
{
if (_rpBuddyGUID)
if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
{
if (roll_chance_i(25))
understudy->AI()->DoAction(ACTION_EMOTE);
else
understudy->AI()->DoAction(ACTION_TALK);
}
});
}
}).Schedule(4s, GROUP_OOC_RP, [this](TaskContext /*context*/)
{
if (_rpBuddyGUID)
if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
understudy->AI()->DoAction(ACTION_FACE_ME);
}).Schedule(10s, GROUP_OOC_RP, [this](TaskContext /*context*/)
{
if (_rpBuddyGUID)
if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
understudy->AI()->DoAction(ACTION_SALUTE);
}).Schedule(13s, GROUP_OOC_RP, [this](TaskContext /*context*/)
{
me->ResumeMovement();
}).Schedule(16s, GROUP_OOC_RP, [this](TaskContext /*context*/)
{
if (_rpBuddyGUID)
if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
understudy->AI()->DoAction(ACTION_BACK_TO_TRAINING);
ScheduleRP();
});
}
void MovementInform(uint32 type, uint32 id) override
{
if (type == POINT_MOTION_TYPE && id == POINT_DEATH_KNIGHT)
{
ScheduleInteractWithDeathKnight();
}
}
void ScheduleRP()
{
_rpBuddyGUID = Acore::Containers::SelectRandomContainerElement(summons);
scheduler.Schedule(60s, 80s, GROUP_OOC_RP, [this](TaskContext context)
{
if (_rpBuddyGUID)
{
if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
{
if (me->GetDistance2d(understudy) <= 6.0f)
{
me->PauseMovement();
scheduler.Schedule(500ms, GROUP_OOC_RP, [this](TaskContext /*context*/)
{
if (_rpBuddyGUID)
if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
me->GetMotionMaster()->MovePoint(POINT_DEATH_KNIGHT, understudy->GetNearPosition(3.2f, understudy->GetRelativeAngle(me)));
});
return;
}
}
}
context.Repeat(2s);
});
}
void KilledUnit(Unit* who) override
{
if (roll_chance_i(30))
{
Talk(RAZUVIOUS_SAY_SLAY);
Talk(SAY_SLAY);
}
if (who->GetTypeId() == TYPEID_PLAYER && pInstance)
{
@@ -108,22 +218,23 @@ public:
void JustDied(Unit* killer) override
{
BossAI::JustDied(killer);
Talk(RAZUVIOUS_SAY_DEATH);
Talk(SAY_DEATH);
me->CastSpell(me, SPELL_HOPELESS, true);
}
void SpellHit(Unit* caster, SpellInfo const* spell) override
{
if (spell->Id == RAZUVIOUS_SPELL_TAUNT)
if (spell->Id == SPELL_TAUNT)
{
Talk(RAZUVIOUS_SAY_TAUNTED, caster);
Talk(SAY_TAUNTED, caster);
}
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
Talk(RAZUVIOUS_SAY_AGGRO);
scheduler.CancelGroup(GROUP_OOC_RP);
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_UNBALANCING_STRIKE, 20s);
events.ScheduleEvent(EVENT_DISRUPTING_SHOUT, 15s);
events.ScheduleEvent(EVENT_JAGGED_KNIFE, 10s);
@@ -132,6 +243,9 @@ public:
void UpdateAI(uint32 diff) override
{
if (!me->IsInCombat())
scheduler.Update(diff);
if (!UpdateVictim())
return;
@@ -159,6 +273,9 @@ public:
}
DoMeleeAttackIfReady();
}
private:
ObjectGuid _rpBuddyGUID;
};
};
@@ -167,20 +284,65 @@ class boss_razuvious_minion : public CreatureScript
public:
boss_razuvious_minion() : CreatureScript("boss_razuvious_minion") { }
CreatureAI* GetAI(Creature* pCreature) const override
CreatureAI* GetAI(Creature* creature) const override
{
return GetNaxxramasAI<boss_razuvious_minionAI>(pCreature);
return GetNaxxramasAI<boss_razuvious_minionAI>(creature);
}
struct boss_razuvious_minionAI : public ScriptedAI
{
explicit boss_razuvious_minionAI(Creature* c) : ScriptedAI(c) { }
EventMap events;
explicit boss_razuvious_minionAI(Creature* creature) : ScriptedAI(creature) { }
void Reset() override
{
events.Reset();
scheduler.CancelAll();
ScheduleAttackDummy();
}
void ScheduleAttackDummy()
{
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY1H);
if (Creature* targetDummy = me->FindNearestCreature(NPC_TARGET_DUMMY, 10.0f))
{
me->SetFacingToObject(targetDummy);
}
scheduler.Schedule(6s, 9s, GROUP_OOC_RP, [this](TaskContext context)
{
me->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK1H);
context.Repeat(6s, 9s);
});
}
void DoAction(int32 action) override
{
switch (action)
{
case ACTION_FACE_ME:
scheduler.CancelGroup(GROUP_OOC_RP);
me->SetSheath(SHEATH_STATE_UNARMED);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
if (InstanceScript* instance = me->GetInstanceScript())
{
if (Creature* creature = instance->GetCreature(DATA_RAZUVIOUS))
{
me->SetFacingToObject(creature);
}
}
break;
case ACTION_TALK:
Talk(SAY_DEATH_KNIGHT_UNDERSTUDY);
break;
case ACTION_EMOTE:
me->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
break;
case ACTION_SALUTE:
me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
break;
case ACTION_BACK_TO_TRAINING:
me->SetSheath(SHEATH_STATE_MELEE);
ScheduleAttackDummy();
break;
}
}
void KilledUnit(Unit* who) override
@@ -193,18 +355,23 @@ public:
void JustEngagedWith(Unit* who) override
{
if (Creature* cr = me->FindNearestCreature(NPC_RAZUVIOUS, 100.0f))
scheduler.CancelGroup(GROUP_OOC_RP);
if (InstanceScript* instance = me->GetInstanceScript())
{
cr->SetInCombatWithZone();
cr->AI()->AttackStart(who);
if (Creature* creature = instance->GetCreature(DATA_RAZUVIOUS))
{
creature->SetInCombatWithZone();
creature->AI()->AttackStart(who);
}
}
}
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff);
if (UpdateVictim())
{
events.Update(diff);
if (!me->HasUnitState(UNIT_STATE_CASTING) || !me->IsCharmed())
{
DoMeleeAttackIfReady();

View File

@@ -52,6 +52,17 @@ inline uint8 GetEruptionSection(float x, float y)
return 3;
}
ObjectData const creatureData[] =
{
{ NPC_RAZUVIOUS, DATA_RAZUVIOUS },
{ 0, 0 }
};
ObjectData const gameObjectData[] =
{
{ 0, 0 }
};
class instance_naxxramas : public InstanceMapScript
{
public:
@@ -68,6 +79,7 @@ public:
{
SetHeaders(DataHeader);
SetBossNumber(MAX_ENCOUNTERS);
LoadObjectData(creatureData, gameObjectData);
for (auto& i : HeiganEruption)
i.clear();
@@ -253,6 +265,8 @@ public:
_lichkingGUID = creature->GetGUID();
return;
}
InstanceScript::OnCreatureCreate(creature);
}
void OnGameObjectCreate(GameObject* pGo) override
@@ -498,6 +512,8 @@ public:
}
break;
}
InstanceScript::OnGameObjectCreate(pGo);
}
void OnGameObjectRemove(GameObject* pGo) override

View File

@@ -58,26 +58,27 @@ enum NXData
DATA_STALAGG_BOSS = 108,
DATA_FEUGEN_BOSS = 109,
DATA_THADDIUS_GATE = 110,
DATA_GOTHIK_BOSS = 111,
DATA_GOTHIK_ENTER_GATE = 112,
DATA_GOTHIK_INNER_GATE = 113,
DATA_GOTHIK_EXIT_GATE = 114,
DATA_HORSEMEN_GATE = 115,
DATA_LICH_KING_BOSS = 116,
DATA_KELTHUZAD_FLOOR = 117,
DATA_ABOMINATION_KILLED = 118,
DATA_FRENZY_REMOVED = 119,
DATA_CHARGES_CROSSED = 120,
DATA_SPORE_KILLED = 121,
DATA_HUNDRED_CLUB = 122,
DATA_DANCE_FAIL = 123,
DATA_IMMORTAL_FAIL = 124,
DATA_KELTHUZAD_GATE = 125,
DATA_HAD_THADDIUS_GREET = 126,
DATA_KELTHUZAD_PORTAL_1 = 127,
DATA_KELTHUZAD_PORTAL_2 = 128,
DATA_KELTHUZAD_PORTAL_3 = 129,
DATA_KELTHUZAD_PORTAL_4 = 130
DATA_RAZUVIOUS = 111,
DATA_GOTHIK_BOSS = 112,
DATA_GOTHIK_ENTER_GATE = 113,
DATA_GOTHIK_INNER_GATE = 114,
DATA_GOTHIK_EXIT_GATE = 115,
DATA_HORSEMEN_GATE = 116,
DATA_LICH_KING_BOSS = 117,
DATA_KELTHUZAD_FLOOR = 118,
DATA_ABOMINATION_KILLED = 119,
DATA_FRENZY_REMOVED = 120,
DATA_CHARGES_CROSSED = 121,
DATA_SPORE_KILLED = 122,
DATA_HUNDRED_CLUB = 123,
DATA_DANCE_FAIL = 124,
DATA_IMMORTAL_FAIL = 125,
DATA_KELTHUZAD_GATE = 126,
DATA_HAD_THADDIUS_GREET = 127,
DATA_KELTHUZAD_PORTAL_1 = 128,
DATA_KELTHUZAD_PORTAL_2 = 129,
DATA_KELTHUZAD_PORTAL_3 = 130,
DATA_KELTHUZAD_PORTAL_4 = 131
};
enum NXGOs
@@ -137,6 +138,9 @@ enum NXNPCs
NPC_STALAGG = 15929,
NPC_FEUGEN = 15930,
// Razuvious
NPC_RAZUVIOUS = 16061,
// Four horseman
NPC_BARON_RIVENDARE = 30549,
NPC_SIR_ZELIEK = 16063,

View File

@@ -20,6 +20,7 @@
#include "Player.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "TaskScheduler.h"
#include "World.h"
// Ours
@@ -506,108 +507,113 @@ enum MinigobData
SPELL_IMPROVED_BLINK = 61995,
EVENT_SELECT_TARGET = 1,
EVENT_BLINK = 2,
EVENT_DESPAWN_VISUAL = 3,
EVENT_DESPAWN = 4,
EVENT_POLYMORPH = 2,
EVENT_LAUGH = 3,
EVENT_MOVE = 4,
EVENT_DESPAWN_VISUAL = 5,
EVENT_DESPAWN = 6,
MAIL_MINIGOB_ENTRY = 264,
MAIL_DELIVER_DELAY_MIN = 5 * MINUTE,
MAIL_DELIVER_DELAY_MAX = 15 * MINUTE
};
class npc_minigob_manabonk : public CreatureScript
struct npc_minigob_manabonk : public ScriptedAI
{
public:
npc_minigob_manabonk() : CreatureScript("npc_minigob_manabonk") {}
struct npc_minigob_manabonkAI : public ScriptedAI
npc_minigob_manabonk(Creature* creature) : ScriptedAI(creature)
{
npc_minigob_manabonkAI(Creature* creature) : ScriptedAI(creature)
{
me->setActive(true);
}
me->setActive(true);
}
void Reset() override
{
me->SetVisible(false);
events.ScheduleEvent(EVENT_SELECT_TARGET, IN_MILLISECONDS);
}
void Reset() override
{
me->SetVisible(false);
events.ScheduleEvent(EVENT_SELECT_TARGET, 1s);
}
Player* SelectTargetInDalaran()
{
std::list<Player*> PlayerInDalaranList;
PlayerInDalaranList.clear();
Player* SelectTargetInDalaran()
{
std::list<Player*> playerInDalaranList;
playerInDalaranList.clear();
Map::PlayerList const& players = me->GetMap()->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
if (Player* player = itr->GetSource()->ToPlayer())
if (player->GetZoneId() == ZONE_DALARAN && !player->IsFlying() && !player->IsMounted() && !player->IsGameMaster())
PlayerInDalaranList.push_back(player);
if (PlayerInDalaranList.empty())
return nullptr;
return Acore::Containers::SelectRandomContainerElement(PlayerInDalaranList);
}
void SendMailToPlayer(Player* player)
{
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
int16 deliverDelay = irand(MAIL_DELIVER_DELAY_MIN, MAIL_DELIVER_DELAY_MAX);
MailDraft(MAIL_MINIGOB_ENTRY, true).SendMailTo(trans, MailReceiver(player), MailSender(MAIL_CREATURE, me->GetEntry()), MAIL_CHECK_MASK_NONE, deliverDelay);
CharacterDatabase.CommitTransaction(trans);
}
void UpdateAI(uint32 diff) override
{
if (!sWorld->getBoolConfig(CONFIG_MINIGOB_MANABONK))
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
me->GetMap()->DoForAllPlayers([&](Player* player)
{
switch (eventId)
{
case EVENT_SELECT_TARGET:
me->SetVisible(true);
DoCast(me, SPELL_TELEPORT_VISUAL);
if (Player* player = SelectTargetInDalaran())
{
me->NearTeleportTo(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), 0.0f);
DoCast(player, SPELL_MANABONKED);
SendMailToPlayer(player);
}
events.ScheduleEvent(EVENT_BLINK, 3ms);
break;
case EVENT_BLINK:
{
DoCast(me, SPELL_IMPROVED_BLINK);
Position pos = me->GetRandomNearPosition((urand(15, 40)));
me->GetMotionMaster()->MovePoint(0, pos.m_positionX, pos.m_positionY, pos.m_positionZ);
events.ScheduleEvent(EVENT_DESPAWN, 3ms);
events.ScheduleEvent(EVENT_DESPAWN_VISUAL, 3ms);
break;
}
case EVENT_DESPAWN_VISUAL:
DoCast(me, SPELL_TELEPORT_VISUAL);
break;
case EVENT_DESPAWN:
if (player->GetZoneId() == ZONE_DALARAN && !player->IsFlying() && !player->IsMounted() && !player->IsGameMaster())
playerInDalaranList.push_back(player);
});
if (playerInDalaranList.empty())
return nullptr;
return Acore::Containers::SelectRandomContainerElement(playerInDalaranList);
}
void SendMailToPlayer(Player* player)
{
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
int16 deliverDelay = irand(MAIL_DELIVER_DELAY_MIN, MAIL_DELIVER_DELAY_MAX);
MailDraft(MAIL_MINIGOB_ENTRY, true).SendMailTo(trans, MailReceiver(player), MailSender(MAIL_CREATURE, me->GetEntry()), MAIL_CHECK_MASK_NONE, deliverDelay);
CharacterDatabase.CommitTransaction(trans);
}
void UpdateAI(uint32 diff) override
{
if (!sWorld->getBoolConfig(CONFIG_MINIGOB_MANABONK))
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_SELECT_TARGET:
me->SetVisible(true);
DoCastSelf(SPELL_TELEPORT_VISUAL);
if (Player* player = SelectTargetInDalaran())
{
playerGUID = player->GetGUID();
Position pos = player->GetPosition();
me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
me->GetMotionMaster()->MoveRandom(10);
}
events.ScheduleEvent(EVENT_POLYMORPH, 30s);
break;
case EVENT_POLYMORPH:
if (Player* player = ObjectAccessor::GetPlayer(*me, playerGUID))
{
DoCast(player, SPELL_MANABONKED);
SendMailToPlayer(player);
}
else
me->DespawnOrUnsummon();
break;
default:
break;
}
events.ScheduleEvent(EVENT_LAUGH, 2s);
break;
case EVENT_LAUGH:
me->GetMotionMaster()->MoveIdle();
me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH_NO_SHEATHE);
events.ScheduleEvent(EVENT_MOVE, 4s);
break;
case EVENT_MOVE:
{
Position pos = me->GetRandomNearPosition((urand(15, 40)));
me->GetMotionMaster()->MovePoint(0, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), true);
}
events.ScheduleEvent(EVENT_DESPAWN_VISUAL, 3s);
events.ScheduleEvent(EVENT_DESPAWN, 4s);
break;
case EVENT_DESPAWN_VISUAL:
DoCastSelf(SPELL_IMPROVED_BLINK);
break;
case EVENT_DESPAWN:
me->DespawnOrUnsummon();
break;
default:
break;
}
}
private:
EventMap events;
};
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_minigob_manabonkAI(creature);
}
private:
ObjectGuid playerGUID;
};
class npc_dalaran_mage : public CreatureScript
@@ -861,8 +867,6 @@ void AddSC_dalaran()
new npc_dalaran_mage();
new npc_dalaran_warrior();
RegisterCreatureAI(npc_cosmetic_toy_plane);
// theirs
new npc_mageguard_dalaran();
new npc_minigob_manabonk();
RegisterCreatureAI(npc_minigob_manabonk);
}

View File

@@ -46,6 +46,7 @@ enum Spells
SPELL_POSSESS_SPIRIT_IMMUNE = 40282,
SPELL_SPIRITUAL_VENGEANCE = 40268,
SPELL_BRIEF_STUN = 41421,
SPELL_BERSERK = 45078,
SPELL_SPIRIT_LANCE = 40157,
SPELL_SPIRIT_CHAINS = 40175,
@@ -54,13 +55,7 @@ enum Spells
enum Misc
{
SET_DATA_INTRO = 1,
EVENT_SPELL_INCINERATE = 1,
EVENT_SPELL_DOOM_BLOSSOM = 2,
EVENT_SPELL_CRUSHING_SHADOWS = 3,
EVENT_SPELL_SHADOW_OF_DEATH = 4,
EVENT_TALK_KILL = 10
SET_DATA_INTRO = 1
};
struct ShadowOfDeathSelector
@@ -73,9 +68,11 @@ struct ShadowOfDeathSelector
struct boss_teron_gorefiend : public BossAI
{
boss_teron_gorefiend(Creature* creature) : BossAI(creature, DATA_TERON_GOREFIEND), intro(false) { }
bool intro;
boss_teron_gorefiend(Creature* creature) : BossAI(creature, DATA_TERON_GOREFIEND)
{
_recentlySpoken = false;
_intro = false;
}
void Reset() override
{
@@ -83,36 +80,72 @@ struct boss_teron_gorefiend : public BossAI
me->CastSpell(me, SPELL_SHADOW_OF_DEATH_REMOVE, true);
}
void JustEngagedWith(Unit* who) override
{
ScheduleTimedEvent(20s, 30s, [&]
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
{
if (roll_chance_i(50))
Talk(SAY_INCINERATE);
me->CastSpell(target, SPELL_INCINERATE, false);
}
}, 20s, 50s);
ScheduleTimedEvent(5s, 10s, [&]
{
if (roll_chance_i(50))
Talk(SAY_BLOSSOM);
me->CastSpell(me, SPELL_SUMMON_DOOM_BLOSSOM, false);
}, 35s);
ScheduleTimedEvent(17s, 22s, [&]
{
if (roll_chance_i(20))
Talk(SAY_CRUSHING);
me->CastCustomSpell(SPELL_CRUSHING_SHADOWS, SPELLVALUE_MAX_TARGETS, 5, me, false);
}, 10s, 26s);
ScheduleTimedEvent(10s, [&]
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, ShadowOfDeathSelector()))
me->CastSpell(target, SPELL_SHADOW_OF_DEATH, false);
}, 30s, 50s);
ScheduleTimedEvent(10min, [&]
{
DoCastSelf(SPELL_BERSERK);
}, 5min);
BossAI::JustEngagedWith(who);
}
void KilledUnit(Unit* victim) override
{
if (!_recentlySpoken && victim->IsPlayer())
{
Talk(SAY_SLAY);
_recentlySpoken = true;
ScheduleUniqueTimedEvent(6s, [&]
{
_recentlySpoken = false;
}, 1);
}
}
void SetData(uint32 type, uint32 id) override
{
if (type || !me->IsAlive())
return;
if (id == SET_DATA_INTRO && !intro)
if (id == SET_DATA_INTRO && !_intro)
{
intro = true;
_intro = true;
Talk(SAY_INTRO);
}
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
events.ScheduleEvent(EVENT_SPELL_INCINERATE, 24000);
events.ScheduleEvent(EVENT_SPELL_DOOM_BLOSSOM, 10000);
events.ScheduleEvent(EVENT_SPELL_CRUSHING_SHADOWS, 17000);
events.ScheduleEvent(EVENT_SPELL_SHADOW_OF_DEATH, 20000);
}
void KilledUnit(Unit* /*victim*/) override
{
if (events.GetNextEventTime(EVENT_TALK_KILL) == 0)
{
Talk(SAY_SLAY);
events.ScheduleEvent(EVENT_TALK_KILL, 6000);
}
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
@@ -130,43 +163,13 @@ struct boss_teron_gorefiend : public BossAI
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_SPELL_INCINERATE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
{
if (roll_chance_i(50))
Talk(SAY_INCINERATE);
me->CastSpell(target, SPELL_INCINERATE, false);
}
events.ScheduleEvent(EVENT_SPELL_INCINERATE, 25000);
break;
case EVENT_SPELL_DOOM_BLOSSOM:
if (roll_chance_i(50))
Talk(SAY_BLOSSOM);
me->CastSpell(me, SPELL_SUMMON_DOOM_BLOSSOM, false);
events.ScheduleEvent(EVENT_SPELL_DOOM_BLOSSOM, 40000);
break;
case EVENT_SPELL_CRUSHING_SHADOWS:
if (roll_chance_i(20))
Talk(SAY_CRUSHING);
me->CastCustomSpell(SPELL_CRUSHING_SHADOWS, SPELLVALUE_MAX_TARGETS, 5, me, false);
events.ScheduleEvent(EVENT_SPELL_CRUSHING_SHADOWS, 15000);
break;
case EVENT_SPELL_SHADOW_OF_DEATH:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, ShadowOfDeathSelector()))
me->CastSpell(target, SPELL_SHADOW_OF_DEATH, false);
events.ScheduleEvent(EVENT_SPELL_SHADOW_OF_DEATH, 30000);
break;
}
scheduler.Update(diff);
DoMeleeAttackIfReady();
}
private:
bool _recentlySpoken;
bool _intro;
};
class spell_teron_gorefiend_shadow_of_death : public AuraScript

View File

@@ -392,34 +392,14 @@ struct boss_kaelthas : public BossAI
}
}
});
scheduler.Schedule(2min, GROUP_PROGRESS_PHASE, [this](TaskContext)
scheduler.Schedule(90s, GROUP_PROGRESS_PHASE, [this](TaskContext)
{
PhaseAllAdvisorsExecute();
});
}, EVENT_PREFIGHT_PHASE52);
break;
case ACTION_PROGRESS_PHASE_CHECK:
if (_phase == PHASE_WEAPONS)
{
bool aliveWeapon = false;
summons.DoForAllSummons([&aliveWeapon](WorldObject* summon)
{
if (Creature* summonedCreature = summon->ToCreature())
{
if (summonedCreature->IsAlive())
{
if (summonedCreature->GetEntry() >= NPC_NETHERSTRAND_LONGBOW && summonedCreature->GetEntry() <= NPC_STAFF_OF_DISINTEGRATION)
{
aliveWeapon = true;
return;
}
}
}
});
if (!aliveWeapon)
PhaseAllAdvisorsExecute();
}
else if (_phase == PHASE_ALL_ADVISORS)
if (_phase == PHASE_ALL_ADVISORS)
{
bool advisorAlive = false;
summons.DoForAllSummons([&advisorAlive](WorldObject* summon)
@@ -1163,9 +1143,19 @@ class spell_kaelthas_mind_control : public SpellScript
targets.remove_if(Acore::ObjectTypeIdCheck(TYPEID_PLAYER, false));
}
void HandleEffect(SpellEffIndex /*effIndex*/)
{
if (!GetCaster() || !GetHitPlayer())
return;
if (Player* player = GetHitPlayer())
GetCaster()->GetThreatMgr().ResetThreat(player);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kaelthas_mind_control::SelectTarget, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_kaelthas_mind_control::HandleEffect, EFFECT_ALL, SPELL_AURA_ANY);
}
};

View File

@@ -16,6 +16,7 @@
*/
#include "CreatureScript.h"
#include "PassiveAI.h"
#include "Player.h"
#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
@@ -253,9 +254,166 @@ public:
};
};
enum ShattrathQuests
{
// QuestID : Creature Template ID
// Heroic Daily Quests
QUEST_H_NAZZAN = 11354, // 24410
QUEST_H_KELIDAN = 11362, // 24413
QUEST_H_BLADEFIST = 11363, // 24414
QUEST_H_QUAG = 11368, // 24419
QUEST_H_BLACKSTALKER = 11369, // 24420
QUEST_H_WARLORD = 11370, // 24421
QUEST_H_IKISS = 11372, // 24422
QUEST_H_SHAFFAR = 11373, // 24423
QUEST_H_EXARCH = 11374, // 24424
QUEST_H_MURMUR = 11375, // 24425
QUEST_H_EPOCH = 11378, // 24427
QUEST_H_AEONUS = 11382, // 24428
QUEST_H_WARP = 11384, // 24431
QUEST_H_CALCULATOR = 11386, // 21504
QUEST_H_SKYRISS = 11388, // 24435
QUEST_H_KAEL = 11499, // 24855
// Normal Daily Quests
QUEST_N_CENTURIONS = 11364, // 24411
QUEST_N_MYRMIDONS = 11371, // 24415
QUEST_N_INSTRUCTORS = 11376, // 24426
QUEST_N_LORDS = 11383, // 24429
QUEST_N_CHANNELERS = 11385, // 24430
QUEST_N_DESTROYERS = 11387, // 24432
QUEST_N_SENTINELS = 11389, // 24434
QUEST_N_SISTERS = 11500, // 24854
ACTION_UPDATE_QUEST_STATUS = 1,
POOL_SHATTRATH_DAILY_H = 356,
POOL_SHATTRATH_DAILY_N = 357,
// Image NPCs
NPC_SHATTRATH_DAILY_H = 24854,
NPC_SHATTRATH_DAILY_N = 24410
};
struct npc_shattrath_daily_quest : public NullCreatureAI
{
npc_shattrath_daily_quest(Creature* c) : NullCreatureAI(c) {}
void DoAction(int32 action) override
{
if (action == ACTION_UPDATE_QUEST_STATUS)
{
uint32 creature = me->GetEntry();
QueryResult result = CharacterDatabase.Query("SELECT `quest_id` FROM `pool_quest_save` WHERE `pool_id` = '{}'", creature == NPC_SHATTRATH_DAILY_H ? POOL_SHATTRATH_DAILY_H : POOL_SHATTRATH_DAILY_N);
if (result)
{
Field *fields = result->Fetch();
int quest_id = fields[0].Get<int>();
uint32 templateID;
if (creature == NPC_SHATTRATH_DAILY_H)
{
switch (quest_id)
{
case QUEST_H_NAZZAN:
templateID = 24410;
break;
case QUEST_H_KELIDAN:
templateID = 24413;
break;
case QUEST_H_BLADEFIST:
templateID = 24414;
break;
case QUEST_H_QUAG:
templateID = 24419;
break;
case QUEST_H_BLACKSTALKER:
templateID = 24420;
break;
case QUEST_H_WARLORD:
templateID = 24421;
break;
case QUEST_H_IKISS:
templateID = 24422;
break;
case QUEST_H_SHAFFAR:
templateID = 24423;
break;
case QUEST_H_EXARCH:
templateID = 24424;
break;
case QUEST_H_MURMUR:
templateID = 24425;
break;
case QUEST_H_EPOCH:
templateID = 24427;
break;
case QUEST_H_AEONUS:
templateID = 24428;
break;
case QUEST_H_WARP:
templateID = 24431;
break;
case QUEST_H_CALCULATOR:
templateID = 21504;
break;
case QUEST_H_SKYRISS:
templateID = 24435;
break;
case QUEST_H_KAEL:
templateID = 24855;
break;
default:
break;
}
}
if (creature == NPC_SHATTRATH_DAILY_N)
{
switch (quest_id)
{
case QUEST_N_CENTURIONS:
templateID = 24411;
break;
case QUEST_N_MYRMIDONS:
templateID = 24415;
break;
case QUEST_N_INSTRUCTORS:
templateID = 24426;
break;
case QUEST_N_LORDS:
templateID = 24429;
break;
case QUEST_N_CHANNELERS:
templateID = 24430;
break;
case QUEST_N_DESTROYERS:
templateID = 24432;
break;
case QUEST_N_SENTINELS:
templateID = 24434;
break;
case QUEST_N_SISTERS:
templateID = 24854;
break;
default:
break;
}
}
if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(templateID))
{
CreatureModel const* model = ObjectMgr::ChooseDisplayId(ci);
me->SetDisplayId(model->CreatureDisplayID, model->DisplayScale);
}
}
}
}
};
void AddSC_shattrath_city()
{
new npc_shattrathflaskvendors();
new npc_zephyr();
new npc_kservant();
RegisterCreatureAI(npc_shattrath_daily_quest);
}

View File

@@ -3990,6 +3990,37 @@ class spell_item_eye_of_grillok_aura : public AuraScript
}
};
enum FelManaPotion
{
SPELL_ALCHEMIST_STONE = 17619,
SPELL_ALCHEMIST_STONE_ENERGIZE = 21400
};
class spell_item_fel_mana_potion : public AuraScript
{
PrepareAuraScript(spell_item_fel_mana_potion)
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_ALCHEMIST_STONE, SPELL_ALCHEMIST_STONE_ENERGIZE });
}
void OnPeriodic(AuraEffect const* /*aurEff*/)
{
if (Unit* caster = GetCaster())
if (caster->HasAura(SPELL_ALCHEMIST_STONE))
{
uint32 val = GetSpellInfo()->Effects[EFFECT_0].BasePoints * 0.4f;
caster->CastCustomSpell(SPELL_ALCHEMIST_STONE_ENERGIZE, SPELLVALUE_BASE_POINT0, val, caster, true);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_item_fel_mana_potion::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_ENERGIZE);
}
};
void AddSC_item_spell_scripts()
{
RegisterSpellScript(spell_item_massive_seaforium_charge);
@@ -4112,5 +4143,6 @@ void AddSC_item_spell_scripts()
RegisterSpellScript(spell_item_venomhide_feed);
RegisterSpellScript(spell_item_scroll_of_retribution);
RegisterSpellAndAuraScriptPair(spell_item_eye_of_grillok, spell_item_eye_of_grillok_aura);
RegisterSpellScript(spell_item_fel_mana_potion);
}