You are not logged in.

Applications: [GameMaster: OPEN] | [Volunteer Testers: OPEN]


This forum will be permanently shut down on Friday 13.07.2018
Please copy or save all important information from old forum before they will be deactivated
We have moved to new board. https://forum.runesofmagic.gameforge.com/Come join us.

Grandpoubba

Beginner

Posts: 4

Location: Just a place...

Occupation: Just a job...

  • Send private message

341

Thursday, January 12th 2012, 7:34am

that g_channel error thingy, well its junk info that sometimes the savedvariables.lua has a hickup, it aint always there, open those main .lua files and search for that string, its a small section , looks pointless but hey, its not diyce related, never made me crash, my guess is that its another addon that has problems reading/writing that section and displays error, maybe related to lag who knows, if it aint broke....
...it's too hard to say "Au Revoir", so let's just say "Au Gratin"...

342

Friday, January 13th 2012, 11:31am

Hello,

I am a R/s and i use diyce. I use the file of mrmisterwaa (http://forum.us.runesofmagic.com/showpos…80&postcount=56) (btw thanks for the file).

I have 2 r/s, on 2 servers. The first one doesn't have it's lvl 50/50 elite skill and here, the diyce works perfectly.
Now, i try to use the diyce on the second R/s who has it's lvl 50/50 elite. So, i used Notepad++ and changed the debuff ID for bleed from 620313 (the ID of bleed when the char doesn't have its elite 50/50) to the ID of 500654 (debuff if the char has its lvl 50/50 elite).

Now, my problem is that my second char only spams "Shadowstab" and doesn't use "Low Blow". Even if I apply "Low Blow" debuff on target, the char won't use "Wound Attack". I only spam "Shadowstab" until target death.

I tried to re download the diyce 2.2 file, I even used my old V1.0 diyce and I still end up with the same issue of spamming one skill.

So, anyone has an idea why i only spam one skill ? (I guess it comes from issues in reading debuff ID but I don't get why changing server would have an impact on debuff ID reading).

mrmisterwaa

Professional

Posts: 670

Location: Kuwait

  • Send private message

343

Friday, January 13th 2012, 11:52am

That is weird, you shouldn't be ble to Spam Shadowstab unless you removed the cooldown check I put.

344

Friday, January 13th 2012, 11:56am

I really only copy-pasted your 2 lua files. ANd it works fine on 1 server and not on the other one. Only change I did from working one is the debuff ID, but then it wasn't working so my diyce is a pure copy of yours.

Edit: I don't know if it matters but my ingame macro is: /run diyce("","1") and not /run KillSequence("","1") since /run KillSequence("","1") doesn't do anything else. (I use /run diyce("","1") on first server but it works just fine)

345

Friday, January 13th 2012, 8:15pm

BuffList

I have a problem with bufflist, a friend is trying to count the number of Vampire Arrows on a target, these can be shot from any number of ppl but have same id.

As far as I can read the code below each Vampire arrow will overwrite the previous entry in the list, i.e. the list will only contain the last entry. Is this as designed?

regards
;)

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function BuffList(tgt)
    local list = {}
    local buffcmd = UnitBuff
    local infocmd = UnitBuffLeftTime

    if UnitCanAttack("player",tgt) then
        buffcmd = UnitDebuff
        infocmd = UnitDebuffLeftTime
    end

    -- There is a max of 100 buffs/debuffs per unit apparently
    for i = 1,100 do
        local buff, _, stackSize, ID = buffcmd(tgt, i)
        local timeRemaining = infocmd(tgt,i)
        if buff then
            -- Ad to list by name
            list[buff:gsub('(%()(.)(%))', '%2')] = { stack = stackSize, time = timeRemaining or 0, id = ID }
            -- We also list by ID in case two different buffs/debuffs have the same name.
            list[ID] = {stack = stackSize, time = timeRemaining or 0, name = buff:gsub("(%()(.)(%))", "%2") }
        else
            break
        end
    end

    return list
end

Peryl

Intermediate

Posts: 313

Location: Elsewhere

  • Send private message

346

Friday, January 13th 2012, 11:44pm

Quoted from "frafall;501579"

I have a problem with bufflist, a friend is trying to count the number of Vampire Arrows on a target, these can be shot from any number of ppl but have same id.

As far as I can read the code below each Vampire arrow will overwrite the previous entry in the list, i.e. the list will only contain the last entry. Is this as designed?

regards
;)

That is correct, it will overwrite the previous entry. If the buff/debuff stacks, then the stack count will increase so you can check that. However, the game has no facilities to check who cast which buff/debuff on a target, therefore there is no way to differentiate the same buffs/debuffs.
2013... The year from hell....

347

Saturday, January 14th 2012, 11:43am

The problem for s/r is that you'd want Deadly Poison Bite to fire when there are at least three vampire arrow dots on the target. The dot works like the Slash dot, i.e. it's not stacked but each dot is treated as a separate debuff.

mrmisterwaa

Professional

Posts: 670

Location: Kuwait

  • Send private message

348

Saturday, January 14th 2012, 12:09pm

Quoted from "Koloid;501708"

The problem for s/r is that you'd want Deadly Poison Bite to fire when there are at least three vampire arrow dots on the target. The dot works like the Slash dot, i.e. it's not stacked but each dot is treated as a separate debuff.


o.O

Since when?

349

Saturday, January 14th 2012, 8:53pm

ok, it DIYCE 1.0 when you put in the attack command your toon would run up to be in melee range of the target, with this new one it doesn't seem to ever make it to that step for me, so my question is how can i get it to hug the mob for me, ie whenever i hit my macro i wanna be on the mob as close as possible.

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- Class: Rogue/Scout
        if mainClass == "THIEF" and subClass == "RANGER" then
        --Combat
            if enemy then
            Skill2 = {
                { name = "Wound Attack",         use = ((EnergyBar1 >= 35) and ((tbuffs[500654]) and (tbuffs[500704]))) },
                { name = "Low Blow",             use = ((EnergyBar1 >= 30) and (tbuffs[500654])) },
                { name = "Shadowstab",           use = (EnergyBar1 >= 35) },
                { name = "Vampire Arrows",         use = (EnergyBar2 >= 20) },
                { name = "Joint Blow",              use = (EnergyBar2 >= 15) },
                { name = "Shot",                   use = ((EnergyBar1 < 20) and (EnergyBar2 < 20)) },
                { name = "Attack",                  use = (thealth == 1) },
            }
            end


thats my code, very simple, just for attacks dont need the bells and whistles i take care of that myself

mrmisterwaa

Professional

Posts: 670

Location: Kuwait

  • Send private message

350

Saturday, January 14th 2012, 11:18pm

Quoted from "Misheara;501754"

ok, it DIYCE 1.0 when you put in the attack command your toon would run up to be in melee range of the target, with this new one it doesn't seem to ever make it to that step for me, so my question is how can i get it to hug the mob for me, ie whenever i hit my macro i wanna be on the mob as close as possible.

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- Class: Rogue/Scout
        if mainClass == "THIEF" and subClass == "RANGER" then
        --Combat
            if enemy then
            Skill2 = {
                { name = "Wound Attack",         use = ((EnergyBar1 >= 35) and ((tbuffs[500654]) and (tbuffs[500704]))) },
                { name = "Low Blow",             use = ((EnergyBar1 >= 30) and (tbuffs[500654])) },
                { name = "Shadowstab",           use = (EnergyBar1 >= 35) },
                { name = "Vampire Arrows",         use = (EnergyBar2 >= 20) },
                { name = "Joint Blow",              use = (EnergyBar2 >= 15) },
                { name = "Shot",                   use = ((EnergyBar1 < 20) and (EnergyBar2 < 20)) },
                { name = "Attack",                  use = (thealth == 1) },
            }
            end
thats my code, very simple, just for attacks dont need the bells and whistles i take care of that myself


Your only condition for the "hugging" the mob is == 1 (when the mob's corpse is a ghost if I remember correctly) and can be looted.

Are you using this for looting or are you using it to hug the mob?

351

Sunday, January 15th 2012, 2:04am

trying to hug the mob

352

Sunday, January 15th 2012, 2:09pm

s/r vampire arrows

Quoted from "Koloid;501708"

The problem for s/r is that you'd want Deadly Poison Bite to fire when there are at least three vampire arrow dots on the target. The dot works like the Slash dot, i.e. it's not stacked but each dot is treated as a separate debuff.


Excactly, and the current BuffList will only show the last Vampire Arrow debuff as index in the list is name or id which is identical for all instances of debuff. So even though there are 2 or more Vampire Arrow debuffs all will be represented in 1 entry which will reflect the last VA debuff one found on mob.

Note that we cant stack these either as they will have different timeouts...or one solution would be to represent them as a stack with the timeout being the timeout of shortest debuff

Perhaps something like below which will be correct for numeric buff/debuff ID's but somewhat incorrect for names as same name can have different ID's (bleed).

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
function BuffList(tgt)
    local list = {}
    local buffcmd = UnitBuff
    local infocmd = UnitBuffLeftTime

    if UnitCanAttack("player",tgt) then
        buffcmd = UnitDebuff
        infocmd = UnitDebuffLeftTime
    end

    -- There is a max of 100 buffs/debuffs per unit apparently
    for i = 1,100 do
        local buff, _, stackSize, ID = buffcmd(tgt, i)
        local timeRemaining = infocmd(tgt,i)
        if buff then
			local name = buff:gsub("(%()(.)(%))", "%2")

			-- Ad to list by name, this wont be correct for names w. different ID's
			if(list[name]) then
				list[name].stack = list[name].stack + stackSize
				if(list[name].time > timeRemaining) then
					list[name].time = timeRemaining
				end
			else           
				list[name] = { stack = stackSize, time = timeRemaining or 0, id = ID }
			end
			
            -- We also list by ID in case two different buffs/debuffs have the same name.
			if(list[ID]) then
				list[ID].stack = list[ID].stack + stackSize
				if(list[ID].time > timeRemaining) then
					list[ID].time = timeRemaining
				end
			else
				list[ID] = {stack = stackSize, time = timeRemaining or 0, name = name }
			end
        else
            break
        end
    end

    return list
end


-f

353

Tuesday, January 17th 2012, 4:11am

only cast frost arrows

I was just wondering if anyone figured out the problem that was causing the s/wd function to cast only frost arrow?
I've been trying to figure it out, but I'm not having any luck. I'm hoping someone might be able to point me in the right direction before my brain explodes? :eek:

krssrb

Beginner

Posts: 20

Location: Serbia

  • Send private message

354

Tuesday, January 17th 2012, 6:03pm

Skip mob's by name

I just added this to my diyce

Source code

1
local MobName = UnitName("target")

and this

Source code

1
2
3
4
5
--Skip mob's by name
if MobName == "Cow Beetle" then
	TargetUnit("")
	return	
end

It skips trash mob's by name. I use it in DoD to skip suicide mob's
you can add more mobs like this

Source code

1
2
3
4
5
6
7
--Skip mob's by name
if MobName == "Cow Beetle" then
	TargetUnit("")
elseif MobName == "Black Boar" then
	TargetUnit("")
	return	
end

Maybe this will be useful to someone :)
Warrior80/Mage80/Warlock80

mrmisterwaa

Professional

Posts: 670

Location: Kuwait

  • Send private message

355

Tuesday, January 17th 2012, 8:14pm

Quoted from "krssrb;502473"

I just added this to my diyce

Source code

1
local MobName = UnitName("target")
and this

Source code

1
2
3
4
5
--Skip mob's by name
if MobName == "Cow Beetle" then
    TargetUnit("")
    return    
end
It skips trash mob's by name. I use it in DoD to skip suicide mob's
you can add more mobs like this

Source code

1
2
3
4
5
6
7
--Skip mob's by name
if MobName == "Cow Beetle" then
    TargetUnit("")
elseif MobName == "Black Boar" then
    TargetUnit("")
    return    
end
Maybe this will be useful to someone :)


Actually ... what you can do is ... make a list of trash mobs that you want to ignore and make it similar to the Interrupt list.

Peryl

Intermediate

Posts: 313

Location: Elsewhere

  • Send private message

356

Tuesday, January 17th 2012, 8:36pm

sekrit/mrmisterwaa beat me to it, but yeah, that would be a better way to go. A much more flexible system. Something like this:

at top of file, add this:

Source code

1
2
3
4
5
local IgnorableMobs = {
        ['Cow Beetle'] = true,
        ['Black Boar'] = true,
        -- Add more names to this list in same fashion
    }


The ignore code then becomes:

Source code

1
2
3
4
--Skip named mobs
if MobName and IgnorableMobs[MobName] then
    TargetUnit("")
end


You still need to set the MobName variable as you have been.
2013... The year from hell....

mrmisterwaa

Professional

Posts: 670

Location: Kuwait

  • Send private message

357

Tuesday, January 17th 2012, 8:52pm

Quoted from "Peryl;502528"

sekrit/mrmisterwaa beat me to it, but yeah, that would be a better way to go. A much more flexible system. Something like this:

at top of file, add this:

Source code

1
2
3
4
5
local IgnorableMobs = {
        ['Cow Beetle'] = true,
        ['Black Boar'] = true,
        -- Add more names to this list in same fashion
    }
The ignore code then becomes:

Source code

1
2
3
4
--Skip named mobs
if MobName and IgnorableMobs[MobName] then
    TargetUnit("")
end
You still need to set the MobName variable as you have been.


I am awesome like that. :cool:

358

Wednesday, January 18th 2012, 2:19am

Wound Attack R/S

Hey!

I am a R/S and I want my DiYCE to attack mobs/elites/bosses with this order:
Shadowstab
Low Blow
Wound Attack

But I want it like this, use Shadowstab untill the target get the "Bleed" from it then use Low Blow untill the target gets the "Grievous Wound" from Low Blow aswell and then use the Wound Attack while the target got the "Bleeds" from Shadowstab & Low Blow and after continue using/spam only Low Blow.

I have tried to do as Mrmisterwaa did but without success, my R/S is only casting Shadowstab and Low Blow, he never uses Wound Attack.

I have attached a txt file containing the changes I did and I also inserted the "local useit = type(Skill[x].use) ~= "function" and Skill[x].use or (type(Skill[x].use) == "function" and Skill[x].use() or false)" I got from Peryl.

Note: I have put the part of the changed code and the "local useit" in a txt file so I am aware of that the "local useit" belongs in DiYCE.lua.

- B
BloodyArrow has attached the following file:
  • MyCurrentDiyc.txt (651 Byte - 16 times downloaded - latest: Jun 26th 2013, 10:26am)

359

Wednesday, January 18th 2012, 2:14pm

Hi all, I have a question about part of code in DIYCE.lua.

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function CD(skillname)
    local firstskill = GetSkillDetail(2,1)
    if (g_skill[firstskill] == nil) or (g_skill[firstskill].page ~= 2) then
        ReadSkills()
    end

    if g_skill[skillname] ~= nil then
        local tt,cd = GetSkillCooldown(g_skill[skillname].page,g_skill[skillname].slot)
        return cd <= 0.4
    elseif skillname == nil then
        return false
    else
        Msg("Skill not available: "..skillname)        --Comment this line out if you do not wish to recieve this error message.
        return
    end
end


It is about line: return cd <= 0.4
Why do we use 0.4? I suppose it's related to ping, so that if it is near equal to 30-40 ms, we assume that skill will be ready and we can cast, but want to make sure. Is it so?
Also, I'm playing on russian server and we only today have got a patch that introduces global cooldown (patch 4.0.5). I tried playing with this number before patch (tried return cd <= 0.4, return cd <= 0.3, return cd <= 0.5) but didn't see any differences actually, so should this number be changed with introduce of GCD?

Many thanks in advance.

mrmisterwaa

Professional

Posts: 670

Location: Kuwait

  • Send private message

360

Wednesday, January 18th 2012, 3:44pm

Quoted from "synops;502734"

Hi all, I have a question about part of code in DIYCE.lua.

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function CD(skillname)
    local firstskill = GetSkillDetail(2,1)
    if (g_skill[firstskill] == nil) or (g_skill[firstskill].page ~= 2) then
        ReadSkills()
    end

    if g_skill[skillname] ~= nil then
        local tt,cd = GetSkillCooldown(g_skill[skillname].page,g_skill[skillname].slot)
        return cd <= 0.4
    elseif skillname == nil then
        return false
    else
        Msg("Skill not available: "..skillname)        --Comment this line out if you do not wish to recieve this error message.
        return
    end
end
It is about line: return cd <= 0.4
Why do we use 0.4? I suppose it's related to ping, so that if it is near equal to 30-40 ms, we assume that skill will be ready and we can cast, but want to make sure. Is it so?
Also, I'm playing on russian server and we only today have got a patch that introduces global cooldown (patch 4.0.5). I tried playing with this number before patch (tried return cd <= 0.4, return cd <= 0.3, return cd <= 0.5) but didn't see any differences actually, so should this number be changed with introduce of GCD?

Many thanks in advance.


You should be increasing it, ever since the Global Cooldown issue, I raised mine to about 0.7 - 0.8 and it started working properly again.

This problem only occurs when you are using melee skills and not ranged though.

@BloodyArrow,

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
-- DIY Combat Engine version 2.2

local g_skill  = {}
local g_lastaction = ""
-- Holds the created timers
local DIYCE_Timers = {}

function Msg(outstr,a1,a2,a3)
    DEFAULT_CHAT_FRAME:AddMessage(tostring(outstr),a1,a2,a3)
end

function ReadSkills()
    g_skill = {}
    local skillname,slot

    for page = 1,4 do
        slot = 1
        skillname = GetSkillDetail(page,slot)
        repeat
            local a1,a2,a3,a4,a5,a6,a7,a8,skillusable = GetSkillDetail(page,slot)
            if skillusable then
                g_skill[skillname] = { ['page'] = page, ['slot'] = slot }
            end
            slot = slot + 1
            skillname = GetSkillDetail(page,slot)
        until skillname == nil
    end
end

-- Read Skills on Log-In/Class Change/Level-Up
        local DIYCE_EventFrame = CreateUIComponent("Frame","DIYCE_EventFrame","UIParent")
        DIYCE_EventFrame:SetScripts("OnUpdate", [=[ DIYCE_TimerUpdate(elapsedTime) ]=] )
            DIYCE_EventFrame:SetScripts("OnEvent", [=[ 
                    if event == 'PLAYER_SKILLED_CHANGED' then
                        ReadSkills()
                        end
                    ]=] )
            DIYCE_EventFrame:RegisterEvent("PLAYER_SKILLED_CHANGED")

function PctH(tgt)
    return (UnitHealth(tgt)/UnitMaxHealth(tgt))
end

function PctM(tgt)
    return (UnitMana(tgt)/UnitMaxMana(tgt))
end

function PctS(tgt)
    return (UnitSkill(tgt)/UnitMaxSkill(tgt))
end

function CancelBuff(buffname)
    local i = 1
    local buff = UnitBuff("player",i)

    while buff ~= nil do
        if buff == buffname then
            CancelPlayerBuff(i)
            return true
        end

        i = i + 1
        buff = UnitBuff("player",i)
    end
    return false
end

function BuffList(tgt)
    local list = {}
    local buffcmd = UnitBuff
    local infocmd = UnitBuffLeftTime

    if UnitCanAttack("player",tgt) then
        buffcmd = UnitDebuff
        infocmd = UnitDebuffLeftTime
    end

    -- There is a max of 100 buffs/debuffs per unit apparently
    for i = 1,100 do
        local buff, _, stackSize, ID = buffcmd(tgt, i)
        local timeRemaining = infocmd(tgt,i)
        if buff then
            -- Ad to list by name
            list[buff:gsub('(%()(.)(%))', '%2')] = { stack = stackSize, time = timeRemaining or 0, id = ID }
            -- We also list by ID in case two different buffs/debuffs have the same name.
            list[ID] = {stack = stackSize, time = timeRemaining or 0, name = buff:gsub("(%()(.)(%))", "%2") }
        else
            break
        end
    end

    return list
end

function CD(skillname)
    local firstskill = GetSkillDetail(2,1)
    if (g_skill[firstskill] == nil) or (g_skill[firstskill].page ~= 2) then
        ReadSkills()
    end

    if g_skill[skillname] ~= nil then
        local tt,cd = GetSkillCooldown(g_skill[skillname].page,g_skill[skillname].slot)
        return cd <= 0.4
    elseif skillname == nil then
        return false
    else
        Msg("Skill not available: "..skillname)        --Comment this line out if you do not wish to recieve this error message.
        return
    end
end

function MyCombat(Skill, arg1)
    local spell_name = UnitCastingTime("player")
    local talktome = ((arg1 == "v1") or (arg1 == "v2"))
    local action,actioncd,actiondef,actioncnt
    
    if spell_name ~= nil then
        if (arg1 == "v2") then Msg("- ['..spell_name..']", 0, 1, 1) end
        return true
    end

    for x,tbl in ipairs(Skill) do
        
    local useit = type(Skill[x].use) ~= "function" and Skill[x].use or (type(Skill[x].use) == "function" and Skill[x].use() or false)
        if useit then
            if string.find(Skill[x].name, "Action:") then
                action = tonumber((string.gsub(Skill[x].name, "(Action:)( *)(%d+)(.*)", "%3")))
                _1,actioncd = GetActionCooldown(action)
                actiondef,_1,actioncnt = GetActionInfo(action)
                if GetActionUsable(action) and (actioncd == 0) and (actiondef ~= nil) and (actioncnt > 0) then
                    if talktome then Msg("- "..Skill[x].name) end
                    UseAction(action)
                    return true
                end
            elseif string.find(Skill[x].name, "Custom:") then
                action = string.gsub(Skill[x].name, "(Custom:)( *)(.*)", "%3")
                if CustomAction(action) then
                    return true
                end
            elseif string.find(Skill[x].name, "Item:") then
                action = string.gsub(Skill[x].name, "(Item:)( *)(.*)", "%3")
                if talktome then Msg("- "..Skill[x].name) end
                UseItemByName(action)
                return true
            elseif (Skill[x].ignoretimer or GetDIYCETimerValue(Skill[x].timer) == 0) and CD(Skill[x].name) then
                if talktome then Msg("- "..Skill[x].name) end
                CastSpellByName(Skill[x].name)
                StartDIYCETimer(Skill[x].timer)
                return true
            elseif string.find(Skill[x].name, "Pet Skill:") then
                action = string.gsub(Skill[x].name, "(Pet Skill:)( *)(%d+)(.*)", "%3")
                    UsePetAction(action)
                if (arg1 == "v2") then Msg(Skill[x].name.." has been fully processed") end
                return true
            end
        end
    end
    if (arg1 == "v2") then Msg("- [IDLE]", 0, 1, 1) end
    
    return false
end

--[[ Timer Update function ]]--
-- Tick down any active timers
function DIYCE_TimerUpdate(elapsed)
    for k,v in pairs(DIYCE_Timers) do
        v.timeLeft = v.timeLeft - elapsed
        if v.timeLeft < 0 then
            v.timeLeft = 0
        end
    end
end

--[[ Create a named timer ]]--
-- if the named timer already exists, this does nothing.
function CreateDIYCETimer(timerName, waitTime)
    if not DIYCE_Timers[timerName] then
        DIYCE_Timers[timerName] = { timeLeft = 0, waitTime = waitTime }
    end
end

--[[ Set/reset waitTimer of an existing timer ]]--
-- if the timer doesn't exist, this does nothing
function SetDIYCETimerDelay(timerName, waitTime)
    if DIYCE_Timers[timerName] then
        DIYCE_Timers[timerName].waitTime = waitTime
    end
end

--[[ Delete named timer ]]--
-- if the timer doesn't exist, this does nothing
-- Not really needed, but added for completeness
function DeleteDIYCETimer(timerName)
    if DIYCE_Timers[timerName] then
        DIYCE_Timers[timerName] = nil
    end
end

--[[ Get a timer's current time ]]--
-- if the timer doesn't exist, this returns 0
function GetDIYCETimerValue(timerName)
    if timerName then
        return DIYCE_Timers[timerName] and DIYCE_Timers[timerName].timeLeft or 0
    end
    return 0
end

--[[ Starts a timer ticking down ]]--
-- if timer doesn't exist, this does nothing
function StartDIYCETimer(timerName)
    if timerName and DIYCE_Timers[timerName] then
        DIYCE_Timers[timerName].timeLeft = DIYCE_Timers[timerName].waitTime
    end
end

function CustomAction(action)
    if CD(action) then
        if IsShiftKeyDown() then Msg("- "..action) end
        g_lastaction = action
        CastSpellByName(action)
        return true
    else
        return false
    end
end

function BuffTimeLeft(tgt, buffname)
    local cnt = 1
    local buff = UnitBuff(tgt,cnt)

    while buff ~= nil do
        if string.find(buff,buffname) then
            return UnitBuffLeftTime(tgt,cnt)
        end
        cnt = cnt + 1
        buff = UnitBuff(tgt,cnt)
    end

    return 0
end

function BuffParty(arg1,arg2)
--    arg1 = Quickbar slot # for targetable, instant-cast buff without a cooldown (eg. Amp Attack) for range checking.
--    arg2 = buff expiration time cutoff (in seconds) for refreshing buffs, default is 45 seconds.

    local selfbuffs = { "Soul Bond", "Enhanced Armor", "Holy Seal" }
    local groupbuffs = { "Grace of Life", "Amplified Attack", "Angel's Blessing", "Essence of Magic", "Magic Barrier", "Blessed Spring Water", "Fire Ward", "Savage Blessing", "Concentration Prayer", "Shadow Fury"  }

    local buffrefresh = arg2 or 45           -- Refresh buff time (seconds)
    local spell = UnitCastingTime("player")  -- Spell being cast?
    local vocal = IsShiftKeyDown()           -- Generate feedback if Shift key held

    if (spell ~= nil) then
        return
    end

    if vocal then Msg("- Checking self buffs on "..UnitName("player")) end
    for i,buff in ipairs(selfbuffs) do
        if (g_skill[buff] ~= nil) and CD(buff) and (BuffTimeLeft("player",buff) <= buffrefresh) then
            if vocal then Msg("- Casting "..buff.." on "..UnitName("player")) end
            TargetUnit("player")
            CastSpellByName(buff)
            return
        end
    end

    if vocal then Msg("- Checking group buffs on "..UnitName("player")) end
    for i,buff in ipairs(groupbuffs) do
        if (g_skill[buff] ~= nil) and CD(buff) and (BuffTimeLeft("player",buff) <= buffrefresh) then
            if vocal then Msg("- Casting "..buff.." on "..UnitName("player")) end
            TargetUnit("player")
            CastSpellByName(buff)
            return
        end
    end

    for num=1,GetNumPartyMembers()-1 do
        TargetUnit("party"..num)
        if GetActionUsable(arg1) and (UnitHealth("party"..num) > 0) then
            if vocal then Msg("- Checking group buffs on "..UnitName("party"..num)) end
            for i,buff in ipairs(groupbuffs) do
                if (g_skill[buff] ~= nil) and CD(buff) and (BuffTimeLeft("target",buff) <= buffrefresh) then
                    if UnitIsUnit("target","party"..num) then
                        if vocal then Msg("- Casting "..buff.." on "..UnitName("target")) end
                        CastSpellByName(buff)
                        return
                    else
                        if vocal then Msg("- Error: "..UnitName("target").." != "..UnitName("party"..num)) end
                    end
                end
            end
        else
            if vocal then Msg("- Player "..UnitName("party"..num).." out of range or dead.") end
        end
    end

    if vocal then Msg("- Nothing to do.") end
end

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
local WHITE = "|cffffffff"
local SILVER = "|cffc0c0c0"
local GREEN = "|cff00ff00"
local LTBLUE = "|cffa0a0ff"

function DIYCE_DebugSkills(skillList)
    DEFAULT_CHAT_FRAME:AddMessage(GREEN.."Skill List:")
    
    for i,v in ipairs(skillList) do
        DEFAULT_CHAT_FRAME:AddMessage(SILVER.."  ['..WHITE..i..SILVER..']: "..LTBLUE.."" "..WHITE..v.name..LTBLUE..""  use = "..WHITE..(v.use and "true" or "false"))
    end

    DEFAULT_CHAT_FRAME:AddMessage(GREEN.."----------")
end

function DIYCE_DebugBuffList(buffList)
    DEFAULT_CHAT_FRAME:AddMessage(GREEN.."Buff List:")
    
    for k,v in pairs(buffList) do
        -- We ignore numbered entries because both the ID and name 
        -- are stored in the list. This avoids doubling the output.
        if type(k) ~= "number" then
            DEFAULT_CHAT_FRAME:AddMessage(SILVER.."  ['..WHITE..k..SILVER..']:  "..LTBLUE.."id: "..WHITE..v.id..LTBLUE.."  stack: "..WHITE..v.stack..LTBLUE.."  time: "..WHITE..v.time)
        end
    end
    
    DEFAULT_CHAT_FRAME:AddMessage(GREEN.."----------")    
end

local silenceList = {
        ['Annihilation']    = true,
        ['King Bug Shock']  = true,
        ['Mana Rift']       = true,
        ['Dream of Gold']   = true,
        ['Flame']           = true,
        ['Flame Spell']     = true,
        ['Wave Bomb']       = true,
        ['Silence']         = true,
        ['Recover']         = true,
        ['Restore Life']    = true,
        ['Heal']            = true,
        ['Curing Shot']     = true,
        ['Leaves of Fire']  = true,
        ['Urgent Heal']     = true,
        ['Heavy Shelling']  = true, --Juggler Apprentice in Grafu
        ['Dark Healing']    = true, --Mini-boss in Sardo
                    }
                    
function PriestFairySequence(arg1)
    local Skill = {}
    local Skill2 = {}
    local i = 0
    local FairyExists = UnitExists("playerpet")
    local FairyBuffs = BuffList("playerpet")
    local combat = GetPlayerCombatState()

    --Determine Class-Combo
    mainClass, subClass = UnitClassToken( "player" )

    --Summon Fairy
    if (not FairyExists) and (not combat) then
        if mainClass == "AUGUR" then
            if subClass == "THIEF" then
                Skill = {
                    { name = "Shadow Fairy",            use = true },
                        }
            elseif subClass == "RANGER" then
                Skill = {
                    { name = "Water Fairy",                use = true },
                        }
            elseif subClass == "MAGE" then
                Skill = {
                    { name = "Wind Fairy",                use = true },
                        }            
            elseif subClass == "KNIGHT" then
                Skill = {
                    { name = "Light Fairy",                use = true },
                        }            
            elseif subClass == "WARRIOR" then
                Skill = {
                    { name = "Fire Fairy",                use = true },
                        }
            end
        end
    end    
    
    --Cast Halo
    if FairyExists then
        if mainClass == "AUGUR" then
            if subClass == "THIEF" then
                if (not FairyBuffs[503459]) then
                    if (arg1 == "v1") then
                        Msg("- Activating Halo", 0, 1, 1)
                    end
                    Skill = {
                        { name = "Pet Skill: 6 (Wraith Halo)",    use = true },
                            }
                end
            elseif subClass == "RANGER" then
                if (not FairyBuffs[503457]) then
                    if (arg1 == "v1") then
                        Msg("- Activating Halo", 0, 1, 1)
                    end
                    Skill = {
                        { name = "Pet Skill: 6 (Frost Halo)",    use = true },
                            }
                end
            elseif subClass == "MAGE" then
                if (not FairyBuffs[503461]) then
                    if (arg1 == "v1") then
                        Msg("- Activating Halo", 0, 1, 1)
                    end
                    Skill = {
                        { name = "Pet Skill: 6 (Windrider Halo)",    use = true },
                            }
                end
            elseif subClass == "KNIGHT" then
                if (not FairyBuffs[503507]) then
                    if (arg1 == "v1") then
                        Msg("- Activating Halo", 0, 1, 1)
                    end
                    Skill = {
                        { name = "Pet Skill: 6 (Devotion Halo)",    use = true },
                            }
                end
            elseif subClass == "WARRIOR" then
                if (not FairyBuffs[503455]) then
                    if (arg1 == "v1") then
                        Msg("- Activating Halo", 0, 1, 1)
                    end
                    Skill = {
                        { name = "Pet Skill: 6 (Accuracy Halo)",    use = true },
                            }
                end
            end
        
            --Cast Conceal
        if (not MyCombat(Skill, arg1)) then
            if (not FairyBuffs[503753]) then
                if (arg1 == "v1") then
                    Msg("- Activating Conceal", 0, 1, 1)
                end
                Skill2 = {
                    { name = "Pet Skill: 7 (Conceal)",    use = true },
                        }
            end
        end
        end
    end
    
    if (not MyCombat(Skill, arg1)) then
        MyCombat(Skill2, arg1)
    end
end
                        
function KillSequence(arg1, goat2, healthpot, manapot, foodslot)
--arg1 = "v1" or "v2" for debugging
--healthpot = # of actionbar slot for health potions
--manapot = # of actionbar slot for mana potions
--foodslot = # of actionbar slot for food (add more args for more foodslots if needed)

    local Skill = {}
    local Skill2 = {}
    local i = 0
    
    -- Player and target status.
    local combat = GetPlayerCombatState()
    local enemy = UnitCanAttack("player","target")
    local EnergyBar1 = UnitMana("player")
    local EnergyBar2 = UnitSkill("player")
    local pctEB1 = PctM("player")
    local pctEB2 = PctS("player")
    local tbuffs = BuffList("target")
    local pbuffs = BuffList("player")
    local tDead = UnitIsDeadOrGhost("target")
    local behind = (not UnitIsUnit("player", "targettarget"))
    local melee = GetActionUsable(2) -- # is your melee range spell slot number
    local a1,a2,a3,a4,a5,ASon = GetActionInfo(13)  -- # is your Autoshot slot number
    local phealth = PctH("player")
    local thealth = PctH("target")
    local LockedOn = UnitExists("target")
    local boss = UnitSex("target") > 2
    local elite = UnitSex("target") == 2
    local party = GetNumPartyMembers() >= 2
    
    
    --Determine Class-Combo
    mainClass, subClass = UnitClassToken( "player" )

    --Silence Logic
    local tSpell,tTime,tElapsed = UnitCastingTime("target")
    local silenceThis = tSpell and silenceList[tSpell] and ((tTime - tElapsed) > 0.1)
    
    --Potion Checks
    healthpot = healthpot or 0
    manapot = manapot or 0
    
    --Equipment and Pet Protection
    if phealth <= .03 then
            SwapEquipmentItem()        --Note: Remove the first double dash to re-enable equipment protection.
        for i=1,6 do
            if (IsPetSummoned(i) == true) then
                ReturnPet(i);
            end
        end        
    end
        
    --Check for level 1 mobs, if it is, drop target and acquire a new one.
    if (LockedOn and (UnitLevel("target") < 2)) then
        TargetUnit("")
        return
    end
    
    --Begin Player Skill Sequences
    
        --Priest = AUGUR, Druid = DRUID, Mage = MAGE, Knight = KNIGHT, 
        --Scout = RANGER, Rogue = THIEF, Warden = WARDEN, Warrior = WARRIOR
        
        -- Class: Rogue/Scout
            if mainClass == "THIEF" and subClass == "RANGER" then
            
            if (enemy) then
            Skill2 = {
                { name = "Wound Attack",                       use = ((EnergyBar1 >= 35) and ((tbuffs[500654]) and (tbuffs[500704]))) },
                { name = "Low Blow",                           use = (((EnergyBar1 >= 25) and (tbuffs[500654])) or (tbuffs['Energy Thief']))},
                { name = "Shadowstab",                         use = (EnergyBar1 >= 20) },
                    }

            --ADD MORE CLASS COMBOS HERE. 
            --USE AN "ELSEIF" TO CONTINUE WITH MORE CLASS COMBOS.
            --THE NEXT "END" STATEMENT IS THE END OF THE CLASS COMBOS STATEMENTS.
            --DO NOT POST BELOW THE FOLLOWING "END" STATEMENT!
            end
    --End Player Skill Sequences
    
    if (arg1=="debugskills") then        --Used for printing the skill table, and true/false usability
        DIYCE_DebugSkills(Skill)
        DIYCE_DebugSkills(Skill2)
    elseif (arg1=="debugpbuffs") then    --Used for printing your buff names, and buffID
        DIYCE_DebugBuffList(pbuffs)
    elseif (arg1=="debugtbuffs") then    --Used for printing target buff names, and buffID
        DIYCE_DebugBuffList(tbuffs)
    elseif (arg1=="debugall") then        --Used for printing all of the above at the same time
        DIYCE_DebugSkills(Skill)
        DIYCE_DebugSkills(Skill2)
        DIYCE_DebugBuffList(pbuffs)
        DIYCE_DebugBuffList(tbuffs)
    end
    
    if (not MyCombat(Skill, arg1)) then
        MyCombat(Skill2, arg1)
    end
        
    --Select Next Enemy
    if (tDead) then
        TargetUnit("")
        return
    end
    if (mainClass == "RANGER") then        --To keep scouts from pulling mobs without meaning to.
        if (not LockedOn) or (not enemy) then
            TargetNearestEnemy()
            return
        end
    elseif mainClass ~= "RANGER" then                    --Let all other classes auto target.
        if (not LockedOn) or (not enemy) then
            TargetNearestEnemy()
            return
        end
    end
end


That should work now, please give it a try.