vanilla-wow-addons – Rev 1
?pathlinks?

local mod = klhtm
local me = { }
mod.net = me
--[[
KTM_Net.lua
This module has all the code for operating the chat channel and sending KLHTM messages on it. Note that it doesn't
deal with parsing / interpreting messages received from the chat channel - this is all done in KTM_NetIn.lua.
]]
me.channelname = ""
me.channelnumber = 0
me.source = ""
me.manualchannel = nil -- manual override
me.lastmtsender = "" -- name of the player who sent the last mt
me.lastmtstring = "" -- name of the last mt, as sent by the player
me.lastmttime = 0 -- time you last updated MT
me.mtrepeattime = 10.0
-- Special onupdate method from Core.lua
me.onupdate = function()
me.updatethreattoraid()
me.checkversionquery()
me.checkadvertise()
-- check to repeat mt string
if me.lastmtsender == UnitName("player") then
-- check if you are still an assistant
if mod.unit.isplayerofficer(UnitName("player")) == nil then
me.lastmtsender = ""
elseif GetTime() > me.lastmttime + me.mtrepeattime then
-- resend and reset timer
me.lastmttime = GetTime()
-- Now, was it a clear or a name?
if me.lastmtstring == "clear" then
-- temporary: only send this to new versions (or else old versions might get spammed!)
if mod.isnewwowversion then
me.clearmastertarget()
end
else
-- temporary: only send this to new versions (or else old versions might get spammed!)
if mod.isnewwowversion then
me.sendmessage("mtpoll " .. me.lastmtstring)
end
end
end
end
end
------------------------------------------------------------------------------------------------
---------------------------------
-- Chat Channel Operation --
---------------------------------
-- return: number, name, method
me.getchannel = function()
local name
local number
local test
-- use the current channel, if that works
number, name = GetChannelName(me.channelname)
if number > 0 then
return number, name, me.source
end
-- Channel broken. look for oRA, CT_RA, manual set channels.
-- First priority: manual override
if me.manualchannel then
number, name = GetChannelName(me.manualchannel)
if number > 0 then
me.channelnumber = number
me.channelname = name
me.source = mod.string.get("print", "network", "channel", "manual")
return number, name, me.source
end
end
-- Second priority: oRA
if oRA_Core then
test = oRA_Core:GetOpt("channel")
if test then
number, name = GetChannelName(test)
if number > 0 then
me.channelnumber = number
me.channelname = name
me.source = mod.string.get("print", "network", "channel", "ora")
return number, name, me.source
end
end
end
-- Third priority: CT_RA
if CT_RA_Channel then
number, name = GetChannelName(CT_RA_Channel)
if number > 0 then
me.channelnumber = number
me.channelname = name
me.source = mod.string.get("print", "network", "channel", "ctra")
return number, name, me.source
end
end
-- can't find it!
return 0
end
--[[
mod.net.sendmessage(message)
Sends a message to the KLHTM chat channel.
<message> is a string. Don't put the "KLHTM " header on it; that's what this method does.
Return: true if the mod could find the right channel, false otherwise.
]]
me.sendmessage = function(message)
-- 1.12 override
if mod.isnewwowversion then
if GetNumRaidMembers() > 0 then
SendAddonMessage("KLHTM", message, "RAID")
elseif GetNumPartyMembers() > 0 then
SendAddonMessage("KLHTM", message, "PARTY")
else
-- Send directly to our input handler
mod.netin.messagein(UnitName("player"), message, 1)
end
return true
end
local channelnumber = me.getchannel()
if channelnumber > 0 then
-- add KLHTM header
message = "KLHTM " .. message
-- send
SendChatMessage(message, "CHANNEL", nil, channelnumber)
-- debug
if mod.out.checktrace("info", me, "message") then
mod.out.printtrace(string.format("Sent this message: %s.", message))
end
return true
else
return false
end
end
------------------------------------------------------------------------------------------------
---------------------------------
-- Special Raid Commands --
---------------------------------
--[[
me.checkpermission()
Returns: non-nil iff you are allowed to send special commands (raid assistant / party leader, etc)
]]
me.checkpermission = function()
if mod.unit.isplayerofficer(UnitName("player")) == true then
return true
else
mod.out.print(mod.string.get("print", "network", "raidpermission"))
return
end
end
--[[
mod.net.clearmastertarget()
Sends a message to clear the master target. This is called from "/ktm mastertarget", or clicking the master target button
when you have no target.
]]
me.clearmastertarget = function()
if me.checkpermission() == nil then
return
end
me.sendmessage("cleartarget")
end
--[[
mod.net.sendmastertarget()
Sends a message to set the master target to your current target. The name of your current target, as you see it, is sent along with the command, in case someone is out of (targetting) range of your target. This is called from
"/ktm mastertarget", or clicking the master target button when you have a target.
]]
me.sendmastertarget = function()
if me.checkpermission() == nil then
return
end
if UnitName("target") == nil then
mod.out.print(mod.string.get("print", "network", "needtarget"))
return
end
me.sendmessage("target " .. UnitName("target"))
end
--[[
mod.net.clearraidthreat()
Commands everyone in the raid to reset their threat. Called when you type "/ktm resetraid" or click the "clear threat"
button on the GUI (which is not visible by default).
]]
me.clearraidthreat = function()
if me.checkpermission() == nil then
return
end
me.sendmessage("clear")
end
-- Commands in the Boss Section
me.startspellreporting = function()
if me.checkpermission() == nil then
return
end
me.sendmessage("spellstart")
end
me.stopspellreporting = function()
if me.checkpermission() == nil then
return
end
me.sendmessage("spellstop")
end
me.reportspelleffect = function(spellname, bossname, result, value1, value2)
if result == "miss" then
me.sendmessage(string.format("spelleffect \"%s\" \"%s\" %s", spellname, bossname, result))
else
me.sendmessage(string.format("spelleffect \"%s\" \"%s\" %s %s %s", spellname, bossname, result, value1, value2))
end
end
me.setspellvalue = function(spellid, bossid, parameter, value)
if me.checkpermission() == nil then
return
end
me.sendmessage(string.format("spellvalue %s %s %s %s", spellid, bossid, parameter, value))
end
-- syntax: <spellid> <bossid> <parameter> <value>
--[[
if it succeeds, it will return just the value that is set.
if it fails, it will return nil, then the error message.
]]
me.checkspellvaluesyntax = function(allvalues)
local x, spellid, bossid, parameter, value, key, message
-- Check their first argument, <spellid>, is valid
spellid = allvalues[1]
if (spellid == nil) or (mod.boss.bossattacks[spellid] == nil) then
message = "The argument |cffffff00" .. tostring(spellid) .. "|r does not match any boss spell id. Valid spellids are|cffffff00"
for key, value in mod.boss.bossattacks do
message = message .. " " .. key
end
message = message .. "|r."
return nil, message
end
-- Check their second argument, <bossid>, is valid
local dataset = mod.boss.bossattacks[spellid]
bossid = allvalues[2]
if (bossid == nil) or (dataset[bossid] == nil) then
message = "The argument |cffffff00" .. tostring(bossid) .. "|r does not match any boss that uses the spell |cffffff00" .. mod.string.get("boss", "spell", spellid) .. "|r. Valid bossids are|cffffff00"
for key, value in dataset do
message = message .. " " .. key
end
message = message .. "|r."
return nil, message
end
-- Check their third argument, <parameter>, is valid
dataset = dataset[bossid]
parameter = allvalues[3]
if (parameter == nil) or (dataset[parameter] == nil) then
message = "The argument |cffffff00" .. tostring(parameter) .. "|r does not match any parameter that can be set. Valid parameters are|cffffff00"
for key, valud in dataset do
message = message .. " " .. key
end
message = message .. "|r."
return nil, message
end
-- 4th parameter is value
-- multiplier / addition: need number
if (parameter == "addition") or (parameter == "multiplier") then
value = tonumber(allvalues[4])
if value == nil then
message = "The argument |cffffff00" .. tostring(allvalues[4]) .. "|r is not a number."
return nil, message
end
elseif parameter == "ticks" then
value = tonumber(allvalues[4])
if (value == nil) or (math.floor(value) ~= value) or (value < 1) then
message = "The argument |cffffff00" .. tostring(allvalues[4]) .. "|r is not a positive integer."
return nil, message
end
elseif parameter == "effectonmiss" then
if value == "true" then
value = true
elseif value == "false" then
value = false
else
message = "The argument |cffffff00" .. tostring(allvalues[4]) .. "|r is not a boolean value."
return nil, message
end
elseif parameter == "type" then
if (value ~= "physical") or (value ~= "debuff") or (value ~= "spell") then
message = "The argument |cffffff00" .. tostring(allvalues[4]) .. "|r is not one of |cffffff00 physical debuff spell|r."
return nil, message
end
end
-- it worked!
return value
end
me.versionnotify = function()
if me.checkpermission() == nil then
return
end
me.sendmessage(string.format("version %d.%d", mod.release, mod.revision))
mod.out.print(mod.string.get("print", "network", "upgradenote"))
end
me.versionquery = function()
if me.checkpermission() == nil then
return
end
-- clear the version table
local key
for key, _ in me.raidversions do
table.remove(me.raidversions, key)
end
-- set the timeout for responses
me.versionquerytimeout = GetTime() + 3
-- Notify the user
mod.out.print(mod.string.get("print", "network", "versionrequest"))
-- send the message
me.sendmessage("versionquery")
end
me.setraidknockbackvalue = function(value, attack)
if me.checkpermission() == nil then
return
end
if mod.boss.isknockbackdiscoveryactive == false then
mod.out.print(mod.string.get("print", "network", "knockbackinactive"))
else
me.sendmessage("knockbackvalue " .. value .. " " .. attack)
end
end
me.sendknockbackevent = function(enemy, ability, value)
if (mod.boss.isknockbackdiscoveryactive == true) and (enemy == mod.boss.mastertarget) then
me.sendmessage("knockaway " .. math.ceil(0.5 + mod.table.getraidthreat()))
me.sendmessage(string.format("knockawaytext {%s, %s, %s}", enemy, ability, value))
end
end
-- don't send an event if one has already been received and confirmed recently.
me.sendevent = function(event)
me.sendmessage("event " .. event)
end
-- Version Querying Stuff. Key = release number, value = array of names
me.raidversions = { }
me.versionquerytimeout = 0 -- 0 = inactive, > 0 = active. Return value of GetTime()
me.addversionresponse = function(playername, version)
local versionstring = tostring(version)
-- ignore unless we are checking versions
if me.versionquerytimeout > 0 then
if me.raidversions[versionstring] == nil then
me.raidversions[versionstring] = { }
end
me.raidversions[versionstring][playername] = true
end
end
-- When we do "/ktm version query", the rest of the raid has 3 seconds to respond.
me.checkversionquery = function()
if me.versionquerytimeout == 0 then
return
end
if GetTime() > me.versionquerytimeout then
-- print it out and stuff
me.versionquerytimeout = 0
local message
local key
local value
local key2
local namesfound = { }
for key, value in me.raidversions do
message = string.format(mod.string.get("print", "network", "versionrecent"), key)
for key2, _ in value do
message = message .. key2 .. ", "
namesfound[key2] = true
end
message = message .. " }."
mod.out.print(message)
table.remove(me.raidversions, key)
end
-- Now print the people who have out of date versions
message = mod.string.get("print", "network", "versionold")
for key, _ in mod.table.raiddata do
if namesfound[key] == nil and mod.unit.isplayeringroup(key) == true then
namesfound[key] = true
message = message .. key .. ", "
end
end
message = message .. " }."
mod.out.print(message)
-- Now print out people who are not talking to us
message = mod.string.get("print", "network", "versionnone")
for value = 1, 40 do
key = GetRaidRosterInfo(value)
if (key ~= nil) and (namesfound[key] == nil) then
namesfound[key] = true
message = message .. key .. ", "
end
end
message = message .. " }."
mod.out.print(message)
end
end
me.lastthreatupdate = 0 -- value of GetTime(). When we last posted our threat to the raid
me.minimumupdateinterval = 0.5 -- minimum time, in seconds, between threat updates to the raid
me.idleupdateinterval = 10.0 -- how often to update when our value is not changing
me.lastthreatvaluesent = -1 -- the name says it all, really
--[[
me.updatethreattoraid()
Posts your threat value to the KLHTM channel if necessary. You will send your threat at most once every
<me.minimumupdateinterval> = 0.5 seconds. If your threat value is unchanged, you will repeat it once every 10
seconds only. If you aren't in a party or raid, you won't repeat your value if it is constant.
]]
me.updatethreattoraid = function()
local interval
local myraidthreat
if mod.my.states.incombat.value == true then
myraidthreat = math.floor(0.5 + mod.table.getraidthreat())
else
myraidthreat = 0
end
if myraidthreat == me.lastthreatvaluesent then
interval = me.idleupdateinterval
-- check for solo, then no updates
if GetNumRaidMembers() == 0 and GetNumPartyMembers() == 0 then
return
end
-- also don't send idle updates when afk
if mod.my.states.afk.value == true then
return
end
else
interval = me.minimumupdateinterval
end
-- check update frequency
if GetTime() < me.lastthreatupdate + interval then
return -- only just sent an update. Wait a bit to send the next one.
end
-- OK. Send.
local message = "threat " .. myraidthreat
if mod.isnewwowversion then
message = "t " .. myraidthreat
end
if me.sendmessage(message) == nil then
if mod.out.checktrace("warning", me, "channel") then
mod.out.printtrace("Threat was not updated because the CTRA Channel is not set up properly.")
end
end
me.lastthreatupdate = GetTime()
me.lastthreatvaluesent = myraidthreat
end
--------------------------------------------------------------------------------------------------
-------------------------------------------------------
-- Advertising KLHTM to people who pull aggro! --
-------------------------------------------------------
me.isadvertising = false
me.lastadvert = 0
me.advertinterval = 300 -- seconds
--[[
mod.net.toggleadvertise()
Switch the advertising function on or off.
]]
me.toggleadvertise = function()
me.isadvertising = not me.isadvertising
if me.isadvertising == true then
mod.out.print(mod.string.get("print", "network", "advertisestart"))
else
mod.out.print(mod.string.get("print", "network", "advertisestop"))
end
end
me.raidnumbers = { } -- {1, 2, 3, ..., 40}
for x = 1, 40 do
me.raidnumbers[x] = x
end
--[[
me.checkadvertise()
Looks for people who have pulled aggro but don't have KLHTM, and tells them to get it. A message will be sent no more than
once every <me.advertinterval> = 5 minutes. Messages will be sent to non-warriors who are being targetted by a mob, so it's
not a complete guarantee that they have aggro.
]]
me.checkadvertise = function()
if me.isadvertising == false then
return
end
-- don't spam
if GetTime() < me.lastadvert + me.advertinterval then
return
end
-- look for someone who has aggro, is not a warrior, is not in the raid threat
if GetNumRaidMembers() <= 0 then
return
end
local target = ""
local player = ""
local x
-- make it a random permutation of the raid, to stop bugging one person
me.scrambleraid(me.raidnumbers)
for y = 1, 40 do
-- get x from scrambled array
x = me.raidnumbers[y]
-- there is a raid player
target = "raid" .. x
if UnitExists(target) == 1 then
-- the player is targetting a mob
target = target .. "target"
if UnitExists(target) == 1 and UnitIsFriend("player", target) ~= 1 then
-- mob has another player targetted
player = target .. "target"
if UnitIsFriend("player", player) == 1 then
-- player is not yourself, not a warrior, is a player
if (UnitIsPlayer(player) == 1) and (UnitName("player") ~= UnitName(player)) then
local _, class = UnitClass(player)
if class ~= "WARRIOR" then
-- check they arne't using the meter
if mod.table.raiddata[UnitName(player)] == nil then
-- send them a message
SendChatMessage(string.format(mod.string.get("print", "network", "advertisemessage"), UnitName(target)), "WHISPER", nil, UnitName(player))
me.lastadvert = GetTime()
return
end
end
end
end
end
end
end
end
--[[
me.scrambleraid(numbers)
Slightly scrambles the array <numbers>. Picks 10 random pairs and swaps them. Since this scramble method gets called
each time we check, the array will be sufficiently inconstant all the time.
]]
me.scrambleraid = function(numbers)
local x
local temp
local box1
local box2
for x = 1, 10 do
box1 = math.random(1, 40)
box2 = math.random(1, 40)
temp = numbers[box1]
numbers[box1] = numbers[box2]
numbers[box2] = temp
end
end
Generated by GNU Enscript 1.6.5.90.