Merge branch 'master' into questXPHook
This commit is contained in:
@@ -37,9 +37,9 @@ void AddGossipItemFor(Player* player, uint32 icon, std::string const& text, uint
|
||||
}
|
||||
|
||||
// Uses gossip item info from DB
|
||||
void AddGossipItemFor(Player* player, uint32 gossipMenuID, uint32 gossipMenuItemID, uint32 sender, uint32 action)
|
||||
void AddGossipItemFor(Player* player, uint32 gossipMenuID, uint32 gossipMenuItemID, uint32 sender, uint32 action, uint32 boxMoney /*= 0*/)
|
||||
{
|
||||
player->PlayerTalkClass->GetGossipMenu().AddMenuItem(gossipMenuID, gossipMenuItemID, sender, action);
|
||||
player->PlayerTalkClass->GetGossipMenu().AddMenuItem(gossipMenuID, gossipMenuItemID, sender, action, boxMoney);
|
||||
}
|
||||
|
||||
void SendGossipMenuFor(Player* player, uint32 npcTextID, ObjectGuid const guid)
|
||||
|
||||
@@ -91,7 +91,7 @@ void AddGossipItemFor(Player* player, uint32 icon, std::string const& text, uint
|
||||
void AddGossipItemFor(Player* player, uint32 icon, std::string const& text, uint32 sender, uint32 action, std::string const& popupText, uint32 popupMoney, bool coded);
|
||||
|
||||
// Uses gossip item info from DB
|
||||
void AddGossipItemFor(Player* player, uint32 gossipMenuID, uint32 gossipMenuItemID, uint32 sender, uint32 action);
|
||||
void AddGossipItemFor(Player* player, uint32 gossipMenuID, uint32 gossipMenuItemID, uint32 sender, uint32 action, uint32 boxMoney = 0);
|
||||
|
||||
// Send menu text
|
||||
void SendGossipMenuFor(Player* player, uint32 npcTextID, ObjectGuid const guid);
|
||||
|
||||
@@ -662,7 +662,10 @@ enum BG_AV_CreaturePlace
|
||||
AV_CPLACE_TRIGGER18 = 319,
|
||||
AV_CPLACE_TRIGGER19 = 320,
|
||||
|
||||
AV_CPLACE_MAX = 321
|
||||
AV_CPLACE_MAX = 321,
|
||||
|
||||
AV_CPLACE_A_BOSS = 381,
|
||||
AV_CPLACE_H_BOSS = 445
|
||||
};
|
||||
|
||||
//x, y, z, o
|
||||
|
||||
@@ -425,8 +425,14 @@ bool Creature::InitEntry(uint32 Entry, const CreatureData* data)
|
||||
SetNativeDisplayId(displayID);
|
||||
|
||||
// Load creature equipment
|
||||
if (!data || data->equipmentId == 0) // use default from the template
|
||||
LoadEquipment(0); // 0 means no equipment for creature table
|
||||
if (!data)
|
||||
{
|
||||
LoadEquipment(); // use default from the template
|
||||
}
|
||||
else if (data->equipmentId == 0)
|
||||
{
|
||||
LoadEquipment(0); // 0 means no equipment for creature table
|
||||
}
|
||||
else
|
||||
{
|
||||
m_originalEquipmentId = data->equipmentId;
|
||||
|
||||
@@ -74,8 +74,9 @@ void GossipMenu::AddMenuItem(int32 menuItemId, uint8 icon, std::string const& me
|
||||
* @param menuItemId Gossip menu item id.
|
||||
* @param sender Identifier of the current menu.
|
||||
* @param action Custom action given to OnGossipHello.
|
||||
* @param boxMoney Custom price for pop-up box. If > 0, it will replace DB value.
|
||||
*/
|
||||
void GossipMenu::AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, uint32 action)
|
||||
void GossipMenu::AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, uint32 action, uint32 boxMoney)
|
||||
{
|
||||
/// Find items for given menu id.
|
||||
GossipMenuItemsMapBounds bounds = sObjectMgr->GetGossipMenuItemsMapBounds(menuId);
|
||||
@@ -126,7 +127,7 @@ void GossipMenu::AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, ui
|
||||
}
|
||||
|
||||
/// Add menu item with existing method. Menu item id -1 is also used in ADD_GOSSIP_ITEM macro.
|
||||
AddMenuItem(-1, itr->second.OptionIcon, strOptionText, sender, action, strBoxText, itr->second.BoxMoney, itr->second.BoxCoded);
|
||||
AddMenuItem(-1, itr->second.OptionIcon, strOptionText, sender, action, strBoxText, boxMoney ? boxMoney : itr->second.BoxMoney, itr->second.BoxCoded);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ public:
|
||||
~GossipMenu();
|
||||
|
||||
void AddMenuItem(int32 menuItemId, uint8 icon, std::string const& message, uint32 sender, uint32 action, std::string const& boxMessage, uint32 boxMoney, bool coded = false);
|
||||
void AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, uint32 action);
|
||||
void AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, uint32 action, uint32 boxMoney);
|
||||
|
||||
void SetMenuId(uint32 menu_id) { _menuId = menu_id; }
|
||||
[[nodiscard]] uint32 GetMenuId() const { return _menuId; }
|
||||
|
||||
@@ -3009,11 +3009,18 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo
|
||||
thisLevel = std::max<int32>(thisLevel, spellInfo->SpellLevel);
|
||||
int32 levelDiff = int32(victim->getLevelForTarget(this)) - thisLevel;
|
||||
|
||||
int32 MISS_CHANCE_MULTIPLIER = sWorld->getRate(
|
||||
int32 MISS_CHANCE_MULTIPLIER;
|
||||
if (sWorld->getBoolConfig(CONFIG_MISS_CHANCE_MULTIPLIER_ONLY_FOR_PLAYERS) && GetTypeId() != TYPEID_PLAYER) // keep it as it was originally (7 and 11)
|
||||
{
|
||||
MISS_CHANCE_MULTIPLIER = victim->GetTypeId() == TYPEID_PLAYER ? 7 : 11;
|
||||
}
|
||||
else
|
||||
{
|
||||
MISS_CHANCE_MULTIPLIER = sWorld->getRate(
|
||||
victim->GetTypeId() == TYPEID_PLAYER
|
||||
? RATE_MISS_CHANCE_MULTIPLIER_TARGET_PLAYER
|
||||
: RATE_MISS_CHANCE_MULTIPLIER_TARGET_CREATURE
|
||||
);
|
||||
: RATE_MISS_CHANCE_MULTIPLIER_TARGET_CREATURE);
|
||||
}
|
||||
|
||||
// Base hit chance from attacker and victim levels
|
||||
int32 modHitChance = levelDiff < 3
|
||||
|
||||
@@ -1235,9 +1235,6 @@ void GameEventMgr::ApplyNewEvent(uint16 event_id)
|
||||
|
||||
LOG_DEBUG("gameevent", "GameEvent {} \"{}\" started.", event_id, mGameEvent[event_id].description);
|
||||
|
||||
//! Run SAI scripts with SMART_EVENT_GAME_EVENT_END
|
||||
RunSmartAIScripts(event_id, true);
|
||||
|
||||
// spawn positive event tagget objects
|
||||
GameEventSpawn(event_id);
|
||||
// un-spawn negative event tagged objects
|
||||
@@ -1255,6 +1252,9 @@ void GameEventMgr::ApplyNewEvent(uint16 event_id)
|
||||
// update bg holiday
|
||||
UpdateBattlegroundSettings();
|
||||
|
||||
//! Run SAI scripts with SMART_EVENT_GAME_EVENT_START
|
||||
RunSmartAIScripts(event_id, true);
|
||||
|
||||
// If event's worldstate is 0, it means the event hasn't been started yet. In that case, reset seasonal quests.
|
||||
// When event ends (if it expires or if it's stopped via commands) worldstate will be set to 0 again, ready for another seasonal quest reset.
|
||||
if (sWorld->getWorldState(event_id) == 0)
|
||||
|
||||
@@ -9246,6 +9246,7 @@ void ObjectMgr::LoadBroadcastTextLocales()
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 locales_count = 0;
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
@@ -9265,9 +9266,10 @@ void ObjectMgr::LoadBroadcastTextLocales()
|
||||
|
||||
AddLocaleString(fields[2].Get<std::string>(), locale, bct->second.MaleText);
|
||||
AddLocaleString(fields[3].Get<std::string>(), locale, bct->second.FemaleText);
|
||||
locales_count++;
|
||||
} while (result->NextRow());
|
||||
|
||||
LOG_INFO("server.loading", ">> Loaded {} Broadcast Text Locales in {} ms", uint32(_broadcastTextStore.size()), GetMSTimeDiffToNow(oldMSTime));
|
||||
LOG_INFO("server.loading", ">> Loaded {} Broadcast Text Locales in {} ms", locales_count, GetMSTimeDiffToNow(oldMSTime));
|
||||
LOG_INFO("server.loading", " ");
|
||||
}
|
||||
|
||||
|
||||
@@ -6377,6 +6377,14 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_MOD_SHAPESHIFT:
|
||||
{
|
||||
if (m_caster && m_caster->HasAura(23397)) // Nefarian Class Call (Warrior): Berserk -- Nefertum: I don't really like this but I didn't find another way.
|
||||
{
|
||||
return SPELL_FAILED_NOT_SHAPESHIFT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1590,6 +1590,19 @@ void Spell::EffectHeal(SpellEffIndex /*effIndex*/)
|
||||
addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
|
||||
}
|
||||
|
||||
// Implemented this way as there is no other way to do it currently (that I know :P)...
|
||||
if (caster->ToPlayer() && caster->ToPlayer()->HasAura(23401)) // Nefarian Corrupted Healing (priest)
|
||||
{
|
||||
if (m_spellInfo->Effects[EFFECT_0].ApplyAuraName != SPELL_AURA_PERIODIC_HEAL ||
|
||||
m_spellInfo->Effects[EFFECT_1].ApplyAuraName != SPELL_AURA_PERIODIC_HEAL ||
|
||||
m_spellInfo->Effects[EFFECT_2].ApplyAuraName != SPELL_AURA_PERIODIC_HEAL)
|
||||
{
|
||||
m_damage = 0;
|
||||
caster->CastSpell(unitTarget, 23402, false); // Nefarian Corrupted Healing Periodic Damage effect.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_damage -= addhealth;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4154,6 +4154,20 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->Effects[EFFECT_1].SpellClassMask[1] = 0x00020000;
|
||||
});
|
||||
|
||||
// Nefarian: Shadowbolt, Shadow Command
|
||||
ApplySpellFix({ 22667, 22677 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(152); // 150 yards
|
||||
});
|
||||
|
||||
// Shadowbolt Volley
|
||||
ApplySpellFix({ 22665 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(152); // 150 yards
|
||||
spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(41); // 150 yards
|
||||
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
|
||||
});
|
||||
|
||||
// Manastorm
|
||||
ApplySpellFix({ 21097 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
@@ -4180,6 +4194,12 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
|
||||
});
|
||||
|
||||
// Improved Blessing Protection (Nefarian Class Call)
|
||||
ApplySpellFix({ 23415 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_TARGET_ENEMY);
|
||||
});
|
||||
|
||||
// Bestial Wrath
|
||||
ApplySpellFix({ 19574 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
|
||||
@@ -173,6 +173,7 @@ enum WorldBoolConfigs
|
||||
CONFIG_REALM_LOGIN_ENABLED,
|
||||
CONFIG_PLAYER_SETTINGS_ENABLED,
|
||||
CONFIG_ALLOW_JOIN_BG_AND_LFG,
|
||||
CONFIG_MISS_CHANCE_MULTIPLIER_ONLY_FOR_PLAYERS,
|
||||
BOOL_CONFIG_VALUE_COUNT
|
||||
};
|
||||
|
||||
|
||||
@@ -572,8 +572,9 @@ void World::LoadConfigSettings(bool reload)
|
||||
rate_values[RATE_ARENA_POINTS] = sConfigMgr->GetOption<float>("Rate.ArenaPoints", 1.0f);
|
||||
rate_values[RATE_INSTANCE_RESET_TIME] = sConfigMgr->GetOption<float>("Rate.InstanceResetTime", 1.0f);
|
||||
|
||||
rate_values[RATE_MISS_CHANCE_MULTIPLIER_TARGET_CREATURE] = sConfigMgr->GetOption<float>("Rate.MissChanceMultiplier.TargetCreature", 11.0f);
|
||||
rate_values[RATE_MISS_CHANCE_MULTIPLIER_TARGET_PLAYER] = sConfigMgr->GetOption<float>("Rate.MissChanceMultiplier.TargetPlayer", 7.0f);
|
||||
rate_values[RATE_MISS_CHANCE_MULTIPLIER_TARGET_CREATURE] = sConfigMgr->GetOption<float>("Rate.MissChanceMultiplier.TargetCreature", 11.0f);
|
||||
rate_values[RATE_MISS_CHANCE_MULTIPLIER_TARGET_PLAYER] = sConfigMgr->GetOption<float>("Rate.MissChanceMultiplier.TargetPlayer", 7.0f);
|
||||
m_bool_configs[CONFIG_MISS_CHANCE_MULTIPLIER_ONLY_FOR_PLAYERS] = sConfigMgr->GetOption<bool>("Rate.MissChanceMultiplier.OnlyAffectsPlayer", false);
|
||||
|
||||
rate_values[RATE_TALENT] = sConfigMgr->GetOption<float>("Rate.Talent", 1.0f);
|
||||
if (rate_values[RATE_TALENT] < 0.0f)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BattlegroundAV.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
@@ -58,6 +59,11 @@ enum Events
|
||||
EVENT_CHECK_RESET = 6
|
||||
};
|
||||
|
||||
enum Factions
|
||||
{
|
||||
FACTION_AV_ALLIANCE = 1534
|
||||
};
|
||||
|
||||
struct SpellPair
|
||||
{
|
||||
uint32 npcEntry;
|
||||
@@ -104,6 +110,46 @@ public:
|
||||
Reset();
|
||||
}
|
||||
|
||||
void AttackStart(Unit* victim) override
|
||||
{
|
||||
ScriptedAI::AttackStart(victim);
|
||||
|
||||
// Boss should attack as well
|
||||
if (BattlegroundMap* bgMap = me->GetMap()->ToBattlegroundMap())
|
||||
{
|
||||
if (Battleground* bg = bgMap->GetBG())
|
||||
{
|
||||
if (Creature* mainBoss = bg->GetBGCreature((me->GetFaction() == FACTION_AV_ALLIANCE ? AV_CPLACE_A_BOSS : AV_CPLACE_H_BOSS)))
|
||||
{
|
||||
if (mainBoss->IsAIEnabled && !mainBoss->IsInCombat())
|
||||
{
|
||||
mainBoss->AI()->AttackStart(victim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode() override
|
||||
{
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
|
||||
// Evade boss
|
||||
if (BattlegroundMap* bgMap = me->GetMap()->ToBattlegroundMap())
|
||||
{
|
||||
if (Battleground* bg = bgMap->GetBG())
|
||||
{
|
||||
if (Creature* mainBoss = bg->GetBGCreature((me->GetFaction() == FACTION_AV_ALLIANCE ? AV_CPLACE_A_BOSS : AV_CPLACE_H_BOSS)))
|
||||
{
|
||||
if (mainBoss->IsAIEnabled && !mainBoss->IsInEvadeMode())
|
||||
{
|
||||
mainBoss->AI()->EnterEvadeMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
// I have a feeling this isn't blizzlike, but owell, I'm only passing by and cleaning up.
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BattlegroundAV.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
@@ -64,7 +65,7 @@ public:
|
||||
YellTimer = urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS); //20 to 30 seconds
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
void EnterCombat(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(YELL_AGGRO);
|
||||
}
|
||||
@@ -75,6 +76,52 @@ public:
|
||||
Talk(YELL_RESPAWN);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* victim) override
|
||||
{
|
||||
ScriptedAI::AttackStart(victim);
|
||||
|
||||
// Mini bosses should attack as well
|
||||
if (BattlegroundMap* bgMap = me->GetMap()->ToBattlegroundMap())
|
||||
{
|
||||
if (Battleground* bg = bgMap->GetBG())
|
||||
{
|
||||
for (uint8 i = AV_CPLACE_H_MARSHAL_ICE; i <= AV_CPLACE_H_MARSHAL_WTOWER; ++i)
|
||||
{
|
||||
if (Creature* marshall = bg->GetBGCreature(i))
|
||||
{
|
||||
if (marshall->IsAIEnabled && !marshall->IsInCombat())
|
||||
{
|
||||
marshall->AI()->AttackStart(victim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode() override
|
||||
{
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
|
||||
// Evade mini bosses
|
||||
if (BattlegroundMap* bgMap = me->GetMap()->ToBattlegroundMap())
|
||||
{
|
||||
if (Battleground* bg = bgMap->GetBG())
|
||||
{
|
||||
for (uint8 i = AV_CPLACE_H_MARSHAL_ICE; i <= AV_CPLACE_H_MARSHAL_WTOWER; ++i)
|
||||
{
|
||||
if (Creature* marshall = bg->GetBGCreature(i))
|
||||
{
|
||||
if (marshall->IsAIEnabled && !marshall->IsInEvadeMode())
|
||||
{
|
||||
marshall->AI()->EnterEvadeMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BattlegroundAV.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
@@ -59,11 +60,57 @@ public:
|
||||
YellTimer = urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
void EnterCombat(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(YELL_AGGRO);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* victim) override
|
||||
{
|
||||
ScriptedAI::AttackStart(victim);
|
||||
|
||||
// Mini bosses should attack as well
|
||||
if (BattlegroundMap* bgMap = me->GetMap()->ToBattlegroundMap())
|
||||
{
|
||||
if (Battleground* bg = bgMap->GetBG())
|
||||
{
|
||||
for (uint8 i = AV_CPLACE_A_MARSHAL_SOUTH; i <= AV_CPLACE_A_MARSHAL_STONE; ++i)
|
||||
{
|
||||
if (Creature* marshall = bg->GetBGCreature(i))
|
||||
{
|
||||
if (marshall->IsAIEnabled && !marshall->IsInCombat())
|
||||
{
|
||||
marshall->AI()->AttackStart(victim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode() override
|
||||
{
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
|
||||
// Evade mini bosses
|
||||
if (BattlegroundMap* bgMap = me->GetMap()->ToBattlegroundMap())
|
||||
{
|
||||
if (Battleground* bg = bgMap->GetBG())
|
||||
{
|
||||
for (uint8 i = AV_CPLACE_A_MARSHAL_SOUTH; i <= AV_CPLACE_A_MARSHAL_STONE; ++i)
|
||||
{
|
||||
if (Creature* marshall = bg->GetBGCreature(i))
|
||||
{
|
||||
if (marshall->IsAIEnabled && !marshall->IsInEvadeMode())
|
||||
{
|
||||
marshall->AI()->EnterEvadeMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
|
||||
@@ -99,4 +99,6 @@ inline AI* GetBlackwingLairAI(T* obj)
|
||||
return GetInstanceAI<AI>(obj, BWLScriptName);
|
||||
}
|
||||
|
||||
#define RegisterBlackwingLairCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetBlackwingLairAI)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,6 +42,21 @@ public:
|
||||
{
|
||||
boss_ebonrocAI(Creature* creature) : BossAI(creature, DATA_EBONROC) { }
|
||||
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
if (type != WAYPOINT_MOTION_TYPE || id != 12)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
me->GetMotionMaster()->MoveRandom(10.f);
|
||||
|
||||
me->m_Events.AddEventAtOffset([this]()
|
||||
{
|
||||
me->GetMotionMaster()->Initialize();
|
||||
}, 15s);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who) override
|
||||
{
|
||||
BossAI::EnterCombat(who);
|
||||
|
||||
+746
-222
File diff suppressed because it is too large
Load Diff
+25
-30
@@ -42,10 +42,10 @@ enum Gossip
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_ESSENCEOFTHERED = 23513,
|
||||
SPELL_FLAMEBREATH = 23461,
|
||||
SPELL_FIRENOVA = 23462,
|
||||
SPELL_TAILSWIPE = 15847,
|
||||
SPELL_ESSENCE_OF_THE_RED = 23513,
|
||||
SPELL_FLAME_BREATH = 23461,
|
||||
SPELL_FIRE_NOVA = 23462,
|
||||
SPELL_TAIL_SWEEP = 15847,
|
||||
SPELL_CLEAVE = 19983, //Chain cleave is most likely named something different and contains a dummy effect
|
||||
SPELL_NEFARIUS_CORRUPTION = 23642,
|
||||
SPELL_RED_LIGHTNING = 19484,
|
||||
@@ -64,12 +64,11 @@ enum Events
|
||||
EVENT_SPEECH_5 = 5,
|
||||
EVENT_SPEECH_6 = 6,
|
||||
EVENT_SPEECH_7 = 7,
|
||||
EVENT_ESSENCEOFTHERED = 8,
|
||||
EVENT_FLAMEBREATH = 9,
|
||||
EVENT_FIRENOVA = 10,
|
||||
EVENT_TAILSWIPE = 11,
|
||||
EVENT_CLEAVE = 12,
|
||||
EVENT_BURNINGADRENALINE = 13,
|
||||
EVENT_FLAME_BREATH = 8,
|
||||
EVENT_FIRE_NOVA = 9,
|
||||
EVENT_TAIL_SWEEP = 10,
|
||||
EVENT_CLEAVE = 11,
|
||||
EVENT_BURNING_ADRENALINE = 12,
|
||||
};
|
||||
|
||||
class boss_vaelastrasz : public CreatureScript
|
||||
@@ -119,15 +118,15 @@ public:
|
||||
{
|
||||
BossAI::EnterCombat(victim);
|
||||
|
||||
DoCast(me, SPELL_ESSENCEOFTHERED);
|
||||
DoCastAOE(SPELL_ESSENCE_OF_THE_RED);
|
||||
// now drop damage requirement to be able to take loot
|
||||
me->ResetPlayerDamageReq();
|
||||
|
||||
events.ScheduleEvent(EVENT_CLEAVE, 10000);
|
||||
events.ScheduleEvent(EVENT_FLAMEBREATH, 15000);
|
||||
events.ScheduleEvent(EVENT_FIRENOVA, 20000);
|
||||
events.ScheduleEvent(EVENT_TAILSWIPE, 11000);
|
||||
events.ScheduleEvent(EVENT_BURNINGADRENALINE, 15000);
|
||||
events.ScheduleEvent(EVENT_FLAME_BREATH, 15000);
|
||||
events.ScheduleEvent(EVENT_FIRE_NOVA, 20000);
|
||||
events.ScheduleEvent(EVENT_TAIL_SWEEP, 11000);
|
||||
events.ScheduleEvent(EVENT_BURNING_ADRENALINE, 15000);
|
||||
}
|
||||
|
||||
void BeginSpeech(Unit* target)
|
||||
@@ -215,23 +214,19 @@ public:
|
||||
events.ScheduleEvent(EVENT_CLEAVE, 15000);
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
break;
|
||||
case EVENT_FLAMEBREATH:
|
||||
DoCastVictim(SPELL_FLAMEBREATH);
|
||||
events.ScheduleEvent(EVENT_FLAMEBREATH, 8000, 14000);
|
||||
case EVENT_FLAME_BREATH:
|
||||
DoCastVictim(SPELL_FLAME_BREATH);
|
||||
events.ScheduleEvent(EVENT_FLAME_BREATH, 8000, 14000);
|
||||
break;
|
||||
case EVENT_FIRENOVA:
|
||||
DoCastVictim(SPELL_FIRENOVA);
|
||||
events.ScheduleEvent(EVENT_FIRENOVA, 15000);
|
||||
case EVENT_FIRE_NOVA:
|
||||
DoCastVictim(SPELL_FIRE_NOVA);
|
||||
events.ScheduleEvent(EVENT_FIRE_NOVA, 15000);
|
||||
break;
|
||||
case EVENT_TAILSWIPE:
|
||||
//Only cast if we are behind
|
||||
/*if (!me->HasInArc(M_PI, me->GetVictim()))
|
||||
{
|
||||
DoCast(me->GetVictim(), SPELL_TAILSWIPE);
|
||||
}*/
|
||||
events.ScheduleEvent(EVENT_TAILSWIPE, 15000);
|
||||
case EVENT_TAIL_SWEEP:
|
||||
DoCastAOE(SPELL_TAIL_SWEEP);
|
||||
events.ScheduleEvent(EVENT_TAIL_SWEEP, 15000);
|
||||
break;
|
||||
case EVENT_BURNINGADRENALINE:
|
||||
case EVENT_BURNING_ADRENALINE:
|
||||
{
|
||||
if (_burningAdrenalineCast < 2) // It's better to use TaskScheduler for this, but zzz
|
||||
{
|
||||
@@ -249,7 +244,7 @@ public:
|
||||
me->CastSpell(me->GetVictim(), SPELL_BURNING_ADRENALINE, true);
|
||||
_burningAdrenalineCast = 0;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_BURNINGADRENALINE, 15000);
|
||||
events.ScheduleEvent(EVENT_BURNING_ADRENALINE, 15000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,11 +257,6 @@ public:
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
|
||||
if (pInstance && pInstance->GetData(TYPE_HODIR) != DONE)
|
||||
{
|
||||
pInstance->SetData(TYPE_SPAWN_HODIR_CACHE, 0);
|
||||
}
|
||||
|
||||
// Reset helpers
|
||||
if (!summons.size())
|
||||
SpawnHelpers();
|
||||
@@ -296,10 +291,13 @@ public:
|
||||
switch (action)
|
||||
{
|
||||
case EVENT_FAIL_HM:
|
||||
if (GameObject* go = me->FindNearestGameObject(GO_HODIR_CHEST_HARD, 500.0f))
|
||||
if (pInstance)
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
events.ScheduleEvent(EVENT_DESPAWN_CHEST, 3000);
|
||||
if (GameObject* go = pInstance->instance->GetGameObject(pInstance->GetGuidData(GO_HODIR_CHEST_HARD)))
|
||||
{
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
events.ScheduleEvent(EVENT_DESPAWN_CHEST, 3000);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -425,7 +423,13 @@ public:
|
||||
case EVENT_HARD_MODE_MISSED:
|
||||
{
|
||||
Talk(TEXT_HM_MISS);
|
||||
me->CastSpell(me->FindNearestGameObject(GO_HODIR_CHEST_HARD, 400.0f), SPELL_SHATTER_CHEST, false);
|
||||
if (pInstance)
|
||||
{
|
||||
if (GameObject* go = pInstance->instance->GetGameObject(pInstance->GetGuidData(GO_HODIR_CHEST_HARD)))
|
||||
{
|
||||
me->CastSpell(go, SPELL_SHATTER_CHEST, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_DESPAWN_CHEST:
|
||||
@@ -1161,15 +1165,17 @@ public:
|
||||
{
|
||||
PrepareSpellScript(spell_hodir_shatter_chestSpellScript)
|
||||
|
||||
void destroyWinterCache()
|
||||
void destroyWinterCache(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
|
||||
if (Unit* hodir = GetCaster())
|
||||
hodir->GetAI()->DoAction(EVENT_FAIL_HM);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterHit += SpellHitFn(spell_hodir_shatter_chestSpellScript::destroyWinterCache);
|
||||
OnEffectHit += SpellEffectFn(spell_hodir_shatter_chestSpellScript::destroyWinterCache, EFFECT_0, SPELL_EFFECT_TRIGGER_MISSILE);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ public:
|
||||
|
||||
// Flame Leviathan
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
m_leviathanTowers[i] = false;
|
||||
m_leviathanTowers[i] = true;
|
||||
|
||||
_leviathanVehicles.clear();
|
||||
m_unbrokenAchievement = 1;
|
||||
@@ -214,75 +214,74 @@ public:
|
||||
SetData(eventId, 0);
|
||||
}
|
||||
|
||||
void SpawnHodirChests(int rd)
|
||||
void SpawnHodirChests(Difficulty diff, Creature* hodir)
|
||||
{
|
||||
if (Creature* cr = instance->GetCreature(m_uiHodirGUID))
|
||||
switch (diff)
|
||||
{
|
||||
switch (rd)
|
||||
case RAID_DIFFICULTY_10MAN_NORMAL: // 10 man chest
|
||||
{
|
||||
case 0: // 10 man chest
|
||||
if (!m_hodirNormalChest)
|
||||
{
|
||||
if (!m_hodirNormalChest)
|
||||
if (GameObject* go = hodir->SummonGameObject(
|
||||
GO_HODIR_CHEST_NORMAL,
|
||||
normalChestPosition.GetPositionX(),
|
||||
normalChestPosition.GetPositionY(),
|
||||
normalChestPosition.GetPositionZ(),
|
||||
normalChestPosition.GetOrientation(), 0, 0, 0, 0, 0))
|
||||
{
|
||||
if (GameObject* go = cr->SummonGameObject(
|
||||
GO_HODIR_CHEST_NORMAL,
|
||||
normalChestPosition.GetPositionX(),
|
||||
normalChestPosition.GetPositionY(),
|
||||
normalChestPosition.GetPositionZ(),
|
||||
normalChestPosition.GetOrientation(), 0, 0, 0, 0, 0))
|
||||
{
|
||||
m_hodirNormalChest = go->GetGUID();
|
||||
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
m_hodirNormalChest = go->GetGUID();
|
||||
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
if (!m_hodirHardmodeChest)
|
||||
{
|
||||
if (GameObject* go = cr->SummonGameObject(
|
||||
GO_HODIR_CHEST_HARD,
|
||||
hardChestPosition.GetPositionX(),
|
||||
hardChestPosition.GetPositionY(),
|
||||
hardChestPosition.GetPositionZ(),
|
||||
hardChestPosition.GetOrientation(), 0, 0, 0, 0, 0))
|
||||
{
|
||||
m_hodirHardmodeChest = go->GetGUID();
|
||||
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
hmHodir = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: // 25 man chest
|
||||
if (!m_hodirHardmodeChest)
|
||||
{
|
||||
if (!m_hodirNormalChest)
|
||||
if (GameObject* go = hodir->SummonGameObject(
|
||||
GO_HODIR_CHEST_HARD,
|
||||
hardChestPosition.GetPositionX(),
|
||||
hardChestPosition.GetPositionY(),
|
||||
hardChestPosition.GetPositionZ(),
|
||||
hardChestPosition.GetOrientation(), 0, 0, 0, 0, 0))
|
||||
{
|
||||
if (GameObject* go = cr->SummonGameObject(
|
||||
GO_HODIR_CHEST_NORMAL_HERO,
|
||||
normalChestPosition.GetPositionX(),
|
||||
normalChestPosition.GetPositionY(),
|
||||
normalChestPosition.GetPositionZ(),
|
||||
normalChestPosition.GetOrientation(), 0, 0, 0, 0, 0))
|
||||
{
|
||||
m_hodirNormalChest = go->GetGUID();
|
||||
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
m_hodirHardmodeChest = go->GetGUID();
|
||||
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
hmHodir = true;
|
||||
}
|
||||
if (!m_hodirHardmodeChest)
|
||||
{
|
||||
if (GameObject* go = cr->SummonGameObject(
|
||||
GO_HODIR_CHEST_HARD_HERO,
|
||||
hardChestPosition.GetPositionX(),
|
||||
hardChestPosition.GetPositionY(),
|
||||
hardChestPosition.GetPositionZ(),
|
||||
hardChestPosition.GetOrientation(), 0, 0, 0, 0, 0))
|
||||
{
|
||||
m_hodirHardmodeChest = go->GetGUID();
|
||||
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
hmHodir = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RAID_DIFFICULTY_25MAN_NORMAL: // 25 man chest
|
||||
{
|
||||
if (!m_hodirNormalChest)
|
||||
{
|
||||
if (GameObject* go = hodir->SummonGameObject(
|
||||
GO_HODIR_CHEST_NORMAL_HERO,
|
||||
normalChestPosition.GetPositionX(),
|
||||
normalChestPosition.GetPositionY(),
|
||||
normalChestPosition.GetPositionZ(),
|
||||
normalChestPosition.GetOrientation(), 0, 0, 0, 0, 0))
|
||||
{
|
||||
m_hodirNormalChest = go->GetGUID();
|
||||
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
if (!m_hodirHardmodeChest)
|
||||
{
|
||||
if (GameObject* go = hodir->SummonGameObject(
|
||||
GO_HODIR_CHEST_HARD_HERO,
|
||||
hardChestPosition.GetPositionX(),
|
||||
hardChestPosition.GetPositionY(),
|
||||
hardChestPosition.GetPositionZ(),
|
||||
hardChestPosition.GetOrientation(), 0, 0, 0, 0, 0))
|
||||
{
|
||||
m_hodirHardmodeChest = go->GetGUID();
|
||||
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
hmHodir = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,6 +328,7 @@ public:
|
||||
break;
|
||||
case NPC_HODIR:
|
||||
m_uiHodirGUID = creature->GetGUID();
|
||||
SpawnHodirChests(instance->GetDifficulty(), creature);
|
||||
break;
|
||||
case NPC_THORIM:
|
||||
m_uiThorimGUID = creature->GetGUID();
|
||||
@@ -690,11 +690,6 @@ public:
|
||||
if (GetData(TYPE_HODIR) == DONE)
|
||||
setChestsLootable(TYPE_HODIR);
|
||||
break;
|
||||
|
||||
case TYPE_SPAWN_HODIR_CACHE:
|
||||
// Is the difficulty 10 man(0) ? return 10 man : return 25 man;
|
||||
SpawnHodirChests(m_difficulty == 0 ? 0 : 1);
|
||||
break;
|
||||
case TYPE_HODIR_HM_FAIL:
|
||||
if (GameObject* go = instance->GetGameObject(m_hodirHardmodeChest))
|
||||
{
|
||||
@@ -909,10 +904,8 @@ public:
|
||||
|
||||
// Hodir chests
|
||||
case GO_HODIR_CHEST_HARD:
|
||||
case GO_HODIR_CHEST_HARD_HERO:
|
||||
return m_hodirHardmodeChest;
|
||||
case GO_HODIR_CHEST_NORMAL:
|
||||
case GO_HODIR_CHEST_NORMAL_HERO:
|
||||
return m_hodirNormalChest;
|
||||
|
||||
// Freya Elders
|
||||
|
||||
@@ -45,9 +45,8 @@ enum UlduarEncounters
|
||||
TYPE_YOGGSARON = 12,
|
||||
TYPE_ALGALON = 13,
|
||||
TYPE_WATCHERS = 14,
|
||||
TYPE_SPAWN_HODIR_CACHE = 15,
|
||||
TYPE_HODIR_HM_FAIL = 16,
|
||||
TYPE_WINTER_CACHE = 17,
|
||||
TYPE_HODIR_HM_FAIL = 15,
|
||||
TYPE_WINTER_CACHE = 16
|
||||
};
|
||||
|
||||
enum UlduarData
|
||||
|
||||
@@ -2550,6 +2550,7 @@ Die.Command.Mode = 1
|
||||
|
||||
# Rate.MissChanceMultiplier.Creature
|
||||
# Rate.MissChanceMultiplier.Player
|
||||
# Rate.MissChanceMultiplier.OnlyAffectsPlayer
|
||||
#
|
||||
# Description: When the target is 3 or more level higher than the player,
|
||||
# the chance to hit is determined by the formula: 94 - (levelDiff - 2) * Rate.MissChanceMultiplier
|
||||
@@ -2557,15 +2558,19 @@ Die.Command.Mode = 1
|
||||
#
|
||||
# Note: this does not affect when the player is less than 3 levels different than the target,
|
||||
# where this (linear) formula is used instead to calculate the hit chance: 96 - levelDiff.
|
||||
# You can set Rate.MissChanceMultiplier.OnlyAffectsPlayer to 1 if you only want to affect the MissChance
|
||||
# for player casters only. This way you won't be affecting creature missing chance.
|
||||
#
|
||||
# Example: if you want the chance to keep growing linearly, use 1.
|
||||
#
|
||||
# Default: Rate.MissChanceMultiplier.TargetCreature = 11
|
||||
# Rate.MissChanceMultiplier.TargetPlayer = 7
|
||||
# Rate.MissChanceMultiplier.OnlyAffectsPlayer = 0
|
||||
#
|
||||
|
||||
Rate.MissChanceMultiplier.TargetCreature = 11
|
||||
Rate.MissChanceMultiplier.TargetPlayer = 7
|
||||
Rate.MissChanceMultiplier.OnlyAffectsPlayer = 0
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
Reference in New Issue
Block a user