You are not logged in.

Dear visitor, welcome to Runes of Magic US / AU. If this is your first visit here, please read the Help. It explains in detail how this page works. To use all features of this page, you should consider registering. Please use the registration form, to register here or read more information about the registration process. If you are already registered, please login here.

ghostwolf82

Professional

  • "ghostwolf82" started this thread

Posts: 859

Location: Kalvans Trunk

Occupation: It's dark in here

  • Send private message

1

Tuesday, November 1st 2011, 5:27am

DIY Combat Engine version 2.0

The original DIYCE thread is quite lengthy, and there are so many new ideas coming out from a few players, and are getting overlooked, that I decided to write up a new guide to the DIYCE with the optimizations that have proven useful, while also having sped up the DIYCE engine.

The code herein is so vastly different from the original DIYCE that it deserved it's own thread. Most of the advanced users are no longer using anything resembling the original, thus it was time for Version 2. Sixpax, the original author of the DIYCE, sadly no longer plays nor is he active on the forums, and is therefor not able to update the code in the aforementioned post to keep up with the new methods for optimization.

I will reiterate the installation instructions provided in the previous version:

Quoted from "Sixpax;213845"

Note that this does not automate your combat (sorry bot lovers), it just picks the best attack to execute every time you hit the macro. You'll have to hit the macro each time you want your character to perform an action.

INSTALLATION:

If you have any trouble setting this up, please read the link in my sig on creating custom functions. I posted a set of instructions (see post #21 of this thread) that might help as well. If there are errors in your code, you'll get an icon around your minimap that is flashing red. Click on that to get the exact error message.

First off, you'll need to create a folder to extract the .zip files (with their path). If you already have other addons, then the folder you need is already there, just navigate to the path.

Here's the path you should create/navigate to:

Runes of Magic\Interface\Addons

Next open the zip file from the bottom of this post. If you are using WinZip, extract the files into that folder (be sure "Use folder names" is checked). If you are using the standard Windows explorer to view the .zip file, just drag the DIYCE folder to that destination.

To verify you have it setup correctly, you will wind up with 3 files (DIYCE.toc, DIYCE.lua, and CustomFunctions.lua) in this folder:

Runes of Magic\Interface\Addons\DIYCE


Here is the code in the DIYCE.lua file simply for reference:

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
-- DIY Combat Engine version 2.2

local g_skill  = {}
local g_lastaction = ""

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("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, id = ID }
            -- We also list by ID in case two different buffs/debuffs have the same name.
            list[ID] = {stack = stackSize, time = timeRemaining, 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 CD(Skill[x].name) then
                if talktome then Msg("- "..Skill[x].name) end
                CastSpellByName(Skill[x].name)
                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

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
Much of how the DIYCE actually functions still works the same as in the original, just at a much more optimized pace, with a different setup to the code itself. One major change is this version will still tell you when a skill is not available, however the rest of the DIYCE will continue to operate. No longer stopping while in the middle of combat, possibly creating problems (eg. Death).

Quoted from "Sixpax;213845"


HOW IT WORKS:

For those that want to know, this is how the Engine operates: The ReadSkills() function gets run whenever you enter the game, level-up, or switch classes. It goes through your skill book and memorizes all of your skill numbering and stores it in a global table (g_skill) to be referenced by the CD() function. The CD() function checks the cooldown on whatever skill is passed to it and will return a value of true if the named skill is not on cooldown and false otherwise, so think of this as a "is the skill ready" check. The MyCombat() function goes through a table (called "Skill") that you define with a list of each action/skill you want to perform looking for the first one that's ready to be used and meets the criteria you specify for that skill.


From here is where version 2 begins to get different enough to warrant a new thread. The custom functions no longer require a separate function for each class combination you have. (I know everyone is used to doing it that way, but this is one of the key optimizations to this new version.) There is now one master function for every class to use, which means one macro for everyone. Every toon you create using this new version of DIYCE will have the exact same macro ( /run Killsequence() ), the only differences from one toon to the next will be the numbers that go inside the parenthesis for the use of potions or foods.

BUILDING YOUR CUSTOM SECTION OF COMBAT SCRIPT:

Again, you are no longer creating a custom function for each class combination you make, you will simply be editing the existing function to include a check to be ran for your particular class combo.

You can have as many checks for class combinations as you need (there are 48 total combinations in the game at this point in time). What your class combination check will do is define a table of skills and the criteria to use those skills. Here is an example of a skill table in DIYCE v2.0:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
            --Potions and buffs
            Skill = {
                { name = "Savage Blessing",                use = (pctEB1 >= .05) and ((not pbuffs['Savage Blessing']) or (pbuffs['Savage Blessing'].time <= 45)) },
                { name = "Concentration Prayer",           use = (pctEB1 >= .05) and ((not pbuffs['Concentration Prayer']) or (pbuffs ['Concentration Prayer'].time <= 45)) },
                { name = "Intensification",                use = (pctEB1 >= .05) and (not pbuffs['Intensification']) and boss and enemy },
                    }
            --Combat
                if enemy then
                Skill2 = {
                    { name = "Binding Silence",            use = (silenceThis) },
                    { name = "Silence",                    use = (silenceThis) },
                    { name = "Weakening Seed",             use = (pctEB1 >= .05) and boss and ((not tbuffs['Weakening Seed']) or (tbuffs['Weakening Seed'].time < 4)) },
                    { name = "Mother Nature's Wrath",      use = (pctEB1 >= .05) },
                    --{ name = "Briar Entwinement",          use = (pctEB1 >= .05) and ((not tbuffs['Briar Entwinement']) or (tbuffs['Briar Entwinement'].time < 4)) },
                    { name = "Lightning",                  use = (pctEB1 >= .05) },
                    { name = "Fireball",                   use = (pctEB1 >= .05) },
                    { name = "Earth Arrow",                use = (pctEB1 >= .05) },
                            }
                end
In this example the Combat Engine is checking for the buffs "Savage Blessing", "Concentration Prayer", and "Intensification" weather there is an enemy target selected or not, and if those buffs are not applied then apply them. This set of checks is done both in and out of combat. Next the Combat Engine checks to see if there is an enemy targeted, and if so then start using the damage spells that are set up based on the criteria to the right of the "use" determinate.

For "Binding Silence" and "Silence" the Combat Engine is referencing the Silence List variable set at the top of the DIYCE.lua file. If one of those spells is being cast by the enemy target, then a silencing spell will be used. Next the Combat Engine checksif you have a boss mob targeted, and if so then it checks to see if it has the debuff from "Weakening Seed", if not apply it. The Combat Engine moves down the rest of the list in this manner.

For each line in the combat script sections, you will want to apply a check to make sure you have enough rage/mana/energy/focus to cast a particular spell. In the example above, this is a script for a druid/mage and since both classes use mana, the check is "(pctEB1 >= .05)", which checks to see if there is more than or equal to 5% mana.

No longer do you need to classify in your variables which form of fuel you are using for your skills to check against. In the KillSequence function the variables you will be using most often are already set (add to it the variables you will need that are not included, but be advised to not change the already existing ones). The energy/rage/focus/mana bars are now read like this:

Source code

1
2
3
4
    local EnergyBar1 = UnitMana("player")
    local EnergyBar2 = UnitSkill("player")
    local pctEB1 = PctM("player")
    local pctEB2 = PctS("player")
Bar1 is the upper bar (the bar of your primary class). Bar2 is the lower bar (the bar of your secondary class. The way to use these in your combat section of the KillSequence function for rage/energy/focus would be to use the variable EnergyBar1 or EnergyBar2, since all three of those forms are based on a hard number, and will remain the same throughout game play. The way to use these in your combat section for mana would be to use either pctEB1 or pctEB2, since the amount of mana used for any given skill goes up as you increase the level of the skill, as well as the amount of mana you have is ever changing, thus it is better to use a percent rather than a static number.

To visualize what this is doing, the Skill table might look like this (with the cooldown check listed as well) in the middle of combat when you hit the macro:

Source code

1
2
3
4
5
6
7
8
 [U]
skill          [/U]  [U]use   [/U]   [U](CD)    [/U]
Savage Blessing  false    true
Concen. Prayer   false    true
Intensification  false    true
Lightning        true     true
Fireball         false    false
Earth Arrow      true     true
The MyCombat() function will go through this table until it finds the first skill with a true condition for "use" that isn't on cooldown. So in this case, "Lightning" will get executed. This does not cycle through the list executing the skills in order, instead it goes through the list every time you run it and finds the first skill that's ready. So you're building a skill priority list, not a sequence.

Notice that I have "Briar Entwinement" defined in the function but I've commented it out ("--" at the beginning of the line). So that way if I want to add it back into my rotation later, I just un-comment the line. If you want to rearrange the priority of the skills, you just cut and paste the entire line wherever you want it in the order.

THE CUSTOM FUNCTION:

The custom function that you will be editing is located in CustomFunctions.lua, and upon opening the file this is what you should see:

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
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
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,
                    }
                    
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, 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(13) -- # is your melee range spell slot number
    local a1,a2,a3,a4,a5,ASon = GetActionInfo(14)  -- # 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 <= .04 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: Warrior/Mage
            if mainClass == "WARRIOR" and subClass == "MAGE" then
                local SurpriseAttack = GetActionUsable(14)
    
            --Potions and Buffs
            Skill = {
                { name = "Action: "..healthpot,            use = (phealth <= .70) },
                { name = "Survival Instinct",              use = (phealth <= .30) and combat },
                { name = "Sense of Danger",                use = (phealth <= .30) and combat },
                { name = "Action: "..manapot,              use = (pctEB2 <= .40) },
                { name = "Action: "..Healslot,             use = (phealth < .70) and (not combat) and (not party) },
                { name = "Action: "..HoTslot,              use = (phealth < .80) and (not party) },
                { name = "Intensification",                use = (pctEB2 >= .05) and (not pbuffs['Intensification']) and boss and enemy },
                { name = "Aggressiveness",                 use = boss and enemy },
                { name = "Electric Attack",                use = (pctEB2 >= .05) and ((not pbuffs['Electric Attack']) or (pbuffs['Electric Attack'].time <= 45)) },
                    }
                    
            --Combat
                if enemy then
                Skill2 = {
                    { name = "Silence",                    use = (silenceThis) },
                    { name = "Surprise Attack",            use = SurpriseAttack },
                    { name = "Enraged",                    use = (EnergyBar1 <= 30) and (boss or elite) },
                    { name = "Electrical Rage",            use = (EnergyBar1 >= 15) and (pctEB2 >=.05) and (not pbuffs['High Voltage III']) },
                    { name = "Thunder Sword",              use = (pctEB2 >= .05) },
                    { name = "Lightning's Touch",          use = (pctEB2 >= .05) },
                    { name = "Attack",                     use = (thealth == 1) },
                        }
                end

            --Class: Rogue/Priest
            elseif mainClass == "THIEF" and subClass == "AUGUR" then
            
            --Potions and Buffs
            Skill = {
                { name = "Regenerate",                    use = (phealth <= .90) and (pctEB2 >= .05) and (not pbuffs['Regenerate']) },
                { name = "Action: "..healthpot,           use = (phealth <= .70) },
                { name = "Action: "..manapot,             use = (pctEB2 <= .40) },
                { name = "Magic Barrier",                 use = (pctEB2 >= .05) and ((not pbuffs['Magic Barrier']) or (pbuffs['Magic Barrier'].time <= 45)) },
                { name = "Quickness Aura",                use = (pctEB2 >= .05) and ((not pbuffs['Quickness Aura']) or (pbuffs['Quickness Aura'].time <= 45)) },
                { name = "Poison",                        use = ((not pbuffs['Poisonous']) or (pbuffs['Poisonous'].time <= 45))},
                    }
                    
            --Combat
                if enemy then
                Skill2 = {
                    { name = "Premeditation",                use = (not combat) and boss and (EnergyBar1 >= 50) },
                    { name = "Slowing Poison",               use = boss },
                    { name = "Informer",                     use = boss },
                    { name = "Fervent Attack",               use = boss },
                    { name = "Assassins Rage",               use = boss },
                    { name = "Kick",                         use = (pctEB2 >= .05) },
                    { name = "Sneak Attack",                 use = (EnergyBar1 >= 20) and boss and behind and party },
                    { name = "Blind Spot Attack",            use = (EnergyBar1 >= 20) and boss and behind and party },
                    { name = "Shadowstab",                   use = (EnergyBar1 >= 20) and (not tbuffs[620313]) },
                    { name = "Low Blow",                     use = (EnergyBar1 >= 30) and (tbuffs[620313]) and (not tbuffs[500704]) },
                    { name = "Wound Attack",                 use = (EnergyBar1 >= 35) },
                    { name = "Shadowstab",                   use = (EnergyBar1 >= 20) },
                    { name = "Attack",                       use = (thealth == 1) },                    
                            }
                end
                
            --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" and (not party) 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
I have left the two class combos (Warrior/Mage and Rogue/Priest) as examples. If you want, you can remove those two class combos, however leaving them there will not harm your use of this script in any way. If you have either of those class combos, then they will already be in there, and you will just have to edit them to your liking.

YOUR IN-GAME MACRO:

With all of this done, it is now time to go in-game and create the macro that will call this script to work for you. The easiest way to test your script is to create a macro like this:

Source code

1
/run KillSequence()
Try the macro and see if it works. If not, start troubleshooting, beginning with the red button with a green glowing circle around it next to your minimap.

For more modifications to the macro, you can add in food and potion buffs, as well as the standard health and mana potions. A more advanced macro would look like this:

Source code

1
/run KillSequence("v1",59,57,"","",20)
You will have to determine just how many arguments you will need for your own use. Everyone will have different needs with this.

The first argument ("arg1") is a feedback control for debugging. If you wish for no feedback then set arg1 as "", for feedback use either "v1" or "v2", depending on what level of feedback you would like.

Quoted from "Sixpax;213845"

I highly recommend downloading and using Notepad++ when editing code. It helps to catch things like unbalanced parentheses and other typos. It also displays the line numbers next to each line so if you get an error in game, you can refer to the line number it lists.
I have provided a link to the Notepad++ website, this is a free tool to download and use.


I do, as always, recomend reading the original DIYCE thread (linked at the beginning) for reference and learning, as many knowledgeable people have posted in that thread over the last two years. Please take the time to learn from those that have come before you to the world of using DIYCE.

Good luck to all of you who attempt to use DIY Combat Engine version 2.0 and keep asking questions!

Your friend,
~GW :cool:


**LINK TO THE CURSE DOWNLOAD OF DIYCE**
ghostwolf82 has attached the following file:
  • DIYCE.zip (14.54 kB - 248 times downloaded - latest: Sep 6th 2017, 8:39pm)

AddOn: DIY Combat Engine v2 AddOn: Auto Ding
Reni - Malkira
Warlock Guide
Retired from RoM with patch 6.1.0

ghostwolf82

Professional

  • "ghostwolf82" started this thread

Posts: 859

Location: Kalvans Trunk

Occupation: It's dark in here

  • Send private message

2

Tuesday, November 1st 2011, 5:44am

With DIYCE v2.1 I have added a few new functions. These new functions are for Priests and Druids.

The "PriestFairySequence" function is for priests who have their level 50 elite skill which calls a fairy to assist you in battle. This function will call your fairy, cast the "Halo" buff, and then cast the "Conceal" buff as well. When your fairy needs a rebuff, this function will do that for you as well. To call this function you can either have it on a separate macro from the main DIYCE macro, or incorporate it into the main macro.

To have it on a separate macro, this is what that macro would look like:

Source code

1
/run PriestFairySequence()
To have it as part of the main DIYCE macro, this is what that would look like:

Source code

1
/run if (not PriestFairySequence() then KillSequence() end
Either way you choose to run the "PriestFairySequence" function, there is the optional parameter to use "v1" or "v2" with it.

The code for the "PriestFairySequence" function is this:

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
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

The other addition to the DIYCE with v2.1 is the reintroduction of "BuffTimeLeft", which is used in the other new function in v2.1 "BuffParty".

"BuffParty" is a function for priests and druids alike to be able to buff their entire party. The code is an older idea that I had a long time ago, and Sixpax eventually wrote it up (to eventually turn it into a full fledged addon), and I am reintroducing it in this version of DIYCE as a part of the main body in an effort to make DIYCE more widely useable by everyone (giving healers a reason to have DIYCE too).

Again, you can call this function as part of the main DIYCE macro, or set it up on its own individual macro (I set mine up on a second macro).
To be ran in a second macro:

Source code

1
/run BuffParty(#)
To be ran in conjunction with the main function:

Source code

1
/run if (not BuffParty(#)) then KillSequence() end
The # in both of those macros represents the action bar slot number you use for a targetable, instant-cast buff without a cooldown (eg. Amp Attack), for range checking.

The code for "BuffTimeLeft" and "BuffParty" is this:

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
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


Just wanted to share this bit of information with everyone:

My current macro in game on my P/R is this -

Source code

1
/run if Potion(57) then return; elseif PriestFairySequence("v1") then return; elseif BuffParty(20) then return; elseif PartyHealer.Main() then return; elseif KillSequence("",59,57) then return; end
This is stringing together many of my functions into one macro, and running them in order. This will first check to see if I need to drink a mana potion, if not then it checks to see if I have my Fairy out and buffed, if I do then it checks to see if everyone in the party is fully buffed up, if they are then it checks to see if everyone is good on health, if they are THEN it runs the combat script I have set up for this toon.

This is just an example of how functions can be strung together to be called in one big "super"macro.

AddOn: DIY Combat Engine v2 AddOn: Auto Ding
Reni - Malkira
Warlock Guide
Retired from RoM with patch 6.1.0

mrmisterwaa

Professional

Posts: 670

Location: Kuwait

  • Send private message

3

Tuesday, November 1st 2011, 5:52am

/clap.

Good job.

When I get back from class, I will make sure to update my RogueScout function.

4

Tuesday, November 1st 2011, 12:11pm

well i have some problems with this new dyce.
i made some modifications to CustomFunctions

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
 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,
                        }    


function KillSequence(arg1, 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(13) -- # is your melee range spell 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
    local a1,a2,a3,a4,a5,ASon = GetActionInfo(4)  -- # is your Autoshot slot number
    
    --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 <= .04 then
            --SwapEquipmentItem()        --Note: Remove the first double dash to re-enable equipment protection.
        for i=1,3 do
            if (IsPetSummoned(i) == true) then
                ReturnPet(i);
            end
        end        
    end
        
    if (LockedOn and (UnitLevel("target") < 2)) then
        TargetUnit("")
        TargetNearestEnemy()
        return
    end
    
    --Begin Player Skill Sequences
    
        --Priest = AUGUR, Druid = DRUID, Mage = MAGE, Knight = KNIGHT, 
        --Scout = RANGER, Rogue = THIEF, Warden = WARDEN, Warrior = WARRIOR
        
        -- Class: Scout/Warden
            if mainClass == "RANGER" and subClass == "WARDEN" then
    
            --Potions and Buffs
            Skill = {

                { name = "Entling Offering",                use = (pctEB2 >= .05) and ((not pbuffs['Entling Offering']) or (pbuffs['Entling Offering'].time <= 45)) },
                { name = "Barriar Shield",                  use = (pctEB2 >= .05) and ((not pbuffs['Barriar Shield']) or (pbuffs['Barriar Shield'].time <= 45)) },
                    }
                    
            --Combat
                if enemy then
                Skill2 = {
                    { name = "Snipe",                      use = (ChkArg(Pbuffs['Hidden Peril'])) },
                    { name = "Combo Shot",                 use = Combo Shot },
                    { name = "Autoshot",                   use = not Ason },
                    { name = "Hidden Peril",               use = Hidden Peril },
                    { name = "Thorn Arrow",                use = Thorn Arrow },
                    { name = "Shoot",                      use = Shoot },
                    { name = "Vampire Arrows",             use = Vampire Arrows },
                    { name = "Piercing Arrow",             use = Piercing Arrow },
                        }
                end

            --Class: Rogue/Scout
            elseif mainClass == "THIEF" and subClass == "RANGER" then
            
            --Potions and Buffs
            Skill = {
                { name = "Combat Master",                 use = ((not pbuffs['Combat Master']) or (pbuffs['Combat Master'].time <= 45)) },
                { name = "Poison",                        use = ((not pbuffs['Poisonous']) or (pbuffs['Poisonous'].time <= 45))},
                    }
                    
            --Combat
                if enemy then
                Skill2 = {
                    { name = "Premeditation",                use = (not combat) and boss and (EnergyBar1 >= 50) },
                    { name = "Assassins Rage",               use = boss },
                    { name = "Energy Thief",                 use = boss },
                    { name = "Sneak Attack",                 use = (EnergyBar1 >= 20) and boss and behind and party },
                    { name = "Blind Spot Attack",            use = (EnergyBar1 >= 20) and boss and behind and party },
                    { name = "Shadowstab",                   use = (EnergyBar1 >= 20) and (not tbuffs[620313]) },
                    { name = "Low Blow",                     use = (EnergyBar1 >= 30) and (tbuffs[620313]) and (not tbuffs[500704]) },
                    { name = "Wound Attack",                 use = (EnergyBar1 >= 35) },
                    { name = "Shadowstab",                   use = (EnergyBar1 >= 20) },
                    { name = "Shot",                         use = Shot },
                    { name = "Attack",                       use = (thealth == 1) },                    
                            }
                end
                
            --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 (not MyCombat(Skill, arg1)) then
        MyCombat(Skill2, arg1)
    end
        
    --Select Next Enemy
    if (tDead) then
        TargetUnit("")
        TargetNearestEnemy()
        return
    elseif (not LockedOn) or (not enemy) then
        TargetNearestEnemy()
        return
    end
    
end

but when enter game and make macro
/run KillSequence("v2") nothing happends.

RoMage

rustyx is lame rogue

Posts: 2,694

Location: web

Occupation: DB Admin

Mood: Unsure

  • Send private message

5

Tuesday, November 1st 2011, 12:17pm

Great! I will change my DIYCE tonight, I have to play a bit more with it.... (haven't done so in a while)


@freym - what are your classes and what was your class once you tried to use this DIYCE??

mrmisterwaa

Professional

Posts: 670

Location: Kuwait

  • Send private message

6

Tuesday, November 1st 2011, 2:51pm

ghostwolf82, I came across a tiny logic problem with Wound Attack.

As a Rogue Scout who has Energy Thief during burn, I tend to set Low Blow to cast if Energy Thief or Grievous Wound is up on (myself for Energy Thief) the target.

How do I make it so Wound Attack will always have a priority over Low Blow when Energy Thief is up?

Here is the RogueScout function of mine, at least the first version of it.

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
            elseif mainClass == "THIEF" and subClass == "RANGER" then
            
            Skill = {
                { name = "Combat Master",                   use = ((not pbuffs['Combat Master')) }
                { name = 'Action: 62',                      use = ((not pbuffs['Yawaka's Blessing')) }
                { name = 'Action: 69',                      use = ((not pbuffs['Unbridled Enthusiasm')) } -- Speed Potion
                { name = 'Poison',                          use = ((not pbuffs['Poisonous']) or (pbuffs['Poisonous'].time <= 45)) },
                    }
                    
            if enemy then
            Skill2 = {
                { name = "Blind Spot",                      use = (EnergyBar1 >= 20) and boss and behind and (pbuffs['Energy Thief'] or pbuffs['Premeditation']) },
                { name = "Shadowstab",                      use = (EnergyBar1 >= 20) and (not tbuffs[620313]) },
                { name = "Low Blow",                        use = (EnergyBar1 >= 25) and (tbuffs[620313]) and ((not tbuffs[500704]) or pbuffs['Energy Thief']) },
                { name = "Wound Attack",                    use = (EnergyBar1 >= 35) },
                { name = "Vampire Arrows",                  use = (thealth > 1) },
                { name = "Shot",                            use = (not EnergyBar1 >= 20) },
                { name = "Wrist Attack",                    use = (EnergyBar2 >= 50) and boss },
                { name = "Throat Attack",                   use = (EnergyBar2 >= 50) and (boss or elite) and silenceThis },
                { name = "Attack",                          use = (thealth == 1) },
                    }
            end
So right now, if I have it right, it will do it the way I want ... except where since it doesn't have a sequence. If Energy Thief is up, it will spam Low Blow.

I want to make it so that Shadowstab & Wound Attack have to be used even though Energy Thief is up.

How do I do that right? o.O

7

Tuesday, November 1st 2011, 3:26pm

Thanks GW..This is awesome...I love DIYCE.

One Question..Why is the silence list in both the .lua and the customfunctions?
Jacobmo 97Scout/97Warden/95Warrior/97Rogue/88D/85M
Allenmo 78S/77R/56P/1W/1K/1M - retired
Bteam all the way

ghostwolf82

Professional

  • "ghostwolf82" started this thread

Posts: 859

Location: Kalvans Trunk

Occupation: It's dark in here

  • Send private message

8

Tuesday, November 1st 2011, 4:00pm

Quickest answer before heading off to work -
@samohn - an error, only meant to be in the customfunctions, I will upload a new version right now. If you grabbed it before the update, you can remove it from the diyce.lua.

AddOn: DIY Combat Engine v2 AddOn: Auto Ding
Reni - Malkira
Warlock Guide
Retired from RoM with patch 6.1.0

bleedingblak

I'm here to troll you

Posts: 1,232

Location: www.youtube.com/user/ihavetourettesxx

Mood: Crying

  • Send private message

9

Tuesday, November 1st 2011, 4:02pm

Quoted from "mrmisterwaa;479820"

ghostwolf82, I came across a tiny logic problem with Wound Attack.

As a Rogue Scout who has Energy Thief during burn, I tend to set Low Blow to cast if Energy Thief or Grievous Wound is up on (myself for Energy Thief) the target.

How do I make it so Wound Attack will always have a priority over Low Blow when Energy Thief is up?

Here is the RogueScout function of mine, at least the first version of it.

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
            elseif mainClass == "THIEF" and subClass == "RANGER" then
            
            Skill = {
                { name = "Combat Master",                   use = ((not pbuffs['Combat Master')) }
                { name = 'Action: 62',                      use = ((not pbuffs['Yawaka's Blessing')) }
                { name = 'Action: 69',                      use = ((not pbuffs['Unbridled Enthusiasm')) } -- Speed Potion
                { name = 'Poison',                          use = ((not pbuffs['Poisonous']) or (pbuffs['Poisonous'].time <= 45)) },
                    }
                    
            if enemy then
            Skill2 = {
                { name = "Blind Spot",                      use = (EnergyBar1 >= 20) and boss and behind and (pbuffs['Energy Thief'] or pbuffs['Premeditation']) },
                { name = "Shadowstab",                      use = (EnergyBar1 >= 20) and (not tbuffs[620313]) },
                { name = "Low Blow",                        use = (EnergyBar1 >= 25) and (tbuffs[620313]) and ((not tbuffs[500704]) or pbuffs['Energy Thief']) },
                { name = "Wound Attack",                    use = (EnergyBar1 >= 35) },
                { name = "Vampire Arrows",                  use = (thealth > 1) },
                { name = "Shot",                            use = (not EnergyBar1 >= 20) },
                { name = "Wrist Attack",                    use = (EnergyBar2 >= 50) and boss },
                { name = "Throat Attack",                   use = (EnergyBar2 >= 50) and (boss or elite) and silenceThis },
                { name = "Attack",                          use = (thealth == 1) },
                    }
            end
So right now, if I have it right, it will do it the way I want ... except where since it doesn't have a sequence. If Energy Thief is up, it will spam Low Blow.

I want to make it so that Shadowstab & Wound Attack have to be used even though Energy Thief is up.

How do I do that right? o.O


Put joint blow skill under shot. It is useful ^_^ just +55 it :) Can hit harder than shot if it crits.


~Fly into the distance, disappear for awhile~

10

Tuesday, November 1st 2011, 4:21pm

I had a feeling that this was going to be happening soon. I delayed writing up a "DIYCE for Dummies" tutorial for my guild because I wanted it to have all the new info in it. I'll do my write-up on DIYCE2 instead.

One quick question Ghostwolf: I am in the process of learning lua programming for the express purpose of writing a GUI for DIYCE. I'm going through Peryl's RoMWiki tutorials on XML and Dynamic Frames. I haven't examined DIYCE2 in detail yet. Is it adaptable to the general writeup that Peryl wrote for a possible GUI? I'd like your thoughts on whether this is an appropriate Addon target now that the playing field has changed.

EDIT:
Also, I noticed this while perusing the Custom Function code:

Quoted from "ghostwolf82;479689"


Source code

1
2
3
4
5
6
7
8
9
    --Equipment and Pet Protection
    if phealth <= .04 then
            --SwapEquipmentItem()        --Note: Remove the first double dash to re-enable equipment protection.
        [B]for i=1,3 do[/B]
            if (IsPetSummoned(i) == true) then
                ReturnPet(i);
            end
        end
    end



Shouldn't that actually be "for i=1,6 do" for this of us that have opened up all 6 pet slots?

EDIT2:

One other item: Would there be any code execution speed gain or any other advantages gained by re-writing the engine and/or custom function and placing certain checks in the macro itself? For instance a macro like this (assuming the proper engine alterations):

Source code

1
2
/script if (UnitSex("target") > 2) then KillSequence("", "boss") else
KillSequence() end


This macro example does not take in to account the pre-defined argument positions that you defined in your custom code earlier. The macros could be made arbitrarily complex. The reason I think it might speed up execution is that some conditional checks could be made before even calling the custom DiYCE2 function. You could then create a section in your custom function where the argument is checked with an if-elseif-else block for the various arguments that could be passed by the macro. Things like health, target casting status, and other "common" arguments could be passed. You obviously couldn't pass something like a melee range condition because it hasn't been defined yet.

It's just a thought. :)

mrmisterwaa

Professional

Posts: 670

Location: Kuwait

  • Send private message

11

Tuesday, November 1st 2011, 4:37pm

Quoted from "bleedingblak;479843"

Put joint blow skill under shot. It is useful ^_^ just +55 it :) Can hit harder than shot if it crits.


Not on end-game, not ranged and costs Focus.

Vampire Arrow and Wrist Attack have a much higher priority.

Either way, as Ghost said, there is no longer a priority on the list, it's not a sequence. So it's position doesn't matter.

12

Tuesday, November 1st 2011, 9:15pm

Seem to be having trouble with my portion of the customfunction. It is not recognizing the parenthesis above the "end" as being associated with the parenthesis on the line "Skill2 = {". I'm not sure why.

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- Class: Scout/Knight
   if mainClass == "RANGER" and subClass == "KNIGHT" then
 
   --Combat
    if enemy then
    Skill2 = [B][COLOR=red]{[/COLOR][/B]
     { name = "Vampire Arrows", use = CD("Vampire Arrows") }
     { name = "Autoshot", use = (not ASon) }
     { name = "Combo Shot", use = CD("Combo Shot") }
     { name = "Reflected Shot", use = (CD("Reflected Shot")) }  
     { name = "Piercing Arrow", use = (CD("Piercing Arrow")) } 
     { name = "Wind Arrows", use = (CD("Wind Arrows")) and (EnergyBar1 >= 35) }  
     { name = "Shot", use = (CD("Shot")) }
              [COLOR=red][B]}[/B][/COLOR]
    end
Jacobmo 97Scout/97Warden/95Warrior/97Rogue/88D/85M
Allenmo 78S/77R/56P/1W/1K/1M - retired
Bteam all the way

13

Tuesday, November 1st 2011, 9:56pm

Quoted from "samohn;479942"

Seem to be having trouble with my portion of the customfunction. It is not recognizing the parenthesis above the "end" as being associated with the parenthesis on the line "Skill2 = {". I'm not sure why.

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- Class: Scout/Knight
   if mainClass == "RANGER" and subClass == "KNIGHT" then
 
   --Combat
    if enemy then
    Skill2 = [B][COLOR=red]{[/COLOR][/B]
     { name = "Vampire Arrows", use = CD("Vampire Arrows") }
     { name = "Autoshot", use = (not ASon) }
     { name = "Combo Shot", use = CD("Combo Shot") }
     { name = "Reflected Shot", use = (CD("Reflected Shot")) }  
     { name = "Piercing Arrow", use = (CD("Piercing Arrow")) } 
     { name = "Wind Arrows", use = (CD("Wind Arrows")) and (EnergyBar1 >= 35) }  
     { name = "Shot", use = (CD("Shot")) }
              [COLOR=red][B]}[/B][/COLOR]
    end


Allen, you need commas at the end of each skill line. Essentially, these lines are elements of an array instead of individual lines of code like the old DIYCE. Hence, a comma is required to separate the individual elements of the array. Without the commas, the array definition closes at the first closing parenthesis. At least that is my understanding if it. (Actually, the individual skills in the old DIYCE were elements of an array also, but the index variable was manually incremented on each line. In the new DIYCE, we're saving some memory overhead by allowing the array to automatically increment the index variable.) Like this:

Source code

1
2
3
4
5
6
7
8
9
10
11
   --Combat
    if enemy then
    Skill2 = {
     { name = "Vampire Arrows", use = CD("Vampire Arrows") },
     { name = "Autoshot", use = (not ASon) },
     { name = "Combo Shot", use = CD("Combo Shot") },
     { name = "Reflected Shot", use = (CD("Reflected Shot")) },
     { name = "Piercing Arrow", use = (CD("Piercing Arrow")) },
     { name = "Wind Arrows", use = (CD("Wind Arrows")) and (EnergyBar1 >= 35) },
     { name = "Shot", use = (CD("Shot")) },
              }


(also, FYI, color tags don't seem to work inside code tags :P )

EDIT:
Oh! Almost forgot. GM/FM/CM sticky please! We need this thread at the top. It's likely to receive significant traffic. :)

ghostwolf82

Professional

  • "ghostwolf82" started this thread

Posts: 859

Location: Kalvans Trunk

Occupation: It's dark in here

  • Send private message

14

Tuesday, November 1st 2011, 11:10pm

Quoted from "freym;479775"

well i have some problems with this new dyce.
i made some modifications to CustomFunctions

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
            --Combat
                if enemy then
                Skill2 = {
                    { name = "Snipe",                      use = (ChkArg(Pbuffs['Hidden Peril'])) },
                    { name = "Combo Shot",                 use = Combo Shot },
                    { name = "Autoshot",                   use = not Ason },
                    { name = "Hidden Peril",               use = Hidden Peril },
                    { name = "Thorn Arrow",                use = Thorn Arrow },
                    { name = "Shoot",                      use = Shoot },
                    { name = "Vampire Arrows",             use = Vampire Arrows },
                    { name = "Piercing Arrow",             use = Piercing Arrow },
                        }
                end
but when enter game and make macro
/run KillSequence("v2") nothing happends.

The problem lies in the way you define the use section. You have it right on some sections, but incorrect for other sections.

Quoted from "mrmisterwaa;479820"

ghostwolf82, I came across a tiny logic problem with Wound Attack.

As a Rogue Scout who has Energy Thief during burn, I tend to set Low Blow to cast if Energy Thief or Grievous Wound is up on (myself for Energy Thief) the target.

How do I make it so Wound Attack will always have a priority over Low Blow when Energy Thief is up?

Here is the RogueScout function of mine, at least the first version of it.

Source code

1
 tbuffs[500704])
So right now, if I have it right, it will do it the way I want ... except where since it doesn't have a sequence. If Energy Thief is up, it will spam Low Blow.

I want to make it so that Shadowstab & Wound Attack have to be used even though Energy Thief is up.

How do I do that right? o.O

Make sure this is the correct corresponding number for the debuff you place on the enemy mob. That number is the one I used for R/P, which I believe is different from other rogues due to an elite skill. Check for what debuffs are on your target with:

Source code

1
/run for i=1,100 do local n,_,_,id=UnitDebuff("target",i) if n then DEFAULT_CHAT_FRAME:AddMessage(n.." = "..id) else break end end
Also, as for wound attack, use this for Low Blow

Source code

1
{ name = "Low Blow",        use = (EnergyBar1 >= 25) and ((tbuffs[620313]) and (not tbuffs[500704])) or (pbuffs['Energy Thief']) },
Again, making sure that your version of Grievous Wound is causing debuff 500704.

Quoted from "jtanner28;479849"

I had a feeling that this was going to be happening soon. I delayed writing up a "DIYCE for Dummies" tutorial for my guild because I wanted it to have all the new info in it. I'll do my write-up on DIYCE2 instead.

One quick question Ghostwolf: I am in the process of learning lua programming for the express purpose of writing a GUI for DIYCE. I'm going through Peryl's RoMWiki tutorials on XML and Dynamic Frames. I haven't examined DIYCE2 in detail yet. Is it adaptable to the general writeup that Peryl wrote for a possible GUI? I'd like your thoughts on whether this is an appropriate Addon target now that the playing field has changed.

EDIT:
Also, I noticed this while perusing the Custom Function code:



Shouldn't that actually be "for i=1,6 do" for this of us that have opened up all 6 pet slots?

EDIT2:

One other item: Would there be any code execution speed gain or any other advantages gained by re-writing the engine and/or custom function and placing certain checks in the macro itself? For instance a macro like this (assuming the proper engine alterations):

Source code

1
2
/script if (UnitSex("target") > 2) then KillSequence("", "boss") else
KillSequence() end
This macro example does not take in to account the pre-defined argument positions that you defined in your custom code earlier. The macros could be made arbitrarily complex. The reason I think it might speed up execution is that some conditional checks could be made before even calling the custom DiYCE2 function. You could then create a section in your custom function where the argument is checked with an if-elseif-else block for the various arguments that could be passed by the macro. Things like health, target casting status, and other "common" arguments could be passed. You obviously couldn't pass something like a melee range condition because it hasn't been defined yet.

It's just a thought. :)

Edited the line you mentioned in the pet protection function, and uploaded a fresh copy. For anyone who already grabbed it, make that change for yourself.

This actually incorporates the changes Peryl had suggested, and is more in line with being prepared for a GUI than the old version, and will translate to such easier. The GUI is why I made these changes in the first place, and was to be the final result for version 3 of DIYCE. Have you already started on creating the GUI? I would gladly take any help I could get in creating a GUI, it's becoming a monumental tasking (part of which was preparing the code structure to accept a front end GUI more readily).

As for code execution, weather the check is in the macro or the function there will be no time difference. About 15ms is what it took DIYCE v1.4 to execute a passthrough, and with version 2.0 it is even faster. The other reason I did not attempt to set up the code to use such macro based conditionals is this version was meant to be easier on the non-coder to learn to use. If you notice a time differential by doing so, and know how to make the needed macros and changes to your personal code, by all means do it. ;) (To note, you actually can set up a melee check in a macro to use before calling the function.)

Quoted from "jtanner28;479962"

Allen, you need commas at the end of each skill line. Essentially, these lines are elements of an array instead of individual lines of code like the old DIYCE. Hence, a comma is required to separate the individual elements of the array. Without the commas, the array definition closes at the first closing parenthesis. At least that is my understanding if it. (Actually, the individual skills in the old DIYCE were elements of an array also, but the index variable was manually incremented on each line. In the new DIYCE, we're saving some memory overhead by allowing the array to automatically increment the index variable.) Like this:

Your understanding is correct, commas are required at the end of each line of the skill array, which is different than the way v1.4 built the array. Yes, memory is saved doing it in this manner, which is one of the reasons it is able to work with more efficiency and process the array faster, leading to quicker reaction times during combat.

AddOn: DIY Combat Engine v2 AddOn: Auto Ding
Reni - Malkira
Warlock Guide
Retired from RoM with patch 6.1.0

ghostwolf82

Professional

  • "ghostwolf82" started this thread

Posts: 859

Location: Kalvans Trunk

Occupation: It's dark in here

  • Send private message

15

Tuesday, November 1st 2011, 11:17pm

Something else, while thinking of the pet protection, here is a small function I wrote up to call and return my pet with one macro button (macro follows):

Source code

1
2
3
4
5
6
function Pet(petnum)
    if IsPetSummoned(petnum)
        then ReturnPet(petnum) 
    else SummonPet(petnum)
    end
end

Source code

1
/run Pet(1)
Just change the number to the corresponding slot your pet resides in.


Here is another function I created for those that do not wish to have the main function handle potion useage for them. Place this function in CustomFunctions.lua, and then call with the macro below:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
function Potion(healthpot,manapot)
    local Skill = {}
    local i = 0
    local pctmana = PctM("player")
    local phealth = PctH("player")
    healthpot = healthpot or 0
    manapot = manapot or 0
    Skill = {
    { name = "Action: "..healthpot,        use = (phealth <= .70) },
    { name = "Action: "..manapot,        use = (pctmana <= .40) },
            }
    MyCombat(Skill,arg1)
end

Source code

1
/run Potion(59,57)
Change the numbers to correspond to the action bar slots you have your health and mana pots in.

AddOn: DIY Combat Engine v2 AddOn: Auto Ding
Reni - Malkira
Warlock Guide
Retired from RoM with patch 6.1.0

16

Wednesday, November 2nd 2011, 12:21am

Quoted from "ghostwolf82;480007"

Something else, while thinking of the pet protection, here is a small function I wrote up to call and return my pet with one macro button (macro follows):

Source code

1
2
3
4
5
6
function Pet(petnum)
    if IsPetSummoned(petnum)
        then ReturnPet(petnum) 
    else SummonPet(petnum)
    end
end

Source code

1
/run Pet(1)
Just change the number to the corresponding slot your pet resides in.


And here's a way to do it with just a macro:

Source code

1
/script if IsPetSummoned(1) then ReturnPet(1) else SummonPet(1) end 


:D

About the GUI, I have not started coding yet. I'm currently in the design phase. I've settled on a basic structure for the GUI that I don't believe will require extensive use of Dynamic Frames. I'll try to throw together a graphical mockup to show you the direction I was headed. I wouldn't mind collaborating on it if you want since it really would end up being DIYCE 3.0 instead if a separate Addon. One thing to note: I'm still essentially in a learning phase with regards to lua and XML. It seems quite straightforward so far though. What I'm probably going to do is keep two separate copies of DIYCE2 going. One that is current with what is posted here and another "beta" copy that will slowly incorporate the frames and string-parsing functions.

ghostwolf82

Professional

  • "ghostwolf82" started this thread

Posts: 859

Location: Kalvans Trunk

Occupation: It's dark in here

  • Send private message

17

Wednesday, November 2nd 2011, 5:20am

Sounds like we are on pretty much the same steps, you may be slightly ahead of me on it. Send me a PM, and we can go over details from there. Collaborating on an addon would make the work that much easier on both of us.

Figuring out these new code methods was the work of almost two years of the original DIYCE being around, implementing many changes along the way, and a couple months of me tweaking it to get everything to work perfectly before I could post it up. If I had to make a GUI alone, it would probably be another 6 months of work on my current schedule lol. I look forward to working with you :)

AddOn: DIY Combat Engine v2 AddOn: Auto Ding
Reni - Malkira
Warlock Guide
Retired from RoM with patch 6.1.0

mrmisterwaa

Professional

Posts: 670

Location: Kuwait

  • Send private message

18

Wednesday, November 2nd 2011, 7:46am

Quoted from "ghostwolf82;480004"

Make sure this is the correct corresponding number for the debuff you place on the enemy mob. That number is the one I used for R/P, which I believe is different from other rogues due to an elite skill. Check for what debuffs are on your target with:

Source code

1
/run for i=1,100 do local n,_,_,id=UnitDebuff("target",i) if n then DEFAULT_CHAT_FRAME:AddMessage(n.." = "..id) else break end end


Also, as for wound attack, use this for Low Blow

Source code

1
{ name = "Low Blow",        use = (EnergyBar1 >= 25) and ((tbuffs[620313]) and (not tbuffs[500704])) or (pbuffs['Energy Thief']) },


Again, making sure that your version of Grievous Wound is causing debuff 500704.


I did not know Rogue Priest had a different buff ID, I guess Rogue Scouts would have a different ID from regular rogues based on the Grevious Wound (since it's a modified one) and same would apply to Shadowstab.

I guess I will have to do some testing.

Ok and to the point about Wound Attack, I thought the new DIYCE would run through the list (in no specific order) and activate whatever skill is available, at least that is what I understood from what you wrote in the OP.

So I was wondering, how does it decide which skill to activate if more then one skill was available to be cast?

If I misunderstood it, please let me know. >.>

ghostwolf82

Professional

  • "ghostwolf82" started this thread

Posts: 859

Location: Kalvans Trunk

Occupation: It's dark in here

  • Send private message

19

Wednesday, November 2nd 2011, 9:22am

It still runs down the list in order, just much quicker and using less memory to do so. Same as in the original, this is a priority list, not a sequence... sort of. It may be difficult to understand, but the way it works really is dependent upon how you set up your conditionals. I can write up a lengthy set of conditionals for a skill sequence, and because of that I can have the skills all out of order and they will still fire in the proper order. The average or new user may not be able to write up such conditionals, thus I suggest keeping the skills in the order you want them to go off in, essentially building it to appear to be a sequence, even though it is not. I really hope this helps to make things more clear, though I fear it will just muddy the waters further, :o heh.

The change made to your Low Blow line is a subtle one, but should work for what you ask for. If (a and b) are both true, OR if c is true, then do not cast Low Blow. Which in this case if you have ET then LB...

Actually, as i read it again, I realize there is still going to be an error... it should be

Source code

1
(not pbuffs['Energy Thief'])
Which would make you use LB if you do not have ET, however if you have ET buff, then skip LB. Sorry for the missing 'not' before. Can't believe I missed that.

AddOn: DIY Combat Engine v2 AddOn: Auto Ding
Reni - Malkira
Warlock Guide
Retired from RoM with patch 6.1.0

20

Wednesday, November 2nd 2011, 12:40pm

I got this new version working but i have 1 question. How do i disable targeting the nearest enemy? Its gonna cause me to wipe a party because im not used to it.