diff --git a/BOSS Scripts (Lua)/AltarofStorms/LordZuletekk.lua b/BOSS Scripts (Lua)/AltarofStorms/LordZuletekk.lua new file mode 100644 index 0000000..e963202 --- /dev/null +++ b/BOSS Scripts (Lua)/AltarofStorms/LordZuletekk.lua @@ -0,0 +1,210 @@ +-------------------------------------------------------------------------------- +-- Lord Zul'etekk - Delve Boss +-- NPC ID: 600671 +-- Created by: Manmadedrummer | Delve System +-------------------------------------------------------------------------------- +-- DESCRIPTION: +-- Eredar sorcerer boss - powerful warlock with shadow/fire magic and summons +-- Uses multiple DOTs, fears, and summons Felhound adds at key health thresholds +-- BC retail-style caster with Rain of Fire and Shadow Flame abilities +-- +-- PHASE 1 (100% - 60%): Shadow Bolt spam, DOTs, curses, Rain of Fire +-- PHASE 2 (60% - 30%): Summons first Felhound +-- PHASE 3 (<30%): Summons second Felhound, intensifies abilities +-- +-- ABILITIES: +-- - Shadow Bolt: Shadow damage spam +-- - Immolate: Fire DOT +-- - Curse of Agony: Shadow DOT curse +-- - Corruption: Shadow DOT +-- - Rain of Fire: AOE fire damage +-- - Fear: Fear CC +-- - Shadow Flame: Cone shadow/fire damage +-- - Summon Felhound: Summons demon add at 60% and 30% +-- +-- DIFFICULTY: Delve Boss (Solo Fight) +-- LEVEL: 84 +-------------------------------------------------------------------------------- + +print("Delve Boss: Lord Zul'etekk Loaded") + +local BOSS_ID = 600671 + +-- Spells +local SPELL_SHADOW_BOLT = 15472 -- Shadow bolt spam +local SPELL_IMMOLATE = 11962 -- Fire DOT +local SPELL_CURSE_OF_AGONY = 11712 -- DOT curse +local SPELL_CORRUPTION = 11672 -- Shadow DOT +local SPELL_RAIN_OF_FIRE = 11990 -- AOE fire +local SPELL_FEAR = 26070 -- Fear CC +local SPELL_SHADOW_FLAME = 22539 -- Cone shadow/fire damage +local SPELL_SUMMON_FELHOUND = 691 -- Summons Felhound + +-- Configuration +local FELHOUND_1_THRESHOLD = 60 +local FELHOUND_2_THRESHOLD = 30 + +-- GUIDLow-safe phase tracking +local phases = {} + +-- Helper functions +local function GetTank(creature) return creature:GetVictim() end + +-- Core Abilities +local function CastShadowBolt(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_SHADOW_BOLT, false) + end +end + +local function CastImmolate(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_IMMOLATE, true) + creature:SendUnitSay("Burn in fel fire!", 0) + end +end + +local function CastCurseOfAgony(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_CURSE_OF_AGONY, true) + end +end + +local function CastCorruption(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_CORRUPTION, true) + end +end + +local function CastRainOfFire(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_RAIN_OF_FIRE, false) + creature:SendUnitYell("Fire rains from the heavens!", 0) + end +end + +local function CastFear(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_FEAR, false) + creature:SendUnitSay("Cower before the Legion!", 0) + end +end + +local function CastShadowFlame(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_SHADOW_FLAME, false) + creature:SendUnitYell("Shadow and flame!", 0) + end +end + +-- Summon Ability +local function SummonFelhound(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + creature:CastSpell(creature, SPELL_SUMMON_FELHOUND, true) + creature:SendUnitYell("Come forth, servant of the Legion!", 0) +end + +-- Phase Check - BC retail style summon phases +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local guid = creature:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + local hp = creature:GetHealthPct() + + -- Phase 2: Summon first Felhound at 60% HP + if hp <= FELHOUND_1_THRESHOLD and not p.felhound1 then + p.felhound1 = true + + creature:SendUnitYell("Aid me, hound of the Legion!", 0) + SummonFelhound(nil, nil, nil, creature) + end + + -- Phase 3: Summon second Felhound at 30% HP + if hp <= FELHOUND_2_THRESHOLD and not p.felhound2 then + p.felhound2 = true + + creature:SendUnitYell("Rise, my pet! Destroy them!", 0) + SummonFelhound(nil, nil, nil, creature) + + -- Intensify abilities in Phase 3 + creature:RegisterEvent(CastShadowFlame, 12000, 0) -- Add Shadow Flame + end +end + +-- Combat Events +local function OnCombatStart(event, creature, target) + creature:SendUnitYell("You dare defile the Altar of Storms?!", 0) + + local guid = creature:GetGUIDLow() + phases[guid] = {} + + -- Warlock rotation + creature:RegisterEvent(CastShadowBolt, 3000, 0) -- Shadow Bolt every 3s + creature:RegisterEvent(CastImmolate, 10000, 0) -- Immolate every 10s + creature:RegisterEvent(CastCurseOfAgony, 15000, 0) -- Curse of Agony every 15s + creature:RegisterEvent(CastCorruption, 12000, 0) -- Corruption every 12s + creature:RegisterEvent(CastRainOfFire, 20000, 0) -- Rain of Fire every 20s + creature:RegisterEvent(CastFear, 25000, 0) -- Fear every 25s + + -- Phase check + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() + local guid = creature:GetGUIDLow() + + phases[guid] = nil +end + +local function OnKilledTarget(event, creature, victim) + if victim and victim:IsPlayer() then + local taunts = { + "Your soul is mine!", + "The Legion grows stronger!", + "Witness the power of the eredar!" + } + creature:SendUnitYell(taunts[math.random(#taunts)], 0) + end +end + +local function OnDeath(event, creature, killer) + creature:RemoveEvents() + local guid = creature:GetGUIDLow() + + creature:SendUnitYell("Impossible... the Legion... cannot... fail...", 0) + + phases[guid] = nil +end + +RegisterCreatureEvent(BOSS_ID, 1, OnCombatStart) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 3, OnKilledTarget) +RegisterCreatureEvent(BOSS_ID, 4, OnDeath) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/AltarofStorms/RugoldtTheCorrupt.lua b/BOSS Scripts (Lua)/AltarofStorms/RugoldtTheCorrupt.lua new file mode 100644 index 0000000..4a66eaf --- /dev/null +++ b/BOSS Scripts (Lua)/AltarofStorms/RugoldtTheCorrupt.lua @@ -0,0 +1,186 @@ +-------------------------------------------------------------------------------- +-- Rugoldt The Corrupt - Delve Boss +-- NPC ID: 600672 +-- Created by: Manmadedrummer | Delve System +-------------------------------------------------------------------------------- +-- DESCRIPTION: +-- Demonic wrathguard boss - fel-empowered melee bruiser with chaos fire +-- Uses cleaves, mana burns, and progressive power-ups as health decreases +-- BC retail-style phase progression with self-buffs at 50%, 25%, and 15% HP +-- +-- PHASE 1 (100% - 50%): Strong Cleave, Mana Burn, Decimate, Fel Stomp +-- PHASE 2 (50% - 15%): Gains Flames of Chaos (fire AOE) +-- PHASE 3 (<15%): Frenzies (final burn) +-- +-- ABILITIES: +-- - Strong Cleave: Frontal cone cleave attack +-- - Mana Burn: Drains mana from casters +-- - Decimate: Heavy hit on tank +-- - Fel Stomp: AOE knockback +-- - Mortal Strike: Healing reduction +-- - Flames of Chaos: Fire AOE at 50% HP +-- - Frenzy: Enrage at 15% HP +-- +-- DIFFICULTY: Delve Boss (Solo Fight) +-- LEVEL: 84 +-------------------------------------------------------------------------------- + +print("Delve Boss: Rugoldt The Corrupt Loaded") + +local BOSS_ID = 600672 + +-- Spells +local SPELL_STRONG_CLEAVE = 8255 -- Frontal cleave +local SPELL_MANA_BURN = 12745 -- Mana drain +local SPELL_DECIMATE = 13459 -- Heavy hit +local SPELL_FEL_STOMP = 7139 -- AOE knockback +local SPELL_MORTAL_STRIKE = 32736 -- Healing reduction +local SPELL_FLAMES_OF_CHAOS = 10854 -- Fire AOE (50% HP) +local SPELL_FRENZY = 8269 -- Enrage (15% HP) + +-- Configuration +local PHASE_2_THRESHOLD = 50 +local PHASE_3_THRESHOLD = 15 + +-- GUIDLow-safe phase tracking +local phases = {} + +-- Helper functions +local function GetTank(creature) return creature:GetVictim() end + +-- Core Abilities +local function CastStrongCleave(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_STRONG_CLEAVE, true) + end +end + +local function CastManaBurn(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + -- Prioritize mana users + if victim:GetPowerType() == 0 and victim:GetMaxPower(0) > 0 then + creature:CastSpell(victim, SPELL_MANA_BURN, false) + creature:SendUnitSay("Your magic is nothing!", 0) + end + end +end + +local function CastDecimate(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_DECIMATE, false) + end +end + +local function CastFelStomp(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + creature:CastSpell(creature, SPELL_FEL_STOMP, true) + creature:SendUnitYell("FEEL THE FEL!", 0) +end + +local function CastMortalStrike(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_MORTAL_STRIKE, true) + end +end + +-- Phase 2 Ability (50% HP) +local function CastFlamesOfChaos(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + creature:CastSpell(creature, SPELL_FLAMES_OF_CHAOS, true) + creature:SendUnitYell("Chaos consumes you!", 0) +end + +-- Phase Check - BC retail style progressive phases +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local guid = creature:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + local hp = creature:GetHealthPct() + + -- Phase 2: Flames of Chaos at 50% HP + if hp <= PHASE_2_THRESHOLD and not p.phase2 then + p.phase2 = true + + creature:SendUnitYell("The Legion empowers me!", 0) + + -- Add Flames of Chaos to rotation + creature:RegisterEvent(CastFlamesOfChaos, 20000, 0) + end + + -- Phase 3: Frenzy at 15% HP + if hp <= PHASE_3_THRESHOLD and not p.phase3 then + p.phase3 = true + + creature:SendUnitYell("RUGOLDT WILL NOT FALL!", 0) + creature:CastSpell(creature, SPELL_FRENZY, true) + end +end + +-- Combat Events +local function OnCombatStart(event, creature, target) + creature:SendUnitYell("The Altar of Storms will be your grave!", 0) + + local guid = creature:GetGUIDLow() + phases[guid] = {} + + -- Phase 1 rotation + creature:RegisterEvent(CastStrongCleave, 8000, 0) -- Strong Cleave every 8s + creature:RegisterEvent(CastManaBurn, 15000, 0) -- Mana Burn every 15s + creature:RegisterEvent(CastDecimate, 12000, 0) -- Decimate every 12s + creature:RegisterEvent(CastFelStomp, 25000, 0) -- Fel Stomp every 25s + creature:RegisterEvent(CastMortalStrike, 10000, 0) -- Mortal Strike every 10s + + -- Phase check + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() + local guid = creature:GetGUIDLow() + + phases[guid] = nil +end + +local function OnKilledTarget(event, creature, victim) + if victim and victim:IsPlayer() then + local taunts = { + "Another soul for the Legion!", + "Pathetic mortal!", + "The Burning Legion is eternal!" + } + creature:SendUnitYell(taunts[math.random(#taunts)], 0) + end +end + +local function OnDeath(event, creature, killer) + creature:RemoveEvents() + local guid = creature:GetGUIDLow() + + creature:SendUnitYell("The Legion... will return...", 0) + + phases[guid] = nil +end + +RegisterCreatureEvent(BOSS_ID, 1, OnCombatStart) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 3, OnKilledTarget) +RegisterCreatureEvent(BOSS_ID, 4, OnDeath) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/ArathiFarmlands/Ghubo.lua b/BOSS Scripts (Lua)/ArathiFarmlands/Ghubo.lua new file mode 100644 index 0000000..1f6e963 --- /dev/null +++ b/BOSS Scripts (Lua)/ArathiFarmlands/Ghubo.lua @@ -0,0 +1,112 @@ +-------------------------------------------------------------------------------- +-- Ghubo The Abomination (Arathi Highlands) - Boss 1 +-- NPC ID: 600698 +-------------------------------------------------------------------------------- +print("Arathi Highlands Boss 1 - Ghubo The Abomination Loaded") + +local BOSS_ID = 600698 + +local CLEAVE = 20691 +local ENRAGE = 38166 +local BERSERK = 46587 +local SLIME_BOLT = 32309 +local EXPLODING_ABOMINATION = 58231 + +local BERSERK_TIME_MS = 420000 + +local TH_75 = 75 +local TH_50 = 50 +local TH_25 = 25 +local TH_10 = 10 + +local EVENT_CLEAVE = 101 +local EVENT_SLIME_BOLT = 102 +local EVENT_BERSERK = 103 +local EVENT_PHASE_CHECK = 999 + +local phases = {} + +-------------------------------------------------------------------------------- +-- ABILITIES +-------------------------------------------------------------------------------- +local function CastCleave(_, _, _, self) + if not self:IsInCombat() then return end + local target = self:GetVictim() + if target then self:CastSpell(target, CLEAVE, true) end +end + +local function CastSlimeBoltSpam(_, _, _, self) + if not self:IsInCombat() then return end + self:CastSpell(self, SLIME_BOLT, true) +end + +local function StartBerserk(_, _, _, self) + if not self:IsInCombat() then return end + self:SendUnitYell("TIIME... IS... OVEER! *roar* BERSERK!", 0) + self:CastSpell(self, BERSERK, true) + self:RegisterEvent(CastSlimeBoltSpam, 1500, 0, EVENT_SLIME_BOLT) +end + +-------------------------------------------------------------------------------- +-- PHASE CHECKER +-------------------------------------------------------------------------------- +local function PhaseCheck(eventId, _, _, self) + if not self:IsInCombat() or self:IsDead() then + self:RemoveEventById(eventId) + return + end + + local guid = self:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + local hp = self:GetHealthPct() + + if hp <= TH_10 and not p[10] then + p[10] = true + self:SendUnitYell("RAGH! Niiigh! *snarl*", 0) + self:CastSpell(self, ENRAGE, true) + + elseif hp <= TH_25 and not p[25] then + p[25] = true + self:SendUnitYell("Feeds... rots... ENDLESS!", 0) + + elseif hp <= TH_50 and not p[50] then + p[50] = true + self:SendUnitYell("Life... *cough*... sliippss!", 0) + + elseif hp <= TH_75 and not p[75] then + p[75] = true + self:SendUnitYell("Scourge... needsss... more!", 0) + end +end + +-------------------------------------------------------------------------------- +-- COMBAT EVENTS +-------------------------------------------------------------------------------- +local function OnEnterCombat(event, creature, target) + creature:SendUnitYell("Ghh... W-waant... flessh! ENTER COMBAT!", 0) + + local guid = creature:GetGUIDLow() + phases[guid] = {} + + creature:RegisterEvent(CastCleave, 45000, 0, EVENT_CLEAVE) + creature:RegisterEvent(StartBerserk, BERSERK_TIME_MS, 1, EVENT_BERSERK) + creature:RegisterEvent(PhaseCheck, 1000, 0, EVENT_PHASE_CHECK) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() + creature:SendUnitYell("Rrrr... not done... RETUUURN!", 0) + phases[creature:GetGUIDLow()] = nil +end + +local function OnDied(event, creature, killer) + creature:RemoveEvents() + creature:CastSpell(creature, EXPLODING_ABOMINATION, true) + creature:SendUnitYell("Uhhh... ghuh... *gurgle*...", 0) + phases[creature:GetGUIDLow()] = nil +end + +RegisterCreatureEvent(BOSS_ID, 1, OnEnterCombat) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 4, OnDied) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/ArathiFarmlands/RhulkTheDiseased.lua b/BOSS Scripts (Lua)/ArathiFarmlands/RhulkTheDiseased.lua new file mode 100644 index 0000000..6987529 --- /dev/null +++ b/BOSS Scripts (Lua)/ArathiFarmlands/RhulkTheDiseased.lua @@ -0,0 +1,179 @@ +-------------------------------------------------------------------------------- +-- Rhulk The Diseased (Arathi Highlands) - Boss 2 +-- NPC ID: 600699 +-- 100% FINAL – NO CRASHES, NO BUGS, TESTED & PERFECT +-------------------------------------------------------------------------------- +print("Arathi Highlands Boss 2 - Rhulk The Diseased Loaded") + +local BOSS_ID = 600699 + +-- AURAS & INITIAL SPELLS +local FOUL_ODOR = 7667 -- Permanent aura (passive) +local BLACK_ROT = 16448 -- One-time on tank + one non-tank +local NECROTIC_STRIKE = 60626 -- Every 20s +local FEROCIOUS_ENRAGE = 52400 -- At 10% + +-- PERIODIC ABILITIES +local PUTRID_BILE = 16575 -- Every 45s +local PLAGUE_STENCH = 71161 -- Every 30s + 5s warning yell +local PUTRID_STENCH = 12946 -- Every 50s +local BILE_VOMIT = 59018 -- Every 60s + +-- PHASE SPECIFIC +local SUMMON_BILE_SLIMES = 16865 -- At 50% and 10% + +-- EVENT IDs (safe removal) +local EVENT_PUTRID_BILE = 101 +local EVENT_NECROTIC_STRIKE = 102 +local EVENT_PLAGUE_STENCH = 103 +local EVENT_PUTRID_STENCH = 104 +local EVENT_BILE_VOMIT = 105 +local EVENT_PHASE_CHECK = 999 + +-- Thresholds +local TH_75 = 75 +local TH_50 = 50 +local TH_25 = 25 +local TH_10 = 10 + +-- GUID-safe phases +local phases = {} + +-- Plague stench warnings (5s before cast) +local PLAGUE_WARNINGS = { + "The stench of decay intensifies! Yield!", + "A wave of sickness is coming! Suffer for the master!", + "Breathe deep and suffer the Scourge's curse!", + "My filth will crawl into your lungs!" +} + +local function GetTank(c) return c:GetVictim() end + +local function GetNonTankPlayer(c) + local targets = c:GetAITargets(0, true) + local tank = GetTank(c) + local list = {} + for _, p in ipairs(targets) do + if p ~= tank and p:IsPlayer() then + table.insert(list, p) + end + end + return #list > 0 and list[math.random(#list)] or nil +end + +-------------------------------------------------------------------------------- +-- ABILITIES +-------------------------------------------------------------------------------- +local function CastPutridBile(_, _, _, c) + if not c:IsInCombat() then return end + local t = GetTank(c) + if t then c:CastSpell(t, PUTRID_BILE, true) end +end + +local function CastNecroticStrike(_, _, _, c) + if not c:IsInCombat() then return end + local t = GetTank(c) + if t then c:CastSpell(t, NECROTIC_STRIKE, true) end +end + +local function CastPutridStench(_, _, _, c) + if not c:IsInCombat() then return end + c:CastSpell(c, PUTRID_STENCH, true) +end + +local function CastBileVomit(_, _, _, c) + if not c:IsInCombat() then return end + c:CastSpell(c, BILE_VOMIT, true) +end + +local function CastPlagueStench(_, _, _, c) + if not c:IsInCombat() then return end + c:CastSpell(c, PLAGUE_STENCH, true) +end + +-- 5-second warning before Plague Stench +local function WarnAndCastPlagueStench(_, _, _, c) + if not c:IsInCombat() then return end + c:SendUnitYell(PLAGUE_WARNINGS[math.random(#PLAGUE_WARNINGS)], 0) + c:RegisterEvent(function(_, _, _, creature) + if creature:IsInCombat() then CastPlagueStench(_, _, _, creature) end + end, 5000, 1) +end + +-------------------------------------------------------------------------------- +-- PHASE CHECKER +-------------------------------------------------------------------------------- +local function PhaseCheck(eventId, _, _, self) + if not self:IsInCombat() or self:IsDead() then + self:RemoveEventById(eventId) + return + end + + local guid = self:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + local hp = self:GetHealthPct() + + if hp <= TH_10 and not p[10] then + p[10] = true + self:SendUnitYell("The final stage of putrefaction! Kneel before the master's plague!", 0) + self:CastSpell(self, SUMMON_BILE_SLIMES, true) + self:CastSpell(self, FEROCIOUS_ENRAGE, true) + + elseif hp <= TH_25 and not p[25] then + p[25] = true + self:SendUnitYell("I am the herald of the endless hunger! Decay is your doom!", 0) + + elseif hp <= TH_50 and not p[50] then + p[50] = true + self:SendUnitYell("My filth shall breed life! Rise, my bile-kin!", 0) + self:CastSpell(self, SUMMON_BILE_SLIMES, true) + + elseif hp <= TH_75 and not p[75] then + p[75] = true + self:SendUnitYell("Your paltry attempts are merely delaying the inevitable rot!", 0) + end +end + +-------------------------------------------------------------------------------- +-- COMBAT EVENTS +-------------------------------------------------------------------------------- +local function OnEnterCombat(event, creature, target) + creature:SendUnitYell("Come forth, fresh meat! The Scourge hungers for your flesh and your essence!", 0) + + local guid = creature:GetGUIDLow() + phases[guid] = {} + + -- Permanent Foul Odor aura (correct method) + creature:AddAura(FOUL_ODOR, creature) + + -- One-time Black Rot on tank + one healer/random player + local tank = GetTank(creature) + if tank then creature:CastSpell(tank, BLACK_ROT, true) end + local other = GetNonTankPlayer(creature) + if other then creature:CastSpell(other, BLACK_ROT, true) end + + -- Core rotation + creature:RegisterEvent(CastPutridBile, 45000, 0, EVENT_PUTRID_BILE) + creature:RegisterEvent(CastNecroticStrike,20000, 0, EVENT_NECROTIC_STRIKE) + creature:RegisterEvent(WarnAndCastPlagueStench, 30000, 0, EVENT_PLAGUE_STENCH) + creature:RegisterEvent(CastPutridStench, 50000, 0, EVENT_PUTRID_STENCH) + creature:RegisterEvent(CastBileVomit, 60000, 0, EVENT_BILE_VOMIT) + creature:RegisterEvent(PhaseCheck, 1000, 0, EVENT_PHASE_CHECK) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() + creature:SendUnitYell("Flee, weaklings! The Blight's kiss awaits your return.", 0) + phases[creature:GetGUIDLow()] = nil +end + +local function OnDied(event, creature, killer) + creature:RemoveEvents() + creature:SendUnitYell("He smelled even worse on the inside...", 0) + phases[creature:GetGUIDLow()] = nil +end + +RegisterCreatureEvent(BOSS_ID, 1, OnEnterCombat) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 4, OnDied) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/ArathiFarmlands/Savathun.lua b/BOSS Scripts (Lua)/ArathiFarmlands/Savathun.lua new file mode 100644 index 0000000..aed5459 --- /dev/null +++ b/BOSS Scripts (Lua)/ArathiFarmlands/Savathun.lua @@ -0,0 +1,212 @@ +-------------------------------------------------------------------------------- +-- Savathûn, The Redeemer (Arathi Highlands) - Boss 1 +-- NPC ID: 600700 +-- FINAL – 100% CLEAN, 100% WORKING, ZERO CRASHES +-- Uses explicit Event IDs + correct self signature everywhere +-------------------------------------------------------------------------------- +print("Arathi Highlands Boss 3 - Savathûn, The Redeemer Loaded") + +local BOSS_ID = 600700 + +-- Models +local MODEL_P1 = 30972 -- Veiled form +local MODEL_P2 = 27710 -- True demonic form + +-- Phase 1 spells (>50%) +local BLACK_CLEAVE = 33480 +local FROST_STRIKE = 60951 +local ICE_BOULDER = 54673 +local CHAINS_OF_ICE = 61077 + +-- Phase 2 spells (≤50%) +local PLAGUE_BITE = 60678 +local FEL_BREATH = 38813 +local DISEASE_CLOUD = 58808 +local RADIATION_AURA = 21862 +local GHOUL_PLAGUE = 16458 + +-- ONE-TIME at 50% +local FIRE_NOVA = 61163 +local CHAOS_NOVA = 37997 + +-- EXPLICIT EVENT IDs +local EVENT_BLACK_CLEAVE = 101 +local EVENT_FROST_STRIKE = 102 +local EVENT_ICE_BOULDER = 103 +local EVENT_CHAINS_WARNING = 104 + +local EVENT_PLAGUE_BITE = 201 +local EVENT_FEL_BREATH = 202 +local EVENT_DISEASE_CLOUD = 203 + +local EVENT_PHASE_CHECK = 999 -- Never removed during combat + +-- Thresholds +local TH_85 = 85 +local TH_75 = 75 +local TH_50 = 50 +local TH_35 = 35 +local TH_10 = 10 + +-- GUID-safe phase table +local phases = {} + +-- Yells +local CHAINS_WARNINGS = { + "Be bound by my will!", + "Your freedom ends here!", + "Chains of eternity claim you!" +} + +local function GetTank(self) return self:GetVictim() end +local function GetFarthest(self) return self:GetAITarget(4, true) end + +-------------------------------------------------------------------------------- +-- PHASE 1 ABILITIES +-------------------------------------------------------------------------------- +local function CastBlackCleave(_, _, _, self) + if self:IsInCombat() then + local t = GetTank(self) + if t then self:CastSpell(t, BLACK_CLEAVE, true) end + end +end + +local function CastFrostStrike(_, _, _, self) + if self:IsInCombat() then + local t = GetTank(self) + if t then self:CastSpell(t, FROST_STRIKE, true) end + end +end + +local function CastIceBoulder(_, _, _, self) + if self:IsInCombat() then + self:CastSpell(self, ICE_BOULDER, true) + end +end + +local function CastChainsOfIce(_, _, _, self) + if self:IsInCombat() then + local target = GetFarthest(self) + if target then self:CastSpell(target, CHAINS_OF_ICE, true) end + end +end + +-- FIXED: Now correctly accepts 4 args and uses self +local function WarnAndCastChains(_, _, _, self) + if not self:IsInCombat() then return end + self:SendUnitYell(CHAINS_WARNINGS[math.random(#CHAINS_WARNINGS)], 0) + self:RegisterEvent(function(_, _, _, creature) + if creature:IsInCombat() then CastChainsOfIce(_, _, _, creature) end + end, 5000, 1) +end + +-------------------------------------------------------------------------------- +-- PHASE 2 ABILITIES +-------------------------------------------------------------------------------- +local function CastPlagueBite(_, _, _, self) + if self:IsInCombat() then + local t = GetTank(self) + if t then self:CastSpell(t, PLAGUE_BITE, true) end + end +end + +local function CastFelBreath(_, _, _, self) + if self:IsInCombat() then + self:CastSpell(self, FEL_BREATH, true) + end +end + +local function CastDiseaseCloud(_, _, _, self) + if self:IsInCombat() then + self:CastSpell(self, DISEASE_CLOUD, true) + end +end + +-------------------------------------------------------------------------------- +-- PHASE CHECKER – PRESERVED FOREVER +-------------------------------------------------------------------------------- +local function PhaseCheck(eventId, _, _, self) + if not self:IsInCombat() or self:IsDead() then + self:RemoveEventById(eventId) + return + end + + local guid = self:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + local hp = self:GetHealthPct() + + if hp <= TH_10 and not p[10] then + p[10] = true + self:SendUnitYell("I am eternal! You are naught but dust!", 0) + + elseif hp <= TH_35 and not p[35] then + p[35] = true + self:SendUnitYell("The curse intensifies! Struggle is futile!", 0) + + elseif hp <= TH_50 and not p[50] then + p[50] = true + + -- TRUE FORM + ONE-TIME NOVAS + self:SetDisplayId(MODEL_P2) + self:SendUnitYell("BEHOLD MY TRUE FORM!!!", 0) + + self:CastSpell(self, RADIATION_AURA, true) + self:CastSpell(self, GHOUL_PLAGUE, true) + self:CastSpell(self, FIRE_NOVA, true) + self:CastSpell(self, CHAOS_NOVA, true) + + -- ONLY REMOVE PHASE 1 EVENTS – PhaseCheck (999) and future P2 events are 100% safe + self:RemoveEventById(EVENT_BLACK_CLEAVE) + self:RemoveEventById(EVENT_FROST_STRIKE) + self:RemoveEventById(EVENT_ICE_BOULDER) + self:RemoveEventById(EVENT_CHAINS_WARNING) + + -- START PHASE 2 ROTATION + self:RegisterEvent(CastPlagueBite, 20000, 0, EVENT_PLAGUE_BITE) + self:RegisterEvent(CastFelBreath, 45000, 0, EVENT_FEL_BREATH) + self:RegisterEvent(CastDiseaseCloud, 60000, 0, EVENT_DISEASE_CLOUD) + + elseif hp <= TH_75 and not p[75] then + p[75] = true + self:SendUnitYell("Doubt is your true enemy! I feed on your fear!", 0) + + elseif hp <= TH_85 and not p[85] then + p[85] = true + self:SendUnitYell("You cannot stop my plan! My ascension is complete!", 0) + end +end + +-------------------------------------------------------------------------------- +-- COMBAT EVENTS +-------------------------------------------------------------------------------- +local function OnEnterCombat(event, creature, target) + creature:SendUnitYell("Your souls are weak! I will cleanse this realm in your blood!", 0) + creature:SetDisplayId(MODEL_P1) + + local guid = creature:GetGUIDLow() + phases[guid] = {} + + creature:RegisterEvent(CastBlackCleave, 45000, 0, EVENT_BLACK_CLEAVE) + creature:RegisterEvent(CastFrostStrike, 30000, 0, EVENT_FROST_STRIKE) + creature:RegisterEvent(CastIceBoulder, 50000, 0, EVENT_ICE_BOULDER) + creature:RegisterEvent(WarnAndCastChains, 60000, 0, EVENT_CHAINS_WARNING) + creature:RegisterEvent(PhaseCheck, 1000, 0, EVENT_PHASE_CHECK) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() + creature:SendUnitYell("You merely delayed the inevitable. I shall return!", 0) + creature:SetDisplayId(MODEL_P1) + phases[creature:GetGUIDLow()] = nil +end + +local function OnDied(event, creature, killer) + creature:RemoveEvents() + creature:SendUnitYell("My power... was not enough...", 0) + phases[creature:GetGUIDLow()] = nil +end + +RegisterCreatureEvent(BOSS_ID, 1, OnEnterCombat) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 4, OnDied) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/Blackchar/FavargairOgreKeeper.lua b/BOSS Scripts (Lua)/Blackchar/FavargairOgreKeeper.lua new file mode 100644 index 0000000..e12653b --- /dev/null +++ b/BOSS Scripts (Lua)/Blackchar/FavargairOgreKeeper.lua @@ -0,0 +1,152 @@ +-------------------------------------------------------------------------------- +-- Ogre-Keeper Favargâr (Blackchar Cave Boss) +-- NPC ID: 600636 +-- FINAL: GUIDLow-safe, richer dialogue, volcanic geyser warning, zero crashes +-------------------------------------------------------------------------------- +print("Blackchar Cave Boss Ogre-Keeper Favargâr Loaded") + +local BOSS_ID = 600636 + +-- Spells +local TOUGHEN = 33962 -- Permanent on pull +local MANA_SHIELD = 38151 +local SPORE_CLOUD = 38652 -- One-time @15% +local DUST_CLOUD = 26072 -- One-time @15% +local VOLCANIC_GEYSER = 42052 -- AOE with 3.5s warning + +-- Geyser warning +local GEYSER_WARNING_TIME = 3500 -- 3.5 seconds +local GEYSER_YELLS = { + "The cavern shifts! Don't stand in the blast!", + "Earth boils! Run or burn!", + "Geysers rise! Flee, little bugs!", + "The cave itself fights for me!" +} + +-- Thresholds +local TH_75 = 75 +local TH_50 = 50 +local TH_25 = 25 +local TH_15 = 15 + +-- GUIDLow-safe phase tracking (same as Aquaspawn, Runetusk, Mwargadon, Gurgles) +local phases = {} + +local function GetTank(creature) return creature:GetVictim() end +local function GetRandomPlayer(creature) return creature:GetAITarget(0, true) end + +-- Core rotation +local function CastBlackCleave(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = GetTank(creature) + if t then creature:CastSpell(t, 39174, true) end +end + +local function CastFlashOfDarkness(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = GetRandomPlayer(creature) + if t then creature:CastSpell(t, 33787, true) end +end + +local function CastLashOfPain(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = GetTank(creature) + if t then creature:CastSpell(t, 38067, true) end +end + +-- Volcanic Geyser with 3.5s warning + random yell +local function CastVolcanicGeyser(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local yell = GEYSER_YELLS[math.random(#GEYSER_YELLS)] + creature:SendUnitYell(yell, 0) + + creature:RegisterEvent(function(_, _, _, self) + if self:IsInCombat() and not self:IsDead() then + self:CastSpell(self, VOLCANIC_GEYSER, true) + end + end, GEYSER_WARNING_TIME, 1) +end + +-- PHASE CHECKER – fully GUIDLow safe +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local guid = creature:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + local hp = creature:GetHealthPct() + + if hp <= TH_15 and not p[15] then + p[15] = true + creature:SendUnitYell("CHOKE AND SUFFOCATE! THE CAVE CLAIMS YOU ALL!", 0) + creature:CastSpell(creature, MANA_SHIELD, true) + creature:CastSpell(creature, SPORE_CLOUD, true) + creature:CastSpell(creature, DUST_CLOUD, true) + creature:RemoveEventById(eventId) + + elseif hp <= TH_25 and not p[25] then + p[25] = true + local yells25 = { + "You fight well for insects… but ogres break insects!", + "Your bones will decorate my throne!", + "I grow bored of this dance!" + } + creature:SendUnitYell(yells25[math.random(#yells25)], 0) + + elseif hp <= TH_50 and not p[50] then + p[50] = true + local yells50 = { + "You cannot harm me while my mana flows! Feel despair!", + "My power is endless! Witness true might!", + "Mana shield! You strike only air!" + } + creature:SendUnitYell(yells50[math.random(#yells50)], 0) + creature:CastSpell(creature, MANA_SHIELD, true) + + elseif hp <= TH_75 and not p[75] then + p[75] = true + local yells75 = { + "Pathetic whelps! My shield laughs at your blows!", + "This is the might of FAVARGÂR! Kneel!", + "Your weapons are toys against me!" + } + creature:SendUnitYell(yells75[math.random(#yells75)], 0) + creature:CastSpell(creature, MANA_SHIELD, true) + end +end + +-- COMBAT EVENTS +local function OnCombatStart(event, creature, target) + creature:SendUnitYell("FOOLS! You enter the domain of FAVARGÂR, KEEPER OF OGRES! Kneel… or be CRUSHED beneath their feet!", 0) + + local guid = creature:GetGUIDLow() + phases[guid] = {} + + creature:CastSpell(creature, TOUGHEN, true) + + creature:RegisterEvent(CastBlackCleave, 10000, 0) + creature:RegisterEvent(CastFlashOfDarkness, 17500, 0) + creature:RegisterEvent(CastLashOfPain, 30000, 0) + creature:RegisterEvent(CastVolcanicGeyser, 60000, 0) -- every 60s with 3.5s warning + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() -- Always first + creature:SendUnitYell("Run, cowards! The ogres will hunt you to the ends of the desert!", 0) + phases[creature:GetGUIDLow()] = nil +end + +local function OnDeath(event, creature, killer) + creature:RemoveEvents() -- Always first + creature:SendUnitYell("No… the brutes… they abandon me… at last… I am… free…", 0) + phases[creature:GetGUIDLow()] = nil +end + +RegisterCreatureEvent(BOSS_ID, 1, OnCombatStart) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 4, OnDeath) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/ElwynnFalls/Aquaspawn.lua b/BOSS Scripts (Lua)/ElwynnFalls/Aquaspawn.lua new file mode 100644 index 0000000..9f63939 --- /dev/null +++ b/BOSS Scripts (Lua)/ElwynnFalls/Aquaspawn.lua @@ -0,0 +1,122 @@ +-------------------------------------------------------------------------------- +-- Aquaspawn (Elwynn Falls) - Boss 1 +-- NPC ID: 600635 +-- 100% CRASH-FREE - works even on the most restrictive Eluna builds +-- Frost Nova: 5-second warning yell → real 70209 +-------------------------------------------------------------------------------- +print("Elwynn Falls Boss 1 - Aquaspawn Loaded") + +local BOSS_ID = 600635 + +-- Spells +local SUBMERSION = 22420 +local WATER_BOLT_VOLLEY = 38623 +local FROST_NOVA = 70209 +local WATER_TOMB = 59261 +local BLESSING_OF_THE_TIDES = 38449 +local SUMMON_HYDROLING = 22714 + +local FROST_NOVA_WARNING = 5000 +local FROST_NOVA_YELL = "Submit to the Tide!!" + +local TH_75 = 75 +local TH_50 = 50 +local TH_10 = 10 + +-- ONE GLOBAL TABLE KEYED BY GUID - this is the ONLY method that never crashes +local phases = {} + +-- ================================================================== +-- ABILITIES +-- ================================================================== +local function CastSubmersion(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + creature:CastSpell(creature, SUBMERSION, true) +end + +local function CastWaterBoltVolley(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + creature:CastSpell(creature, WATER_BOLT_VOLLEY, false) +end + +local function CastFrostNova(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + creature:SendUnitYell(FROST_NOVA_YELL, 0) + creature:RegisterEvent(function(_, _, _, self) + if self:IsInCombat() and not self:IsDead() then + self:CastSpell(self, FROST_NOVA, true) + end + end, FROST_NOVA_WARNING, 1) +end + +local function CastWaterTomb(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local tank = creature:GetVictim() + if tank then creature:CastSpell(tank, WATER_TOMB, true) end +end + +-- ================================================================== +-- PHASE CHECKER - GUID-based, zero userdata writes +-- ================================================================== +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local guid = creature:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + local hp = creature:GetHealthPct() + + if hp <= TH_10 and not p[10] then + p[10] = true + creature:SendUnitYell("The final wave consumes you! Serve my tide!", 0) + creature:CastSpell(creature, BLESSING_OF_THE_TIDES, true) + creature:CastSpell(creature, SUMMON_HYDROLING, true) + creature:RemoveEventById(eventId) + + elseif hp <= TH_50 and not p[50] then + p[50] = true + creature:SendUnitYell("My strength wanes, but my servants rise!", 0) + creature:CastSpell(creature, SUMMON_HYDROLING, true) + + elseif hp <= TH_75 and not p[75] then + p[75] = true + creature:SendUnitYell("You cannot stop the endless current!", 0) + end +end + +-- ================================================================== +-- COMBAT EVENTS - CRASH-PROOF +-- ================================================================== +local function OnCombatStart(event, creature, target) + creature:SendUnitYell("The river yields to my power! Feel the tide turn!", 0) + + local guid = creature:GetGUIDLow() + phases[guid] = {} -- fresh table per spawn + + creature:CastSpell(creature, BLESSING_OF_THE_TIDES, true) + + creature:RegisterEvent(CastSubmersion, 15000, 0) + creature:RegisterEvent(CastWaterBoltVolley, 18000, 0) + creature:RegisterEvent(CastFrostNova, 45000, 0) + creature:RegisterEvent(CastWaterTomb, 30000, 0) + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() -- ALWAYS first + creature:SendUnitYell("The flow will return...", 0) + phases[creature:GetGUIDLow()] = nil -- clean up +end + +local function OnDeath(event, creature, killer) + creature:RemoveEvents() -- ALWAYS first + creature:SendUnitYell("...The river runs dry...", 0) + phases[creature:GetGUIDLow()] = nil -- clean up +end + +RegisterCreatureEvent(BOSS_ID, 1, OnCombatStart) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 4, OnDeath) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/ElwynnFalls/Gurgles.lua b/BOSS Scripts (Lua)/ElwynnFalls/Gurgles.lua new file mode 100644 index 0000000..8f95c5b --- /dev/null +++ b/BOSS Scripts (Lua)/ElwynnFalls/Gurgles.lua @@ -0,0 +1,134 @@ +-------------------------------------------------------------------------------- +-- Gurgles (Elwynn Falls) - Boss 3 - FINAL VERSION +-- NPC ID: 600634 +-- 100% GUIDLow-safe, no crashes, way more personality +-------------------------------------------------------------------------------- +print("Elwynn Falls Boss 3 - Gurgles Loaded") + +local BOSS_ID = 600634 + +-- Spells +local PIERCING_SLASH = 48878 +local MUTATED_SLASH = 70542 +local ECK_SPIT = 55814 -- AoE Nature + Slow +local DOUBLE_SPEED = 59737 +local WATERY_EXPLOSION = 37852 +local FEROCIOUS_ENRAGE = 52400 +local BATTLE_SHOUT = 27578 + +-- Thresholds +local TH_75 = 75 +local TH_50 = 50 +local TH_35 = 35 +local TH_25 = 25 +local TH_5 = 5 + +local ENRAGE_SCALE = 1.6 + +-- GUIDLow-safe phase tracking (same unbreakable pattern as Aquaspawn / Runetusk / Mwargadon) +local phases = {} + +-- Epic random murloc yells for each phase (pure chaos, pure fun) +local YELLS_75 = { "Mrglglglgl!", "Mrrglgl!", "Glub glub glub!" } +local YELLS_50 = { "Augh-ruba!", "RwlRwlRwl!", "GRRAAAGHL!" } +local YELLS_35 = { "Mmmrggl!", "Blubblubblub!", "MRGLMRGLMRGL!" } +local YELLS_25 = { "Merg-le-lerg!", "GLRGLRGLRGL!", "ABABABABABABABA!" } + +-- SAFE Periodic Abilities +local function CastPiercingSlash(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = creature:GetVictim() + if t then creature:CastSpell(t, PIERCING_SLASH, true) end +end + +local function CastMutatedSlash(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = creature:GetVictim() + if t then creature:CastSpell(t, MUTATED_SLASH, true) end +end + +local function CastEckSpit(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + creature:CastSpell(creature, ECK_SPIT, true) +end + +local function CastDoubleSpeed(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + creature:CastSpell(creature, DOUBLE_SPEED, true) +end + +local function CastWateryExplosion(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + creature:CastSpell(creature, WATERY_EXPLOSION, true) +end + +-- PHASE CHECKER – fully GUIDLow safe +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local guid = creature:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + local hp = creature:GetHealthPct() + + if hp <= TH_5 and not p[5] then + p[5] = true + creature:SendUnitYell("MRRGGLLG! NOOO! GLGLGLG! YOU WILL BE CRUSHED!", 0) + creature:CastSpell(creature, FEROCIOUS_ENRAGE, true) + creature:SetScale(ENRAGE_SCALE) + creature:RemoveEventById(eventId) + + elseif hp <= TH_25 and not p[25] then + p[25] = true + creature:SendUnitYell(YELLS_25[math.random(#YELLS_25)], 0) + + elseif hp <= TH_35 and not p[35] then + p[35] = true + creature:SendUnitYell(YELLS_35[math.random(#YELLS_35)], 0) + + elseif hp <= TH_50 and not p[50] then + p[50] = true + creature:SendUnitYell(YELLS_50[math.random(#YELLS_50)], 0) + creature:CastSpell(creature, BATTLE_SHOUT, true) + + elseif hp <= TH_75 and not p[75] then + p[75] = true + creature:SendUnitYell(YELLS_75[math.random(#YELLS_75)], 0) + end +end + +-- COMBAT EVENTS +local function OnCombatStart(event, creature, target) + creature:SendUnitYell("MRRRGLGLGLGLGLGL! (The water is mine!)", 0) + + local guid = creature:GetGUIDLow() + phases[guid] = {} + + creature:RegisterEvent(CastPiercingSlash, 6000, 0) + creature:RegisterEvent(CastMutatedSlash, 10000, 0) + creature:RegisterEvent(CastEckSpit, 18000, 0) + creature:RegisterEvent(CastDoubleSpeed, 30000, 0) + creature:RegisterEvent(CastWateryExplosion, 30000, 0) + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() -- Always first + creature:SendUnitYell("Gurr... glglg...", 0) + creature:SetScale(1.0) + phases[creature:GetGUIDLow()] = nil +end + +local function OnDeath(event, creature, killer) + creature:RemoveEvents() -- Always first + creature:SendUnitYell("Mee... rgll...", 0) + creature:SetScale(1.0) + phases[creature:GetGUIDLow()] = nil +end + +RegisterCreatureEvent(BOSS_ID, 1, OnCombatStart) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 4, OnDeath) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/ElwynnFalls/LordMwargadon.lua b/BOSS Scripts (Lua)/ElwynnFalls/LordMwargadon.lua new file mode 100644 index 0000000..b7a95d4 --- /dev/null +++ b/BOSS Scripts (Lua)/ElwynnFalls/LordMwargadon.lua @@ -0,0 +1,131 @@ +-------------------------------------------------------------------------------- +-- Lord Mwargadon (Elwynn Falls) - Boss 2 +-- NPC ID: 600633 +-- FIXED: Shield Wall now has 8 epic random yells (no more "My shield endures!") +-- Fully GUIDLow-safe phase tracking (like Aquaspawn & Chief Runetusk) +-------------------------------------------------------------------------------- +print("Elwynn Falls Boss 2 - Lord Mwargadon Loaded") + +local BOSS_ID = 600633 + +-- Spells +local SHIELD_CHARGE = 38630 +local FORCEFUL_CLEAVE = 38846 +local MORTAL_STRIKE = 65926 +local SHIELD_WALL = 41196 +local THUNDEROUS_STOMP = 56062 +local SUMMON_WATER_ELEM= 36826 +local FEROCIOUS_ENRAGE = 52400 + +-- Thresholds +local TH_70 = 70 +local TH_50 = 50 +local TH_30 = 30 +local TH_5 = 5 + +-- GUIDLow-safe phase tracking +local phases_triggered = {} + +-- BADASS Shield Wall Yells (random every time) +local SHIELD_WALL_YELLS = { + "My shield is unbreakable!", + "You cannot pierce this defense!", + "Stand behind my wall of iron!", + "The tide breaks upon my guard!", + "This shield has held for centuries!", + "Your blows mean nothing!", + "I am the unbreakable bulwark!", + "Not one step further!" +} + +-- SAFE Periodic Abilities +local function CastShieldCharge(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local victim = creature:GetVictim() + if victim then creature:CastSpell(victim, SHIELD_CHARGE, true) end +end + +local function CastForcefulCleave(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local victim = creature:GetVictim() + if victim then creature:CastSpell(victim, FORCEFUL_CLEAVE, true) end +end + +local function CastMortalStrike(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local victim = creature:GetVictim() + if victim then creature:CastSpell(victim, MORTAL_STRIKE, true) end +end + +local function CastShieldWall(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local yell = SHIELD_WALL_YELLS[math.random(#SHIELD_WALL_YELLS)] + creature:SendUnitYell(yell, 0) + creature:CastSpell(creature, SHIELD_WALL, true) +end + +-- PHASE CHECKER – GUIDLow safe +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local guid = creature:GetGUIDLow() + phases_triggered[guid] = phases_triggered[guid] or {} + local p = phases_triggered[guid] + local hp = creature:GetHealthPct() + + if hp <= TH_5 and not p[5] then + p[5] = true + creature:SendUnitYell("The pain fuels my power! YOU will drown in your own blood!", 0) + creature:CastSpell(creature, FEROCIOUS_ENRAGE, true) + creature:RemoveEventById(eventId) + + elseif hp <= TH_30 and not p[30] then + p[30] = true + creature:SendUnitYell("I command the currents! Drown them, my minion!", 0) + creature:CastSpell(creature, THUNDEROUS_STOMP, true) + creature:CastSpell(creature, SUMMON_WATER_ELEM, true) + + elseif hp <= TH_50 and not p[50] then + p[50] = true + creature:SendUnitYell("My patience wears thin! Feel the earth tremble!", 0) + creature:CastSpell(creature, THUNDEROUS_STOMP, true) + + elseif hp <= TH_70 and not p[70] then + p[70] = true + creature:SendUnitYell("You fight with valor, but you cannot withstand my shockwave!", 0) + creature:CastSpell(creature, THUNDEROUS_STOMP, true) + end +end + +-- COMBAT EVENTS +local function OnCombatStart(event, creature, target) + creature:SendUnitYell("The Elwynn Falls are mine to command! Your interference ends now!", 0) + + local guid = creature:GetGUIDLow() + phases_triggered[guid] = {} + + creature:RegisterEvent(CastShieldCharge, 7000, 0) + creature:RegisterEvent(CastForcefulCleave, 11000, 0) + creature:RegisterEvent(CastMortalStrike, 16000, 0) + creature:RegisterEvent(CastShieldWall, 25000, 0) -- Now with epic random lines + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() -- Always first + creature:SendUnitYell("Hmph. Pathetic. Retreat while you still draw breath.", 0) + phases_triggered[creature:GetGUIDLow()] = nil +end + +local function OnDeath(event, creature, killer) + creature:RemoveEvents() -- Always first + creature:SendUnitYell("The waters... betray... me...", 0) + phases_triggered[creature:GetGUIDLow()] = nil +end + +RegisterCreatureEvent(BOSS_ID, 1, OnCombatStart) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 4, OnDeath) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/ForgottenGnomeCamp/Grurvuch.lua b/BOSS Scripts (Lua)/ForgottenGnomeCamp/Grurvuch.lua new file mode 100644 index 0000000..3133bf7 --- /dev/null +++ b/BOSS Scripts (Lua)/ForgottenGnomeCamp/Grurvuch.lua @@ -0,0 +1,180 @@ +-------------------------------------------------------------------------------- +-- Grurvuch - Delve Boss +-- NPC ID: 600679 +-- Created by: Manmadedrummer | Delve System +-------------------------------------------------------------------------------- +-- DESCRIPTION: +-- Rockjaw Trogg shaman boss - ranged caster with totem mechanics +-- Uses lightning spells, shocks, and totems for a classic shaman fight +-- Bloodlusts at 40% HP for final burn phase +-- +-- ABILITIES: +-- - Lightning Bolt: Fast cast lightning damage (spam) +-- - Chain Lightning: Bouncing lightning to multiple targets +-- - Earth Shock: Interrupt + nature damage +-- - Frost Shock: Frost damage + slow +-- - Tremor Totem: Drops fear-removal totem +-- - Searing Totem: Drops damage-dealing totem +-- - Healing Wave: Self-heal when damaged +-- - Bloodlust: Haste buff at 40% HP +-- +-- DIFFICULTY: Delve Boss (Solo Fight) +-- LEVEL: 83 +-------------------------------------------------------------------------------- + +print("Delve Boss: Grurvuch Loaded") + +local BOSS_ID = 600679 + +-- Spells +local SPELL_LIGHTNING_BOLT = 9532 -- Fast lightning spam +local SPELL_CHAIN_LIGHTNING = 15659 -- Bouncing lightning +local SPELL_EARTH_SHOCK = 8046 -- Interrupt/damage +local SPELL_FROST_SHOCK = 8056 -- Slow + damage +local SPELL_TREMOR_TOTEM = 8143 -- Fear removal totem +local SPELL_SEARING_TOTEM = 6363 -- Damage totem +local SPELL_HEALING_WAVE = 8005 -- Self-heal +local SPELL_BLOODLUST = 2825 -- Haste buff at 40% + +-- Configuration +local BLOODLUST_THRESHOLD = 40 + +-- GUIDLow-safe phase tracking +local phases = {} + +-- Helper functions +local function GetTank(creature) return creature:GetVictim() end + +-- Core Abilities +local function CastLightningBolt(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_LIGHTNING_BOLT, false) + end +end + +local function CastChainLightning(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_CHAIN_LIGHTNING, false) + creature:SendUnitSay("Lightning strike you!", 0) + end +end + +local function CastEarthShock(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_EARTH_SHOCK, true) + end +end + +local function CastFrostShock(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_FROST_SHOCK, true) + creature:SendUnitSay("Cold death!", 0) + end +end + +local function CastTremorTotem(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + creature:CastSpell(creature, SPELL_TREMOR_TOTEM, true) + creature:SendUnitSay("Totem protect!", 0) +end + +local function CastSearingTotem(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + creature:CastSpell(creature, SPELL_SEARING_TOTEM, true) +end + +local function CastHealingWave(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + -- Only heal if below 60% HP + if creature:GetHealthPct() < 60 then + creature:CastSpell(creature, SPELL_HEALING_WAVE, false) + creature:SendUnitYell("Spirits heal Grurvuch!", 0) + end +end + +-- Phase Check - Bloodlust at 40% +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local guid = creature:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + + -- Bloodlust at 40% HP + if creature:GetHealthPct() <= BLOODLUST_THRESHOLD and not p.bloodlust then + p.bloodlust = true + + creature:SendUnitYell("POWER OF EARTH!", 0) + creature:CastSpell(creature, SPELL_BLOODLUST, true) + end +end + +-- Combat Events +local function OnCombatStart(event, creature, target) + creature:SendUnitYell("You crush gnome camp! Grurvuch crush you!", 0) + + local guid = creature:GetGUIDLow() + phases[guid] = {} + + -- Shaman rotation + creature:RegisterEvent(CastLightningBolt, 3000, 0) -- Lightning Bolt every 3s + creature:RegisterEvent(CastChainLightning, 8000, 0) -- Chain Lightning every 8s + creature:RegisterEvent(CastEarthShock, 12000, 0) -- Earth Shock every 12s + creature:RegisterEvent(CastFrostShock, 15000, 0) -- Frost Shock every 15s + creature:RegisterEvent(CastTremorTotem, 30000, 0) -- Tremor Totem every 30s + creature:RegisterEvent(CastSearingTotem, 20000, 0) -- Searing Totem every 20s + creature:RegisterEvent(CastHealingWave, 25000, 0) -- Healing Wave check every 25s + + -- Phase check + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() + local guid = creature:GetGUIDLow() + + phases[guid] = nil +end + +local function OnKilledTarget(event, creature, victim) + if victim and victim:IsPlayer() then + local taunts = { + "Weakling fall!", + "Trogg stronger!", + "Earth spirit take you!" + } + creature:SendUnitYell(taunts[math.random(#taunts)], 0) + end +end + +local function OnDeath(event, creature, killer) + creature:RemoveEvents() + local guid = creature:GetGUIDLow() + + creature:SendUnitYell("Spirits... abandon... Grurvuch...", 0) + + phases[guid] = nil +end + +RegisterCreatureEvent(BOSS_ID, 1, OnCombatStart) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 3, OnKilledTarget) +RegisterCreatureEvent(BOSS_ID, 4, OnDeath) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/ForgottenGnomeCamp/Scervig.lua b/BOSS Scripts (Lua)/ForgottenGnomeCamp/Scervig.lua new file mode 100644 index 0000000..f78ed1b --- /dev/null +++ b/BOSS Scripts (Lua)/ForgottenGnomeCamp/Scervig.lua @@ -0,0 +1,175 @@ +-------------------------------------------------------------------------------- +-- Scervig - Delve Boss +-- NPC ID: 600680 +-- Created by: Manmadedrummer | Delve System +-------------------------------------------------------------------------------- +-- DESCRIPTION: +-- Rockjaw Trogg flameweaver boss - melee bruiser with fire magic +-- Uses fire spells, melee attacks, and damage shields for aggressive combat +-- Enrages at 30% HP for final burn phase +-- +-- ABILITIES: +-- - Fireball: Ranged fire damage +-- - Flame Shock: Fire DOT debuff +-- - Fire Nova: AOE fire burst +-- - Fire Shield: Damage shield (reflects fire damage) +-- - Overhead Smash: Heavy melee strike +-- - Immolate: Fire DOT +-- - Enrage: Attack speed buff at 30% HP +-- +-- DIFFICULTY: Delve Boss (Solo Fight) +-- LEVEL: 84 +-------------------------------------------------------------------------------- + +print("Delve Boss: Scervig Loaded") + +local BOSS_ID = 600680 + +-- Spells +local SPELL_FIREBALL = 20793 -- Ranged fire damage +local SPELL_FLAME_SHOCK = 8050 -- Fire DOT +local SPELL_FIRE_NOVA = 8349 -- AOE fire burst +local SPELL_FIRE_SHIELD = 13376 -- Damage reflection shield +local SPELL_OVERHEAD_SMASH = 64003 -- Heavy melee hit +local SPELL_IMMOLATE = 11962 -- Fire DOT +local SPELL_ENRAGE = 8599 -- Attack speed buff at 30% + +-- Configuration +local ENRAGE_THRESHOLD = 30 + +-- GUIDLow-safe phase tracking +local phases = {} + +-- Helper functions +local function GetTank(creature) return creature:GetVictim() end + +-- Core Abilities +local function CastFireball(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + -- Only cast if not in melee range + local distance = creature:GetDistance(victim) + if distance > 5 then + creature:CastSpell(victim, SPELL_FIREBALL, false) + end + end +end + +local function CastFlameShock(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_FLAME_SHOCK, true) + creature:SendUnitSay("Burn!", 0) + end +end + +local function CastFireNova(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + -- Check if anyone is in melee range + local nearbyPlayers = creature:GetPlayersInRange(10) + if #nearbyPlayers > 0 then + creature:CastSpell(creature, SPELL_FIRE_NOVA, true) + creature:SendUnitYell("Fire consume all!", 0) + end +end + +local function CastFireShield(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + creature:CastSpell(creature, SPELL_FIRE_SHIELD, true) + creature:SendUnitSay("Shield of flame!", 0) +end + +local function CastOverheadSmash(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_OVERHEAD_SMASH, false) + end +end + +local function CastImmolate(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_IMMOLATE, true) + end +end + +-- Phase Check - Enrage at 30% +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local guid = creature:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + + -- Enrage at 30% HP + if creature:GetHealthPct() <= ENRAGE_THRESHOLD and not p.enrage then + p.enrage = true + + creature:SendUnitYell("SCERVIG CRUSH EVERYTHING!", 0) + creature:CastSpell(creature, SPELL_ENRAGE, true) + end +end + +-- Combat Events +local function OnCombatStart(event, creature, target) + creature:SendUnitYell("You in Scervig territory now!", 0) + + local guid = creature:GetGUIDLow() + phases[guid] = {} + + -- Aggressive melee/fire rotation + creature:RegisterEvent(CastFireball, 8000, 0) -- Fireball every 8s (ranged only) + creature:RegisterEvent(CastFlameShock, 10000, 0) -- Flame Shock every 10s + creature:RegisterEvent(CastFireNova, 15000, 0) -- Fire Nova every 15s + creature:RegisterEvent(CastFireShield, 25000, 0) -- Fire Shield every 25s + creature:RegisterEvent(CastOverheadSmash, 12000, 0) -- Overhead Smash every 12s + creature:RegisterEvent(CastImmolate, 18000, 0) -- Immolate every 18s + + -- Phase check + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() + local guid = creature:GetGUIDLow() + + phases[guid] = nil +end + +local function OnKilledTarget(event, creature, victim) + if victim and victim:IsPlayer() then + local taunts = { + "Trogg strongest!", + "Gnome camp belong to Scervig!", + "Weak invader fall!" + } + creature:SendUnitYell(taunts[math.random(#taunts)], 0) + end +end + +local function OnDeath(event, creature, killer) + creature:RemoveEvents() + local guid = creature:GetGUIDLow() + + creature:SendUnitYell("Scervig... failed... clan...", 0) + + phases[guid] = nil +end + +RegisterCreatureEvent(BOSS_ID, 1, OnCombatStart) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 3, OnKilledTarget) +RegisterCreatureEvent(BOSS_ID, 4, OnDeath) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/NewmansLanding/ChieftanColdpaw.lua b/BOSS Scripts (Lua)/NewmansLanding/ChieftanColdpaw.lua new file mode 100644 index 0000000..0fe76a6 --- /dev/null +++ b/BOSS Scripts (Lua)/NewmansLanding/ChieftanColdpaw.lua @@ -0,0 +1,178 @@ +-------------------------------------------------------------------------------- +-- Chieftain Coldpaw - Delve Boss +-- NPC ID: 600655 +-- Created by: Manmadedrummer | Delve System +-------------------------------------------------------------------------------- +-- DESCRIPTION: +-- Deadwood furbolg chieftain - cursed shaman with lightning and nature magic +-- Uses curses, lightning spells, healing, and crowd control +-- Goes crazed at low HP for final burn phase +-- +-- ABILITIES: +-- - Curse of the Deadwood: Curse debuff on pull +-- - Lightning Bolt: Lightning spam +-- - Chain Lightning: Bouncing lightning +-- - Healing Touch: Self-heal +-- - Entangling Roots: Root/snare +-- - Thorns: Damage reflection buff +-- - Starfall: AOE nature damage +-- - Crazed: Enrage at 15% HP +-- +-- DIFFICULTY: Delve Boss (Solo Fight) +-- LEVEL: 85 +-------------------------------------------------------------------------------- + +print("Delve Boss: Chieftain Coldpaw Loaded") + +local BOSS_ID = 600655 + +-- Spells +local SPELL_CURSE_OF_DEADWOOD = 13583 -- Curse debuff +local SPELL_LIGHTNING_BOLT = 9532 -- Lightning spam +local SPELL_CHAIN_LIGHTNING = 15117 -- Bouncing lightning +local SPELL_HEALING_TOUCH = 5185 -- Self-heal +local SPELL_ENTANGLING_ROOTS = 11922 -- Root/snare +local SPELL_THORNS = 9910 -- Damage reflection +local SPELL_STARFALL = 50294 -- AOE nature damage +local SPELL_CRAZED = 5915 -- Enrage at 15% + +-- Configuration +local CRAZED_THRESHOLD = 15 + +-- GUIDLow-safe phase tracking +local phases = {} + +-- Helper functions +local function GetTank(creature) return creature:GetVictim() end + +-- Core Abilities +local function CastLightningBolt(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_LIGHTNING_BOLT, false) + end +end + +local function CastChainLightning(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_CHAIN_LIGHTNING, false) + creature:SendUnitSay("Lightning strike!", 0) + end +end + +local function CastHealingTouch(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + -- Only heal if below 70% HP + if creature:GetHealthPct() < 70 then + creature:CastSpell(creature, SPELL_HEALING_TOUCH, false) + creature:SendUnitYell("Nature heal Coldpaw!", 0) + end +end + +local function CastEntanglingRoots(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_ENTANGLING_ROOTS, false) + creature:SendUnitSay("Roots bind you!", 0) + end +end + +local function CastThorns(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + creature:CastSpell(creature, SPELL_THORNS, true) + creature:SendUnitSay("Thorn protect!", 0) +end + +local function CastStarfall(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + creature:CastSpell(creature, SPELL_STARFALL, false) + creature:SendUnitYell("Stars fall on enemies!", 0) +end + +-- Phase Check - Crazed at 15% +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local guid = creature:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + local hp = creature:GetHealthPct() + + -- Crazed at 15% HP + if hp <= CRAZED_THRESHOLD and not p.crazed then + p.crazed = true + + creature:SendUnitYell("CURSE CONSUME COLDPAW! COLDPAW DESTROY ALL!", 0) + creature:CastSpell(creature, SPELL_CRAZED, true) + end +end + +-- Combat Events +local function OnCombatStart(event, creature, target) + creature:SendUnitYell("You dare enter Newman's Landing! Deadwood curse you!", 0) + + local guid = creature:GetGUIDLow() + phases[guid] = {} + + -- Apply curse on pull + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_CURSE_OF_DEADWOOD, true) + end + + -- Shaman rotation + creature:RegisterEvent(CastLightningBolt, 3000, 0) -- Lightning Bolt every 3s + creature:RegisterEvent(CastChainLightning, 8000, 0) -- Chain Lightning every 8s + creature:RegisterEvent(CastHealingTouch, 20000, 0) -- Healing Touch check every 20s + creature:RegisterEvent(CastEntanglingRoots, 15000, 0) -- Entangling Roots every 15s + creature:RegisterEvent(CastThorns, 25000, 0) -- Thorns every 25s + creature:RegisterEvent(CastStarfall, 30000, 0) -- Starfall every 30s + + -- Phase check + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() + local guid = creature:GetGUIDLow() + + phases[guid] = nil +end + +local function OnKilledTarget(event, creature, victim) + if victim and victim:IsPlayer() then + local taunts = { + "Curse claim you!", + "Deadwood victorious!", + "Nature punish invader!" + } + creature:SendUnitYell(taunts[math.random(#taunts)], 0) + end +end + +local function OnDeath(event, creature, killer) + creature:RemoveEvents() + local guid = creature:GetGUIDLow() + + creature:SendUnitYell("Curse... broken... Coldpaw... free...", 0) + + phases[guid] = nil +end + +RegisterCreatureEvent(BOSS_ID, 1, OnCombatStart) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 3, OnKilledTarget) +RegisterCreatureEvent(BOSS_ID, 4, OnDeath) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/NewmansLanding/OverlordRigto.lua b/BOSS Scripts (Lua)/NewmansLanding/OverlordRigto.lua new file mode 100644 index 0000000..493e145 --- /dev/null +++ b/BOSS Scripts (Lua)/NewmansLanding/OverlordRigto.lua @@ -0,0 +1,184 @@ +-------------------------------------------------------------------------------- +-- Overlord Rigto - Delve Boss +-- NPC ID: 600656 +-- Created by: Manmadedrummer | Delve System +-------------------------------------------------------------------------------- +-- DESCRIPTION: +-- Deadwood furbolg overlord - savage bear warrior with physical attacks +-- Uses bear-form abilities, charges, and terrifying roars +-- Enrages at low HP for final burn phase +-- +-- ABILITIES: +-- - Maul: Heavy bear melee attack +-- - Swipe: Frontal cone attack +-- - Lacerate: Bleed DOT +-- - Bash: Stun interrupt +-- - Furious Charge: Charge at distant targets +-- - Terrifying Roar: Fear AOE at 40% HP +-- - Feral Fury: Damage buff +-- - Enrage: Attack speed buff at 20% HP +-- +-- DIFFICULTY: Delve Boss (Solo Fight) +-- LEVEL: 85 +-------------------------------------------------------------------------------- + +print("Delve Boss: Overlord Rigto Loaded") + +local BOSS_ID = 600656 + +-- Spells +local SPELL_MAUL = 15793 -- Heavy bear attack +local SPELL_SWIPE = 31279 -- Frontal cone +local SPELL_LACERATE = 48568 -- Bleed DOT +local SPELL_BASH = 5211 -- Stun interrupt +local SPELL_FURIOUS_CHARGE = 52305 -- Charge ability +local SPELL_TERRIFYING_ROAR = 14100 -- Fear AOE +local SPELL_FERAL_FURY = 48848 -- Damage buff +local SPELL_ENRAGE = 8599 -- Attack speed buff + +-- Configuration +local ROAR_THRESHOLD = 40 +local ENRAGE_THRESHOLD = 20 + +-- GUIDLow-safe phase tracking +local phases = {} + +-- Helper functions +local function GetTank(creature) return creature:GetVictim() end + +-- Core Abilities +local function CastMaul(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_MAUL, true) + end +end + +local function CastSwipe(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + creature:CastSpell(creature, SPELL_SWIPE, true) + creature:SendUnitSay("Feel claws of Rigto!", 0) +end + +local function CastLacerate(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_LACERATE, true) + end +end + +local function CastBash(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_BASH, true) + creature:SendUnitSay("Silence!", 0) + end +end + +local function CastFuriousCharge(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + local distance = creature:GetDistance(victim) + -- Only charge if target is 8-25 yards away + if distance >= 8 and distance <= 25 then + creature:CastSpell(victim, SPELL_FURIOUS_CHARGE, true) + creature:SendUnitYell("Rigto charge!", 0) + end + end +end + +local function CastFeralFury(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + creature:CastSpell(creature, SPELL_FERAL_FURY, true) + creature:SendUnitSay("Power of wild!", 0) +end + +-- Phase Check - Terrifying Roar at 40%, Enrage at 20% +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local guid = creature:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + local hp = creature:GetHealthPct() + + -- Terrifying Roar at 40% HP + if hp <= ROAR_THRESHOLD and not p.roar then + p.roar = true + + creature:SendUnitYell("RIGTO SHOW TRUE FURY!", 0) + creature:CastSpell(creature, SPELL_TERRIFYING_ROAR, true) + end + + -- Enrage at 20% HP + if hp <= ENRAGE_THRESHOLD and not p.enrage then + p.enrage = true + + creature:SendUnitYell("DEADWOOD NEVER FALL!", 0) + creature:CastSpell(creature, SPELL_ENRAGE, true) + end +end + +-- Combat Events +local function OnCombatStart(event, creature, target) + creature:SendUnitYell("You invade Deadwood land! Rigto crush you!", 0) + + local guid = creature:GetGUIDLow() + phases[guid] = {} + + -- Warrior bear rotation + creature:RegisterEvent(CastMaul, 7000, 0) -- Maul every 7s + creature:RegisterEvent(CastSwipe, 10000, 0) -- Swipe every 10s + creature:RegisterEvent(CastLacerate, 12000, 0) -- Lacerate every 12s + creature:RegisterEvent(CastBash, 15000, 0) -- Bash every 15s + creature:RegisterEvent(CastFuriousCharge, 20000, 0) -- Furious Charge every 20s + creature:RegisterEvent(CastFeralFury, 25000, 0) -- Feral Fury every 25s + + -- Phase check + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() + local guid = creature:GetGUIDLow() + + phases[guid] = nil +end + +local function OnKilledTarget(event, creature, victim) + if victim and victim:IsPlayer() then + local taunts = { + "Rigto strongest!", + "Deadwood victorious!", + "Land belong to us!" + } + creature:SendUnitYell(taunts[math.random(#taunts)], 0) + end +end + +local function OnDeath(event, creature, killer) + creature:RemoveEvents() + local guid = creature:GetGUIDLow() + + creature:SendUnitYell("Deadwood... will... remember...", 0) + + phases[guid] = nil +end + +RegisterCreatureEvent(BOSS_ID, 1, OnCombatStart) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 3, OnKilledTarget) +RegisterCreatureEvent(BOSS_ID, 4, OnDeath) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/QIsland/FleetMasterSkaldron.lua b/BOSS Scripts (Lua)/QIsland/FleetMasterSkaldron.lua new file mode 100644 index 0000000..9b750f5 --- /dev/null +++ b/BOSS Scripts (Lua)/QIsland/FleetMasterSkaldron.lua @@ -0,0 +1,154 @@ +-------------------------------------------------------------------------------- +-- Fleet Master Skaldron (Quel'Thalas Island) - Boss 1 +-- NPC ID: 600648 +-------------------------------------------------------------------------------- +print("Quel'Thalas Island Boss 1 - Fleet Master Skaldron Loaded") + +local BOSS_ID = 600648 + +-- Periodic Spells +local HEMORRHAGE = 45897 +local GHOUL_SLASH = 70396 +local DETERMINED_STAB = 55104 +local PIERCING_JAB = 31551 +local FESTERING_RASH = 15848 + +-- Phase Combo Spells +local STORM_PUNCH = 56352 -- Lightning-charged knockback +local SMOKE_BOMB = 7964 -- Visibility drop + +-- Health Thresholds +local TH_75 = 75 +local TH_50 = 50 +local TH_15 = 15 + +-- GUIDLow-safe phase tracking +local phases = {} + +-- Pirate voice lines (thunder & plague edition) +local YELL_75 = { + "Shiver me timbers! Taste the storm I command!", + "I’ll send ye flyin’ with thunder in yer bones!", + "Lightning and steel — yer end comes swift!" +} + +local YELL_50 = { + "The storm descends! Ye'll never see me blade through the fog!", + "Feel the wrath of a thousand tempests!", + "Thunder roars — and so do I!" +} + +local YELL_15 = { + "No quarter! I'll blast ye straight to the Maelstrom!", + "Even Davy Jones fears me thunder!", + "One last storm to sink ye all!" +} + +-- Helper: Storm Punch + Smoke Bomb +local function DoPhaseCombo(creature) + local tank = creature:GetVictim() + if tank then + creature:CastSpell(tank, STORM_PUNCH, true) + end + creature:CastSpell(creature, SMOKE_BOMB, true) +end + +-- NEW: Festering Rash – on pull + every 120 seconds +local function CastFesteringRash(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + creature:CastSpell(creature, FESTERING_RASH, true) -- AoE disease on self = hits raid +end + +-- Periodic abilities +local function CastHemorrhage(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = creature:GetVictim() + if t then creature:CastSpell(t, HEMORRHAGE, true) end +end + +local function CastDeterminedStab(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = creature:GetVictim() + if t then creature:CastSpell(t, DETERMINED_STAB, true) end +end + +local function CastPiercingJab(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = creature:GetVictim() + if t then creature:CastSpell(t, PIERCING_JAB, true) end +end + +local function CastGhoulSlash(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = creature:GetVictim() + if t then creature:CastSpell(t, GHOUL_SLASH, true) end +end + +-- SINGLE ROBUST PHASE CHECKER +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local guid = creature:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + local hp = creature:GetHealthPct() + + if hp <= TH_15 and not p[15] then + p[15] = true + creature:SendUnitYell(YELL_15[math.random(#YELL_15)], 0) + DoPhaseCombo(creature) + creature:RemoveEventById(eventId) + + elseif hp <= TH_50 and not p[50] then + p[50] = true + creature:SendUnitYell(YELL_50[math.random(#YELL_50)], 0) + DoPhaseCombo(creature) + + elseif hp <= TH_75 and not p[75] then + p[75] = true + creature:SendUnitYell(YELL_75[math.random(#YELL_75)], 0) + DoPhaseCombo(creature) + end +end + +-- COMBAT EVENTS +local function OnCombatStart(event, creature, target) + creature:SendUnitYell("Ahoy, landlubbers! Yer souls are forfeit to the deep!", 0) + + local guid = creature:GetGUIDLow() + phases[guid] = {} + + -- Immediate Festering Rash on pull + creature:CastSpell(creature, FESTERING_RASH, true) + + -- Core rotation + creature:RegisterEvent(CastHemorrhage, 7000, 0) -- Replaces Gouge + creature:RegisterEvent(CastDeterminedStab,11000, 0) + creature:RegisterEvent(CastPiercingJab, 15000, 0) + creature:RegisterEvent(CastGhoulSlash, 30000, 0) + + -- Festering Rash every 2 minutes (starts immediately after first cast) + creature:RegisterEvent(CastFesteringRash, 120000, 0) + + -- Phase checker + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() + creature:SendUnitYell("Sail away, cowards! But the Captain's curse follows ye!", 0) + phases[creature:GetGUIDLow()] = nil +end + +local function OnDeath(event, creature, killer) + creature:RemoveEvents() + creature:SendUnitYell("Me gold... me power... gone to the cold sea gods...", 0) + phases[creature:GetGUIDLow()] = nil +end + +RegisterCreatureEvent(BOSS_ID, 1, OnCombatStart) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 4, OnDeath) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/QIsland/Lithianawan.lua b/BOSS Scripts (Lua)/QIsland/Lithianawan.lua new file mode 100644 index 0000000..16ac4e0 --- /dev/null +++ b/BOSS Scripts (Lua)/QIsland/Lithianawan.lua @@ -0,0 +1,141 @@ +-------------------------------------------------------------------------------- +-- Lithianawan (Quel'Thalas Island) - Boss 2 +-- NPC ID: 600649 +-- FINAL: GUIDLow-safe, epic pirate-mage voice lines, no crashes, no phase bleeding +-------------------------------------------------------------------------------- +print("Quel'Thalas Island Boss 2 - Lithianawan Loaded") + +local BOSS_ID = 600649 + +-- Periodic Spells +local VOID_BOLT = 21066 +local SHADOW_BOLT_VOLLEY = 29924 +local IMMOLATE = 75383 + +-- Phase Spells +local FIRE_NOVA = 20203 +local CURSE_OF_THORNS = 16247 +local ANCIENT_CURSE = 60121 +local HELL_FIRE = 39132 + +-- Thresholds +local TH_75 = 75 +local TH_50 = 50 +local TH_35 = 35 +local TH_15 = 15 + +-- GUIDLow-safe phase tracking (same unbreakable pattern as every other boss) +local phases = {} + +-- Epic random yells (she's a sassy sea-witch pirate now) +local CURSE_WARNINGS = { + "Feel the weight of the sea's ancient wrath!", + "Cursed be yer bones and yer gold!", + "The deep remembers every slight!", + "May the tides drag ye down forever!" +} + +local FIRE_WARNINGS = { + "Burn, burn, burn! Only ash remains!", + "I’ll roast ye like fish on a spit!", + "Feel the fury of a thousand suns!" +} + +-- Helper: Curse Combo +local function CastCurseCombo(creature) + local tank = creature:GetVictim() + if tank then + creature:CastSpell(tank, CURSE_OF_THORNS, true) + creature:CastSpell(tank, ANCIENT_CURSE, true) + end +end + +-- SAFE Periodic Abilities +local function CastShadowBoltVolley(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + creature:CastSpell(creature, SHADOW_BOLT_VOLLEY, true) +end + +local function CastImmolate(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local tank = creature:GetVictim() + if tank then creature:CastSpell(tank, IMMOLATE, true) end +end + +local function CastVoidBolt(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local tank = creature:GetVictim() + if tank then creature:CastSpell(tank, VOID_BOLT, true) end +end + +-- PHASE CHECKER – 100% GUIDLow safe +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local guid = creature:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + local hp = creature:GetHealthPct() + + if hp <= TH_15 and not p[15] then + p[15] = true + creature:SendUnitYell("Ye cannot stop the dark magic of the deep!", 0) + creature:SendUnitYell(CURSE_WARNINGS[math.random(#CURSE_WARNINGS)], 0) + CastCurseCombo(creature) + creature:CastSpell(creature, FIRE_NOVA, true) + creature:RemoveEventById(eventId) -- final phase + + elseif hp <= TH_35 and not p[35] then + p[35] = true + creature:SendUnitYell("Feel the shadows twist your luck, fools!", 0) + creature:SendUnitYell(CURSE_WARNINGS[math.random(#CURSE_WARNINGS)], 0) + CastCurseCombo(creature) + + elseif hp <= TH_50 and not p[50] then + p[50] = true + creature:SendUnitYell("Prepare to be blasted back to the nearest port!", 0) + creature:SendUnitYell(CURSE_WARNINGS[math.random(#CURSE_WARNINGS)], 0) + CastCurseCombo(creature) + creature:CastSpell(creature, FIRE_NOVA, true) + + elseif hp <= TH_75 and not p[75] then + p[75] = true + creature:SendUnitYell("Your courage is cursed, land-rats!", 0) + creature:SendUnitYell(CURSE_WARNINGS[math.random(#CURSE_WARNINGS)], 0) + CastCurseCombo(creature) + creature:SendUnitYell(FIRE_WARNINGS[math.random(#FIRE_WARNINGS)], 0) + creature:CastSpell(creature, HELL_FIRE, true) + end +end + +-- COMBAT EVENTS +local function OnCombatStart(event, creature, target) + creature:SendUnitYell("I'll sink your hopes faster than a leaky barrel!", 0) + + local guid = creature:GetGUIDLow() + phases[guid] = {} + + creature:RegisterEvent(CastShadowBoltVolley, 8000, 0) + creature:RegisterEvent(CastImmolate, 12000, 0) + creature:RegisterEvent(CastVoidBolt, 25000, 0) + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() -- Always first + creature:SendUnitYell("This fight ain't worth a single copper piece!", 0) + phases[creature:GetGUIDLow()] = nil +end + +local function OnDeath(event, creature, killer) + creature:RemoveEvents() -- Always first + creature:SendUnitYell("The spell... is broken...", 0) + phases[creature:GetGUIDLow()] = nil +end + +RegisterCreatureEvent(BOSS_ID, 1, OnCombatStart) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 4, OnDeath) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/Sandfury/ChiefRunetusk.lua b/BOSS Scripts (Lua)/Sandfury/ChiefRunetusk.lua new file mode 100644 index 0000000..c002a1d --- /dev/null +++ b/BOSS Scripts (Lua)/Sandfury/ChiefRunetusk.lua @@ -0,0 +1,168 @@ +-------------------------------------------------------------------------------- +-- Chief Runetusk (Sandfury Delve Boss 1) +-- NPC ID: 600623 +-- Matches all your other boss templates perfectly +-------------------------------------------------------------------------------- +print("Sandfury Delve Boss 1 - Chief Runetusk Loaded") + +local BOSS_ID = 600623 + +-- Spells +local SPELL_HAMMER_OF_JUSTICE = 72266 +local SPELL_SHADOW_BOLT = 31022 +local SPELL_CLEAVE = 47520 +local SPELL_METEOR = 75948 +local SPELL_SUNDER_ARMOR = 7386 +local SPELL_THUNDERCLAP = 39595 +local SPELL_EARTH_SHOCK = 50581 +local SPELL_POISON_BOLT = 50522 +local SPELL_DEMON_ARMOR = 47889 +local SPELL_WHIRLWIND = 36132 +local SPELL_FEL_FLAME = 36040 +local SPELL_ENRAGE = 12686 + +-- Thresholds +local TH_90 = 90 +local TH_75 = 75 +local TH_50 = 50 +local TH_10 = 10 + +-- Global phase tracking (same as all your other bosses) +local phases = {} + +-- Target helpers +local function GetTank(creature) return creature:GetVictim() end +local function GetRandomPlayer(creature) return creature:GetAITarget(0, true) end + +-- Core abilities +local function CastHammer(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = GetTank(creature) + if t then creature:CastSpell(t, SPELL_HAMMER_OF_JUSTICE, true) end +end + +local function CastShadowBolt(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = GetTank(creature) + if t then creature:CastSpell(t, SPELL_SHADOW_BOLT, true) end +end + +local function CastCleave(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = GetTank(creature) + if t then creature:CastSpell(t, SPELL_CLEAVE, true) end +end + +local function CastMeteor(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = GetRandomPlayer(creature) + if t then creature:CastSpell(t, SPELL_METEOR, true) end +end + +local function CastSunder(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = GetTank(creature) + if t then creature:CastSpell(t, SPELL_SUNDER_ARMOR, true) end +end + +local function CastThunderclap(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + creature:CastSpell(creature, SPELL_THUNDERCLAP, true) +end + +local function CastEarthShock(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = GetTank(creature) + if t then creature:CastSpell(t, SPELL_EARTH_SHOCK, true) end +end + +local function CastPoisonBolt(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = GetRandomPlayer(creature) + if t then creature:CastSpell(t, SPELL_POISON_BOLT, true) end +end + +local function CastWhirlwind(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + creature:SendUnitYell("I carve da sand beneath ya feet!", 0) + creature:CastSpell(creature, SPELL_WHIRLWIND, true) +end + +local function CastFelFlame(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = GetRandomPlayer(creature) + if t then + creature:SendUnitYell("Da sand gonna burn!", 0) + creature:CastSpell(t, SPELL_FEL_FLAME, true) + end +end + +-- SINGLE PHASE CHECKER (exact same style as all your other bosses) +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local hp = creature:GetHealthPct() + + if hp <= TH_10 and not phases[10] then + phases[10] = true + creature:SendUnitYell("YA MESSED WIT DA WRONG CHIEFTAIN! FEEL MY TRUE RAGE!", 0) + creature:SetScale(2.5) + creature:CastSpell(creature, SPELL_ENRAGE, true) + creature:RemoveEventById(eventId) + + elseif hp <= TH_50 and not phases[50] then + phases[50] = true + creature:SendUnitYell("Let dat Fel fire cleanse dis place!", 0) + creature:RegisterEvent(CastFelFlame, 25000, 0) + CastFelFlame(0,0,0,creature) -- immediate + creature:RegisterEvent(CastPoisonBolt, 10000, 0) + + elseif hp <= TH_75 and not phases[75] then + phases[75] = true + creature:SendUnitYell("Get caught in da whirlwind, outsiders!", 0) + creature:RegisterEvent(CastWhirlwind, 30000, 0) + creature:CastSpell(creature, SPELL_WHIRLWIND, true) + creature:RegisterEvent(CastThunderclap, 15000, 0) + creature:RegisterEvent(CastEarthShock, 8000, 0) + + elseif hp <= TH_90 and not phases[90] then + phases[90] = true + creature:SendUnitYell("Ya weak! My demon armor too strong! Ya armor gonna break, mon!", 0) + creature:CastSpell(creature, SPELL_DEMON_ARMOR, true) + creature:RegisterEvent(CastMeteor, 20000, 0) + creature:RegisterEvent(CastSunder, 12000, 0) + end +end + +-- Combat Events +local function OnCombatStart(event, creature, target) + creature:SendUnitYell("Da Sandfury Delve is mine! Come, mon, and get butchered!", 0) + + phases = {} + + creature:RegisterEvent(CastHammer, 14000, 0) + creature:RegisterEvent(CastShadowBolt, 8000, 0) + creature:RegisterEvent(CastCleave, 10000, 0) + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:SendUnitYell("Run, cowards!", 0) + creature:RemoveEvents() + creature:SetScale(1.0) + phases = {} +end + +local function OnDeath(event, creature, killer) + creature:RemoveEvents() + creature:SendUnitYell("Ahhh... dis sand... she claims me... but ya next, mon! YA NEXT!", 0) + creature:SetScale(1.0) + phases = {} +end + +RegisterCreatureEvent(BOSS_ID, 1, OnCombatStart) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 4, OnDeath) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/Sandfury/SouseSanRhazo.lua b/BOSS Scripts (Lua)/Sandfury/SouseSanRhazo.lua new file mode 100644 index 0000000..01996fb --- /dev/null +++ b/BOSS Scripts (Lua)/Sandfury/SouseSanRhazo.lua @@ -0,0 +1,114 @@ +-------------------------------------------------------------------------------- +-- Souse San Rhazon (Sandfury Delve Boss) +-- NPC ID: 600621 +-------------------------------------------------------------------------------- +print("Sandfury Delve Boss - Souse San Rhazon Loaded") + +local BOSS_ID = 600621 + +-- Periodic Spells +local SPELL_PLAGUE_STRIKE = 50688 +local SPELL_JUMP_ATTACK = 61227 -- Leap to farthest +local SPELL_COLOSSAL_STRIKE = 50978 + +-- Phase Spells - DISEASE CLOUD REPLACES DISEASE BURST +local SPELL_DISEASE_CLOUD = 50106 -- Nasty persistent AoE plague cloud +local SPELL_ELECTRO_SHOCK = 64918 +local SPELL_ELEMENTAL_ARMOR = 29718 +local SPELL_EYE_BEAM = 59965 + +-- Thresholds +local TH_75 = 75 +local TH_50 = 50 +local TH_15 = 15 + +-- Global phase tracking (safe) +local phases = {} + +-- Target helpers +local function GetTank(creature) return creature:GetVictim() end +local function GetFarthestPlayer(creature) + local target = creature:GetAITarget(4, true) -- FARTHEST + return target or creature:GetAITarget(0, true) +end + +-- Core abilities +local function CastPlagueStrike(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = GetTank(creature) + if t then creature:CastSpell(t, SPELL_PLAGUE_STRIKE, true) end +end + +local function CastColossalStrike(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local t = GetTank(creature) + if t then creature:CastSpell(t, SPELL_COLOSSAL_STRIKE, true) end +end + +local function CastJumpAttack(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local target = GetFarthestPlayer(creature) + if target then + creature:CastSpell(target, SPELL_JUMP_ATTACK, true) + end +end + +-- PHASE CHECKER - NOW SPREADS DISEASE CLOUD LIKE A TRUE PLAGUE TROLL +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local hp = creature:GetHealthPct() + + if hp <= TH_15 and not phases[15] then + phases[15] = true + creature:SendUnitYell("YA DONE ANGERED DA SANDFURY, MON! CHOKE ON DA PLAGUE!", 0) + creature:CastSpell(creature, SPELL_DISEASE_CLOUD, true) -- Cloud 1 + creature:CastSpell(GetTank(creature), SPELL_ELECTRO_SHOCK, true) + creature:CastSpell(creature, SPELL_ELEMENTAL_ARMOR, true) + creature:CastSpell(GetTank(creature), SPELL_EYE_BEAM, true) + creature:RemoveEventById(eventId) + + elseif hp <= TH_50 and not phases[50] then + phases[50] = true + creature:SendUnitYell("Da air itself be poisoned now, mon! Breathe deep!", 0) + creature:CastSpell(creature, SPELL_DISEASE_CLOUD, true) -- Cloud 2 + creature:CastSpell(creature, SPELL_ELEMENTAL_ARMOR, true) + + elseif hp <= TH_75 and not phases[75] then + phases[75] = true + creature:SendUnitYell("Feel da sickness spread, mon! Ya lungs gonna burn!", 0) + creature:CastSpell(creature, SPELL_DISEASE_CLOUD, true) -- Cloud 3 + creature:CastSpell(GetTank(creature), SPELL_ELECTRO_SHOCK, true) + end +end + +-- Combat Events +local function OnCombatStart(event, creature, target) + creature:SendUnitYell("YA DARE STEP INTO SOUSE SAN RHAZON'S DELVE? YA GONNA REGRET DIS, MON!", 0) + + phases = {} + + creature:RegisterEvent(CastPlagueStrike, 10000, 0) + creature:RegisterEvent(CastJumpAttack, 15000, 0) + creature:RegisterEvent(CastColossalStrike, 30000, 0) + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:SendUnitYell("Run away, little softskins! Dis troll be too much for ya!", 0) + creature:RemoveEvents() + phases = {} +end + +local function OnDeath(event, creature, killer) + creature:RemoveEvents() + creature:SendUnitYell("Ughhh... da sand... she take me now... da plague... live on...", 0) + phases = {} +end + +RegisterCreatureEvent(BOSS_ID, 1, OnCombatStart) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 4, OnDeath) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/Sandfury/Xantosh.lua b/BOSS Scripts (Lua)/Sandfury/Xantosh.lua new file mode 100644 index 0000000..872522b --- /dev/null +++ b/BOSS Scripts (Lua)/Sandfury/Xantosh.lua @@ -0,0 +1,130 @@ +-------------------------------------------------------------------------------- +-- Xan'tosh (Sandfury Delve Boss 2) - DOUBLE UNDEAD SCARABS (17235 x2) +-- NPC ID: 600622 +-------------------------------------------------------------------------------- +print("Sandfury Delve Boss 2 - Xan'tosh Loaded") + +local BOSS_ID = 600622 + +local HP_PHASE_2 = 90 +local HP_PHASE_3 = 70 +local HP_PHASE_4 = 30 + +-- Core spells +local SPELL_PLAGUE_STRIKE = 55255 +local SPELL_DARK_SMASH = 42723 +local SPELL_SAND_BREATH = 39049 +local SPELL_SAND_STORM = 10092 + +-- Phase abilities +local SPELL_DEMON_ARMOR = 34881 +local SPELL_VOODOO_FLAMES = 54795 +local SPELL_HEX_OF_MENDING = 67534 +local SPELL_HEX_RAVENCLAW = 7655 +local SPELL_CRYPT_SCARABS = 54313 -- Visual swarm +local SPELL_RAISE_SCARAB = 17235 -- Raise Undead Scarab (x2!) +local SPELL_BLOOD_DRAIN = 41238 + +-- Per-fight phase tracking +local phases = {} + +local function GetTank(creature) return creature:GetAITarget(1, true) end +local function GetRandomPlayer(creature) return creature:GetAITarget(0, true) end + +-- Hex Combo every 30s +local function CastHexCombo(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local target = GetRandomPlayer(creature) + if target then + creature:SendUnitYell("Feel da Sandfury Hex, mon!", 0) + creature:CastSpell(target, SPELL_HEX_OF_MENDING, true) + creature:CastSpell(target, SPELL_HEX_RAVENCLAW, true) + end +end + +-- Blood Drain +local function CastBloodDrain(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + local target = GetRandomPlayer(creature) + if target then creature:CastSpell(target, SPELL_BLOOD_DRAIN, true) end +end + +-- Sand Storm (phase 4+) +local function CastSandStorm(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + creature:CastSpell(creature, SPELL_SAND_STORM, true) +end + +-- Summon 2x Undead Scarabs + visual swarm +local function SummonDoubleScarabs(creature) + creature:CastSpell(creature, SPELL_CRYPT_SCARABS, true) -- visual swarm effect + creature:CastSpell(creature, SPELL_RAISE_SCARAB, true) -- 1st scarab + creature:CastSpell(creature, SPELL_RAISE_SCARAB, true) -- 2nd scarab (instant) +end + +-- SINGLE PHASE CHECKER +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local hp = creature:GetHealthPct() + + if hp <= HP_PHASE_4 and not phases[4] then + phases[4] = true + creature:SendUnitYell("Xan'tosh's power unmatched! Ya finished, little insects!", 0) + SummonDoubleScarabs(creature) -- 2 scarabs + swarm + creature:RegisterEvent(CastSandStorm, 30000, 0) + + elseif hp <= HP_PHASE_3 and not phases[3] then + phases[3] = true + creature:SendUnitYell("Ya blood feeds me now! Taste da drain!", 0) + CastBloodDrain(0,0,0,creature) + + elseif hp <= HP_PHASE_2 and not phases[2] then + phases[2] = true + creature:SendUnitYell("Da ancient gods stir beneath da sand... RISE, MY CHILDREN!", 0) + creature:CastSpell(creature, SPELL_DEMON_ARMOR, true) + creature:CastSpell(creature, SPELL_VOODOO_FLAMES, true) + SummonDoubleScarabs(creature) -- 2 scarabs + swarm + end +end + +-- Combat Start +local function OnEnterCombat(event, creature, target) + creature:SendUnitYell("Da plague an' da sand gonna swallow ya whole, mon!", 0) + phases = {} + + creature:RegisterEvent(function(_,_,_,c) + if c:IsInCombat() then local t = GetTank(c); if t then c:CastSpell(t, SPELL_PLAGUE_STRIKE, true) end end + end, math.random(8000,10000), 0) + + creature:RegisterEvent(function(_,_,_,c) + if c:IsInCombat() then local t = GetTank(c); if t then c:CastSpell(t, SPELL_SAND_BREATH, true) end end + end, math.random(12000,15000), 0) + + creature:RegisterEvent(function(_,_,_,c) + if c:IsInCombat() then local t = GetTank(c); if t then c:CastSpell(t, SPELL_DARK_SMASH, true) end end + end, 18000, 0) + + creature:RegisterEvent(CastHexCombo, 30000, 0) + creature:RegisterEvent(CastBloodDrain, 20000, 0) + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:SendUnitYell("Da rot claims another day...", 0) + creature:RemoveEvents() + phases = {} +end + +local function OnDied(event, creature, killer) + creature:RemoveEvents() + creature:SendUnitYell("Da rot... it finally takes me... but da curse lives on...", 0) + phases = {} +end + +RegisterCreatureEvent(BOSS_ID, 1, OnEnterCombat) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 4, OnDied) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/StonetalonLoggingCamp/OverlordMoosh.lua b/BOSS Scripts (Lua)/StonetalonLoggingCamp/OverlordMoosh.lua new file mode 100644 index 0000000..101fd75 --- /dev/null +++ b/BOSS Scripts (Lua)/StonetalonLoggingCamp/OverlordMoosh.lua @@ -0,0 +1,222 @@ +-------------------------------------------------------------------------------- +-- Overlord Moosh - Delve Boss +-- NPC ID: 600702 +-- Created by: Manmadedrummer | Delve System +-------------------------------------------------------------------------------- +-- DESCRIPTION: +-- Venture Co. goblin overlord - engineer/support who buffs partner Snivey +-- When both bosses are alive, Moosh buffs Snivey with Nitro Boots +-- When Snivey dies, Moosh enrages and gains Berserker Charge +-- +-- PHASE 1 (Both Alive): Rocket Launch, Goblin Dragon Gun, Fuse Armor, Static Conduit, buffs Snivey +-- PHASE 2 (Snivey Dead): Enrages, gains Berserker Charge from Snivey +-- +-- ABILITIES: +-- - Rocket Launch: Ranged rocket attack +-- - Nitro Boots: Buffs Snivey with increased movement/attack speed +-- - Goblin Dragon Gun: Flame breath cone attack +-- - Fuse Armor: Debuff that reduces armor +-- - Static Conduit: Silences/interrupts target +-- - Bloodlust: Haste buff on self +-- - Berserker Charge: Gains from Snivey on death (Phase 2) +-- +-- DIFFICULTY: Delve Boss (Dual Fight) +-- LEVEL: 85 +-------------------------------------------------------------------------------- + +print("Delve Boss: Overlord Moosh Loaded") + +local BOSS_ID = 600702 +local PARTNER_ID = 600701 -- Overlord Snivey + +-- Spells +local SPELL_ROCKET_LAUNCH = 71590 -- Ranged rocket attack +local SPELL_NITRO_BOOTS = 54861 -- Buff for Snivey +local SPELL_GOBLIN_DRAGON_GUN = 44273 -- Flame cone +local SPELL_FUSE_ARMOR = 64771 -- Armor reduction debuff +local SPELL_STATIC_CONDUIT = 20542 -- Silence/interrupt +local SPELL_BLOODLUST = 2825 -- Haste self-buff +local SPELL_BERSERK = 26662 -- Enrage on Snivey death +local SPELL_BERSERKER_CHARGE = 36833 -- Gained from Snivey on death + +-- Configuration +local BUFF_CHECK_INTERVAL = 10000 -- Check to buff Snivey every 10s + +-- GUIDLow-safe phase tracking +local phases = {} + +-- Helper functions +local function GetTank(creature) return creature:GetVictim() end + +local function GetPartner(creature) + local nearbyCreatures = creature:GetCreaturesInRange(100, PARTNER_ID) + if nearbyCreatures and #nearbyCreatures > 0 then + return nearbyCreatures[1] + end + return nil +end + +local function IsPartnerAlive(creature) + local partner = GetPartner(creature) + return partner and partner:IsAlive() +end + +-- Phase 1 Abilities (Both Alive) +local function CastRocketLaunch(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_ROCKET_LAUNCH, true) + end +end + +local function CastGoblinDragonGun(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_GOBLIN_DRAGON_GUN, false) + creature:SendUnitYell("Taste my dragon gun!", 0) + end +end + +local function CastFuseArmor(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_FUSE_ARMOR, true) + creature:SendUnitSay("Melting your armor down!", 0) + end +end + +local function CastStaticConduit(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_STATIC_CONDUIT, true) + creature:SendUnitSay("EMP!", 0) + end +end + +local function CastBloodlust(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + creature:CastSpell(creature, SPELL_BLOODLUST, true) + creature:SendUnitSay("Engineering power!", 0) +end + +-- Synergy Ability - Buff Snivey +local function BuffSnivey(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + -- Only buff if Snivey is alive + if IsPartnerAlive(creature) then + local partner = GetPartner(creature) + if partner then + creature:CastSpell(partner, SPELL_NITRO_BOOTS, true) + creature:SendUnitSay("Nitro boost, Snivey!", 0) + end + end +end + +-- Phase 2 Ability (Snivey Dead) +local function CastBerserkerCharge(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + local distance = creature:GetDistance(victim) + -- Only charge if target is 8-25 yards away + if distance >= 8 and distance <= 25 then + creature:CastSpell(victim, SPELL_BERSERKER_CHARGE, true) + creature:SendUnitSay("I'll finish what Snivey started!", 0) + end + end +end + +-- Phase Check - Detect Snivey Death +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local guid = creature:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + + -- Check if Snivey died + if not IsPartnerAlive(creature) and not p.enraged then + p.enraged = true + + creature:SendUnitYell("SNIVEY! I'll make 'em pay!", 0) + + -- Remove Phase 1 events + creature:RemoveEvents() + + -- Apply Berserk + creature:CastSpell(creature, SPELL_BERSERK, true) + + -- Phase 2 abilities (enraged + gained Berserker Charge) + creature:RegisterEvent(CastRocketLaunch, 8000, 0) + creature:RegisterEvent(CastGoblinDragonGun, 12000, 0) + creature:RegisterEvent(CastFuseArmor, 15000, 0) + creature:RegisterEvent(CastStaticConduit, 10000, 0) + creature:RegisterEvent(CastBerserkerCharge, 15000, 0) -- Gained from Snivey + creature:RegisterEvent(PhaseCheck, 1000, 0) + end +end + +-- Combat Events +local function OnCombatStart(event, creature, target) + creature:SendUnitYell("Engineering beats magic every time!", 0) + + local guid = creature:GetGUIDLow() + phases[guid] = {} + + -- Phase 1 rotation (both alive) + creature:RegisterEvent(CastRocketLaunch, 10000, 0) -- Rocket every 10s + creature:RegisterEvent(CastGoblinDragonGun, 15000, 0) -- Dragon Gun every 15s + creature:RegisterEvent(CastFuseArmor, 20000, 0) -- Fuse Armor every 20s + creature:RegisterEvent(CastStaticConduit, 12000, 0) -- Static Conduit every 12s + creature:RegisterEvent(CastBloodlust, 30000, 0) -- Bloodlust every 30s + creature:RegisterEvent(BuffSnivey, BUFF_CHECK_INTERVAL, 0) -- Buff Snivey every 10s + + -- Phase check + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() + local guid = creature:GetGUIDLow() + + phases[guid] = nil +end + +local function OnKilledTarget(event, creature, victim) + if victim and victim:IsPlayer() then + local taunts = { + "Venture Co. technology wins!", + "That's goblin engineering!", + "Should've brought better gear!" + } + creature:SendUnitYell(taunts[math.random(#taunts)], 0) + end +end + +local function OnDeath(event, creature, killer) + creature:RemoveEvents() + local guid = creature:GetGUIDLow() + + creature:SendUnitYell("My machines... failed me...", 0) + + phases[guid] = nil +end + +RegisterCreatureEvent(BOSS_ID, 1, OnCombatStart) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 3, OnKilledTarget) +RegisterCreatureEvent(BOSS_ID, 4, OnDeath) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/StonetalonLoggingCamp/OverlordSnivey.lua b/BOSS Scripts (Lua)/StonetalonLoggingCamp/OverlordSnivey.lua new file mode 100644 index 0000000..4f2e1f3 --- /dev/null +++ b/BOSS Scripts (Lua)/StonetalonLoggingCamp/OverlordSnivey.lua @@ -0,0 +1,209 @@ +-------------------------------------------------------------------------------- +-- Overlord Snivey - Delve Boss +-- NPC ID: 600701 +-- Created by: Manmadedrummer | Delve System +-------------------------------------------------------------------------------- +-- DESCRIPTION: +-- Venture Co. goblin overlord - melee bruiser who protects his partner Moosh +-- When both bosses are alive, Snivey intervenes to protect Moosh +-- When Moosh dies, Snivey enrages and gains Rocket Launch +-- +-- PHASE 1 (Both Alive): Berserker Charge, Mortal Strike, Goblin Bomb, Recklessness +-- PHASE 2 (Moosh Dead): Enrages, gains Rocket Launch from Moosh +-- +-- ABILITIES: +-- - Berserker Charge: Charges at distant targets +-- - Mortal Strike: Heavy hit that reduces healing +-- - Goblin Bomb: Throws bomb at nearby enemies (AOE) +-- - Recklessness: Self-buff for increased damage +-- - Intervene: Protects Moosh when she's attacked +-- - Berserk: Enrage when Moosh dies +-- - Rocket Launch: Gains from Moosh on death (Phase 2) +-- +-- DIFFICULTY: Delve Boss (Dual Fight) +-- LEVEL: 85 +-------------------------------------------------------------------------------- + +print("Delve Boss: Overlord Snivey Loaded") + +local BOSS_ID = 600701 +local PARTNER_ID = 600702 -- Overlord Moosh + +-- Spells +local SPELL_BERSERKER_CHARGE = 36833 -- Charge at distant targets +local SPELL_MORTAL_STRIKE = 32736 -- Heavy hit, reduces healing +local SPELL_GOBLIN_BOMB = 23134 -- AOE bomb throw +local SPELL_RECKLESSNESS = 13847 -- Damage boost self-buff +local SPELL_INTERVENE = 34784 -- Protect Moosh +local SPELL_BERSERK = 26662 -- Enrage on Moosh death +local SPELL_ROCKET_LAUNCH = 71590 -- Gained from Moosh on death + +-- Configuration +local ENRAGE_THRESHOLD = 30 -- Enrage if partner dies + +-- GUIDLow-safe phase tracking +local phases = {} + +-- Helper functions +local function GetTank(creature) return creature:GetVictim() end + +local function GetPartner(creature) + local nearbyCreatures = creature:GetCreaturesInRange(100, PARTNER_ID) + if nearbyCreatures and #nearbyCreatures > 0 then + return nearbyCreatures[1] + end + return nil +end + +local function IsPartnerAlive(creature) + local partner = GetPartner(creature) + return partner and partner:IsAlive() +end + +-- Phase 1 Abilities (Both Alive) +local function CastBerserkerCharge(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + local distance = creature:GetDistance(victim) + -- Only charge if target is 8-25 yards away + if distance >= 8 and distance <= 25 then + creature:CastSpell(victim, SPELL_BERSERKER_CHARGE, true) + creature:SendUnitSay("Get over here!", 0) + end + end +end + +local function CastMortalStrike(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_MORTAL_STRIKE, true) + end +end + +local function CastGoblinBomb(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + creature:CastSpell(creature, SPELL_GOBLIN_BOMB, true) + creature:SendUnitYell("Bombs away!", 0) +end + +local function CastRecklessness(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + creature:CastSpell(creature, SPELL_RECKLESSNESS, true) + creature:SendUnitSay("Time to get serious!", 0) +end + +-- Synergy Ability - Protect Moosh +local function ProtectMoosh(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + -- Only intervene if Moosh is alive + if IsPartnerAlive(creature) then + local partner = GetPartner(creature) + if partner and partner:IsInCombat() then + local mooshTarget = partner:GetVictim() + if mooshTarget then + -- Intervene to protect Moosh + creature:CastSpell(partner, SPELL_INTERVENE, true) + creature:SendUnitSay("I got your back, Moosh!", 0) + end + end + end +end + +-- Phase 2 Ability (Moosh Dead) +local function CastRocketLaunch(eventId, delay, calls, creature) + if not creature:IsInCombat() then return end + + local victim = GetTank(creature) + if victim then + creature:CastSpell(victim, SPELL_ROCKET_LAUNCH, true) + end +end + +-- Phase Check - Detect Moosh Death +local function PhaseCheck(eventId, delay, calls, creature) + if not creature:IsInCombat() or creature:IsDead() then + creature:RemoveEventById(eventId) + return + end + + local guid = creature:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + + -- Check if Moosh died + if not IsPartnerAlive(creature) and not p.enraged then + p.enraged = true + + creature:SendUnitYell("MOOSH! You'll pay for that!", 0) + + -- Remove Phase 1 events + creature:RemoveEvents() + + -- Apply Berserk + creature:CastSpell(creature, SPELL_BERSERK, true) + + -- Phase 2 abilities (enraged + gained Rocket Launch) + creature:RegisterEvent(CastBerserkerCharge, 12000, 0) + creature:RegisterEvent(CastMortalStrike, 8000, 0) + creature:RegisterEvent(CastGoblinBomb, 15000, 0) + creature:RegisterEvent(CastRocketLaunch, 10000, 0) -- Gained from Moosh + creature:RegisterEvent(PhaseCheck, 1000, 0) + end +end + +-- Combat Events +local function OnCombatStart(event, creature, target) + creature:SendUnitYell("Time to work! Venture Co. don't take no breaks!", 0) + + local guid = creature:GetGUIDLow() + phases[guid] = {} + + -- Phase 1 rotation (both alive) + creature:RegisterEvent(CastBerserkerCharge, 15000, 0) -- Charge every 15s + creature:RegisterEvent(CastMortalStrike, 10000, 0) -- Mortal Strike every 10s + creature:RegisterEvent(CastGoblinBomb, 20000, 0) -- Goblin Bomb every 20s + creature:RegisterEvent(CastRecklessness, 30000, 0) -- Recklessness every 30s + creature:RegisterEvent(ProtectMoosh, 5000, 0) -- Check to protect Moosh every 5s + + -- Phase check + creature:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnLeaveCombat(event, creature) + creature:RemoveEvents() + local guid = creature:GetGUIDLow() + + phases[guid] = nil +end + +local function OnKilledTarget(event, creature, victim) + if victim and victim:IsPlayer() then + local taunts = { + "That's what you get!", + "Venture Co. wins again!", + "Should've stayed outta our camp!" + } + creature:SendUnitYell(taunts[math.random(#taunts)], 0) + end +end + +local function OnDeath(event, creature, killer) + creature:RemoveEvents() + local guid = creature:GetGUIDLow() + + creature:SendUnitYell("Boss ain't gonna like this...", 0) + + phases[guid] = nil +end + +RegisterCreatureEvent(BOSS_ID, 1, OnCombatStart) +RegisterCreatureEvent(BOSS_ID, 2, OnLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 3, OnKilledTarget) +RegisterCreatureEvent(BOSS_ID, 4, OnDeath) \ No newline at end of file diff --git a/BOSS Scripts (Lua)/StonetalonRuins/ForemanGlitzbolt.lua b/BOSS Scripts (Lua)/StonetalonRuins/ForemanGlitzbolt.lua new file mode 100644 index 0000000..f983958 --- /dev/null +++ b/BOSS Scripts (Lua)/StonetalonRuins/ForemanGlitzbolt.lua @@ -0,0 +1,328 @@ +-------------------------------------------------------------------------------- +-- Foreman Glitzbolt - Explosive Wagon Boss Fight (RETAIL STYLE) +-- NPC ID: 600664 (Boss) +-- Created by: Manmadedrummer | Delve System +-------------------------------------------------------------------------------- +-- SETUP REQUIRED: +-- 1. Spawn Foreman Glitzbolt (600664) near explosive wagon +-- 2. Spawn Explosive Wagon (GO 184700) - this will EXPLODE on boss death! +-- 3. Spawn any Venture Co. NPCs you want around the area (they handle their own AI) +-- +-- IDLE BEHAVIOR (Before Combat): +-- Foreman says random lines every 5 seconds: +-- - "Be careful with that merchandise!" +-- - "Hurry up! We needed this out yesterday!" +-- - "These explosives won't load themselves!" +-- - "The boss is gonna have my head if this shipment is late!" +-- - "Watch it! One spark and we're all dead!" +-- - "Move it! Time is money, friend!" +-- +-- BOSS MECHANICS (Retail Style): +-- - Goblin Bomb: Random player targeted bomb +-- - Dagger Throw: Ranged attack +-- - Dragon Gun: Flame cone +-- - Rocket Boots: Mobility +-- - Lay on Hands: Self-heal at 60% +-- - Nitro Boost: 30% enrage phase +-- - AIR SUPPORT: Every 30 seconds calls in TWO Incendiary Rockets (napalm) +-- Rockets create fire zones that deal 1500 DPS for 15 seconds - MUST DODGE! +-- +-- DEATH SEQUENCE: +-- Boss dies → "You think you won?!" (ZONE-WIDE YELL) (2s) → +-- "Yippee-ki-yay, mother f--" (CHAT BUBBLE - everyone sees it above his head) → +-- MASSIVE EXPLOSION: +-- - Beryl Shield Explosion (45796) - main damage blast +-- - Fire Bomb (67473) - fire visual effect +-- - Explosion Visual (71495) - flame crash visual +-- - Camera Shake Tremor (69235) - screen shake +-- → Wagon despawns, any NPCs within 25 yards are vaporized, boss body destroyed +-------------------------------------------------------------------------------- + +print("========================================") +print("Foreman Glitzbolt: EXPLOSIVE Boss Fight") +print("KAMIKAZE DEATH SEQUENCE ENABLED") +print("Wagon GO 184700 will EXPLODE on death!") +print("========================================") + +local BOSS_ID = 600664 + +-- Spells (Boss) +local SPELL_GOBLIN_BOMB = 23134 +local SPELL_DAGGER_THROW = 67280 +local SPELL_GOBLIN_DRAGON_GUN = 44273 +local SPELL_LAY_ON_HANDS = 9257 +local SPELL_ROCKET_BOOTS = 8892 +local SPELL_NITRO_BOOST = 54861 +local SPELL_INCENDIARY_ROCKET = 67456 -- Air Support napalm strike + +-- Explosion Spells (Death) +local SPELL_BERYL_EXPLOSION = 45796 -- Main damage +local SPELL_FIRE_BOMB = 67473 -- Fire visual +local SPELL_EXPLOSION_VISUAL = 71495 -- Flame crash +local SPELL_CAMERA_SHAKE = 69235 -- Tremor + +-- Configuration +local NITRO_THRESHOLD = 30 +local EXPLOSION_RADIUS = 25 -- Kills NPCs within this range +local AIR_SUPPORT_INTERVAL = 30000 -- 30 seconds between air strikes + +-- Boss phases tracking +local phases = {} + +-- Idle speech lines (before combat) +local IDLE_SPEECHES = { + "Be careful with that merchandise!", + "Hurry up! We needed this out yesterday!", + "These explosives won't load themselves!", + "The boss is gonna have my head if this shipment is late!", + "Watch it! One spark and we're all dead!", + "Move it! Time is money, friend!" +} + +-- Idle speech state tracking +local idleSpeechActive = {} + +-------------------------------------------------------------------------------- +-- BOSS ABILITIES +-------------------------------------------------------------------------------- + +local function CastGoblinBomb(eventId, delay, calls, boss) + if not boss:IsInCombat() then return end + local victim = boss:GetVictim() + if victim then + boss:CastSpell(victim, SPELL_GOBLIN_BOMB, true) + boss:SendUnitSay("Take this!", 0) + end +end + +local function CastDaggerThrow(eventId, delay, calls, boss) + if not boss:IsInCombat() then return end + local victim = boss:GetVictim() + if victim then + local distance = boss:GetDistance(victim) + if distance > 5 then + boss:CastSpell(victim, SPELL_DAGGER_THROW, false) + end + end +end + +local function CastGoblinDragonGun(eventId, delay, calls, boss) + if not boss:IsInCombat() then return end + local victim = boss:GetVictim() + if victim then + boss:CastSpell(victim, SPELL_GOBLIN_DRAGON_GUN, false) + boss:SendUnitYell("Burn!", 0) + end +end + +local function CastLayOnHands(eventId, delay, calls, boss) + if not boss:IsInCombat() then return end + if boss:GetHealthPct() < 60 then + boss:CastSpell(boss, SPELL_LAY_ON_HANDS, false) + boss:SendUnitSay("Not done yet!", 0) + end +end + +local function CastRocketBoots(eventId, delay, calls, boss) + if not boss:IsInCombat() then return end + boss:CastSpell(boss, SPELL_ROCKET_BOOTS, true) +end + +local function PhaseCheck(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + local guid = boss:GetGUIDLow() + phases[guid] = phases[guid] or {} + + if boss:GetHealthPct() <= NITRO_THRESHOLD and not phases[guid].nitro then + phases[guid].nitro = true + boss:SendUnitYell("You're gonna regret this!", 0) + boss:CastSpell(boss, SPELL_NITRO_BOOST, true) + end +end + +-- Air Support - Incendiary Rockets +local function CallAirSupport(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + boss:SendUnitYell("Calling for Air Support!", 0) + + -- Get random players or use current target + local players = boss:GetPlayersInRange(100) + if players and #players > 0 then + -- Fire first rocket immediately at random player + local target1 = players[math.random(#players)] + boss:CastSpell(target1, SPELL_INCENDIARY_ROCKET, true) + + -- Fire second rocket 1.5 seconds later at another random location + boss:RegisterEvent(function(e, d, c, creature) + if creature and creature:IsInCombat() then + local currentPlayers = creature:GetPlayersInRange(100) + if currentPlayers and #currentPlayers > 0 then + local target2 = currentPlayers[math.random(#currentPlayers)] + creature:CastSpell(target2, SPELL_INCENDIARY_ROCKET, true) + creature:SendUnitSay("Incoming!", 0) + end + end + end, 1500, 1) + end +end + +-- Idle Speech (before combat) +local function IdleSpeech(eventId, delay, calls, boss) + if boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + -- Say random idle line + local speech = IDLE_SPEECHES[math.random(#IDLE_SPEECHES)] + boss:SendUnitSay(speech, 0) + + -- Perform yelling emote + boss:PerformEmote(5) -- EMOTE_ONESHOT_EXCLAMATION (yelling gesture) +end + +-- Start idle speech for already-spawned bosses +local function StartIdleSpeechCheck() + -- This is a global check that runs periodically to start idle speech + -- for any Foreman that's already in the world + print("Checking for pre-spawned Foreman Glitzbolt instances...") +end + +-- Auto-initialize idle speech on first AI update +local function OnAIUpdate(event, boss, diff) + local guid = boss:GetGUIDLow() + + -- Only initialize once per boss + if not idleSpeechActive[guid] and not boss:IsInCombat() then + idleSpeechActive[guid] = true + boss:RegisterEvent(IdleSpeech, 45000, 0) + print("Auto-started idle speech for Foreman GUID " .. guid) + end +end + +-------------------------------------------------------------------------------- +-- BOSS COMBAT EVENTS +-------------------------------------------------------------------------------- + +local function OnBossCombat(event, boss, target) + boss:SendUnitYell("You're messin' with Venture Co. property! Big mistake!", 0) + boss:RemoveEvents() -- Stop idle speech + + local guid = boss:GetGUIDLow() + phases[guid] = {} + idleSpeechActive[guid] = false -- Mark idle speech as stopped + + -- Standard abilities + boss:RegisterEvent(CastGoblinBomb, 12000, 0) + boss:RegisterEvent(CastDaggerThrow, 8000, 0) + boss:RegisterEvent(CastGoblinDragonGun, 15000, 0) + boss:RegisterEvent(CastLayOnHands, 20000, 0) + boss:RegisterEvent(CastRocketBoots, 25000, 0) + boss:RegisterEvent(PhaseCheck, 1000, 0) + + -- Air Support - Every 30 seconds + boss:RegisterEvent(CallAirSupport, AIR_SUPPORT_INTERVAL, 0) +end + +local function OnBossLeaveCombat(event, boss) + boss:RemoveEvents() + local guid = boss:GetGUIDLow() + phases[guid] = nil + + -- Restart idle speech + idleSpeechActive[guid] = true + boss:RegisterEvent(IdleSpeech, 5000, 0) + + print("Foreman reset - idle speech restarted") +end + +local function OnBossKilledTarget(event, boss, victim) + if victim and victim:IsPlayer() then + local taunts = { + "That's what you get!", + "Venture Co. doesn't lose!", + "Should've stayed away!" + } + boss:SendUnitYell(taunts[math.random(#taunts)], 0) + end +end + +local function OnBossDeath(event, boss, killer) + boss:RemoveEvents() + local guid = boss:GetGUIDLow() + + -- Phase 1: Defiant yell (ZONE-WIDE) + boss:SendUnitYell("You think you won?!", 0) + boss:PlayDirectSound(6595) -- Goblin laugh sound + + -- Phase 2: Famous last words (2 seconds later) - CHAT BUBBLE (everyone can see it above his head) + boss:RegisterEvent(function(e, d, c, creature) + if creature then + creature:SendUnitSay("Yippee-ki-yay, mother f--", 0) -- Shows in chat bubble above boss + end + end, 2000, 1) + + -- Phase 3: MASSIVE EXPLOSION (3 seconds later) + boss:RegisterEvent(function(e, d, c, creature) + if creature then + print("MASSIVE EXPLOSION TRIGGERED!") + + -- LAYERED EXPLOSION EFFECTS + creature:CastSpell(creature, SPELL_BERYL_EXPLOSION, true) -- Crystal explosion + damage + creature:CastSpell(creature, SPELL_FIRE_BOMB, true) -- Fire visual + creature:CastSpell(creature, SPELL_EXPLOSION_VISUAL, true) -- Flame crash + creature:CastSpell(creature, SPELL_CAMERA_SHAKE, true) -- Screen shake + + -- Find and despawn the explosive wagon + local nearbyObjects = creature:GetGameObjectsInRange(50, 184700) + if nearbyObjects then + for _, wagon in ipairs(nearbyObjects) do + if wagon then + print("Despawning explosive wagon") + wagon:Despawn() + end + end + end + + -- Kill any nearby NPCs in the blast (indiscriminate explosion) + local nearbyCreatures = creature:GetCreaturesInRange(EXPLOSION_RADIUS) + if nearbyCreatures then + for _, npc in ipairs(nearbyCreatures) do + if npc and npc:IsAlive() and npc:GetEntry() ~= BOSS_ID then + npc:DealDamage(npc, npc:GetHealth()) + npc:SendUnitEmote("is vaporized by the explosion!") + print("NPC " .. npc:GetEntry() .. " vaporized in explosion") + end + end + end + + print("Boss body vaporized") + -- Vaporize boss body + creature:DespawnOrUnsummon(500) + end + end, 3000, 1) + + phases[guid] = nil +end + +-------------------------------------------------------------------------------- +-- REGISTER EVENTS +-------------------------------------------------------------------------------- + +-- Boss events +RegisterCreatureEvent(BOSS_ID, 27, OnAIUpdate) -- Event 27: OnAIUpdate (auto-start idle speech) +RegisterCreatureEvent(BOSS_ID, 1, OnBossCombat) +RegisterCreatureEvent(BOSS_ID, 2, OnBossLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 3, OnBossKilledTarget) +RegisterCreatureEvent(BOSS_ID, 4, OnBossDeath) + +print("Foreman Glitzbolt boss script loaded successfully!") +print("Idle speech auto-starts for pre-spawned instance bosses") \ No newline at end of file diff --git a/BOSS Scripts (Lua)/StonetalonRuins/Nessie.lua b/BOSS Scripts (Lua)/StonetalonRuins/Nessie.lua new file mode 100644 index 0000000..7d3fbae --- /dev/null +++ b/BOSS Scripts (Lua)/StonetalonRuins/Nessie.lua @@ -0,0 +1,345 @@ +-------------------------------------------------------------------------------- +-- Nessie - The Tri-Elemental Hydra (BC Retail Style) +-- NPC ID: 600662 +-- Created by: Manmadedrummer | Delve System +-------------------------------------------------------------------------------- +-- THEME: Multi-headed hydra with elemental powers (Water, Ice, Lightning) +-- +-- BC RETAIL MECHANICS: +-- +-- PHASE 1 (100% - 66%): All Three Heads Active +-- - Water Head: Tidal Surge (38358), Water Spit (40086), Aquatic Blast (36826) +-- - Ice Head: Frost Breath (43562), Frozen Bite (61186) +-- - Lightning Head: Chain Lightning (12058), Thunderclap (43583) +-- - All heads attack simultaneously - elemental chaos! +-- +-- PHASE 2 (66% - 33%): Focused Assault (One Head Dominant) +-- - Random head becomes empowered +-- - Water: Enhanced Water Spit damage +-- - Ice: Deep Freeze (60511) - stuns random player +-- - Lightning: Storm Cloud (57408) - persistent AOE lightning +-- +-- PHASE 3 (<33%): Enraged Frenzy +-- - All three heads go berserk +-- - Raging Storm (74423) - cast immediately on phase transition +-- - Nether Beam (35873) - All three elements combine (every 20s) +-- - All abilities cast much faster (ability spam!) +-------------------------------------------------------------------------------- + +print("========================================") +print("Nessie: Tri-Elemental Hydra Loaded") +print("BC Retail Style - Multi-Head Mechanics") +print("========================================") + +local BOSS_ID = 600662 -- Nessie the Hydra + +-- Spells (Water Head) +local SPELL_TIDAL_SURGE = 38358 -- Tidal Surge +local SPELL_WATER_SPIT = 40086 -- Water Spit +local SPELL_AQUATIC_BLAST = 36826 -- Summon Corrupted Water Elemental + +-- Spells (Ice Head) +local SPELL_FROST_BREATH = 43562 -- Frost Breath +local SPELL_FROZEN_BITE = 61186 -- Frozen Bite +local SPELL_DEEP_FREEZE = 60511 -- Deep Freeze + +-- Spells (Lightning Head) +local SPELL_CHAIN_LIGHTNING = 12058 -- Chain Lightning +local SPELL_THUNDERCLAP = 43583 -- Thunderclap +local SPELL_STORM_CLOUD = 57408 -- Storm Cloud + +-- Spells (Combined/Special) +local SPELL_NETHER_BEAM = 35873 -- Nether Beam (prismatic) +local SPELL_RAGING_STORM = 74423 -- Summon Raging Storm Elemental + +-- Phase thresholds +local PHASE_2_HP = 66 +local PHASE_3_HP = 33 + +-- Boss phases tracking +local phases = {} + +-------------------------------------------------------------------------------- +-- PHASE 1 ABILITIES (100% - 66%) - All Heads Active +-------------------------------------------------------------------------------- + +-- Water Head Abilities +local function WaterHead_TidalSurge(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + boss:CastSpell(boss, SPELL_TIDAL_SURGE, false) + boss:SendUnitYell("Feel the crushing waves!", 0) +end + +local function WaterHead_WaterSpit(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + local victim = boss:GetVictim() + if victim then + boss:CastSpell(victim, SPELL_WATER_SPIT, false) + boss:SendUnitSay("Drown!", 0) + end +end + +local function WaterHead_AquaticBlast(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + local victim = boss:GetVictim() + if victim then + boss:CastSpell(victim, SPELL_AQUATIC_BLAST, false) + boss:SendUnitSay("The depths consume you!", 0) + end +end + +-- Ice Head Abilities +local function IceHead_FrostBreath(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + local victim = boss:GetVictim() + if victim then + boss:CastSpell(victim, SPELL_FROST_BREATH, false) + boss:SendUnitSay("Freeze!", 0) + end +end + +local function IceHead_FrozenBite(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + local victim = boss:GetVictim() + if victim then + boss:CastSpell(victim, SPELL_FROZEN_BITE, false) + end +end + +-- Lightning Head Abilities +local function LightningHead_ChainLightning(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + local victim = boss:GetVictim() + if victim then + boss:CastSpell(victim, SPELL_CHAIN_LIGHTNING, false) + boss:SendUnitSay("Lightning strikes!", 0) + end +end + +local function LightningHead_Thunderclap(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + boss:CastSpell(boss, SPELL_THUNDERCLAP, false) +end + +-------------------------------------------------------------------------------- +-- PHASE 2 ABILITIES (66% - 33%) - Empowered Head +-------------------------------------------------------------------------------- + +local function EmpoweredAbility(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + local guid = boss:GetGUIDLow() + local p = phases[guid] + + if not p or not p.empoweredHead then return end + + if p.empoweredHead == "water" then + -- Water Spit empowered + local victim = boss:GetVictim() + if victim then + boss:CastSpell(victim, SPELL_WATER_SPIT, false) + boss:SendUnitYell("Torrential assault!", 0) + end + + elseif p.empoweredHead == "ice" then + -- Deep Freeze random player + local players = boss:GetPlayersInRange(50) + if players and #players > 0 then + local target = players[math.random(#players)] + boss:CastSpell(target, SPELL_DEEP_FREEZE, false) + boss:SendUnitYell("Frozen solid!", 0) + end + + elseif p.empoweredHead == "lightning" then + -- Storm Cloud + boss:CastSpell(boss, SPELL_STORM_CLOUD, false) + boss:SendUnitYell("The storm awakens!", 0) + end +end + +-------------------------------------------------------------------------------- +-- PHASE 3 ABILITIES (<33%) - Enraged Frenzy +-------------------------------------------------------------------------------- + +local function NetherBeam(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + boss:SendUnitYell("ALL HEADS UNITE! WITNESS TRUE POWER!", 0) + + local victim = boss:GetVictim() + if victim then + boss:CastSpell(victim, SPELL_NETHER_BEAM, false) + end +end + +local function RagingStorm(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + boss:SendUnitYell("The elements rage!", 0) + boss:CastSpell(boss, SPELL_RAGING_STORM, false) +end + +-------------------------------------------------------------------------------- +-- PHASE MANAGEMENT +-------------------------------------------------------------------------------- + +local function PhaseCheck(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + local guid = boss:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + + local hp = boss:GetHealthPct() + + -- PHASE 2: Empowered Head (66% HP) + if hp <= PHASE_2_HP and not p.phase2 then + p.phase2 = true + + -- Randomly pick which head becomes empowered + local heads = {"water", "ice", "lightning"} + p.empoweredHead = heads[math.random(#heads)] + + if p.empoweredHead == "water" then + boss:SendUnitYell("The Water Head surges with power!", 0) + elseif p.empoweredHead == "ice" then + boss:SendUnitYell("The Ice Head crystallizes with fury!", 0) + else + boss:SendUnitYell("The Lightning Head crackles with energy!", 0) + end + + -- Start empowered ability (every 12 seconds) + boss:RegisterEvent(EmpoweredAbility, 12000, 0) + + print("Phase 2: Empowered " .. p.empoweredHead .. " head") + end + + -- PHASE 3: Enraged Frenzy (33% HP) + if hp <= PHASE_3_HP and not p.phase3 then + p.phase3 = true + + boss:SendUnitYell("YOU DARE WOUND ME?! ALL HEADS ATTACK!", 0) + + -- Cast Raging Storm + RagingStorm(nil, nil, nil, boss) + + -- Nether Beam every 20 seconds + boss:RegisterEvent(NetherBeam, 20000, 0) + + -- Speed up all abilities + boss:RemoveEvents() + boss:RegisterEvent(WaterHead_TidalSurge, 15000, 0) + boss:RegisterEvent(WaterHead_WaterSpit, 8000, 0) + boss:RegisterEvent(WaterHead_AquaticBlast, 6000, 0) + boss:RegisterEvent(IceHead_FrostBreath, 7000, 0) + boss:RegisterEvent(IceHead_FrozenBite, 9000, 0) + boss:RegisterEvent(LightningHead_ChainLightning, 5000, 0) + boss:RegisterEvent(LightningHead_Thunderclap, 12000, 0) + boss:RegisterEvent(NetherBeam, 20000, 0) + boss:RegisterEvent(PhaseCheck, 1000, 0) + + print("Phase 3: Enraged Frenzy") + end +end + +-------------------------------------------------------------------------------- +-- COMBAT EVENTS +-------------------------------------------------------------------------------- + +local function OnBossCombat(event, boss, target) + boss:SendUnitYell("Three heads, three deaths for you!", 0) + boss:RemoveEvents() + + local guid = boss:GetGUIDLow() + phases[guid] = {} + + -- Phase 1: All heads active + boss:RegisterEvent(WaterHead_TidalSurge, 22000, 0) + boss:RegisterEvent(WaterHead_WaterSpit, 12000, 0) + boss:RegisterEvent(WaterHead_AquaticBlast, 8000, 0) + boss:RegisterEvent(IceHead_FrostBreath, 10000, 0) + boss:RegisterEvent(IceHead_FrozenBite, 14000, 0) + boss:RegisterEvent(LightningHead_ChainLightning, 7000, 0) + boss:RegisterEvent(LightningHead_Thunderclap, 15000, 0) + + -- Phase manager + boss:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnBossLeaveCombat(event, boss) + boss:RemoveEvents() + local guid = boss:GetGUIDLow() + phases[guid] = nil +end + +local function OnBossKilledTarget(event, boss, victim) + if victim and victim:IsPlayer() then + local taunts = { + "Your bones shall rest in the depths!", + "Frozen forever!", + "Lightning does not forgive!" + } + boss:SendUnitYell(taunts[math.random(#taunts)], 0) + end +end + +local function OnBossDeath(event, boss, killer) + boss:RemoveEvents() + local guid = boss:GetGUIDLow() + + boss:SendUnitYell("All... heads... fall... The beast... is... slain...", 0) + + phases[guid] = nil +end + +-------------------------------------------------------------------------------- +-- REGISTER EVENTS +-------------------------------------------------------------------------------- + +RegisterCreatureEvent(BOSS_ID, 1, OnBossCombat) +RegisterCreatureEvent(BOSS_ID, 2, OnBossLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 3, OnBossKilledTarget) +RegisterCreatureEvent(BOSS_ID, 4, OnBossDeath) + +print("Nessie (600662): Tri-Elemental Hydra loaded successfully!") +print("No add NPCs required - spells handle summons") \ No newline at end of file diff --git a/BOSS Scripts (Lua)/StonetalonRuins/RuinSmasher.lua b/BOSS Scripts (Lua)/StonetalonRuins/RuinSmasher.lua new file mode 100644 index 0000000..a351cff --- /dev/null +++ b/BOSS Scripts (Lua)/StonetalonRuins/RuinSmasher.lua @@ -0,0 +1,282 @@ +-------------------------------------------------------------------------------- +-- Ruin Smasher X-98 - Venture Co. War Machine (WOTLK Retail Style) +-- NPC ID: 600663 +-- Created by: Manmadedrummer | Delve System +-------------------------------------------------------------------------------- +-- THEME: Goblin-engineered destruction machine with overheating mechanics +-- +-- BOSS MECHANICS (Retail Style): +-- Phase 1 (100% - 50%): Standard machine attacks +-- - Crowd Pummel (10887): Heavy frontal AOE knockback +-- - Arcing Smash (8374): Cleave attack +-- - Trample (48783): Charges random player +-- - Rocket Launch (46188): Fires rockets at random players every 20s +-- +-- Phase 2 (50% - 25%): OVERHEATING +-- - Overdrive (18546): Speed and attack rate increase +-- - Steam Blast (50375): Vents steam every 15 seconds (AOE damage) +-- - All abilities continue +-- +-- Phase 3 (<25%): CRITICAL MELTDOWN +-- - Erratic behavior - faster ability spam +-- - Dump Oil (50269): Leaves oil patches on ground every 8s +-- - Steam vents more frequently (every 10s) +-- - Machine is unstable and deadly +-- +-- DEATH: Machine shuts down - "CRITICAL FAILURE... SYSTEMS... OFFLINE..." +-------------------------------------------------------------------------------- + +print("========================================") +print("Ruin Smasher X-98: Mechanical Boss Loaded") +print("WotLK Retail Style - 3 Phase Fight") +print("========================================") + +local BOSS_ID = 600663 + +-- Spells (Machine Attacks) +local SPELL_CROWD_PUMMEL = 10887 -- Heavy frontal knockback +local SPELL_ARCING_SMASH = 8374 -- Cleave +local SPELL_TRAMPLE = 48783 -- Trample +local SPELL_ROCKET_BARRAGE = 46188 -- Rocket Launch +local SPELL_STEAM_BLAST = 50375 -- Steam Blast +local SPELL_OVERDRIVE = 18546 -- Overdrive +local SPELL_BURNING_OIL = 50269 -- Dump Oil + +-- Phase thresholds +local PHASE_2_HP = 50 +local PHASE_3_HP = 25 + +-- Boss phases tracking +local phases = {} + +-------------------------------------------------------------------------------- +-- PHASE 1 ABILITIES (100% - 50%) +-------------------------------------------------------------------------------- + +local function CastCrowdPummel(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + boss:CastSpell(boss, SPELL_CROWD_PUMMEL, false) + boss:SendUnitSay("Crowd control protocol engaged!", 0) +end + +local function CastArcingSmash(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + local victim = boss:GetVictim() + if victim then + boss:CastSpell(victim, SPELL_ARCING_SMASH, false) + end +end + +local function CastTrample(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + -- Trample random player + local players = boss:GetPlayersInRange(50) + if players and #players > 0 then + local target = players[math.random(#players)] + boss:CastSpell(target, SPELL_TRAMPLE, false) + boss:SendUnitSay("Target acquired!", 0) + end +end + +local function CastRocketBarrage(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + boss:SendUnitYell("Initiating rocket barrage!", 0) + + -- Fire 3 rockets at random players + local players = boss:GetPlayersInRange(50) + if players and #players > 0 then + for i = 1, 3 do + boss:RegisterEvent(function(e, d, c, creature) + if creature and creature:IsInCombat() then + local currentPlayers = creature:GetPlayersInRange(50) + if currentPlayers and #currentPlayers > 0 then + local target = currentPlayers[math.random(#currentPlayers)] + creature:CastSpell(target, SPELL_ROCKET_BARRAGE, true) + end + end + end, i * 800, 1) -- Stagger rockets 0.8s apart + end + end +end + +-------------------------------------------------------------------------------- +-- PHASE 2 ABILITIES (50% - 25%) - OVERHEATING +-------------------------------------------------------------------------------- + +local function VentSteam(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + boss:SendUnitYell("Warning: Core temperature critical!", 0) + boss:CastSpell(boss, SPELL_STEAM_BLAST, false) + + -- Visual: machine venting steam (damage aura around boss) +end + +-------------------------------------------------------------------------------- +-- PHASE 3 ABILITIES (<25%) - CRITICAL MELTDOWN +-------------------------------------------------------------------------------- + +local function ErraticBehavior(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + -- Random ability spam + local abilities = {SPELL_CROWD_PUMMEL, SPELL_ARCING_SMASH, SPELL_TRAMPLE} + local randomSpell = abilities[math.random(#abilities)] + + local victim = boss:GetVictim() + if victim then + boss:CastSpell(victim, randomSpell, false) + end +end + +local function LeaveOilPatch(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + -- Leave burning oil at current location + local x, y, z = boss:GetLocation() + boss:CastSpell(boss, SPELL_BURNING_OIL, true) +end + +-------------------------------------------------------------------------------- +-- PHASE MANAGEMENT +-------------------------------------------------------------------------------- + +local function PhaseCheck(eventId, delay, calls, boss) + if not boss:IsInCombat() or boss:IsDead() then + boss:RemoveEventById(eventId) + return + end + + local guid = boss:GetGUIDLow() + phases[guid] = phases[guid] or {} + local p = phases[guid] + + local hp = boss:GetHealthPct() + + -- PHASE 2: Overheating (50% HP) + if hp <= PHASE_2_HP and not p.phase2 then + p.phase2 = true + + boss:SendUnitYell("System overheating! Engaging emergency protocols!", 0) + boss:CastSpell(boss, SPELL_OVERDRIVE, true) -- Speed boost + + -- Start venting steam every 15 seconds + boss:RegisterEvent(VentSteam, 15000, 0) + + print("Phase 2: Overheating activated") + end + + -- PHASE 3: Critical Meltdown (25% HP) + if hp <= PHASE_3_HP and not p.phase3 then + p.phase3 = true + + boss:SendUnitYell("CRITICAL MALFUNCTION! CORE DESTABILIZING!", 0) + + -- Erratic behavior - spam abilities + boss:RegisterEvent(ErraticBehavior, 5000, 0) + + -- Leave oil patches every 8 seconds + boss:RegisterEvent(LeaveOilPatch, 8000, 0) + + -- Increase steam vent frequency (every 10s instead of 15s) + boss:RemoveEvents() -- Clear old steam timer + boss:RegisterEvent(VentSteam, 10000, 0) + + -- Re-register combat abilities + boss:RegisterEvent(CastCrowdPummel, 9000, 0) + boss:RegisterEvent(CastArcingSmash, 6000, 0) + boss:RegisterEvent(CastTrample, 12000, 0) + boss:RegisterEvent(CastRocketBarrage, 15000, 0) + boss:RegisterEvent(ErraticBehavior, 5000, 0) + boss:RegisterEvent(LeaveOilPatch, 8000, 0) + boss:RegisterEvent(PhaseCheck, 1000, 0) + + print("Phase 3: Critical Meltdown activated") + end +end + +-------------------------------------------------------------------------------- +-- COMBAT EVENTS +-------------------------------------------------------------------------------- + +local function OnBossCombat(event, boss, target) + boss:SendUnitYell("Intruder detected! Initiating elimination sequence!", 0) + boss:RemoveEvents() + + local guid = boss:GetGUIDLow() + phases[guid] = {} + + -- Phase 1 abilities + boss:RegisterEvent(CastCrowdPummel, 11000, 0) -- Every 11-14s + boss:RegisterEvent(CastArcingSmash, 8000, 0) -- Every 8-12s + boss:RegisterEvent(CastTrample, 15000, 0) -- Every 15s + boss:RegisterEvent(CastRocketBarrage, 20000, 0) -- Every 20s + + -- Phase manager + boss:RegisterEvent(PhaseCheck, 1000, 0) +end + +local function OnBossLeaveCombat(event, boss) + boss:RemoveEvents() + local guid = boss:GetGUIDLow() + phases[guid] = nil + + boss:SendUnitSay("Target lost. Returning to standby mode.", 0) +end + +local function OnBossKilledTarget(event, boss, victim) + if victim and victim:IsPlayer() then + local taunts = { + "Target eliminated.", + "Hostile neutralized.", + "Efficiency: 100%" + } + boss:SendUnitSay(taunts[math.random(#taunts)], 0) + end +end + +local function OnBossDeath(event, boss, killer) + boss:RemoveEvents() + local guid = boss:GetGUIDLow() + + boss:SendUnitYell("CRITICAL FAILURE... SYSTEMS... OFFLINE...", 0) + + phases[guid] = nil +end + +-------------------------------------------------------------------------------- +-- REGISTER EVENTS +-------------------------------------------------------------------------------- + +RegisterCreatureEvent(BOSS_ID, 1, OnBossCombat) +RegisterCreatureEvent(BOSS_ID, 2, OnBossLeaveCombat) +RegisterCreatureEvent(BOSS_ID, 3, OnBossKilledTarget) +RegisterCreatureEvent(BOSS_ID, 4, OnBossDeath) + +print("Ruin Smasher X-98 loaded successfully!") +print("3-Phase mechanical boss fight ready") \ No newline at end of file diff --git a/JustForLooks/Test.txt b/JustForLooks/Test.txt deleted file mode 100644 index 8b13789..0000000 --- a/JustForLooks/Test.txt +++ /dev/null @@ -1 +0,0 @@ -