Thread Tools Display Modes
08-18-12, 05:48 PM   #1
cky71321
A Defias Bandit
Join Date: Aug 2012
Posts: 3
Need some help with detecting Divine Purpose.

Long story short, I edited a script for CLCInfo's Retribution module around 4.3, and now I can't seem to get it working on the beta.

Code:
	inqdp = {
		id = inqId,
		GetCD = function()
			if s_inq <= db.inqRefresh and s_dp > 0 then
				return 0
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5 / s_haste
			s_inq = 100
			if s_dp > 0 then s_dp = 0 end
		end,
To keep it simple, s_dp > 0 worked perfectly fine on live, but in the beta it's sending back nil value errors. Has something changed to break this or am I completely overlooking something?
  Reply With Quote
08-18-12, 06:50 PM   #2
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Where is the variable s_dp defined? You're going to have to post a lot more code than that (preferrably the whole addon) if you expect anyone to be able to help you.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
08-18-12, 06:59 PM   #3
cky71321
A Defias Bandit
Join Date: Aug 2012
Posts: 3
Full addon, as requested:
Code:
-- don't load if class is wrong
local _, class = UnitClass("player")
if class ~= "PALADIN" then return end

local GetTime = GetTime
local debug = clcInfo.debug

local version = 4000606

local modName = "__retribution"
local mod = clcInfo:RegisterClassModule(modName)
local emod = clcInfo.env
local db -- template based

local ef = CreateFrame("Frame") 
ef:Hide()

local defaults = {
	version = version,
	
	prio = "inqa inqrhp tvhp cs inqrdp tvdp exoud how exo j hw cons",
	prioZeal = "tvhp cs tvdp",
	usePrioZeal = false,
	rangePerSkill = false,
	inqRefresh = 5,
	inqApplyMin = 3,
	inqRefreshMin = 3,
	undead = "Undead",
	demon = "Demon",
	jClash = 0,
	hwClash = 1,
	consClash = 1,
	consMana = 20000,
}

-- @defines
--------------------------------------------------------------------------------
local gcdId 				= 85256 -- tv for gcd
-- list of spellId
local howId 				=	24275	-- hammer of wrath
local csId 					= 35395	-- crusader strike
local tvId					= 85256	-- templar's verdict
local inqId					= 84963	-- inquisition
local dsId					= 53385	-- divine storm
local jId						= 20271	-- judgement
local consId				= 26573	-- consecration
local exoId					= 879		-- exorcism
local hwId					= 2812 	-- holy wrath
local zealId				= 85696 -- zealotry
local inqId					= 84963 -- inquisition
-- csName to pass as argument for melee range checks
local csName			= GetSpellInfo(csId)
-- buffs
local buffZeal 	= GetSpellInfo(zealId)	-- zealotry
local buffDP		= GetSpellInfo(90174)		-- divine purpose
local buffAoW		= GetSpellInfo(59578)		-- the art of war
local buffInq 	= GetSpellInfo(inqId)		-- inquisition

-- status vars
local s1, s2
local s_ctime, s_otime, s_gcd, s_hp, s_inq, s_zeal, s_aow, s_dp, s_haste, s_targetType

function mod:OnTemplatesUpdate()
	db = clcInfo:RegisterClassModuleTDB(modName, defaults)
	if db then
		if not db.version or db.version < version then
			-- fix stuff
			clcInfo.AdaptConfigAndClean(modName, db, defaults)
			db.version = version
		end
		
		mod:UpdateQueue()
	end
end

-- the queue
local qn = {} 		-- normal queue
local qz = {} 		-- zeal queue
local q 					-- working var

local function GetCooldown(id)
	local start, duration = GetSpellCooldown(id)
	local cd = start + duration - s_ctime - s_gcd
	if cd < 0 then return 0 end
	return cd
end

-- actions ---------------------------------------------------------------------
local actions = {
	-- inquisition, apply, 3 hp
	inqa = {
		id = inqId,
		GetCD = function()
			if s_inq <= 0 and (s_hp >= db.inqApplyMin or s_dp > 0) then
				return 0
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5 / s_haste
			s_inq = 100	-- make sure it's not shown for next skill
			if s_dp > 0 then s_dp = 0 else s_hp = 0 end -- adjust hp/dp
		end,
		info = "apply Inquisition",
	},
	inqahp = {
		id = inqId,
		GetCD = function()
			if s_inq <= 0 and s_hp >= db.inqApplyMin then
				return 0
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5 / s_haste
			s_inq = 100	-- make sure it's not shown for next skill
			if s_dp > 0 then s_dp = 0 else s_hp = 0 end -- adjust hp/dp
		end,
		info = "apply Inquisition at x HP",
	},
	inqadp = {
		id = inqId,
		GetCD = function()
			if s_inq <= 0 and s_dp > 0 then
				return 0
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5 / s_haste
			s_inq = 100	-- make sure it's not shown for next skill
			if s_dp > 0 then s_dp = 0 else s_hp = 0 end -- adjust hp/dp
		end,
		info = "apply Inquisition at DP",
	},
	inqr = {
		id = inqId,
		GetCD = function()
			if s_inq > 0 and s_inq <= db.inqRefresh and (s_hp >= db.inqRefreshMin or s_dp > 0) then
				return 0
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5 / s_haste
			s_inq = 100	-- make sure it's not shown for next skill
			if s_dp > 0 then s_dp = 0 else s_hp = 0 end -- adjust hp/dp
		end,
		info = "refresh Inquisition",
	},
	inqrhp = {
		id = inqId,
		GetCD = function()
			if s_inq > 0 and s_inq <= db.inqRefresh and s_hp >= db.inqRefreshMin then
				return 0
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5 / s_haste
			s_inq = 100	-- make sure it's not shown for next skill
			if s_dp > 0 then s_dp = 0 else s_hp = 0 end -- adjust hp/dp
		end,
		info = "refresh Inquisition at x HP",
	},
	inqrdp = {
		id = inqId,
		GetCD = function()
			if s_inq > 0 and s_inq <= db.inqRefresh and s_dp > 0 then
				return 0
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5 / s_haste
			s_inq = 100	-- make sure it's not shown for next skill
			if s_dp > 0 then s_dp = 0 else s_hp = 0 end -- adjust hp/dp
		end,
		info = "refresh Inquisition at DP",
	},
	exoud = {
		id = exoId,
		GetCD = function()
			if (s_targetType == db.undead or s_targetType == db.demon) and s_aow > 0 then
				return 0
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5 / s_haste
			s_aow = 0 -- make sure it's not shown for next skill
		end,
		info = "Exorcism with guaranteed crit",
	},
	exo = {
		id = exoId,
		GetCD = function()
			if s_aow > 0 then
				return 0
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5 / s_haste
			s_aow = 0 -- make sure it's not shown for next skill
		end,
		info = "Exorcism",
	},
	how = {
		id = howId,
		GetCD = function()
			if IsUsableSpell(howId) and s1 ~= howId then
				return GetCooldown(howId)
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5 / s_haste
		end,
		info = "Hammer of Wrath",
	},
	tv = {
		id = tvId,
		GetCD = function()
			if s_hp >= 3 or s_dp > 0 then
				return 0
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5
			if s_dp > 0 then s_dp = 0 else s_hp = 0 end -- adjust hp/dp
		end,
		info = "Templar's Verdict",
	},
	tvhp = {
		id = tvId,
		GetCD = function()
			if s_hp >= 3 then
				return 0
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5
			if s_dp > 0 then s_dp = 0 else s_hp = 0 end -- adjust hp/dp
		end,
		info = "Templar's Verdict at 3 HP",
	},
	tvdp = {
		id = tvId,
		GetCD = function()
			if s_dp > 0 then
				return 0
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5
			if s_dp > 0 then s_dp = 0 else s_hp = 0 end -- adjust hp/dp
		end,
		info = "Templar's Verdict at DP",
	},
	cs = {
		id = csId,
		GetCD = function()
			if s_hp >= 3 then return 100 end
			if s1 == csId then
				return (4.5 / s_haste - 1.5)
			else
				return GetCooldown(csId)
			end
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5
			if s_zeal > 0 then
				s_hp = 3
			else
				s_hp = s_hp + 1
			end
		end,
		info = "Crusader Strike",
	},
	j = {
		id = jId,
		GetCD = function()
			if s1 ~= jId then
				return GetCooldown(jId) + db.jClash
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5
		end,
		info = "Judgement",
	},
	jhp = {
		id = jId,
		GetCD = function()
			if s_hp >= 3 then return 100 end
			if s1 ~= jId then
				return GetCooldown(jId) + db.jClash
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5
			s_hp = s_hp + 1
		end,
		info = "Judgement that generates 1 HP",
	},
	hw = {
		id = hwId,
		GetCD = function()
			if s1 ~= hwId then
				return GetCooldown(hwId) + db.hwClash
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5 / s_haste
		end,
		info = "Holy Wrath",
	},
	cons = {
		id = consId,
		GetCD = function()
			if s1 ~= consId and UnitPower("player") > db.consMana then
				return GetCooldown(consId) + db.consClash
			end
			return 100
		end,
		UpdateStatus = function()
			s_ctime = s_ctime + s_gcd + 1.5 / s_haste
		end,
		info = "Consecration",
	},
}
mod.actions = actions
--------------------------------------------------------------------------------

function mod:UpdateQueue()
	-- normal queue
	qn = {}
	for v in string.gmatch(db.prio, "[^ ]+") do
		if actions[v] then
			table.insert(qn, v)
		else
			print("clcInfo", modName, "invalid action:", v)
		end
	end
	db.prio = table.concat(qn, " ")
	
	-- zealotry queue
	qz = {}
	for v in string.gmatch(db.prioZeal, "[^ ]+") do
		if actions[v] then
			table.insert(qz, v)
		else
			print("clcInfo", modName, "invalid action (zealotry prio):", v)
		end
	end
	db.prioZeal = table.concat(qz, " ")
end

local function GetBuff(buff)
	local left
	_, _, _, _, _, _, expires = UnitBuff("player", buff, nil, "PLAYER")
	if expires then
		left = expires - s_ctime - s_gcd
		if left < 0 then left = 0 end
	else
		left = 0
	end
	return left
end

-- reads all the interesting data
local function GetStatus()
	-- current time
	s_ctime = GetTime()
	
	-- gcd value
	local start, duration = GetSpellCooldown(gcdId)
	s_gcd = start + duration - s_ctime
	if s_gcd < 0 then s_gcd = 0 end
	
	-- the buffs
	s_dp = GetBuff(buffDP)
	s_aow = GetBuff(buffAoW)
	s_zeal = GetBuff(buffZeal)
	s_inq = GetBuff(buffInq)
	
	-- client hp and haste
	s_hp = UnitPower("player", SPELL_POWER_HOLY_POWER)
	s_haste = 1 + UnitSpellHaste("player") / 100
	
	-- undead/demon -> different exorcism
	s_targetType = UnitCreatureType("target")
end

local function GetNextAction()
	-- decide which queue to use
	if s_zeal > 0 and db.usePrioZeal then
		q = qz
	else
		q = qn
	end

	local n = #q
	
	-- parse once, get cooldowns, return first 0
	for i = 1, n do
		local action = actions[q[i]]
		local cd = action.GetCD()
		if debug.enabled then
			debug:AddBoth(q[i], cd)
		end
		if cd == 0 then
			return action.id, q[i]
		end
		action.cd = cd
	end
	
	-- parse again, return min cooldown
	local minQ = 1
	local minCd = actions[q[1]].cd
	for i = 2, n do
		local action = actions[q[i]]
		if minCd > action.cd then
			minCd = action.cd
			minQ = i
		end
	end
	return actions[q[minQ]].id, q[minQ]
end

local function RetRotation()
	s1 = nil
	GetStatus()
	if debug.enabled then
		debug:Clear()
		debug:AddBoth("ctime", s_ctime)
		debug:AddBoth("gcd", s_gcd)
		debug:AddBoth("hp", s_hp)
		debug:AddBoth("zeal", s_zeal)
		debug:AddBoth("aow", s_aow)
		debug:AddBoth("inq", s_inq)
		debug:AddBoth("dp", s_dp)
		debug:AddBoth("haste", s_haste)
	end
	local action
	s1, action = GetNextAction()
	if debug.enabled then
		debug:AddBoth("s1", action)
	end
	-- 
	s_otime = s_ctime -- save it so we adjust buffs for next
	actions[action].UpdateStatus()
	
	-- adjust buffs
	s_otime = s_ctime - s_otime
	s_dp = max(0, s_dp - s_otime)
	s_aow = max(0, s_aow - s_otime)
	s_zeal = max(0, s_zeal - s_otime)
	s_inq = max(0, s_inq - s_otime)
	
	if debug.enabled then
		debug:AddBoth("ctime", s_ctime)
		debug:AddBoth("otime", s_otime)
		debug:AddBoth("gcd", s_gcd)
		debug:AddBoth("hp", s_hp)
		debug:AddBoth("zeal", s_zeal)
		debug:AddBoth("aow", s_aow)
		debug:AddBoth("inq", s_inq)
		debug:AddBoth("dp", s_dp)
		debug:AddBoth("haste", s_haste)
	end
	s2, action = GetNextAction()
	if debug.enabled then
		debug:AddBoth("s2", action)
	end
end


-- plug in
--------------------------------------------------------------------------------
local secondarySkill
function emod.IconRet1(...)
	RetRotation(...)
	if secondarySkill then secondarySkill:DoUpdate() end
	return emod.IconSpell(s1, db.rangePerSkill or csName)
end
local function SecondaryExec()
	return emod.IconSpell(s2, db.rangePerSkill or csName)
end
local function ExecCleanup2()
	secondarySkill = nil
end
function emod.IconRet2(...)
	secondarySkill = emod.___e
	secondarySkill:SetScript("OnUpdate", nil)
	secondarySkill.exec = SecondaryExec
	secondarySkill.ExecCleanup = ExecCleanup2
end

-- giving queue as command line
local function CmdRet(args)
	db.prio = table.concat(args, " ")
	mod:UpdateQueue()
	clcInfo:UpdateOptions()
end
clcInfo.cmdList["retprio"] = CmdRet

-- for zeal too
local function CmdRetZeal(args)
	db.prioZeal = table.concat(args, " ")
	mod:UpdateQueue()
	clcInfo:UpdateOptions()
end
clcInfo.cmdList["retpriozeal"] = CmdRetZeal
  Reply With Quote
08-19-12, 10:29 AM   #4
cky71321
A Defias Bandit
Join Date: Aug 2012
Posts: 3
Double checked everything this morning after checking everything in the coding and got it up and running with some quick additions.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Need some help with detecting Divine Purpose.


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off