diff --git a/Encounters/BossPrototype.lua b/Encounters/BossPrototype.lua
index dbb266f..6893442 100644
--- a/Encounters/BossPrototype.lua
+++ b/Encounters/BossPrototype.lua
@@ -93,10 +93,10 @@ end
function EncounterPrototype:RegisterDatachronEvent(sSearchMessage, sMatch, fHandler)
assert(type(sSearchMessage) == "string")
assert(type(fHandler) == "function")
- assert(sMatch == "MATCH" or sMatch == "FIND")
+ assert(sMatch == "MATCH" or sMatch == "FIND" or sMatch == "EQUAL")
sSearchMessage = self.L[sSearchMessage]
self.tDatachronEvents[sSearchMessage] = self.tDatachronEvents[sSearchMessage] or {}
- table.insert(self.tDatachronEvents[sSearchMessage], {fHandler = fHandler, bMatch = sMatch == "MATCH"})
+ table.insert(self.tDatachronEvents[sSearchMessage], {fHandler = fHandler, sMatch = sMatch })
end
-- Register events to a single unit
@@ -131,12 +131,13 @@ end
-- @param sEnglishText English text to search in language dictionnary.
-- @param nDuration Timer duration.
-- @param bEmphasize Timer count down requested (nil take the default one).
+-- @param sColor Color for the timer bar (nil take the default one)..
-- @param fHandler function to call on timeout
-- @param tClass Class used by callback action on timeout
-- @param tData Data forwarded by callback action on timeout
--
-- Note: If the English translation is not found, the current string will be used like that.
-function EncounterPrototype:AddTimerBar(sKey, sEnglishText, nDuration, bEmphasize, fHandler, tClass, tData)
+function EncounterPrototype:AddTimerBar(sKey, sEnglishText, nDuration, bEmphasize, sColor, fHandler, tClass, tData)
local tOptions = nil
local sLocalText = self.L[sEnglishText]
if self.tDefaultTimerBarsOptions[sKey] then
@@ -147,6 +148,10 @@ function EncounterPrototype:AddTimerBar(sKey, sEnglishText, nDuration, bEmphasiz
if bEmphasize ~= nil then
tOptions["bEmphasize"] = bEmphasize and true
end
+ if sColor ~= nil then
+ assert(type(sColor) == "string")
+ tOptions["sColor"] = sColor
+ end
local tCallback = nil
if type(fHandler) == "function" then
tCallback = {
diff --git a/Encounters/RMT/Engineers.lua b/Encounters/RMT/Engineers.lua
index d2a2299..fb10812 100644
--- a/Encounters/RMT/Engineers.lua
+++ b/Encounters/RMT/Engineers.lua
@@ -27,49 +27,229 @@ mod:RegisterEnglishLocale({
["Cooling Turbine"] = "Cooling Turbine",
["Spark Plug"] = "Spark Plug",
["Lubricant Nozzle"] = "Lubricant Nozzle",
- ["Head Engineer Orvulgh"] = "Head Engineer Orvulgh",
- ["Chief Engineer Wilbargh"] = "Chief Engineer Wilbargh",
+ ["Head Engineer Orvulgh"] = "Head Engineer Orvulgh", -- Engineer
+ ["Chief Engineer Wilbargh"] = "Chief Engineer Wilbargh", -- Warrior
["Air Current"] = "Air Current",
["Friendly Invisible Unit for Fields"] = "Friendly Invisible Unit for Fields",
["Hostile Invisible Unit for Fields (0 hit radius)"] = "Hostile Invisible Unit for Fields (0 hit radius)",
- -- Cast names
+ ["Discharged Plasma"] = "Discharged Plasma", -- Fire Orb
+ -- Cast names.
["Liquidate"] = "Liquidate",
- -- Datachron
- ["Hornious Eversong suffers from Electroshock"] = "",
+ ["Electroshock"] = "Electroshock",
+ -- Datachron.
+ ["([^%s]+%s[^%s]+) suffers from Electroshock"] = "([^%s]+%s[^%s]+) suffers from Electroshock",
+ -- Messages.
+ ["electroshock.next"] = "Next Electroshock in",
+ ["liquidate.next"] = "Next Liquidate in",
+ ["liquidate.stack"] = "Stack",
+ ["electroshock.swap.other"] = "%s SWAP TO WARRIOR",
+ ["electroshock.swap.you"] = "YOU SWAP TO WARRIOR",
+ ["fire_orb.next"] = "Next Fire Orb in",
+ ["fire_orb.you"] = "FIRE ORB ON YOU",
+ ["fire_orb.spawned"] = "Fire Orb spawned",
+ ["fire_orb.pop.timer"] = "Fire Orb is safe to pop in",
+ ["fire_orb.pop.msg"] = "Pop the Fire Orb!",
+ ["core.health.high.warning"] = "%s pillar at 85%%!",
+ ["core.health.low.warning"] = "%s pillar at 15%%!"
})
----------------------------------------------------------------------------------------------------
-- Constants.
----------------------------------------------------------------------------------------------------
+local DEBUFF_ION_CLASH = 84051
+local DEBUFF_UNSTABLE_VOLTAGE = 84045
+local DEBUFF_ELECTROSHOCK_VULNERABILITY = 83798
+local DEBUFF_DIMINISHING_FUSION_REACTION = 87214
+local BUFF_INSULATION = 83987
+-- Timers
+local FIRST_ELECTROSHOCK_TIMER = 11
+local ELECTROSHOCK_TIMER = 18
+local JUMP_ELECTROSHOCK_TIMER = 12
+local NEXT_FIRE_ORB_TIMER = 24
+local FIRE_ORB_SAFE_TIMER = 14
+
+local FIRST_LIQUIDATE_TIMER = 12
+local LIQUIDATE_TIMER = 22
+
+local FUSION_CORE = 1
+local COOLING_TURBINE = 2
+local SPARK_PLUG = 3
+local LUBRICANT_NOZZLE = 4
+local CORE_NAMES = {
+ ["Fusion Core"] = FUSION_CORE,
+ ["Cooling Turbine"] = COOLING_TURBINE,
+ ["Spark Plug"] = SPARK_PLUG,
+ ["Lubricant Nozzle"] = LUBRICANT_NOZZLE
+}
+--shorten these
+local CORE_NICKNAMES = {
+ [FUSION_CORE] = "Fusion Core",
+ [COOLING_TURBINE] = "Cooling Turbine",
+ [SPARK_PLUG] = "Spark Plug",
+ [LUBRICANT_NOZZLE] = "Lubricant Nozzle"
+}
+
+local WARRIOR = 1
+local ENGINEER = 2
+local ENGINEER_NAMES = {
+ ["Chief Engineer Wilbargh"] = WARRIOR,
+ ["Head Engineer Orvulgh"] = ENGINEER,
+}
+local ENGINEER_START_LOCATION = {
+ [WARRIOR] = SPARK_PLUG,
+ [ENGINEER] = COOLING_TURBINE,
+}
+local ENGINEER_NICKNAMES = {
+ [WARRIOR] = "Warrior",
+ [ENGINEER] = "Engineer",
+}
----------------------------------------------------------------------------------------------------
--- Locals.
+-- Functions.
----------------------------------------------------------------------------------------------------
local GetUnitById = GameLib.GetUnitById
-local GetPlayerUnit = GameLib.GetPlayerUnit
local GetGameTime = GameLib.GetGameTime
----------------------------------------------------------------------------------------------------
+-- Locals.
+----------------------------------------------------------------------------------------------------
+--Do not reset coreUnits since they don't get destroyed after each pull
+local coreUnits = {}
+local engineerUnits
+local player
+local orbUnits
+
+local fireOrbTargetTestTimer = ApolloTimer.Create(1, false, "RegisterOrbTarget", mod)
+----------------------------------------------------------------------------------------------------
+-- Settings.
+----------------------------------------------------------------------------------------------------
+mod:RegisterDefaultSetting("BarsCoreHealth", false)
+mod:RegisterDefaultSetting("LineElectroshock")
+mod:RegisterDefaultSetting("SoundLiquidate")
+mod:RegisterDefaultSetting("SoundElectroshock")
+mod:RegisterDefaultSetting("SoundElectroshockSwap")
+mod:RegisterDefaultSetting("SoundElectroshockSwapYou")
+mod:RegisterDefaultSetting("SoundFireOrb")
+mod:RegisterDefaultSetting("SoundFireOrbAlt")
+mod:RegisterDefaultSetting("SoundFireOrbPop")
+mod:RegisterDefaultSetting("SoundCoreHealthWarning")
+----------------------------------------------------------------------------------------------------
+-- Raw event handlers.
+----------------------------------------------------------------------------------------------------
+Apollo.RegisterEventHandler("UnitDestroyed", "OnUnitDestroyedRaw", mod)
+----------------------------------------------------------------------------------------------------
-- Encounter description.
----------------------------------------------------------------------------------------------------
function mod:OnBossEnable()
+ player = {}
+ player.unit = GameLib.GetPlayerUnit()
+ player.location = 0
+ engineerUnits = {}
+ orbUnits = {}
+ --locales
+ for name, id in pairs(CORE_NAMES) do
+ CORE_NAMES[name] = nil
+ CORE_NAMES[self.L[name]] = id
+ end
+ for name, id in pairs(ENGINEER_NAMES) do
+ ENGINEER_NAMES[name] = nil
+ ENGINEER_NAMES[self.L[name]] = id
+ end
+
+ for id, coreUnit in pairs(coreUnits) do
+ coreUnit.healthWarning = false
+ end
+
+ mod:AddTimerBar("NEXT_ELEKTROSHOCK_TIMER", self.L["electroshock.next"], FIRST_ELECTROSHOCK_TIMER)
+ mod:AddTimerBar("NEXT_LIQUIDATE_TIMER", self.L["liquidate.next"], FIRST_LIQUIDATE_TIMER)
+end
+function mod:OnBossDisable()
+ mod:RemoveUnits()
end
-function mod:OnBuffAdd(nId, nSpellId, nStack, fTimeRemaining)
+function mod:AddUnits()
+ for engineerId, engineer in pairs(engineerUnits) do
+ core:WatchUnit(engineer.unit)
+ core:AddUnit(engineer.unit)
+ end
+ for coreId, coreUnit in pairs(coreUnits) do
+ core:WatchUnit(coreUnit.unit)
+ if mod:GetSetting("BarsCoreHealth") then
+ core:AddUnit(coreUnit.unit)
+ end
+ end
end
-function mod:OnCastStart(nId, sCastName, nCastEndTime, sName)
+function mod:RemoveUnits()
+ for engineerId, engineer in pairs(engineerUnits) do
+ core:RemoveUnit(engineer.unit)
+ end
+ for coreId, coreUnit in pairs(coreUnits) do
+ if mod:GetSetting("BarsCoreHealth") then
+ core:RemoveUnit(coreUnit.unit)
+ end
+ end
end
-function mod:OnDebuffAdd(nId, nSpellId, nStack, fTimeRemaining)
+function mod:GetUnitPlatform(unit)
+ local shortestDistance = 100000
+ local currentDistance
+ local location = 0
+ for coreId, coreUnit in pairs(coreUnits) do
+ currentDistance = mod:GetDistanceBetweenUnits(unit, coreUnit.unit)
+ if shortestDistance > currentDistance then
+ shortestDistance = currentDistance
+ location = coreId
+ end
+ end
+ return location
+end
+function mod:OnEngiChangeLocation(engineerId, oldCoreId, newCoreId)
end
-function mod:OnUnitDestroyed(nId, tUnit, sName)
+function mod:OnBuffRemove(id, spellId)
+ if spellId == BUFF_INSULATION then
+ for engineerId, engineer in pairs(engineerUnits) do
+ local oldLocation = engineerUnits[engineerId].location
+ local newLocation = mod:GetUnitPlatform(engineer.unit)
+ if newLocation ~= oldLocation then
+ engineerUnits[engineerId].location = newLocation
+ mod:OnEngiChangeLocation(engineerId, oldLocation, newLocation)
+ end
+ end
+ end
+end
+function mod:OnDebuffAdd(id, spellId, stack, timeRemaining)
+ if DEBUFF_ELECTROSHOCK_VULNERABILITY == spellId then
+ local target = GetUnitById(id)
+ local targetName = target:GetName()
+ local isOnMyself = targetName == player.unit:GetName()
+ local electroshockOnX = ""
+ local messageId = string.format("ELECTROSHOCK_MSG_%s", targetName)
+ local sound
+ if bIsOnMyself then
+ electroshockOnX = self.L["electroshock.swap.you"]
+ sound = mod:GetSetting("SoundElectroshockSwapYou") == true and "RunAway"
+ else
+ electroshockOnX = self.L["electroshock.swap.other"]:format(targetName)
+ sound = mod:GetSetting("SoundElectroshockSwap") == true and "Info"
+ end
+
+ mod:AddMsg(messageId, electroshockOnX, 5, sound, "Red")
+ end
end
-function mod:OnUnitCreated(nId, unit, sName)
+function mod:IsPlayerOnPlatform(coreId)
+ player.location = mod:GetUnitPlatform(player.unit)
+ return player.location == coreId
+end
+function mod:OnUnitDestroyedRaw(unit)
+ local name = unit:GetName()
+ if CORE_NAMES[name] ~= nil then
+ coreUnits[CORE_NAMES[name]] = nil
+ end
end
mod:RegisterUnitEvents({
@@ -79,28 +259,147 @@ mod:RegisterUnitEvents({
"Spark Plug",
"Lubricant Nozzle"
},{
- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
- core:AddUnit(tUnit)
- core:WatchUnit(tUnit)
+ ["OnUnitCreated"] = function (self, id, unit, name)
+ if CORE_NAMES[name] ~= nil then
+ coreUnits[CORE_NAMES[name]] = {
+ unit = unit,
+ healthWarning = false,
+ }
+ elseif ENGINEER_NAMES[name] ~= nil then
+ local engineerId = ENGINEER_NAMES[name]
+ engineerUnits[engineerId] = {
+ unit = unit,
+ location = ENGINEER_START_LOCATION[engineerId],
+ }
+ end
+ if #coreUnits == 4 and #engineerUnits == 2 then
+ mod:AddUnits()
+ end
end,
}
)
+
+-- Cores
+mod:RegisterUnitEvents({
+ "Fusion Core",
+ "Cooling Turbine",
+ "Spark Plug",
+ "Lubricant Nozzle"
+ },{
+ ["OnHealthChanged"] = function (self, id, percent, name)
+ local coreUnit = coreUnits[CORE_NAMES[name]]
+ if percent > 15 and percent < 85 then
+ coreUnit.healthWarning = false
+ elseif percent >= 85 and not coreUnit.healthWarning then
+ coreUnit.healthWarning = true
+ mod:AddMsg("CORE_HEALTH_HIGH_WARN", self.L["core.health.high.warning"]:format(name), 5, mod:GetSetting("SoundCoreHealthWarning") and "Info")
+ elseif percent <= 15 and not coreUnit.healthWarning then
+ coreUnit.healthWarning = true
+ mod:AddMsg("CORE_HEALTH_LOW_WARN", self.L["core.health.low.warning"]:format(name), 5, mod:GetSetting("SoundCoreHealthWarning") and "Info")
+ end
+ end
+ }
+)
+
+-- Warrior
mod:RegisterUnitEvents("Chief Engineer Wilbargh",{
- ["OnCastStart"] = function (self, nId, sCastName, nCastEndTime, sName)
- if self.L["Liquidate"] == sCastName then
- --Stack
+ ["OnCastStart"] = function (self, id, castName, castEndTime, name)
+ if self.L["Liquidate"] == castName then
+ if mod:IsPlayerOnPlatform(engineerUnits[WARRIOR].location) then
+ mod:AddMsg("LIQUIDATE_MSG", self.L["liquidate.stack"], 5, mod:GetSetting("SoundLiquidate") == true and "Info")
+ end
+ end
+ end,
+ ["OnCastEnd"] = function (self, id, castName, castEndTime, name)
+ if self.L["Rocket Jump"] == castName then
+ mod:RemoveTimerBar("NEXT_LIQUIDATE_TIMER")
+ end
+ if self.L["Liquidate"] == castName then
+ mod:RemoveTimerBar("NEXT_LIQUIDATE_TIMER")
+ mod:AddTimerBar("NEXT_LIQUIDATE_TIMER", self.L["liquidate.next"], LIQUIDATE_TIMER)
+ end
+ end,
+ }
+)
+
+function mod:IsUnitFacingOtherUnit(unit, otherUnit)
+ local unitVector = Vector3.New(unit:GetPosition())
+ local otherUnitVector = Vector3.New(otherUnit:GetPosition())
+ local difference = otherUnitVector - unitVector
+ local normalized = difference:Normal()
+ normalized.y = 0
+ local facing = Vector3.New(unit:GetFacing())
+ local facingDifference = normalized - facing
+
+ return math.abs(facingDifference.x) < 0.01 and math.abs(facingDifference.z) < 0.01
+end
+
+-- Engineer
+mod:RegisterUnitEvents("Head Engineer Orvulgh",{
+ ["OnCastStart"] = function (self, id, castName, castEndTime, name)
+ if self.L["Electroshock"] == castName then
+ if mod:GetSetting("LineElectroshock") then
+ core:AddPixie("ELECTROSHOCK_PIXIE", 2, engineerUnits[ENGINEER].unit, nil, "Red", 10, 80, 0)
+ end
+ if mod:IsPlayerOnPlatform(engineerUnits[ENGINEER].location) then
+ mod:AddMsg("ELECTROSHOCK_CAST_MSG", self.L["Electroshock"], 5, mod:GetSetting("SoundElectroshock") == true and "Beware")
+ end
+ end
+ end,
+ ["OnCastEnd"] = function (self, id, castName, castEndTime, name)
+ if self.L["Rocket Jump"] == castName then
+ mod:RemoveTimerBar("NEXT_ELEKTROSHOCK_TIMER")
+ mod:AddTimerBar("NEXT_ELEKTROSHOCK_TIMER", self.L["electroshock.next"], JUMP_ELECTROSHOCK_TIMER)
end
+ if self.L["Electroshock"] == castName then
+ if mod:GetSetting("LineElectroshock") then
+ core:DropPixie("ELECTROSHOCK_PIXIE")
+ end
+ mod:RemoveTimerBar("NEXT_ELEKTROSHOCK_TIMER")
+ mod:AddTimerBar("NEXT_ELEKTROSHOCK_TIMER", self.L["electroshock.next"], ELECTROSHOCK_TIMER)
+ end
+ end,
+ }
+)
+
+function mod:PopFireOrb()
+ if mod:IsPlayerOnPlatform(FUSION_CORE) then
+ mod:AddMsg("FIRE_ORB_POP_MSG", self.L["fire_orb.pop.msg"], 5, mod:GetSetting("SoundFireOrbPop") == true and "Alarm")
+ end
+end
+
+mod:RegisterUnitEvents("Discharged Plasma",{
+ ["OnUnitCreated"] = function (self, id, unit, name)
+ core:WatchUnit(unit)
+ mod:RemoveTimerBar("NEXT_FIRE_ORB_TIMER")
+ mod:AddTimerBar("NEXT_FIRE_ORB_TIMER", self.L["fire_orb.next"], NEXT_FIRE_ORB_TIMER)
+ mod:AddTimerBar(string.format("FIRE_ORB_SAFE_TIMER %d", id), self.L["fire_orb.pop.timer"], FIRE_ORB_SAFE_TIMER, false, "Red", mod.PopFireOrb, mod)
+ fireOrbTargetTestTimer:Start()
+ orbUnits[id] = {
+ unit = unit,
+ checkedTarget = false,
+ popMessageSent = false,
+ timer = testTimer
+ }
+ end,
+ ["OnUnitDestroyed"] = function (self, id, unit, name)
+ orbUnits[id] = nil
+ mod:RemoveTimerBar(string.format("FIRE_ORB_SAFE_TIMER %d", id))
end,
}
)
--- mod:RegisterUnitEvents({"Friendly Invisible Unit for Fields"},{
--- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
--- core:AddPixie(nId, 2, tUnit, nil, "Green", 10, 50, 0)
--- core:AddPixie(nId, 2, tUnit, nil, "Green", 10, 20, 180)
--- end,
--- ["OnUnitDestroyed"] = function (self, nId, tUnit, sName)
--- core:DropPixie(nId)
--- end,
--- }
--- )
+function mod:RegisterOrbTarget()
+ for orbId, orbUnit in pairs(orbUnits) do
+ if not orbUnit.checkedTarget then
+ orbUnit.checkedTarget = true
+ local target = orbUnit.unit:GetTarget()
+ local isOnMyself = target == player.unit
+ if isOnMyself then
+ mod:AddMsg("DISCHARGED_PLASMA_MSG", self.L["fire_orb.you"], 5, mod:GetSetting("SoundFireOrb") == true and "RunAway")
+ elseif mod:IsPlayerOnPlatform(FUSION_CORE) then
+ mod:AddMsg("DISCHARGED_PLASMA_MSG", self.L["fire_orb.spawned"], 2, mod:GetSetting("SoundFireOrbAlt") == true and "Info")
+ end
+ end
+ end
+end
diff --git a/Encounters/RMT/Mordechai.lua b/Encounters/RMT/Mordechai.lua
index 6fa3b85..51a3b36 100644
--- a/Encounters/RMT/Mordechai.lua
+++ b/Encounters/RMT/Mordechai.lua
@@ -16,6 +16,7 @@ if not mod then return end
----------------------------------------------------------------------------------------------------
mod:RegisterTrigMob("ALL", { "Mordechai Redmoon" })
mod:RegisterEnglishLocale({
+ -- Unit names.
["Mordechai Redmoon"] = "Mordechai Redmoon"
})
----------------------------------------------------------------------------------------------------
@@ -36,28 +37,28 @@ function mod:OnBossEnable()
end
-function mod:OnBuffAdd(nId, nSpellId, nStack, fTimeRemaining)
+function mod:OnBuffAdd(id, spellId, stack, timeRemaining)
end
-function mod:OnCastStart(nId, sCastName, nCastEndTime, sName)
+function mod:OnCastStart(id, castName, castEndTime, name)
end
-function mod:OnDebuffAdd(nId, nSpellId, nStack, fTimeRemaining)
+function mod:OnDebuffAdd(id, spellId, stack, timeRemaining)
end
-function mod:OnUnitDestroyed(nId, tUnit, sName)
+function mod:OnUnitDestroyed(id, tUnit, name)
end
-function mod:OnUnitCreated(nId, unit, sName)
+function mod:OnUnitCreated(id, unit, name)
end
mod:RegisterUnitEvents("Mordechai Redmoon",{
- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
- core:AddUnit(tUnit)
- core:WatchUnit(tUnit)
+ ["OnUnitCreated"] = function (self, id, unit, name)
+ core:AddUnit(unit)
+ core:WatchUnit(unit)
end,
}
)
diff --git a/Encounters/RMT/Robomination.lua b/Encounters/RMT/Robomination.lua
index 22de6ad..a00f0c1 100644
--- a/Encounters/RMT/Robomination.lua
+++ b/Encounters/RMT/Robomination.lua
@@ -16,22 +16,22 @@ if not mod then return end
----------------------------------------------------------------------------------------------------
mod:RegisterTrigMob("ANY", { "Robomination" })
mod:RegisterEnglishLocale({
- --Unit names.
+ -- Unit names.
["Robomination"] = "Robomination",
["Trash Compactor"] = "Trash Compactor",
["Cannon Arm"] = "Cannon Arm",
["Flailing Arm"] = "Flailing Arm",
["Scanning Eye"] = "Scanning Eye",
- --Casts
+ -- Cast names.
["Cannon Fire"] = "Cannon Fire",
["Incineration Laser"] = "Incineration Laser",
["Noxious Belch"] = "Noxious Belch",
- --Datachron
- ["Robomination tries to crush"] = "Robomination tries to crush",
- ["The Robomination tries to incinerate"] = "The Robomination tries to incinerate",
+ -- Datachron.
+ ["Robomination tries to crush ([^%s]+%s[^!]+)!$"] = "Robomination tries to crush ([^%s]+%s[^!]+)!$",
+ ["Robomination tries to incinerate ([^%s]+%s.+)$"] = "Robomination tries to incinerate ([^%s]+%s.+)$",
["The Robomination sinks down into the trash."] = "The Robomination sinks down into the trash.",
["The Robomination erupts back into the fight!"] = "The Robomination erupts back into the fight!",
- --Message bars
+ -- Messages.
["SNAKE ON %s"] = "SNAKE ON %s",
["SNAKE ON YOU"] = "SNAKE ON YOU",
["SNAKE NEAR ON %s"] = "SNAKE NEAR ON %s",
@@ -50,19 +50,28 @@ mod:RegisterEnglishLocale({
----------------------------------------------------------------------------------------------------
-- Constants.
----------------------------------------------------------------------------------------------------
-local NO_BREAK_SPACE = string.char(194, 160)
+-- Spell ids.
local DEBUFF_SNAKE = 75126
+
+-- Phases.
local DPS_PHASE = 1
local MAZE_PHASE = 2
local MID_MAZE_PHASE = 3
+
+-- Timers.
local FIRST_SNAKE_TIMER = 7.5
local SNAKE_TIMER = 17.5
+
local FIRST_INCINERATE_TIMER = 18.5
local INCINERATE_TIMER = 42.5
+
local FIRST_SPEW_TIMER = 15.6
local SPEW_TIMER = 31.75
local MAZE_SPEW_TIMER = 10
+
local ARMS_TIMER = 45
+
+-- Compactors.
local COMPACTORS_EDGE = {
{ y = -203.4208984375, x = 0.71257400512695, z = -1349.8697509766 },
{ y = -203.4208984375, x = 10.955376625061, z = -1339.6927490234 },
@@ -125,40 +134,40 @@ function mod:OnBossEnable()
mod:DrawCompactorGrid()
end
-mod:RegisterDatachronEvent("Robomination tries to crush", "FIND", function (self, sMessage)
- local sSnakeTarget = GetPlayerUnitByName(string.match(sMessage, self.L["Robomination tries to crush"].." ".."([^%s]+%s[^!]+)!$"))
- local bIsOnMyself = sSnakeTarget == playerUnit
- local bSnakeNearYou = not bIsOnMyself and mod:GetDistanceBetweenUnits(playerUnit, sSnakeTarget) < 10
- local sSound = nil
- local sSnakeOnX = ""
- if bIsOnMyself then
- sSound = mod:GetSetting("SoundSnake") == true and "RunAway"
- sSnakeOnX = self.L["SNAKE ON YOU"]
- elseif bSnakeNearYou then
+mod:RegisterDatachronEvent("Robomination tries to crush ([^%s]+%s[^!]+)!$", "MATCH", function (self, message, snakeTargetName)
+ local snakeTarget = GetPlayerUnitByName(snakeTargetName)
+ local isOnMyself = snakeTarget == playerUnit
+ local isSnakeNearYou = not isOnMyself and mod:GetDistanceBetweenUnits(playerUnit, snakeTarget) < 10
+ local sound = nil
+ local snakeOnX = ""
+ if isOnMyself then
+ sound = mod:GetSetting("SoundSnake") == true and "RunAway"
+ snakeOnX = self.L["SNAKE ON YOU"]
+ elseif isSnakeNearYou then
if mod:GetSetting("SoundSnakeNear") then
if mod:GetSetting("SoundSnakeNearAlt") then
- sSound = "Destruction"
+ sound = "Destruction"
else
- sSound = "RunAway"
+ sound = "RunAway"
end
end
- sSnakeOnX = self.L["SNAKE NEAR ON %s"]:format(sSnakeTarget:GetName())
+ snakeOnX = self.L["SNAKE NEAR ON %s"]:format(snakeTarget:GetName())
else
- sSnakeOnX = self.L["SNAKE ON %s"]:format(sSnakeTarget:GetName())
+ snakeOnX = self.L["SNAKE ON %s"]:format(snakeTarget:GetName())
end
if mod:GetSetting("CrosshairSnake") then
- core:AddPicture("SNAKE_CROSSHAIR", sSnakeTarget:GetId(), "Crosshair", 20)
+ core:AddPicture("SNAKE_CROSSHAIR", snakeTarget:GetId(), "Crosshair", 20)
end
mod:RemoveTimerBar("NEXT_SNAKE_TIMER")
core:AddTimerBar("NEXT_SNAKE_TIMER", self.L["Next snake in"], SNAKE_TIMER, nil, { sColor = "xkcdBrown" })
- mod:AddMsg("SNAKE_MSG", sSnakeOnX, 5, sSound, "Blue")
+ mod:AddMsg("SNAKE_MSG", snakeOnX, 5, sound, "Blue")
end
)
-mod:RegisterDatachronEvent("The Robomination sinks down into the trash.", "MATCH", function (self, sMessage)
+mod:RegisterDatachronEvent("The Robomination sinks down into the trash.", "EQUAL", function (self, message)
phase = MAZE_PHASE
core:RemoveMsg("ROBO_MAZE")
mod:RemoveTimerBar("NEXT_SNAKE_TIMER")
@@ -173,7 +182,7 @@ mod:RegisterDatachronEvent("The Robomination sinks down into the trash.", "MATCH
end
)
-mod:RegisterDatachronEvent("The Robomination erupts back into the fight!", "MATCH", function (self, sMessage)
+mod:RegisterDatachronEvent("The Robomination erupts back into the fight!", "EQUAL", function (self, message)
phase = DPS_PHASE
core:RemoveLineBetweenUnits("ROBO_MAZE_LINE")
core:AddTimerBar("NEXT_SNAKE_TIMER", self.L["Next snake in"], FIRST_SNAKE_TIMER, nil, { sColor = "xkcdBrown" })
@@ -184,24 +193,24 @@ mod:RegisterDatachronEvent("The Robomination erupts back into the fight!", "MATC
end
)
-mod:RegisterDatachronEvent("Robomination tries to incinerate", "FIND", function (self, sMessage)
- local tLaserTarget = GetPlayerUnitByName(string.match(sMessage, self.L["Robomination tries to incinerate"].." ".."([^%s]+%s.+)$"))
- local bIsOnMyself = tLaserTarget == playerUnit
- local sSound = mod:GetSetting("SoundLaser") == true and "Burn"
- local sLaserOnX = ""
- if bIsOnMyself then
- sLaserOnX = self.L["LASER ON YOU"]
+mod:RegisterDatachronEvent("Robomination tries to incinerate ([^%s]+%s.+)$", "MATCH", function (self, message, laserTargetName)
+ local laserTarget = GetPlayerUnitByName(laserTargetName)
+ local isOnMyself = laserTarget == playerUnit
+ local sound = mod:GetSetting("SoundLaser") == true and "Burn"
+ local laserOnX = ""
+ if isOnMyself then
+ laserOnX = self.L["LASER ON YOU"]
else
- sLaserOnX = self.L["LASER ON %s"]:format(tLaserTarget:GetName())
+ laserOnX = self.L["LASER ON %s"]:format(laserTarget:GetName())
end
if mod:GetSetting("CrosshairLaser") then
- core:AddPicture("LASER_CROSSHAIR", tLaserTarget:GetId(), "Crosshair", 30, 0, 0, nil, "Red")
+ core:AddPicture("LASER_CROSSHAIR", laserTarget:GetId(), "Crosshair", 30, 0, 0, nil, "Red")
end
mod:RemoveTimerBar("NEXT_INCINERATE_TIMER")
core:AddTimerBar("NEXT_INCINERATE_TIMER", self.L["Next incinerate in"], INCINERATE_TIMER, nil, { sColor = "red", bEmphasize = mod:GetSetting("SoundLaser") })
- mod:AddMsg("LASER_MSG", sLaserOnX, 5, sSound, "Red")
+ mod:AddMsg("LASER_MSG", laserOnX, 5, sound, "Red")
end
)
@@ -232,8 +241,8 @@ function mod:HelperCompactorGrid(compactors, isCorner, isAdding)
end
end
-function mod:OnDebuffRemove(nId, nSpellId, nStack, fTimeRemaining)
- if nSpellId == DEBUFF_SNAKE then
+function mod:OnDebuffRemove(id, spellId, stack, timeRemaining)
+ if spellId == DEBUFF_SNAKE then
core:RemovePicture("SNAKE_CROSSHAIR")
end
end
@@ -244,26 +253,26 @@ mod:RegisterUnitEvents({
"Robomination",
"Scanning Eye",
},{
- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
- core:AddUnit(tUnit)
+ ["OnUnitCreated"] = function (self, id, unit, name)
+ core:AddUnit(unit)
end,
}
)
mod:RegisterUnitEvents("Scanning Eye",{
- ["OnUnitDestroyed"] = function (self, nId, tUnit, sName)
+ ["OnUnitDestroyed"] = function (self, id, unit, name)
phase = MID_MAZE_PHASE
end,
}
)
mod:RegisterUnitEvents({"Cannon Arm", "Flailing Arm"},{
- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
+ ["OnUnitCreated"] = function (self, id, unit, name)
if phase == MID_MAZE_PHASE then
mazeArmCount = mazeArmCount + 1
end
end,
- ["OnUnitDestroyed"] = function (self, nId, tUnit, sName)
+ ["OnUnitDestroyed"] = function (self, id, unit, name)
if phase == MID_MAZE_PHASE then
mazeArmCount = mazeArmCount - 1
if mazeArmCount == 0 then
@@ -279,65 +288,65 @@ mod:RegisterUnitEvents({"Cannon Arm", "Flailing Arm"},{
function mod:RedrawCannonArmLines()
if mod:GetSetting("LineCannonArm") then
- for nId, tUnit in pairs(cannonArms) do
- core:AddLineBetweenUnits(string.format("CANNON_ARM_LINE %d", nId), playerUnit:GetId(), nId, 5)
+ for id, tUnit in pairs(cannonArms) do
+ core:AddLineBetweenUnits(string.format("CANNON_ARM_LINE %d", id), playerUnit:GetId(), id, 5)
end
end
end
function mod:RemoveCannonArmLines()
if mod:GetSetting("LineCannonArm") then
- for nId, tUnit in pairs(cannonArms) do
- core:RemoveLineBetweenUnits(string.format("CANNON_ARM_LINE %d", nId))
+ for id, tUnit in pairs(cannonArms) do
+ core:RemoveLineBetweenUnits(string.format("CANNON_ARM_LINE %d", id))
end
end
end
mod:RegisterUnitEvents("Cannon Arm",{
- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
- cannonArms[nId] = tUnit
- core:WatchUnit(tUnit)
+ ["OnUnitCreated"] = function (self, id, unit, name)
+ cannonArms[id] = unit
+ core:WatchUnit(unit)
if mod:GetSetting("LineCannonArm") then
- core:AddLineBetweenUnits(string.format("CANNON_ARM_LINE %d", nId), playerUnit:GetId(), nId, 5)
+ core:AddLineBetweenUnits(string.format("CANNON_ARM_LINE %d", id), playerUnit:GetId(), id, 5)
end
if phase == DPS_PHASE then
mod:AddTimerBar("NEXT_ARMS_TIMER", self.L["Arms spawning in"], ARMS_TIMER)
end
mod:AddMsg("ARMS_MSG", self.L["Cannon arm spawned"], 5, mod:GetSetting("SoundArmSpawn") == true and "Info", "Red")
end,
- ["OnCastStart"] = function (self, nId, sCastName, nCastEndTime, sName)
- if self.L["Cannon Fire"] == sCastName then
- if mod:GetDistanceBetweenUnits(playerUnit, GetUnitById(nId)) < 45 then
+ ["OnCastStart"] = function (self, id, castName, castEndTime, name)
+ if self.L["Cannon Fire"] == castName then
+ if mod:GetDistanceBetweenUnits(playerUnit, GetUnitById(id)) < 45 then
mod:AddMsg("ARMS_MSG", self.L["INTERRUPT CANNON!"], 2, mod:GetSetting("SoundCannonInterrupt") == true and "Inferno")
end
end
end,
- ["OnUnitDestroyed"] = function (self, nId, tUnit, sName)
- cannonArms[nId] = nil
- core:RemoveLineBetweenUnits(string.format("CANNON_ARM_LINE %d", nId))
+ ["OnUnitDestroyed"] = function (self, id, unit, name)
+ cannonArms[id] = nil
+ core:RemoveLineBetweenUnits(string.format("CANNON_ARM_LINE %d", id))
end,
}
)
mod:RegisterUnitEvents("Robomination",{
- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
- core:WatchUnit(tUnit)
- roboUnit = tUnit
+ ["OnUnitCreated"] = function (self, id, unit, name)
+ core:WatchUnit(unit)
+ roboUnit = unit
end,
- ["OnHealthChanged"] = function (self, nId, nPourcent, sName)
- if nPourcent >= 75.5 and nPourcent <= 76.5 then
+ ["OnHealthChanged"] = function (self, id, percent, name)
+ if percent >= 75.5 and percent <= 76.5 then
mod:AddMsg("ROBO_MAZE", self.L["MAZE SOON!"], 5, mod:GetSetting("SoundPhaseChangeClose") and "Info")
end
end,
- ["OnCastStart"] = function (self, nId, sCastName, nCastEndTime, sName)
- if self.L["Noxious Belch"] == sCastName then
+ ["OnCastStart"] = function (self, id, castName, castEndTime, name)
+ if self.L["Noxious Belch"] == castName then
mod:RemoveTimerBar("NEXT_SPEW_TIMER")
core:AddTimerBar("NEXT_SPEW_TIMER", self.L["Next spew in"], SPEW_TIMER, nil, { sColor = "green" })
mod:AddMsg("SPEW_MSG", self.L["Spew!"], 4, mod:GetSetting("SoundSpew") == true and "Beware")
end
end,
- ["OnCastEnd"] = function (self, nId, sCastName, isInterrupted, nCastEndTime, sName)
- if self.L["Incineration Laser"] == sCastName then
+ ["OnCastEnd"] = function (self, id, castName, isInterrupted, castEndTime, name)
+ if self.L["Incineration Laser"] == castName then
core:RemovePicture("LASER_CROSSHAIR")
end
end,
diff --git a/Encounters/RMT/Shredder.lua b/Encounters/RMT/Shredder.lua
index 6c9a8f3..e491a4d 100644
--- a/Encounters/RMT/Shredder.lua
+++ b/Encounters/RMT/Shredder.lua
@@ -22,7 +22,7 @@ if not mod then return end
----------------------------------------------------------------------------------------------------
mod:RegisterTrigMob("ALL", { "Swabbie Ski'Li" })
mod:RegisterEnglishLocale({
- --Unit names
+ -- Unit names.
["Swabbie Ski'Li"] = "Swabbie Ski'Li",
["Sawblade"] = "Sawblade", -- big saw
["Saw"] = "Saw", -- little saw
@@ -38,7 +38,7 @@ mod:RegisterEnglishLocale({
["Junk Trap"] = "Junk Trap",
-- Datachron messages.
["WARNING: THE SHREDDER IS STARTING!"] = "WARNING: THE SHREDDER IS STARTING!",
- --Cast names
+ -- Cast names.
["Swabbie Swoop"] = "Swabbie Swoop",
["Risen Repellent"] = "Risen Repellent",
["Crush"] = "Crush",
@@ -46,33 +46,13 @@ mod:RegisterEnglishLocale({
["Deathwail"] = "Deathwail",
["Necrotic Lash"] = "Necrotic Lash",
["Swabbie Swoop"] = "Swabbie Swoop",
- --Messages
+ -- Messages.
["%d BILE STACKS!"] = "%d BILE STACKS!",
- })
-
-mod:RegisterFrenchLocale({
- -- --Unit names
- -- ["Swabbie Ski'Li"] = "Swabbie Ski'Li",
- -- ["Sawblade"] = "Sawblade", -- big saw
- -- ["Saw"] = "Saw", -- little saw
- -- ["Noxious Nabber"] = "Noxious Nabber",
- -- ["Risen Redmoon Grunt"] = "Risen Redmoon Grunt",
- -- ["Regor the Rancid"] = "Regor the Rancid",
- -- ["Braugh the Bloated"] = "Braugh the Bloated",
- -- ["Bilious Brute"] = "Bilious Brute",
- -- ["Putrid Pouncer"] = "Putrid Pouncer",
- -- ["Risen Redmoon Plunderer"] = "Risen Redmoon Plunderer",
- -- ["Risen Redmoon Cadet"] = "Risen Redmoon Cadet",
- -- -- Datachron messages.
- -- ["WARNING: THE SHREDDER IS STARTING!"] = "WARNING: THE SHREDDER IS STARTING!",
- -- --Cast names
- -- ["Swabbie Swoop"] = "Swabbie Swoop",
- -- ["Risen Repellent"] = "Risen Repellent",
- -- ["Crush"] = "Crush",
- -- ["Gravedigger"] = "Gravedigger",
- -- ["Deathwail"] = "Deathwail",
- -- ["Necrotic Lash"] = "Necrotic Lash",
- -- ["Swabbie Swoop"] = "Swabbie Swoop",
+ ["SAW IN MIDDLE"] = "SAW IN MIDDLE",
+ ["SAFE SPOT %s"] = "SAFE SPOT %s",
+ ["LEFT"] = "LEFT",
+ ["MIDDLE"] = "MIDDLE",
+ ["RIGHT"] = "RIGHT",
})
----------------------------------------------------------------------------------------------------
-- Settings
@@ -87,6 +67,8 @@ mod:RegisterDefaultSetting("SoundMiniboss")
mod:RegisterDefaultSetting("SoundNecroticLash")
mod:RegisterDefaultSetting("SoundMinibossCast")
mod:RegisterDefaultSetting("SoundOozeStacksWarning")
+mod:RegisterDefaultSetting("SoundMidSawWarning")
+mod:RegisterDefaultSetting("SoundSawSafeSpot")
----------------------------------------------------------------------------------------------------
-- Constants.
----------------------------------------------------------------------------------------------------
@@ -108,23 +90,46 @@ function circular(t)
return setmetatable(t, lmt)
end
+-- Coordinates
local START_POSITION = Vector3.New({x = -20.054916381836,y = 597.66021728516,z = -809.42694091797})
local END_POSITION = Vector3.New({x = -20.499969482422,y = 597.88836669922,z = -973.21472167969})
local WALKING_DISTANCE = (END_POSITION-START_POSITION):Length()
-local NO_BREAK_SPACE = string.char(194, 160)
+
+-- Phases.
local WALKING = 0
local SHREDDER = 1
local ADD_PHASES = circular{ 11, 45, 66, 0 }
+
+-- Spell ids.
local DEBUFF_OOZING_BILE = 84321
+
+-- Saw stuff.
+local WEST_POSITION = -42
+local MIDDLE_WEST_POSITION = -28
+local MIDDLE_EAST_POSITION = -14
+local EAST_POSITION = 0
+local SAW_WEST = 1
+local SAW_MID = 2
+local SAW_WEST = 4
+local SAW_SAFESPOT = {
+ [3] = "LEFT", --SAW_WEST + SAW_MID
+ [5] = "MIDDLE", --SAW_WEST + SAW_EAST
+ [6] = "RIGHT", --SAW_MID + SAW_EAST
+}
----------------------------------------------------------------------------------------------------
--- Locals.
+-- Functions.
----------------------------------------------------------------------------------------------------
local GetUnitById = GameLib.GetUnitById
local GetPlayerUnit = GameLib.GetPlayerUnit
local GetGameTime = GameLib.GetGameTime
+----------------------------------------------------------------------------------------------------
+-- Locals.
+----------------------------------------------------------------------------------------------------
local phase
local addPhase
local previousAddPhase
+local firstShredderSaw
+local secondShredderSaw
----------------------------------------------------------------------------------------------------
-- Encounter description.
-----------------------------------------------------------------------------------------------------
@@ -133,12 +138,14 @@ function mod:OnBossEnable()
phase = WALKING
addPhase = 4
previousAddPhase = 0
+ firstShredderSaw = nil
+ secondShredderSaw = nil
end
-function mod:OnDebuffUpdate(nId, nSpellId, nStack, fTimeRemaining)
- if DEBUFF_OOZING_BILE == nSpellId then
- if GameLib.GetPlayerUnit():GetId() == nId and nStack >= 8 then
- mod:AddMsg("OOZE_MSG", string.format(self.L["%d BILE STACKS!"], nStack), 5, nStack == 8 and mod:GetSetting("SoundOozeStacksWarning") and "Beware")
+function mod:OnDebuffUpdate(id, spellId, stack, timeRemaining)
+ if DEBUFF_OOZING_BILE == spellId then
+ if GameLib.GetPlayerUnit():GetId() == id and stack >= 8 then
+ mod:AddMsg("OOZE_MSG", string.format(self.L["%d BILE STACKS!"], stack), 5, stack == 8 and mod:GetSetting("SoundOozeStacksWarning") and "Beware")
end
end
end
@@ -176,23 +183,25 @@ function mod:NextAddWave()
end
function mod:PhaseChange()
- local sText = "Walking "
+ local text = "Walking "
if phase == SHREDDER then
phase = WALKING
- sText = sText.." North"
+ text = text.." North"
mod:NextAddWave()
else
- sText = sText.." South"
+ text = text.." South"
phase = SHREDDER
+ firstShredderSaw = nil
+ secondShredderSaw = nil
end
- mod:AddProgressBar("WALKING_PROGRESS", sText, mod.GetWalkingProgress, mod, mod.PhaseChange)
+ mod:AddProgressBar("WALKING_PROGRESS", text, mod.GetWalkingProgress, mod, mod.PhaseChange)
end
function mod:StartProgressBar()
mod:AddProgressBar("WALKING_PROGRESS", "Walking North", mod.GetWalkingProgress, mod, mod.PhaseChange)
mod:NextAddWave()
- _tStartProgressBar:Stop()
- _tStartProgressBar = nil
+ startProgressBarTimer:Stop()
+ startProgressBarTimer = nil
end
mod:RegisterUnitEvents({
@@ -205,75 +214,110 @@ mod:RegisterUnitEvents({
"Risen Redmoon Plunderer",
"Risen Redmoon Cadet"
},{
- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
- core:WatchUnit(tUnit)
+ ["OnUnitCreated"] = function (self, id, unit, name)
+ core:WatchUnit(unit)
end,
- ["OnUnitDestroyed"] = function (self, nId, tUnit, sName)
- core:RemovePicture(nId)
+ ["OnUnitDestroyed"] = function (self, id, unit, name)
+ core:RemovePicture(id)
end,
- ["OnHealthChanged"] = function (self, nId, nPourcent, sName)
- if nPourcent <= 1 and mod:GetSetting("CrosshairAdds") then
- core:AddPicture(nId, nId, "Crosshair", 20)
+ ["OnHealthChanged"] = function (self, id, percent, name)
+ if percent <= 1 and mod:GetSetting("CrosshairAdds") then
+ core:AddPicture(id, id, "Crosshair", 20)
end
end,
}
)
mod:RegisterUnitEvents({ "Bilious Brute", "Noxious Nabber" },{
- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
+ ["OnUnitCreated"] = function (self, id, unit, name)
if mod:GetSetting("CrosshairPriority") then
- core:AddPicture(nId, nId, "Crosshair", 30, 0, 0, nil, "red")
+ core:AddPicture(id, id, "Crosshair", 30, 0, 0, nil, "red")
end
end,
}
)
mod:RegisterUnitEvents("Swabbie Ski'Li",{
- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
- core:AddUnit(tUnit)
- core:WatchUnit(tUnit)
- self.swabbieUnit = tUnit
+ ["OnUnitCreated"] = function (self, id, unit, name)
+ core:AddUnit(unit)
+ core:WatchUnit(unit)
+ self.swabbieUnit = unit
end,
- ["OnUnitDestroyed"] = function (self, nId, tUnit, sName)
- core:RemoveUnit(tUnit)
+ ["OnUnitDestroyed"] = function (self, id, unit, name)
+ core:RemoveUnit(unit)
self:RemoveProgressBar("WALKING_PROGRESS")
self:RemoveProgressBar("ADDS_PROGRESS")
end,
- ["OnCastStart"] = function (self, nId, sCastName, nCastEndTime, sName)
- if self.L["Risen Repellent"] == sCastName then
+ ["OnCastStart"] = function (self, id, castName, castEndTime, name)
+ if self.L["Risen Repellent"] == castName then
mod:AddMsg("KNOCKBACK", "KNOCKBACK", 2)
end
end,
- ["OnCastEnd"] = function (self, nId, sCastName, isInterrupted, nCastEndTime, sName)
- if self.L["Swabbie Swoop"] == sCastName then
- _tStartProgressBar = ApolloTimer.Create(1, true, "StartProgressBar", mod)
- _tStartProgressBar:Start()
+ ["OnCastEnd"] = function (self, id, castName, isInterrupted, castEndTime, name)
+ if self.L["Swabbie Swoop"] == castName then
+ startProgressBarTimer = ApolloTimer.Create(1, true, "StartProgressBar", mod)
+ startProgressBarTimer:Start()
end
end,
}
)
+function mod:DetermineSawLocation(unit)
+ local x = unit:GetPosition().x
+ if WEST_POSITION < x and x < MIDDLE_WEST_POSITION then
+ return SAW_WEST
+ elseif MIDDLE_WEST_POSITION < x and x < MIDDLE_EAST_POSITION then
+ return SAW_MID
+ elseif MIDDLE_EAST_POSITION < x and x < EAST_POSITION then
+ return SAW_EAST
+ end
+end
+
+function mod:HandleShredderSaw(sawLocation)
+ if firstShredderSaw == nil then
+ firstShredderSaw = sawLocation
+ return
+ elseif secondShredderSaw == nil then
+ secondShredderSaw = sawLocation
+ else
+ return
+ end
+
+ local safeSpotLocation = SAW_SAFESPOT[firstShredderSaw + secondShredderSaw]
+ local message = string.format(self.L["SAFE SPOT %s"], self.L[safeSpotLocation])
+ local sound = mod:GetSetting("SoundSawSafeSpot") == true and "Info"
+ mod:AddMsg("SAW_MSG", message, 5, sound)
+end
+
mod:RegisterUnitEvents("Sawblade",{
- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
+ ["OnUnitCreated"] = function (self, id, unit, name)
if mod:GetSetting("LineSawblade") then
- core:AddPixie(nId, 2, tUnit, nil, "Red", 10, 60, 0)
+ core:AddPixie(id, 2, unit, nil, "Red", 10, 60, 0)
+ end
+ local sawLocation = mod:DetermineSawLocation(unit)
+ if phase == WALKING and sawLocation == SAW_MID then
+ mod:AddMsg("SAW_MSG", self.L["SAW IN MIDDLE"], 5,
+ mod:GetSetting("SoundMidSawWarning") == true and "Beware"
+ )
+ elseif phase == SHREDDER then
+ mod:HandleShredderSaw(sawLocation)
end
end,
- ["OnUnitDestroyed"] = function (self, nId, tUnit, sName)
- core:DropPixie(nId)
+ ["OnUnitDestroyed"] = function (self, id, unit, name)
+ core:DropPixie(id)
end,
}
)
mod:RegisterUnitEvents("Noxious Nabber",{
- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
+ ["OnUnitCreated"] = function (self, id, unit, name)
core:RemoveMsg("ADDS_MSG")
mod:AddMsg("ADDS_MSG", "NOXIOUS NABBER SPAWNED", 5, mod:GetSetting("SoundAdds") and "Info")
end,
- ["OnCastStart"] = function (self, nId, sCastName, nCastEndTime, sName)
- if self.L["Necrotic Lash"] == sCastName then
- local tUnit = GetUnitById(nId)
- if mod:GetDistanceBetweenUnits(playerUnit, tUnit) < 45 and sSpellName == sCastName then
+ ["OnCastStart"] = function (self, id, castName, castEndTime, name)
+ if self.L["Necrotic Lash"] == castName then
+ local unit = GetUnitById(id)
+ if mod:GetDistanceBetweenUnits(playerUnit, unit) < 45 and sSpellName == castName then
mod:AddMsg("NABBER", "INTERRUPT NECROTIC LASH!", 5, mod:GetSetting("SoundNecroticLash") == true and "Inferno")
end
end
@@ -282,13 +326,13 @@ mod:RegisterUnitEvents("Noxious Nabber",{
)
mod:RegisterUnitEvents({"Regor the Rancid", "Braugh the Bloated"},{
- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
+ ["OnUnitCreated"] = function (self, id, unit, name)
mod:AddMsg("MINIBOSS", "MINIBOSS SPAWNED", 5, mod:GetSetting("SoundMiniboss") and "Info")
end,
- ["OnCastStart"] = function (self, nId, sCastName, nCastEndTime, sName)
- if self.L["Gravedigger"] == sCastName or
- self.L["Deathwail"] == sCastName or
- self.L["Crush"] == sCastName then
+ ["OnCastStart"] = function (self, id, castName, castEndTime, name)
+ if self.L["Gravedigger"] == castName or
+ self.L["Deathwail"] == castName or
+ self.L["Crush"] == castName then
core:RemoveMsg("MINIBOSS")
mod:AddMsg("MINIBOSS", "INTERRUPT MINIBOSS!", 5, mod:GetSetting("SoundMinibossCast") and "Inferno")
end
@@ -297,25 +341,25 @@ mod:RegisterUnitEvents({"Regor the Rancid", "Braugh the Bloated"},{
)
mod:RegisterUnitEvents("Tether Anchor",{
- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
+ ["OnUnitCreated"] = function (self, id, unit, name)
if mod:GetSetting("CrosshairTether") then
- core:AddPicture(nId, nId, "Crosshair", 25, 0, 0, nil, "FFFFF569")
+ core:AddPicture(id, id, "Crosshair", 25, 0, 0, nil, "FFFFF569")
end
end,
- ["OnUnitDestroyed"] = function (self, nId, tUnit, sName)
- core:RemovePicture(nId)
+ ["OnUnitDestroyed"] = function (self, id, unit, name)
+ core:RemovePicture(id)
end,
}
)
mod:RegisterUnitEvents("Junk Trap",{
- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
+ ["OnUnitCreated"] = function (self, id, unit, name)
if mod:GetSetting("SquareTethers") then
- core:AddPolygon(nId, nId, 5, 45, 6, nil, 4)
+ core:AddPolygon(id, id, 5, 45, 6, nil, 4)
end
end,
- ["OnUnitDestroyed"] = function (self, nId, tUnit, sName)
- core:RemovePolygon(nId)
+ ["OnUnitDestroyed"] = function (self, id, unit, name)
+ core:RemovePolygon(id)
end,
}
)
diff --git a/Encounters/RMT/miniboss/Lockjaw.lua b/Encounters/RMT/miniboss/Lockjaw.lua
index 49a3689..cdf42e3 100644
--- a/Encounters/RMT/miniboss/Lockjaw.lua
+++ b/Encounters/RMT/miniboss/Lockjaw.lua
@@ -16,37 +16,27 @@ if not mod then return end
----------------------------------------------------------------------------------------------------
mod:RegisterTrigMob("ALL", { "Chief Warden Lockjaw" })
mod:RegisterEnglishLocale({
+ -- Unit names.
["Chief Warden Lockjaw"] = "Chief Warden Lockjaw",
["Hostile Invisible Unit for Fields (0 hit radius)"] = "Hostile Invisible Unit for Fields (0 hit radius)",
["Blaze Shackle"] = "Blaze Shackle",
+ -- Cast names.
["Blaze Shackles"] = "Blaze Shackles",
})
----------------------------------------------------------------------------------------------------
-- Settings.
----------------------------------------------------------------------------------------------------
mod:RegisterDefaultSetting("CrosshairTethers")
-----------------------------------------------------------------------------------------------------
--- Constants.
-----------------------------------------------------------------------------------------------------
-
-----------------------------------------------------------------------------------------------------
--- Locals.
-----------------------------------------------------------------------------------------------------
-
----------------------------------------------------------------------------------------------------
-- Encounter description.
----------------------------------------------------------------------------------------------------
-function mod:OnBossEnable()
-
-end
-
mod:RegisterUnitEvents("Chief Warden Lockjaw",{
- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
- core:AddUnit(tUnit)
- core:WatchUnit(tUnit)
+ ["OnUnitCreated"] = function (self, id, unit, name)
+ core:AddUnit(unit)
+ core:WatchUnit(unit)
end,
- ["OnCastStart"] = function (self, nId, sCastName, nCastEndTime, sName)
- if self.L["Blaze Shackles"] == sCastName then
+ ["OnCastStart"] = function (self, id, castName, castEndTime, name)
+ if self.L["Blaze Shackles"] == castName then
mod:AddMsg("CIRCLES", "DODGE CIRCLES", 5, "Info")
end
end,
@@ -54,13 +44,13 @@ mod:RegisterUnitEvents("Chief Warden Lockjaw",{
)
mod:RegisterUnitEvents("Blaze Shackle",{
- ["OnUnitCreated"] = function (self, nId, tUnit, sName)
+ ["OnUnitCreated"] = function (self, id, unit, name)
if mod:GetSetting("CrosshairTethers") then
- core:AddPicture(nId, nId, "Crosshair", 25)
+ core:AddPicture(id, id, "Crosshair", 25)
end
end,
- ["OnUnitDestroyed"] = function (self, nId, tUnit, sName)
- core:RemovePicture(nId)
+ ["OnUnitDestroyed"] = function (self, id, unit, name)
+ core:RemovePicture(id)
end,
}
)
diff --git a/Encounters/RMT/miniboss/Skooty.lua b/Encounters/RMT/miniboss/Skooty.lua
new file mode 100644
index 0000000..86c7309
--- /dev/null
+++ b/Encounters/RMT/miniboss/Skooty.lua
@@ -0,0 +1,75 @@
+----------------------------------------------------------------------------------------------------
+-- Client Lua Script for RaidCore Addon on WildStar Game.
+--
+-- Copyright (C) 2015 RaidCore
+----------------------------------------------------------------------------------------------------
+----------------------------------------------------------------------------------------------------
+-- Description:
+-- TODO
+----------------------------------------------------------------------------------------------------
+local core = Apollo.GetPackage("Gemini:Addon-1.1").tPackage:GetAddon("RaidCore")
+local mod = core:NewEncounter("Skooty", 104, 548, 552)
+if not mod then return end
+
+----------------------------------------------------------------------------------------------------
+-- Registering combat.
+----------------------------------------------------------------------------------------------------
+mod:RegisterTrigMob("ALL", { "Assistant Technician Skooty" })
+mod:RegisterEnglishLocale({
+ -- Unit names.
+ ["Assistant Technician Skooty"] = "Assistant Technician Skooty",
+ ["Hostile Invisible Unit for Fields (0 hit radius)"] = "Hostile Invisible Unit for Fields (0 hit radius)",
+ ["Jumpstart Charge"] = "Jumpstart Charge",
+ -- Cast names.
+ ["Pulse Cannon"] = "Pulse Cannon",
+ })
+----------------------------------------------------------------------------------------------------
+-- Settings.
+----------------------------------------------------------------------------------------------------
+mod:RegisterDefaultSetting("PulseCannon")
+mod:RegisterDefaultSetting("BombLines")
+----------------------------------------------------------------------------------------------------
+-- Constants.
+----------------------------------------------------------------------------------------------------
+
+----------------------------------------------------------------------------------------------------
+-- Locals.
+----------------------------------------------------------------------------------------------------
+local jumpStarts
+local playerUnit
+----------------------------------------------------------------------------------------------------
+-- Encounter description.
+----------------------------------------------------------------------------------------------------
+function mod:OnBossEnable()
+ playerUnit = GameLib.GetPlayerUnit()
+end
+
+mod:RegisterUnitEvents("Assistant Technician Skooty",{
+ ["OnUnitCreated"] = function (self, id, unit, name)
+ core:AddUnit(unit)
+ core:WatchUnit(unit)
+ end,
+ ["OnCastStart"] = function (self, id, castName, castEndTime, name)
+ if self.L["Pulse Cannon"] == castName then
+ mod:AddMsg("PULSECANNON", "GET OUT", 5, mod:GetSetting("PulseCannon") == true and "RunAway")
+ end
+ end,
+ }
+)
+
+mod:RegisterUnitEvents("Jumpstart Charge",{
+ ["OnUnitCreated"] = function (self, id, unit, name)
+ jumpStarts[id] = unit
+ core:WatchUnit(unit)
+ if mod:GetSetting("BombLines") then
+ core:AddLineBetweenUnits(string.format("JUMP_START_LINE %d", id), playerUnit:GetId(), id, 5)
+ end
+ end,
+ ["OnUnitDestroyed"] = function (self, id, unit, name)
+ jumpStarts[id] = nil
+ if mod:GetSetting("BombLines") then
+ core:RemoveLineBetweenUnits(string.format("JUMP_START_LINE %d", id))
+ end
+ end,
+ }
+)
diff --git a/Encounters/RMT/miniboss/Thrag.lua b/Encounters/RMT/miniboss/Thrag.lua
new file mode 100644
index 0000000..f0bd6a3
--- /dev/null
+++ b/Encounters/RMT/miniboss/Thrag.lua
@@ -0,0 +1,75 @@
+----------------------------------------------------------------------------------------------------
+-- Client Lua Script for RaidCore Addon on WildStar Game.
+--
+-- Copyright (C) 2015 RaidCore
+----------------------------------------------------------------------------------------------------
+----------------------------------------------------------------------------------------------------
+-- Description:
+-- TODO
+----------------------------------------------------------------------------------------------------
+local core = Apollo.GetPackage("Gemini:Addon-1.1").tPackage:GetAddon("RaidCore")
+local mod = core:NewEncounter("Thrag", 104, 548, 552)
+if not mod then return end
+
+----------------------------------------------------------------------------------------------------
+-- Registering combat.
+----------------------------------------------------------------------------------------------------
+mod:RegisterTrigMob("ALL", { "Chief Engine Scrubber Thrag" })
+mod:RegisterEnglishLocale({
+ -- Unit names.
+ ["Chief Engine Scrubber Thrag"] = "Chief Engine Scrubber Thrag",
+ ["Hostile Invisible Unit for Fields (0 hit radius)"] = "Hostile Invisible Unit for Fields (0 hit radius)",
+ ["Jumpstart Charge"] = "Jumpstart Charge",
+ -- Cast names.
+ ["Gigavolt"] = "Gigavolt",
+ })
+----------------------------------------------------------------------------------------------------
+-- Settings.
+----------------------------------------------------------------------------------------------------
+mod:RegisterDefaultSetting("Gigavolt")
+mod:RegisterDefaultSetting("BombLines")
+----------------------------------------------------------------------------------------------------
+-- Constants.
+----------------------------------------------------------------------------------------------------
+
+----------------------------------------------------------------------------------------------------
+-- Locals.
+----------------------------------------------------------------------------------------------------
+local jumpStarts
+local playerUnit
+----------------------------------------------------------------------------------------------------
+-- Encounter description.
+----------------------------------------------------------------------------------------------------
+function mod:OnBossEnable()
+ playerUnit = GameLib.GetPlayerUnit()
+end
+
+mod:RegisterUnitEvents("Chief Engine Scrubber Thrag",{
+ ["OnUnitCreated"] = function (self, id, unit, name)
+ core:AddUnit(unit)
+ core:WatchUnit(unit)
+ end,
+ ["OnCastStart"] = function (self, id, castName, castEndTime, name)
+ if self.L["Gigavolt"] == castName then
+ mod:AddMsg("GIGAVOLT", "GET OUT", 5, mod:GetSetting("Gigavolt") == true and "RunAway")
+ end
+ end,
+ }
+)
+
+mod:RegisterUnitEvents("Jumpstart Charge",{
+ ["OnUnitCreated"] = function (self, id, unit, name)
+ jumpStarts[id] = unit
+ core:WatchUnit(unit)
+ if mod:GetSetting("BombLines") then
+ core:AddLineBetweenUnits(string.format("JUMP_START_LINE %d", id), playerUnit:GetId(), id, 5)
+ end
+ end,
+ ["OnUnitDestroyed"] = function (self, id, unit, name)
+ jumpStarts[id] = nil
+ if mod:GetSetting("BombLines") then
+ core:RemoveLineBetweenUnits(string.format("JUMP_START_LINE %d", id))
+ end
+ end,
+ }
+)
diff --git a/Encounters/TEST/GalerasTest.lua b/Encounters/TEST/GalerasTest.lua
index 5aa07b2..a81b735 100644
--- a/Encounters/TEST/GalerasTest.lua
+++ b/Encounters/TEST/GalerasTest.lua
@@ -46,20 +46,20 @@ mod:RegisterDefaultTimerBarConfigs({
-- Locals.
----------------------------------------------------------------------------------------------------
local function InfiniteTimer2()
- mod:AddTimerBar("INFINITE2", "Loop Timer outside", 10, nil, InfiniteTimer2)
+ mod:AddTimerBar("INFINITE2", "Loop Timer outside", 10, nil, nil, InfiniteTimer2)
end
----------------------------------------------------------------------------------------------------
-- Encounter description.
----------------------------------------------------------------------------------------------------
function mod:OnBossEnable()
- mod:AddTimerBar("INFINITE", "Timer in class", 12, false, mod.InfiniteTimer, mod)
- mod:AddTimerBar("INFINITE2", "Timer outside", 12, nil, InfiniteTimer2)
+ mod:AddTimerBar("INFINITE", "Timer in class", 12, false, nil, mod.InfiniteTimer, mod)
+ mod:AddTimerBar("INFINITE2", "Timer outside", 12, nil, nil, InfiniteTimer2)
mod:AddTimerBar("LONG", "Long long timer...", 1000)
end
function mod:InfiniteTimer()
- mod:AddTimerBar("INFINITE", "Loop Timer in class", 10, false, mod.InfiniteTimer, mod)
+ mod:AddTimerBar("INFINITE", "Loop Timer in class", 10, false, nil, mod.InfiniteTimer, mod)
end
function mod:OnUnitCreated(nId, unit, sName)
diff --git a/README.md b/README.md
index 57cd006..e721024 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@ RaidCore
================
Raidcore is a boss-mods addon for Wildstar game, it's intend to:
- - Aid with fights in Genetic Archives, Datascape and Core-Y83 raids.
+ - Aid with fights in Genetic Archives, Datascape, Core-Y83 and Red Moon Terror Raids.
- It supports the english and french game version, for german some translations are missing.
Please open an issue if you notice problems, or if you have a idea of improvement.
-All rights reserved.
\ No newline at end of file
+All rights reserved.
diff --git a/RaidCore.lua b/RaidCore.lua
index 84be361..3099d72 100644
--- a/RaidCore.lua
+++ b/RaidCore.lua
@@ -32,7 +32,7 @@ local next, pcall = next, pcall
-- Should be 5.23 when replacement tokens will works (see #88 issue).
local RAIDCORE_CURRENT_VERSION = "6"
-- Should be deleted.
-local ADDON_DATE_VERSION = 16082301
+local ADDON_DATE_VERSION = 16090417
-- Sometimes Carbine have inserted some no-break-space, for fun.
-- Behavior seen with French language. This problem is not present in English.
local NO_BREAK_SPACE = string.char(194, 160)
@@ -89,6 +89,9 @@ local function OnEncounterUnitEvents(sMethod, ...)
elseif sMethod == "OnHealthChanged" then
local nId, nPourcent, sName = ...
tEncounter = _tCurrentEncounter.tUnitEvents[sMethod][sName]
+ elseif sMethod == "OnEnteredCombat" then
+ local nId, tUnit, sName, bInCombat = ...
+ tEncounter = _tCurrentEncounter.tUnitEvents[sMethod][sName]
end
if tEncounter then
@@ -107,11 +110,20 @@ local function OnEncounterDatachronEvents(sMethod, ...)
for sSearchMessage, tEvents in pairs(_tCurrentEncounter.tDatachronEvents) do
for _, tEvent in pairs(tEvents) do
local sMessage = ...
- local bMatch = tEvent.bMatch
+ local sMatch = tEvent.sMatch
local fHandler = tEvent.fHandler
- if (bMatch == true and sSearchMessage == sMessage) or
- (bMatch == false and sMessage:find(sSearchMessage)) then
- fHandler(_tCurrentEncounter, ...)
+ local result = nil
+
+ if sMatch == "EQUAL" then
+ result = sSearchMessage == sMessage
+ elseif sMatch == "FIND" then
+ result = sMessage:find(sSearchMessage)
+ elseif sMatch == "MATCH" then
+ result = sMessage:match(sSearchMessage)
+ end
+
+ if result ~= nil then
+ fHandler(_tCurrentEncounter, sMessage, result)
end
end
end
diff --git a/RaidCore.xml b/RaidCore.xml
index ec1ed30..24c7e94 100644
--- a/RaidCore.xml
+++ b/RaidCore.xml
@@ -1544,10 +1544,34 @@