• Hail, we're RedGuides. We want you to play six (yes, 6!) EverQuest characters at once. We have scripts and a friendly community to help, please join our playstyle and say hello! 👋
Resource icon

Release Lua Event Manager (LEM) Event Library

aquietone submitted a new resource:

Lua Event Manager (LEM) Event Library - mlem!

Lua Event Manager (LEM) is a lua script which combines features of MQ2Events and MQ2React plugins. It allows you to manage small lua scripts which will run based on text based events or as reactions to conditions like the current state of a TLO.

The purpose of this resource is to collect LEM event definitions that have been created and shared by the community so that they are easier to discover and maintain. Try to keep the discussion thread limited to submitting new events or reporting on...

Read more about this resource...
 
Shei Vintras multi Class Banish

Required ressources:
- LEM installed, the Lua Event Manager
- boxr installed and running if any other tools apart kissassist running, its used to hold automation and restart them, for small period when banishing is needed

I checked serveral Luas to do the job for some of my chars.
Somehow they interfere with Kissassist or caused too much lag and this way where preventing the also needed cures.

Than I found events for LEM which worked better for me.

Finally I mixed some of the code and added some lines to it and so I was able to create the event which best fits my wishes.
This event seems to be very ressource-effizent and does the job without any feeling of lag. My cleric does all the heals and cures necessary aside doing also all the banishing needed, when on duty.

attn: Post #12 has the actual best working event for the import
Update: as of 2022.10.05 #12 got updated and will find the right Rankname of spells by itself. No known bugs atm.


Shei Vintras Banish Multi-Class
Code:
do not Import this, get the best Version from post #12

I tried to create a well structured event.
One of the benefits is, That StopDps and ResumeDps are dedicated functions, which may can be improved in futur to work still more efficient.
Another part is the definitions for the different classes and which functionallity is used to iniitiate the banish:

Banish-bane definitions
Lua:
local banes = {
    BRD={name='Slumber of the Diabo',type='spell'},
    CLR={name='Blessed Chains',type='aa'},
    ENC={name='Beguiler\'s Banishment',type='aa'},
    Pal={name='Shackles of Tunare',type='aa'},
    SHM={name='Virulent Paralysis',type='aa'},
    Nec={name='Pestilent Paralysis',type='aa'},
    DRU={name='Paralytic Spores',type='aa'},
    RNG={name='Grasp of Sylvan Spirits',type='aa'},
}
Some classes have different possibillities to root or mezz ... which is the needed functionallity to bansih the spawning adds in the fight.
If someone i.e. prefers to use the spell instead of the aas, (recast of spells sometimes are faster than recast of the aa) you can modify the name and type of that class on your own, if you whish to change it.
You want another, not yet mentioned, class to do the job? Just add a line for that class with the scructure provided within this definitions.

Each Char who should help with the banishing or do this job alone, needs to have lem running and the checkbox for that event activated like:
1664287955649.png

Below you can find the full code:

Full Source Code
Lua:
-- pls check post #12 for the actual version

_____________________________________________________________________________________________

- improvements I want to implement in future:
1. Line 52
Line 52 cause error
Code:
--if mq.TLO.Me.Gem(bane.name) > 0 then return end  -- Should be memmed already
If the spell needed is already memmed, I want to avoud to try to mem it into spellgem 13 ... actually there will be a message when the spell is memmed, which does not cause any problems
This line as is has a bug, I couldn't figure out yet what exactly needs to be changed

2. within the functions "StopDps" and "ResumeDps" I would like to surpress the output of "/mqp on" and "/mqp off" into the mq.window ... as those occure repeatedly and could feel a little like spam
 
Last edited:
Questions for improvement:

1. Line 52 mentioned above resumes in an output like: you attempt to compare ressources instead of numbers ...
avoud to attempt to mem spell aready memmed
Lua:
if mq.TLO.Me.Gem(bane.name) > 0 then return end
"Me.Gem(bane.name)" should result in the number of the gem, when the spell is already memmed, isnt it?
I couldn't figure out the right syntax.

2. I would like to temporary supress the output from "/mqp on" and "/mqp off" into the mq.window.
Is there a command to allow to disable the output temporary?
 
Questions for improvement:

1. Line 52 mentioned above resumes in an output like: you attempt to compare ressources instead of numbers ...
avoud to attempt to mem spell aready memmed
Lua:
if mq.TLO.Me.Gem(bane.name) > 0 then return end
"Me.Gem(bane.name)" should result in the number of the gem, when the spell is already memmed, isnt it?
I couldn't figure out the right syntax.

2. I would like to temporary supress the output from "/mqp on" and "/mqp off" into the mq.window.
Is there a command to allow to disable the output temporary?

mq.TLO.Me.Gem(bane.name)() should output the gem number or nil, make sure you have the trailing () on it.

You can use /squelch /mqp on
 
/echo ${Me.Gem('spell')} returns Null where 'spell' was the name of a memmed spell, tryed even with a spell without rank
/echo ${Me.Gem('spell')()} returns Null where 'spell' was the name of a memmed spell, tryed even with a spell without rank

mq.TLO.Me.Gem(bane.name)() within the event even didn't work

Does anyone have an idea, how to make this condition work?
 
/echo ${Me.Gem('spell')} returns Null where 'spell' was the name of a memmed spell, tryed even with a spell without rank
/echo ${Me.Gem('spell')()} returns Null where 'spell' was the name of a memmed spell, tryed even with a spell without rank

mq.TLO.Me.Gem(bane.name)() within the event even didn't work

Does anyone have an idea, how to make this condition work?
On my Ranger parked in the GH

/echo Me.Gem[Desperate Geyser]: ${Me.Gem[Desperate Geyser]}
/lua parse print("mq.TLO.Me.Gem('Desperate Geyser')(): ", mq.TLO.Me.Gem('Desperate Geyser')())

kicked out the following results

MeGem.png

This spell specifically isn't a Rk. II/III.

Check that bane.name has the value you expect.
 
Ohh, sqare brackets for echo was error no1
Will add a print(bane.name) to check for the second, next time i am logged in.
Didn‘t know about the „/Lua parse print..“, will help me for shure for coming debuggings :)
Ty again.
 
For normal reporting, you don't need print(). I used it to display a multi-part message. I could've done /lua parse string.format("value: %s", mq.TLO.Me.Gem("Desperate Geyser")()). I used it only because I wanted the text of the value as well as the result to show in the MQ window (for screen capture).
 
Update:
the points above are solved.

ATTN: best version can be found at the post #12 below

Important:
For classes using spells, actually you still have to insert the full name of the spell including the Rank, like "BRD={name='Slumber of the Diabo RK. II',type='spell'}"


SheiBanish Import-Code
Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJMUzB0UUhSNWNHVWdUWEVLTFMwdFFIUjVjR1VnU1cxSGRXa0tDbXh2WTJGc0lHMXhJRDBnY21WeGRXbHlaU2duYlhFbktRb0tiRzlqWVd3Z2NtVnhkV2x5WldSZmVtOXVaU0E5SUNkaGEyaGxkbUYwZDI5ZmJXbHpjMmx2YmljS2JHOWpZV3dnWW1GdVpWOXRiMkpmYm1GdFpTQTlJQ2RrWVhScFlYSWdlR2tnZEdGMmRXVnNhVzBuQ214dlkyRnNJRk53Wld4c1RHOWhaR1ZrSUQwZ2RISjFaUW9LYkc5allXd2dZbUZ1WlhNZ1BTQjdDaUFnSUNCQ1VrUTllMjVoYldVOUoxTnNkVzFpWlhJZ2IyWWdkR2hsSUVScFlXSnZJRkpMTGlCSlNTY3NkSGx3WlQwbmMzQmxiR3duZlN3S0lDQWdJRU5NVWoxN2JtRnRaVDBuUW14bGMzTmxaQ0JEYUdGcGJuTW5MSFI1Y0dVOUoyRmhKMzBzQ2lBZ0lDQkZUa005ZTI1aGJXVTlKMEpsWjNWcGJHVnlYQ2R6SUVKaGJtbHphRzFsYm5RbkxIUjVjR1U5SjJGaEozMHNDaUFnSUNCUVlXdzllMjVoYldVOUoxTm9ZV05yYkdWeklHOW1JRlIxYm1GeVpTY3NkSGx3WlQwbllXRW5mU3dLSUNBZ0lGTklUVDE3Ym1GdFpUMG5WbWx5ZFd4bGJuUWdVR0Z5WVd4NWMybHpKeXgwZVhCbFBTZGhZU2Q5TEFvZ0lDQWdUbVZqUFh0dVlXMWxQU2RRWlhOMGFXeGxiblFnVUdGeVlXeDVjMmx6Snl4MGVYQmxQU2RoWVNkOUxBb2dJQ0FnUkZKVlBYdHVZVzFsUFNkUVlYSmhiSGwwYVdNZ1UzQnZjbVZ6Snl4MGVYQmxQU2RoWVNkOUxBb2dJQ0FnVWs1SFBYdHVZVzFsUFNkSGNtRnpjQ0J2WmlCVGVXeDJZVzRnVTNCcGNtbDBjeWNzZEhsd1pUMG5ZV0VuZlN3S2ZRb0tiRzlqWVd3Z1puVnVZM1JwYjI0Z1UzUnZjRVJRVXlncENpQWdJQ0J0Y1M1amJXUW9KeTl6Y1hWbGJHTm9JQzl0Y1hBZ2IyNG5LUW9nSUNBZ2JYRXVaR1ZzWVhrb01UQXBDaUFnSUNCcFppQnRjUzVVVEU4dVRXVXVRMnhoYzNNdVUyaHZjblJPWVcxbEtDa2dQVDBnSjBKU1JDY2dkR2hsYmdvZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDNOeGRXVnNZMmdnTDNSM2FYTjBJRzltWmljcENpQWdJQ0FnSUNBZ2JYRXVaR1ZzWVhrb01UQXBDaUFnSUNBZ0lDQWdiWEV1WTIxa0tDY3ZjM0YxWld4amFDQXZjM1J2Y0hOdmJtY25LUW9nSUNBZ0lDQWdJRzF4TG1SbGJHRjVLREV3S1FvZ0lDQWdaVzVrQ2lBZ0lDQXRMVzF4TG1OdFpDZ25MMkYwZEdGamF5QnZabVluS1FvZ0lDQWdMUzF0Y1M1a1pXeGhlU2d4TUNrS0lDQWdJRzF4TG1OdFpDZ25MM054ZFdWc1kyZ2dMMkp2ZUhJZ2NHRjFjMlVuS1FvZ0lDQWdiWEV1WkdWc1lYa29NVEFwQ2lBZ0lDQjNhR2xzWlNCdGNTNVVURTh1VFdVdVEyRnpkR2x1Wnk1SlJDZ3BJR1J2Q2lBZ0lDQWdJQ0J0Y1M1a1pXeGhlU2d5TURBcENpQWdJQ0JsYm1RS1pXNWtDZ3BzYjJOaGJDQm1kVzVqZEdsdmJpQlNaWE4xYldWRVVGTW9LUW9nSUNCdGNTNWpiV1FvSnk5emNYVmxiR05vSUM5dGNYQWdiMlptSnlrS0lDQWdiWEV1WkdWc1lYa29NVEFwQ2lBZ0lHbG1JRzF4TGxSTVR5NU5aUzVEYkdGemN5NVRhRzl5ZEU1aGJXVW9LU0E5UFNBblFsSkVKeUIwYUdWdUNpQWdJQ0J0Y1M1amJXUW9KeTl6Y1hWbGJHTm9JQzkwZDJsemRDQnZiaWNwQ2lBZ0lDQnRjUzVrWld4aGVTZ3hNQ2tLSUNBZ1pXNWtDaUFnSUcxeExtTnRaQ2duTDNOeGRXVnNZMmdnTDJKdmVISWdkVzV3WVhWelpTY3BDaUFnSUcxeExtUmxiR0Y1S0RFd0tRcGxibVFLQ214dlkyRnNJR1oxYm1OMGFXOXVJRzl1WDJ4dllXUW9LUW9nSUNBZ2FXWWdiWEV1VkV4UExscHZibVV1VTJodmNuUk9ZVzFsS0NrZ2ZqMGdjbVZ4ZFdseVpXUmZlbTl1WlNCMGFHVnVJSEpsZEhWeWJpQmxibVFLSUNBZ0lHeHZZMkZzSUdKaGJtVWdQU0JpWVc1bGMxdHRjUzVVVEU4dVRXVXVRMnhoYzNNdVUyaHZjblJPWVcxbEtDbGRDaUFnSUNCcFppQmlZVzVsSUdGdVpDQmlZVzVsTG5SNWNHVWdQVDBnSjNOd1pXeHNKeUIwYUdWdUNpQWdJQ0FnSUNBZ2FXWWdiWEV1VkV4UExrMWxMa2RsYlNoaVlXNWxMbTVoYldVcEtDa2dQaUF3SUhSb1pXNGdjbVYwZFhKdUlHVnVaQ0FnTFMwZ1UyaHZkV3hrSUdKbElHMWxiVzFsWkNCaGJISmxZV1I1Q2lBZ0lDQWdJQ0FnVTNSdmNFUlFVeWdwQ2lBZ0lDQWdJQ0FnYlhFdVkyMWtaaWduTDIxbGJYTndaV3hzSURFeklDSWxjeUluTENCaVlXNWxMbTVoYldVcENpQWdJQ0FnSUNBZ2JYRXVaR1ZzWVhrb0p6UnpKeWtLSUNBZ0lDQWdJQ0J0Y1M1VVRFOHVWMmx1Wkc5M0tDZFRjR1ZzYkVKdmIydFhibVFuS1M1RWIwTnNiM05sS0NrS0lDQWdJQ0FnSUNCU1pYTjFiV1ZFVUZNb0tRb2dJQ0FnWlc1a0NtVnVaQW9LTFMwdFFISmxkSFZ5YmlCaWIyOXNaV0Z1SUVCU1pYUjFjbTV6SUhSeWRXVWdhV1lnZEdobElHRmpkR2x2YmlCemFHOTFiR1FnWm1seVpTd2diM1JvWlhKM2FYTmxJR1poYkhObExncHNiMk5oYkNCbWRXNWpkR2x2YmlCamIyNWthWFJwYjI0b0tRb2dJQ0FnY21WMGRYSnVJRzF4TGxSTVR5NWFiMjVsTGxOb2IzSjBUbUZ0WlNncElEMDlJSEpsY1hWcGNtVmtYM3B2Ym1VZ1lXNWtJRzF4TGxSTVR5NVRjR0YzYmtOdmRXNTBLQ2duSlhNZ2JuQmpKeWs2Wm05eWJXRjBLR0poYm1WZmJXOWlYMjVoYldVcEtTZ3BJRDRnTUFwbGJtUUtDbXh2WTJGc0lHWjFibU4wYVc5dUlIUmhjbWRsZEY5aVlXNWxYMjF2WWlncENpQWdJQ0JwWmlCdGNTNVVURTh1VkdGeVoyVjBMa05zWldGdVRtRnRaU2dwSUg0OUlHSmhibVZmYlc5aVgyNWhiV1VnZEdobGJnb2dJQ0FnSUNBZ0lHMXhMbU50WkdZb0p5OXRjWFJoY2lBbGN5QnVjR01uTENCaVlXNWxYMjF2WWw5dVlXMWxLUW9nSUNBZ0lDQWdJRzF4TG1SbGJHRjVLRFV3S1FvZ0lDQWdaVzVrQ21WdVpBb0tiRzlqWVd3Z1puVnVZM1JwYjI0Z1kyRnpkQ2h6Y0dWc2JDa0tJQ0FnSUcxeExtTnRaR1lvSnk5allYTjBJQ1Z6Snl3Z2MzQmxiR3d1VW1GdWEwNWhiV1VvS1NrS0lDQWdJRzF4TG1SbGJHRjVLRFV3SzNOd1pXeHNMazE1UTJGemRGUnBiV1VvS1NrS1pXNWtDZ3BzYjJOaGJDQm1kVzVqZEdsdmJpQjFjMlZmWVdFb1lXRXBDaUFnSUNCdGNTNWpiV1JtS0NjdllXeDBJR0ZqZEdsMllYUmxJQ1Z6Snl3Z1lXRXVTVVFvS1NrS0lDQWdJRzF4TG1SbGJHRjVLRFV3SzJGaExsTndaV3hzTGtOaGMzUlVhVzFsS0NrcENtVnVaQW9LYkc5allXd2dablZ1WTNScGIyNGdZbUZ1WlY5eVpXRmtlU2hpWVc1bEtRb2dJQ0FnYVdZZ1ltRnVaUzUwZVhCbElEMDlJQ2R6Y0dWc2JDY2dkR2hsYmdvZ0lDQWdJQ0FnSUhKbGRIVnliaUJ0Y1M1VVRFOHVUV1V1VTNCbGJHeFNaV0ZrZVNoaVlXNWxMbTVoYldVcElHRnVaQ0J1YjNRZ2JYRXVWRXhQTGsxbExrTmhjM1JwYm1jb0tRb2dJQ0FnWld4elpXbG1JR0poYm1VdWRIbHdaU0E5UFNBbllXRW5JSFJvWlc0S0lDQWdJQ0FnSUNCeVpYUjFjbTRnYlhFdVZFeFBMazFsTGtGc2RFRmlhV3hwZEhsU1pXRmtlU2hpWVc1bExtNWhiV1VwSUdGdVpDQnViM1FnYlhFdVZFeFBMazFsTGtOaGMzUnBibWNvS1FvZ0lDQWdaVzVrQ21WdVpBb0tiRzlqWVd3Z1puVnVZM1JwYjI0Z1lXTjBhVzl1S0NrS0lDQWdJR3h2WTJGc0lHMTVYMk5zWVhOeklEMGdiWEV1VkV4UExrMWxMa05zWVhOekxsTm9iM0owVG1GdFpTZ3BDaUFnSUNCc2IyTmhiQ0JpWVc1bElEMGdZbUZ1WlhOYmJYbGZZMnhoYzNOZENpQWdJQ0F0TFNCcFppQnViM1FnWVNCaVlXNWxJR05zWVhOekxDQnlaWFIxY200S0lDQWdJR2xtSUc1dmRDQmlZVzVsSUhSb1pXNGdjbVYwZFhKdUlHVnVaQW9nSUNBZ0xTMGdhV1lnWW1GdVpTQmhZbWxzYVhSNUlHbHpiaWQwSUhKbFlXUjVMQ0J5WlhSMWNtNEtJQ0FnSUdsbUlHMTVYMk5zWVhOeklINDlJQ2RDVWtRbklHRnVaQ0J1YjNRZ1ltRnVaVjl5WldGa2VTaGlZVzVsS1NCMGFHVnVJSEpsZEhWeWJpQmxibVFLSUNBZ0lGTjBiM0JFVUZNb0tRb2dJQ0FnZEdGeVoyVjBYMkpoYm1WZmJXOWlLQ2tLSUNBZ0lHbG1JR0poYm1VdWRIbHdaU0E5UFNBbmMzQmxiR3duSUhSb1pXNEtJQ0FnSUNBZ0lDQmpZWE4wS0cxeExsUk1UeTVUY0dWc2JDaGlZVzVsTG01aGJXVXBLUW9nSUNBZ1pXeHpaUW9nSUNBZ0lDQWdJSFZ6WlY5aFlTaHRjUzVVVEU4dVRXVXVRV3gwUVdKcGJHbDBlU2hpWVc1bExtNWhiV1VwS1FvZ0lDQWdaVzVrQ2lBZ0lDQjNhR2xzWlNCdGNTNVVURTh1VFdVdVEyRnpkR2x1WnlncElHUnZDaUFnSUNBZ0lDQWdiWEV1Wkc5bGRtVnVkSE1vS1FvZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RVd0tRb2dJQ0FnWlc1a0NpQWdJQ0JTWlhOMWJXVkVVRk1vS1FwbGJtUUtDbkpsZEhWeWJpQjdiMjVzYjJGa1BXOXVYMnh2WVdRc0lHTnZibVJtZFc1alBXTnZibVJwZEdsdmJpd2dZV04wYVc5dVpuVnVZejFoWTNScGIyNTkiLAogY2F0ZWdvcnkgPSAiVG9sIiwKIHR5cGUgPSAiY29uZGl0aW9ucyIsCiBuYW1lID0gIlNoZWlCYW5pc2giLAp9

The Source-code follows:
Source-code
Lua:
---@type Mq
---@type ImGui
local mq = require('mq')
local required_zone = 'akhevatwo_mission'
local bane_mob_name = 'datiar xi tavuelim'
local SpellLoaded = true
local banes = {
    BRD={name='Slumber of the Diabo RK. II',type='spell'},
    CLR={name='Blessed Chains',type='aa'},
    ENC={name='Beguiler\'s Banishment',type='aa'},
    Pal={name='Shackles of Tunare',type='aa'},
    SHM={name='Virulent Paralysis',type='aa'},
    Nec={name='Pestilent Paralysis',type='aa'},
    DRU={name='Paralytic Spores',type='aa'},
    RNG={name='Grasp of Sylvan Spirits',type='aa'},
}
local function StopDPS()
    mq.cmd('/squelch /mqp on')
    mq.delay(10)
    if mq.TLO.Me.Class.ShortName() == 'BRD' then
        mq.cmd('/squelch /twist off')
        mq.delay(10)
        mq.cmd('/squelch /stopsong')
        mq.delay(10)
    end
    --mq.cmd('/attack off')  ... maybe deactivate attack but save state to reactivate at StartDps
    --mq.delay(10)
    mq.cmd('/squelch /boxr pause')
    mq.delay(10)
    while mq.TLO.Me.Casting.ID() do
       mq.delay(200)
    end
end
local function ResumeDPS()
   mq.cmd('/squelch /mqp off')
   mq.delay(10)
   if mq.TLO.Me.Class.ShortName() == 'BRD' then
    mq.cmd('/squelch /twist on')
    mq.delay(10)
   end
   mq.cmd('/squelch /boxr unpause')
   mq.delay(10)
end
local function on_load()
    if mq.TLO.Zone.ShortName() ~= required_zone then return end
    local bane = banes[mq.TLO.Me.Class.ShortName()]
    if bane and bane.type == 'spell' then
        if mq.TLO.Me.Gem(bane.name)() > 0 then return end  -- Should be memmed already
        StopDPS()
        mq.cmdf('/memspell 13 "%s"', bane.name)
        mq.delay('4s')
        mq.TLO.Window('SpellBookWnd').DoClose()
        ResumeDPS()
    end
end
---@return boolean @Returns true if the action should fire, otherwise false.
local function condition()
    return mq.TLO.Zone.ShortName() == required_zone and mq.TLO.SpawnCount(('%s npc'):format(bane_mob_name))() > 0
end
local function target_bane_mob()
    if mq.TLO.Target.CleanName() ~= bane_mob_name then
        mq.cmdf('/mqtar %s npc', bane_mob_name)
        mq.delay(50)
    end
end
local function cast(spell)
    mq.cmdf('/cast %s', spell.RankName())
    mq.delay(50+spell.MyCastTime())
end
local function use_aa(aa)
    mq.cmdf('/alt activate %s', aa.ID())
    mq.delay(50+aa.Spell.CastTime())
end
local function bane_ready(bane)
    if bane.type == 'spell' then
        return mq.TLO.Me.SpellReady(bane.name) and not mq.TLO.Me.Casting()
    elseif bane.type == 'aa' then
        return mq.TLO.Me.AltAbilityReady(bane.name) and not mq.TLO.Me.Casting()
    end
end
local function action()
    local my_class = mq.TLO.Me.Class.ShortName()
    local bane = banes[my_class]
    -- if not a bane class, return
    if not bane then return end
    -- if bane ability isn't ready, return
    if my_class ~= 'BRD' and not bane_ready(bane) then return end
    StopDPS()
    target_bane_mob()
    if bane.type == 'spell' then
        cast(mq.TLO.Spell(bane.name))
    else
        use_aa(mq.TLO.Me.AltAbility(bane.name))
    end
    while mq.TLO.Me.Casting() do
        mq.doevents()
        mq.delay(50)
    end
    ResumeDPS()
end
return {onload=on_load, condfunc=condition, actionfunc=action}

For me it now works almost exact as I wanted it to do.

Possible Improvements:
- find a way to remove the need to insert the rank of spells, when using spells for banishing
- "DpsOff" and "DpsResume" could be improved by saving the attack-mode in DpsOff and disable attack with "/attack off" and reactivate attack on DpsResume
for the functionallity its not needed and will result in a slight dps-loss ... so still not shure if its a good idea
 
Last edited:
Shei Vintras multi Class Banish
My Actual best Version here
Edit: post
#121 contains an improved update from @a_moss_snake
Update:
- Bugfix ... when spell really wasn't already memmed, there could be an errormessage caused by the return of "NIL"
- found the syntax to eliminate the need of the spells precise rankname within the declaration

Attn 1: Fixed and running, the event now will select the right Rank of the spell, if a ranked spell is used to banish the mobs. At the full code you see "BRD={name='Slumber of the Diabo',type='spell'}," despite the fact that my bard uses RK. II
Attn 2: if using a spell to banish mobs, it's best to mem it befor starting events. If Spell is not memmed, Ill attemt to load it into gem 13. Some automation might remem the spell it considered right for gem 13


Bugfix and Rankname of spells
Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJMUzB0UUhSNWNHVWdUWEVLTFMwdFFIUjVjR1VnU1cxSGRXa0tDbXh2WTJGc0lHMXhJRDBnY21WeGRXbHlaU2duYlhFbktRb0tiRzlqWVd3Z2NtVnhkV2x5WldSZmVtOXVaU0E5SUNkaGEyaGxkbUYwZDI5ZmJXbHpjMmx2YmljS2JHOWpZV3dnWW1GdVpWOXRiMkpmYm1GdFpTQTlJQ2RrWVhScFlYSWdlR2tnZEdGMmRXVnNhVzBuQ214dlkyRnNJRk53Wld4c1RHOWhaR1ZrSUQwZ2RISjFaUXBzYjJOaGJDQmlZVzVsY3lBOUlIc0tJQ0FnSUVKU1JEMTdibUZ0WlQwblUyeDFiV0psY2lCdlppQjBhR1VnUkdsaFltOG5MSFI1Y0dVOUozTndaV3hzSjMwc0NpQWdJQ0JEVEZJOWUyNWhiV1U5SjBKc1pYTnpaV1FnUTJoaGFXNXpKeXgwZVhCbFBTZGhZU2Q5TEFvZ0lDQWdSVTVEUFh0dVlXMWxQU2RDWldkMWFXeGxjbHduY3lCQ1lXNXBjMmh0Wlc1MEp5eDBlWEJsUFNkaFlTZDlMQW9nSUNBZ1VHRnNQWHR1WVcxbFBTZFRhR0ZqYTJ4bGN5QnZaaUJVZFc1aGNtVW5MSFI1Y0dVOUoyRmhKMzBzQ2lBZ0lDQlRTRTA5ZTI1aGJXVTlKMVpwY25Wc1pXNTBJRkJoY21Gc2VYTnBjeWNzZEhsd1pUMG5ZV0VuZlN3S0lDQWdJRTVsWXoxN2JtRnRaVDBuVUdWemRHbHNaVzUwSUZCaGNtRnNlWE5wY3ljc2RIbHdaVDBuWVdFbmZTd0tJQ0FnSUVSU1ZUMTdibUZ0WlQwblVHRnlZV3g1ZEdsaklGTndiM0psY3ljc2RIbHdaVDBuWVdFbmZTd0tJQ0FnSUZKT1J6MTdibUZ0WlQwblIzSmhjM0FnYjJZZ1UzbHNkbUZ1SUZOd2FYSnBkSE1uTEhSNWNHVTlKMkZoSjMwc0NuMEtiRzlqWVd3Z1puVnVZM1JwYjI0Z1UzUnZjRVJRVXlncENpQWdJQ0J0Y1M1amJXUW9KeTl6Y1hWbGJHTm9JQzl0Y1hBZ2IyNG5LUW9nSUNBZ2JYRXVaR1ZzWVhrb01UQXBDaUFnSUNCcFppQnRjUzVVVEU4dVRXVXVRMnhoYzNNdVUyaHZjblJPWVcxbEtDa2dQVDBnSjBKU1JDY2dkR2hsYmdvZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDNOeGRXVnNZMmdnTDNSM2FYTjBJRzltWmljcENpQWdJQ0FnSUNBZ2JYRXVaR1ZzWVhrb01UQXBDaUFnSUNBZ0lDQWdiWEV1WTIxa0tDY3ZjM0YxWld4amFDQXZjM1J2Y0hOdmJtY25LUW9nSUNBZ0lDQWdJRzF4TG1SbGJHRjVLREV3S1FvZ0lDQWdaVzVrQ2lBZ0lDQXRMVzF4TG1OdFpDZ25MMkYwZEdGamF5QnZabVluS1NBZ0xpNHVJRzFoZVdKbElHUmxZV04wYVhaaGRHVWdZWFIwWVdOcklHSjFkQ0J6WVhabElITjBZWFJsSUhSdklISmxZV04wYVhaaGRHVWdZWFFnVTNSaGNuUkVjSE1LSUNBZ0lDMHRiWEV1WkdWc1lYa29NVEFwQ2lBZ0lDQnRjUzVqYldRb0p5OXpjWFZsYkdOb0lDOWliM2h5SUhCaGRYTmxKeWtLSUNBZ0lHMXhMbVJsYkdGNUtERXdLUW9nSUNBZ2QyaHBiR1VnYlhFdVZFeFBMazFsTGtOaGMzUnBibWN1U1VRb0tTQmtid29nSUNBZ0lDQWdiWEV1WkdWc1lYa29NakF3S1FvZ0lDQWdaVzVrQ21WdVpBcHNiMk5oYkNCbWRXNWpkR2x2YmlCU1pYTjFiV1ZFVUZNb0tRb2dJQ0J0Y1M1amJXUW9KeTl6Y1hWbGJHTm9JQzl0Y1hBZ2IyWm1KeWtLSUNBZ2JYRXVaR1ZzWVhrb01UQXBDaUFnSUdsbUlHMXhMbFJNVHk1TlpTNURiR0Z6Y3k1VGFHOXlkRTVoYldVb0tTQTlQU0FuUWxKRUp5QjBhR1Z1Q2lBZ0lDQnRjUzVqYldRb0p5OXpjWFZsYkdOb0lDOTBkMmx6ZENCdmJpY3BDaUFnSUNCdGNTNWtaV3hoZVNneE1Da0tJQ0FnWlc1a0NpQWdJRzF4TG1OdFpDZ25MM054ZFdWc1kyZ2dMMkp2ZUhJZ2RXNXdZWFZ6WlNjcENpQWdJRzF4TG1SbGJHRjVLREV3S1FwbGJtUUtiRzlqWVd3Z1puVnVZM1JwYjI0Z2IyNWZiRzloWkNncENpQWdJQ0JwWmlCdGNTNVVURTh1V205dVpTNVRhRzl5ZEU1aGJXVW9LU0IrUFNCeVpYRjFhWEpsWkY5NmIyNWxJSFJvWlc0Z2NtVjBkWEp1SUdWdVpBb2dJQ0FnYkc5allXd2dZbUZ1WlNBOUlHSmhibVZ6VzIxeExsUk1UeTVOWlM1RGJHRnpjeTVUYUc5eWRFNWhiV1VvS1YwS0lDQWdJR3h2WTJGc0lITndaV3hzYm1GdFpTQTlJRzF4TGxSTVR5NVRjR1ZzYkNoMGIzTjBjbWx1WnloaVlXNWxMbTVoYldVcEtTNVNZVzVyVG1GdFpTZ3BDaUFnSUNCd2NtbHVkQ2h6Y0dWc2JHNWhiV1VwQ2lBZ0lDQnBaaUJpWVc1bElHRnVaQ0JpWVc1bExuUjVjR1VnUFQwZ0ozTndaV3hzSnlCMGFHVnVDaUFnSUNBZ0lDQWdhV1lnYlhFdVZFeFBMazFsTGtkbGJTaHpjR1ZzYkc1aGJXVXBLQ2tnUGlBd0lIUm9aVzRnY21WMGRYSnVJR1Z1WkNBZ0xTMGdVMmh2ZFd4a0lHSmxJRzFsYlcxbFpDQmhiSEpsWVdSNUNpQWdJQ0FnSUNBZ1UzUnZjRVJRVXlncENpQWdJQ0FnSUNBZ2JYRXVZMjFrWmlnbkwyMWxiWE53Wld4c0lERXpJQ0lsY3lJbkxDQnpjR1ZzYkc1aGJXVXBDaUFnSUNBZ0lDQWdiWEV1WkdWc1lYa29KelJ6SnlrS0lDQWdJQ0FnSUNCdGNTNVVURTh1VjJsdVpHOTNLQ2RUY0dWc2JFSnZiMnRYYm1RbktTNUViME5zYjNObEtDa0tJQ0FnSUNBZ0lDQlNaWE4xYldWRVVGTW9LUW9nSUNBZ1pXNWtDbVZ1WkFvdExTMUFjbVYwZFhKdUlHSnZiMnhsWVc0Z1FGSmxkSFZ5Ym5NZ2RISjFaU0JwWmlCMGFHVWdZV04wYVc5dUlITm9iM1ZzWkNCbWFYSmxMQ0J2ZEdobGNuZHBjMlVnWm1Gc2MyVXVDbXh2WTJGc0lHWjFibU4wYVc5dUlHTnZibVJwZEdsdmJpZ3BDaUFnSUNCeVpYUjFjbTRnYlhFdVZFeFBMbHB2Ym1VdVUyaHZjblJPWVcxbEtDa2dQVDBnY21WeGRXbHlaV1JmZW05dVpTQmhibVFnYlhFdVZFeFBMbE53WVhkdVEyOTFiblFvS0NjbGN5QnVjR01uS1RwbWIzSnRZWFFvWW1GdVpWOXRiMkpmYm1GdFpTa3BLQ2tnUGlBd0NpQWdJQ0F0TFhKbGRIVnliaUIwY25WbENtVnVaQXBzYjJOaGJDQm1kVzVqZEdsdmJpQjBZWEpuWlhSZlltRnVaVjl0YjJJb0tRb2dJQ0FnYVdZZ2JYRXVWRXhQTGxSaGNtZGxkQzVEYkdWaGJrNWhiV1VvS1NCK1BTQmlZVzVsWDIxdllsOXVZVzFsSUhSb1pXNEtJQ0FnSUNBZ0lDQnRjUzVqYldSbUtDY3ZiWEYwWVhJZ0pYTWdibkJqSnl3Z1ltRnVaVjl0YjJKZmJtRnRaU2tLSUNBZ0lDQWdJQ0J0Y1M1a1pXeGhlU2cxTUNrS0lDQWdJR1Z1WkFwbGJtUUtiRzlqWVd3Z1puVnVZM1JwYjI0Z1kyRnpkQ2h6Y0dWc2JDa0tJQ0FnSUcxeExtTnRaR1lvSnk5allYTjBJQ1Z6Snl3Z2MzQmxiR3d1VW1GdWEwNWhiV1VvS1NrS0lDQWdJRzF4TG1SbGJHRjVLRFV3SzNOd1pXeHNMazE1UTJGemRGUnBiV1VvS1NrS1pXNWtDbXh2WTJGc0lHWjFibU4wYVc5dUlIVnpaVjloWVNoaFlTa0tJQ0FnSUcxeExtTnRaR1lvSnk5aGJIUWdZV04wYVhaaGRHVWdKWE1uTENCaFlTNUpSQ2dwS1FvZ0lDQWdiWEV1WkdWc1lYa29OVEFyWVdFdVUzQmxiR3d1UTJGemRGUnBiV1VvS1NrS1pXNWtDbXh2WTJGc0lHWjFibU4wYVc5dUlHSmhibVZmY21WaFpIa29ZbUZ1WlNrS0lDQWdJR2xtSUdKaGJtVXVkSGx3WlNBOVBTQW5jM0JsYkd3bklIUm9aVzRLSUNBZ0lDQWdJQ0J5WlhSMWNtNGdiWEV1VkV4UExrMWxMbE53Wld4c1VtVmhaSGtvWW1GdVpTNXVZVzFsS1NCaGJtUWdibTkwSUcxeExsUk1UeTVOWlM1RFlYTjBhVzVuS0NrS0lDQWdJR1ZzYzJWcFppQmlZVzVsTG5SNWNHVWdQVDBnSjJGaEp5QjBhR1Z1Q2lBZ0lDQWdJQ0FnY21WMGRYSnVJRzF4TGxSTVR5NU5aUzVCYkhSQlltbHNhWFI1VW1WaFpIa29ZbUZ1WlM1dVlXMWxLU0JoYm1RZ2JtOTBJRzF4TGxSTVR5NU5aUzVEWVhOMGFXNW5LQ2tLSUNBZ0lHVnVaQXBsYm1RS2JHOWpZV3dnWm5WdVkzUnBiMjRnWVdOMGFXOXVLQ2tLSUNBZ0lHeHZZMkZzSUcxNVgyTnNZWE56SUQwZ2JYRXVWRXhQTGsxbExrTnNZWE56TGxOb2IzSjBUbUZ0WlNncENpQWdJQ0JzYjJOaGJDQmlZVzVsSUQwZ1ltRnVaWE5iYlhsZlkyeGhjM05kQ2lBZ0lDQXRMU0JwWmlCdWIzUWdZU0JpWVc1bElHTnNZWE56TENCeVpYUjFjbTRLSUNBZ0lHbG1JRzV2ZENCaVlXNWxJSFJvWlc0Z2NtVjBkWEp1SUdWdVpBb2dJQ0FnTFMwZ2FXWWdZbUZ1WlNCaFltbHNhWFI1SUdsemJpZDBJSEpsWVdSNUxDQnlaWFIxY200S0lDQWdJR2xtSUcxNVgyTnNZWE56SUg0OUlDZENVa1FuSUdGdVpDQnViM1FnWW1GdVpWOXlaV0ZrZVNoaVlXNWxLU0IwYUdWdUlISmxkSFZ5YmlCbGJtUUtJQ0FnSUZOMGIzQkVVRk1vS1FvZ0lDQWdkR0Z5WjJWMFgySmhibVZmYlc5aUtDa0tJQ0FnSUdsbUlHSmhibVV1ZEhsd1pTQTlQU0FuYzNCbGJHd25JSFJvWlc0S0lDQWdJQ0FnSUNCallYTjBLRzF4TGxSTVR5NVRjR1ZzYkNoaVlXNWxMbTVoYldVcEtRb2dJQ0FnWld4elpRb2dJQ0FnSUNBZ0lIVnpaVjloWVNodGNTNVVURTh1VFdVdVFXeDBRV0pwYkdsMGVTaGlZVzVsTG01aGJXVXBLUW9nSUNBZ1pXNWtDaUFnSUNCM2FHbHNaU0J0Y1M1VVRFOHVUV1V1UTJGemRHbHVaeWdwSUdSdkNpQWdJQ0FnSUNBZ2JYRXVaRzlsZG1WdWRITW9LUW9nSUNBZ0lDQWdJRzF4TG1SbGJHRjVLRFV3S1FvZ0lDQWdaVzVrQ2lBZ0lDQlNaWE4xYldWRVVGTW9LUXBsYm1RS2NtVjBkWEp1SUh0dmJteHZZV1E5YjI1ZmJHOWhaQ3dnWTI5dVpHWjFibU05WTI5dVpHbDBhVzl1TENCaFkzUnBiMjVtZFc1alBXRmpkR2x2Ym4wPSIsCiBjYXRlZ29yeSA9ICJUb2wiLAogdHlwZSA9ICJjb25kaXRpb25zIiwKIG5hbWUgPSAiU2hlaUJhbmlzaCIsCn0=

full source code:
SheiBanish sourcecode
Code:
---@type Mq
---@type ImGui
local mq = require('mq')
local required_zone = 'akhevatwo_mission'
local bane_mob_name = 'datiar xi tavuelim'
local SpellLoaded = true
local banes = {
    BRD={name='Slumber of the Diabo',type='spell'},
    CLR={name='Blessed Chains',type='aa'},
    ENC={name='Beguiler\'s Banishment',type='aa'},
    Pal={name='Shackles of Tunare',type='aa'},
    SHM={name='Virulent Paralysis',type='aa'},
    Nec={name='Pestilent Paralysis',type='aa'},
    DRU={name='Paralytic Spores',type='aa'},
    RNG={name='Grasp of Sylvan Spirits',type='aa'},
}
local function StopDPS()
    mq.cmd('/squelch /mqp on')
    mq.delay(10)
    if mq.TLO.Me.Class.ShortName() == 'BRD' then
        mq.cmd('/squelch /twist off')
        mq.delay(10)
        mq.cmd('/squelch /stopsong')
        mq.delay(10)
    end
    --mq.cmd('/attack off')  ... maybe deactivate attack but save state to reactivate at StartDps
    --mq.delay(10)
    mq.cmd('/squelch /boxr pause')
    mq.delay(10)
    while mq.TLO.Me.Casting.ID() do
       mq.delay(200)
    end
end
local function ResumeDPS()
   mq.cmd('/squelch /mqp off')
   mq.delay(10)
   if mq.TLO.Me.Class.ShortName() == 'BRD' then
    mq.cmd('/squelch /twist on')
    mq.delay(10)
   end
   mq.cmd('/squelch /boxr unpause')
   mq.delay(10)
end
local function on_load()
    if mq.TLO.Zone.ShortName() ~= required_zone then return end
    local bane = banes[mq.TLO.Me.Class.ShortName()]
    local spellname = mq.TLO.Spell(tostring(bane.name)).RankName()
    print(spellname)
    if bane and bane.type == 'spell' then
        if mq.TLO.Me.Gem(spellname)() > 0 then return end  -- Should be memmed already
        StopDPS()
        mq.cmdf('/memspell 13 "%s"', spellname)
        mq.delay('4s')
        mq.TLO.Window('SpellBookWnd').DoClose()
        ResumeDPS()
    end
end
---@return boolean @Returns true if the action should fire, otherwise false.
local function condition()
    return mq.TLO.Zone.ShortName() == required_zone and mq.TLO.SpawnCount(('%s npc'):format(bane_mob_name))() > 0
    --return true
end
local function target_bane_mob()
    if mq.TLO.Target.CleanName() ~= bane_mob_name then
        mq.cmdf('/mqtar %s npc', bane_mob_name)
        mq.delay(50)
    end
end
local function cast(spell)
    mq.cmdf('/cast %s', spell.RankName())
    mq.delay(50+spell.MyCastTime())
end
local function use_aa(aa)
    mq.cmdf('/alt activate %s', aa.ID())
    mq.delay(50+aa.Spell.CastTime())
end
local function bane_ready(bane)
    if bane.type == 'spell' then
        return mq.TLO.Me.SpellReady(bane.name) and not mq.TLO.Me.Casting()
    elseif bane.type == 'aa' then
        return mq.TLO.Me.AltAbilityReady(bane.name) and not mq.TLO.Me.Casting()
    end
end
local function action()
    local my_class = mq.TLO.Me.Class.ShortName()
    local bane = banes[my_class]
    -- if not a bane class, return
    if not bane then return end
    -- if bane ability isn't ready, return
    if my_class ~= 'BRD' and not bane_ready(bane) then return end
    StopDPS()
    target_bane_mob()
    if bane.type == 'spell' then
        cast(mq.TLO.Spell(bane.name))
    else
        use_aa(mq.TLO.Me.AltAbility(bane.name))
    end
    while mq.TLO.Me.Casting() do
        mq.doevents()
        mq.delay(50)
    end
    ResumeDPS()
end
return {onload=on_load, condfunc=condition, actionfunc=action}
 
Last edited:
Created a LEM to turn tribute off when not in a raid and timer active.
No more wasted Tribute!

String
Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENteHZZMkZzSUdaMWJtTjBhVzl1SUdOdmJtUnBkR2x2YmlncENpQWdJQ0J5WlhSMWNtNGdiWEV1VkV4UExsSmhhV1F1VFdWdFltVnljeWdwSUQwOUlEQWdZVzVrSUcxeExsUk1UeTVOWlM1VWNtbGlkWFJsUVdOMGFYWmxLQ2tnUFQwZ2RISjFaUXBsYm1RS2JHOWpZV3dnWm5WdVkzUnBiMjRnWVdOMGFXOXVLQ2tLSUNBZ0lHMXhMbU50WkNnbkwzUnlhV0oxZEdVZ2NHVnljMjl1WVd3Z2IyWm1KeWtLSUNBZ0lHMXhMbU50WkNnbkwzUnliM0JvZVNCd1pYSnpiMjVoYkNCdlptWW5LUXBsYm1RS2NtVjBkWEp1SUh0amIyNWtablZ1WXoxamIyNWthWFJwYjI0c0lHRmpkR2x2Ym1aMWJtTTlZV04wYVc5dWZRPT0iLAogY2F0ZWdvcnkgPSAiUW9MIiwKIHR5cGUgPSAiY29uZGl0aW9ucyIsCiBuYW1lID0gIlRyaWJ1dGVfT2ZmIiwKfQ==

Tribute Off
Lua:
local mq = require('mq')
local function condition()
    return mq.TLO.Raid.Members() == 0 and mq.TLO.Me.TributeActive() == true
end
local function action()
    mq.cmd('/tribute personal off')
    mq.cmd('/trophy personal off')
end
return {condfunc=condition, actionfunc=action}
 
Last edited:
Infight Shortbuff recast based on XTarget
My usecase: I want my mage(s) to cast and recast their shortbuff-ds at the tank, as soon as atleast one mob is on aggro (and therefor on their extended target list), despite not beeing in same group( or raid)

Again I found serveral nice ideas, reading the Luas available here.
What I noted: lot of code seems posted here, in a way, that I thought these would be working code.
Snipping parts of them to reuse it, while testing them, I noted that there where sometimes even far from beein a working syntax.
I would like to be able to disctinct "concept code" from "working code".
Code I post may have bug(s), but usually should be tested by myself in different variant uses. (Hopefully in all).

Instructions:
local XTarNr = 11 -- set the number of the slot of Xtarget, where your shortbuff shall land. Usually that will be the tank. Default: tank is on XTarget No. 11

local dsSpells = {
MAG={name='Scorching Skin',type='spell'},
DRU={name='Daggerthorn',type='aa'},
}
Define Class-Ability which Buff/AA shall be cast; NOTE: Daggerthorn is not the DRU best Ds, nor an aa ... this line is there just to show the possible format of an entry for an aa.
For each class, there shall be only one entry. You may add more Classes with an entry, if you find other classes useful infight-shortbuffs
The buffs/aas will be cast on its cooldown, no validation if buff is still on the target or not
As soon as the mob is down and no more mobs are on aggro, the spamming of the ds (or any other shortbuff) will hold

Import Block
Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJMUzB0UUhSNWNHVWdUWEVLTFMwdFFIUjVjR1VnU1cxSGRXa0tDbXh2WTJGc0lHMXhJRDBnY21WeGRXbHlaU2duYlhFbktRcHNiMk5oYkNCVGNHVnNiRzVoYldVOUp5Y0tDaTB0SUdsbUlGaFVZWEpPY2lBOVBTQXdJSFJvWlc0Z2JtOGdkR0Z5WjJWMGFXNW5JSE5vWVd4c0lHSmxJRzVsWldSbFpBb3RMU0JwYlhCdmNuUmhiblFnZEc4Z2JXRnJaU0IwYUdseklIZHZjbXM2SUdsdWMyVnlkQ0IwYUdVZ2MyeHZkQ0JwYmlCWVZHRnlaMlYwVjJsdVpHOTNJSGRvWlhKbElIUm9aU0JVWVc1cklISmxjMmxrWlhNZ2QyaHZJSE5vWld4c0lHZGxkQ0IwYUdVZ1pITW5aWE1LYkc5allXd2dXRlJoY2s1eUlEMGdNVEVnSUMwdElFRlVWRTQ2SUhObGRDQjViM1Z5SUZSaGJtc2dkRzhnWVNCemNHVmphV1pwWXlCWWRHVnVaR1ZrSUZSaGNtZGxkQ0JUYkc5MElHRnVaQ0JwYm5ObGNuUWdiblZ0WW1WeUlHaGxjbVVLQ214dlkyRnNJR1J6VTNCbGJHeHpJRDBnZXdvZ0lDQWdUVUZIUFh0dVlXMWxQU2RUWTI5eVkyaHBibWNnVTJ0cGJpY3NkSGx3WlQwbmMzQmxiR3duZlN3S0lDQWdJRVJTVlQxN2JtRnRaVDBuUkdGbloyVnlkR2h2Y200bkxIUjVjR1U5SjNOd1pXeHNKMzBzQ24wS0NteHZZMkZzSUdaMWJtTjBhVzl1SUZOMGIzQkVVRk1vS1FvZ0lDQWdiWEV1WTIxa0tDY3ZjM0YxWld4amFDQXZiWEZ3SUc5dUp5a0tJQ0FnSUcxeExtUmxiR0Y1S0RFd0tRb2dJQ0FnYVdZZ2JYRXVWRXhQTGsxbExrTnNZWE56TGxOb2IzSjBUbUZ0WlNncElEMDlJQ2RDVWtRbklIUm9aVzRLSUNBZ0lDQWdJQ0J0Y1M1amJXUW9KeTl6Y1hWbGJHTm9JQzkwZDJsemRDQnZabVluS1FvZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RFd0tRb2dJQ0FnSUNBZ0lHMXhMbU50WkNnbkwzTnhkV1ZzWTJnZ0wzTjBiM0J6YjI1bkp5a0tJQ0FnSUNBZ0lDQnRjUzVrWld4aGVTZ3hNQ2tLSUNBZ0lHVnVaQW9nSUNBZ0xTMXRjUzVqYldRb0p5OWhkSFJoWTJzZ2IyWm1KeWtLSUNBZ0lDMHRiWEV1WkdWc1lYa29NVEFwQ2lBZ0lDQnRjUzVqYldRb0p5OXpjWFZsYkdOb0lDOWliM2h5SUhCaGRYTmxKeWtLSUNBZ0lHMXhMbVJsYkdGNUtERXdLUW9nSUNBZ2QyaHBiR1VnYlhFdVZFeFBMazFsTGtOaGMzUnBibWN1U1VRb0tTQmtid29nSUNBZ0lDQWdiWEV1WkdWc1lYa29NVEF3S1FvZ0lDQWdaVzVrQ21WdVpBb0tiRzlqWVd3Z1puVnVZM1JwYjI0Z1VtVnpkVzFsUkZCVEtDa0tJQ0FnYlhFdVkyMWtLQ2N2YzNGMVpXeGphQ0F2YlhGd0lHOW1aaWNwQ2lBZ0lHMXhMbVJsYkdGNUtERXdLUW9nSUNCcFppQnRjUzVVVEU4dVRXVXVRMnhoYzNNdVUyaHZjblJPWVcxbEtDa2dQVDBnSjBKU1JDY2dkR2hsYmdvZ0lDQWdiWEV1WTIxa0tDY3ZjM0YxWld4amFDQXZkSGRwYzNRZ2IyNG5LUW9nSUNBZ2JYRXVaR1ZzWVhrb01UQXBDaUFnSUdWdVpBb2dJQ0J0Y1M1amJXUW9KeTl6Y1hWbGJHTm9JQzlpYjNoeUlIVnVjR0YxYzJVbktRb2dJQ0J0Y1M1a1pXeGhlU2d4TUNrS1pXNWtDZ3BzYjJOaGJDQm1kVzVqZEdsdmJpQnZibDlzYjJGa0tDa0tJQ0FnSUd4dlkyRnNJR1J6VTNCbGJHd2dQU0JrYzFOd1pXeHNjMXR0Y1M1VVRFOHVUV1V1UTJ4aGMzTXVVMmh2Y25ST1lXMWxLQ2xkQ2lBZ0lDQlRjR1ZzYkc1aGJXVWdQU0J0Y1M1VVRFOHVVM0JsYkd3b2RHOXpkSEpwYm1jb1pITlRjR1ZzYkM1dVlXMWxLU2t1VW1GdWEwNWhiV1VvS1FvZ0lDQWdhV1lnWkhOVGNHVnNiQ0JoYm1RZ1pITlRjR1ZzYkM1MGVYQmxJRDA5SUNkemNHVnNiQ2NnWVc1a0lGaFVZWEpPY2lBK0lEQWdkR2hsYmdvZ0lDQWdJQ0FnSUdsbUlHMXhMbFJNVHk1TlpTNUhaVzBvVTNCbGJHeHVZVzFsS1NncElHRnVaQ0J0Y1M1VVRFOHVUV1V1UjJWdEtGTndaV3hzYm1GdFpTa29LU0ErSURBZ2RHaGxiaUJ5WlhSMWNtNGdaVzVrQ2lBZ0lDQWdJQ0FnVTNSdmNFUlFVeWdwQ2lBZ0lDQWdJQ0FnYlhFdVkyMWtaaWduTDIxbGJYTndaV3hzSURFeklDSWxjeUluTENCVGNHVnNiRzVoYldVcENpQWdJQ0FnSUNBZ2JYRXVaR1ZzWVhrb0p6UnpKeWtLSUNBZ0lDQWdJQ0J0Y1M1VVRFOHVWMmx1Wkc5M0tDZFRjR1ZzYkVKdmIydFhibVFuS1M1RWIwTnNiM05sS0NrS0lDQWdJQ0FnSUNCU1pYTjFiV1ZFVUZNb0tRb2dJQ0FnWlc1a0NtVnVaQW9LTFMwdFFISmxkSFZ5YmlCaWIyOXNaV0Z1SUVCU1pYUjFjbTV6SUhSeWRXVWdhV1lnZEdobElHRmpkR2x2YmlCemFHOTFiR1FnWm1seVpTd2diM1JvWlhKM2FYTmxJR1poYkhObExncHNiMk5oYkNCbWRXNWpkR2x2YmlCamIyNWthWFJwYjI0b0tRb3RMUzFBWkdsaFoyNXZjM1JwWXlCa2FYTmhZbXhsTFc1bGVIUXRiR2x1WlRvZ2RXNWtaV1pwYm1Wa0xXWnBaV3hrQ2lBZ0lDQnlaWFIxY200Z2JYRXVWRXhQTGxoQmMzTnBjM1F1V0ZSR2RXeHNTR0YwWlhKRGIzVnVkQ2dwSUQ0Z01Bb2dJQ0FnTFMxeVpYUjFjbTRnYlhFdVZFeFBMazFsTGtOdmJXSmhkQ2dwSUMwdGIzSWdXRlJoY21kbGRBcGxibVFLQ214dlkyRnNJR1oxYm1OMGFXOXVJSFJoY21kbGRGOVVZVzVyS0NrS0lDQWdJR2xtSUZoVVlYSk9jaUErSURBZ2RHaGxiZ29nSUNBZ0lDQWdJRzF4TG1OdFpHWW9KeTk0ZEdGeUlDVnBKeXdnV0ZSaGNrNXlLUW9nSUNBZ0lDQWdJRzF4TG1SbGJHRjVLREl3S1FvZ0lDQWdaVzVrQ21WdVpBb0tiRzlqWVd3Z1puVnVZM1JwYjI0Z1kyRnpkQ2h6Y0dWc2JDa0tJQ0FnSUcxeExtTnRaR1lvSnk5allYTjBJQ1Z6Snl3Z2MzQmxiR3dwQ2lBZ0lDQnRjUzVrWld4aGVTZ3lNQ2tLSUNBZ0lHMXhMbVJ2WlhabGJuUnpLQ2tLTFMwdFFHUnBZV2R1YjNOMGFXTWdaR2x6WVdKc1pTMXVaWGgwTFd4cGJtVTZJSFZ1WkdWbWFXNWxaQzFtYVdWc1pBb2dJQ0FnYlhFdVpHVnNZWGtvTWpBcmJYRXVWRXhQTGsxbExrTmhjM1JVYVcxbFRHVm1kQzVTWVhjcENpQWdJQzB0SUcxeExtUmxiR0Y1S0RJd0syMXhMbFJNVHk1VGNHVnNiQ2h6Y0dWc2JDa3VUWGxEWVhOMFZHbHRaUzVTWVhjcENtVnVaQW9LYkc5allXd2dablZ1WTNScGIyNGdkWE5sWDJGaEtHRmhLUW9nSUNBZ2JYRXVZMjFrWmlnbkwyRnNkQ0JoWTNScGRtRjBaU0FsY3ljc0lGUk1UeTVOWlM1QmJIUkJZbWxzYVhSNUtHRmhLUzVKUkNrS0lDQWdJRzF4TG1SbGJHRjVLREl3S1FvZ0lDQWdiWEV1Wkc5bGRtVnVkSE1vS1FvdExTMUFaR2xoWjI1dmMzUnBZeUJrYVhOaFlteGxMVzVsZUhRdGJHbHVaVG9nZFc1a1pXWnBibVZrTFdacFpXeGtDaUFnSUNCdGNTNWtaV3hoZVNneU1DdHRjUzVVVEU4dVRXVXVRMkZ6ZEZScGJXVk1aV1owTGxKaGR5a0taVzVrQ2dwc2IyTmhiQ0JtZFc1amRHbHZiaUJrYzE5eVpXRmtlU2hrY3lrS0lDQWdJR2xtSUdSekxuUjVjR1VnUFQwZ0ozTndaV3hzSnlCMGFHVnVDaUFnSUNBZ0lDQWdjbVYwZFhKdUlHMXhMbFJNVHk1TlpTNVRjR1ZzYkZKbFlXUjVLRk53Wld4c2JtRnRaU2tnWVc1a0lHNXZkQ0J0Y1M1VVRFOHVUV1V1UTJGemRHbHVaeWdwQ2lBZ0lDQmxiSE5sYVdZZ1pITXVkSGx3WlNBOVBTQW5ZV0VuSUhSb1pXNEtJQ0FnSUNBZ0lDQnlaWFIxY200Z2JYRXVWRXhQTGsxbExrRnNkRUZpYVd4cGRIbFNaV0ZrZVNoMGIzTjBjbWx1Wnloa2N5NXVZVzFsS1NrZ1lXNWtJRzV2ZENCdGNTNVVURTh1VFdVdVEyRnpkR2x1WnlncENpQWdJQ0JsYm1RS1pXNWtDZ3BzYjJOaGJDQm1kVzVqZEdsdmJpQmhZM1JwYjI0b0tRb2dJQ0FnYkc5allXd2diWGxmWTJ4aGMzTWdQU0J0Y1M1VVRFOHVUV1V1UTJ4aGMzTXVVMmh2Y25ST1lXMWxLQ2tLSUNBZ0lHeHZZMkZzSUdSeklEMGdaSE5UY0dWc2JITmJiWGxmWTJ4aGMzTmRDaUFnSUNBdExTQnBaaUJ1YjNRZ1lTQmtjeUJqYkdGemN5d2djbVYwZFhKdUNpQWdJQ0JwWmlCdWIzUWdaSE1nZEdobGJpQnlaWFIxY200Z1pXNWtDaUFnSUNBdExTQnBaaUJrY3lCaFltbHNhWFI1SUdsemJpZDBJSEpsWVdSNUxDQnlaWFIxY200S0lDQWdJR2xtSUcxNVgyTnNZWE56SUg0OUlDZENVa1FuSUdGdVpDQnViM1FnWkhOZmNtVmhaSGtvZEc5emRISnBibWNvWkhNdWJtRnRaU2twSUhSb1pXNGdjbVYwZFhKdUlHVnVaQW9nSUNBZ1UzUnZjRVJRVXlncENpQWdJQ0IwWVhKblpYUmZWR0Z1YXlncENpQWdJQ0JwWmlCa2N5NTBlWEJsSUQwOUlDZHpjR1ZzYkNjZ2RHaGxiZ29nSUNBZ0lDQWdJR05oYzNRb1UzQmxiR3h1WVcxbEtRb2dJQ0FnWld4elpRb2dJQ0FnSUNBZ0lIVnpaVjloWVNoMGIzTjBjbWx1Wnloa2N5NXVZVzFsS1NrS0lDQWdJR1Z1WkFvZ0lDQWdkMmhwYkdVZ2JYRXVWRXhQTGsxbExrTmhjM1JwYm1jb0tTQmtid29nSUNBZ0lDQWdJRzF4TG1SdlpYWmxiblJ6S0NrS0lDQWdJQ0FnSUNCdGNTNWtaV3hoZVNnMU1Da0tJQ0FnSUdWdVpBb2dJQ0FnVW1WemRXMWxSRkJUS0NrS1pXNWtDZ3B5WlhSMWNtNGdlMjl1Ykc5aFpEMXZibDlzYjJGa0xDQmpiMjVrWm5WdVl6MWpiMjVrYVhScGIyNHNJR0ZqZEdsdmJtWjFibU05WVdOMGFXOXVmUT09IiwKIGNhdGVnb3J5ID0gImdlbmVyYWwiLAogdHlwZSA9ICJjb25kaXRpb25zIiwKIG5hbWUgPSAiQ2hhaW5EcyIsCn0=


Full Source Code
Code:
---@type Mq
---@type ImGui

local mq = require('mq')
local Spellname=''

-- if XTarNr == 0 then no targeting shall be needed
-- important to make this work: insert the slot in XTargetWindow where the Tank resides who shell get the ds'es
local XTarNr = 11  -- ATTN: set your Tank to a specific Xtended Target Slot and insert number here

local dsSpells = {
    MAG={name='Scorching Skin',type='spell'},
    DRU={name='Daggerthorn',type='spell'},
}

local function StopDPS()
    mq.cmd('/squelch /mqp on')
    mq.delay(10)
    if mq.TLO.Me.Class.ShortName() == 'BRD' then
        mq.cmd('/squelch /twist off')
        mq.delay(10)
        mq.cmd('/squelch /stopsong')
        mq.delay(10)
    end
    --mq.cmd('/attack off')
    --mq.delay(10)
    mq.cmd('/squelch /boxr pause')
    mq.delay(10)
    while mq.TLO.Me.Casting.ID() do
       mq.delay(100)
    end
end

local function ResumeDPS()
   mq.cmd('/squelch /mqp off')
   mq.delay(10)
   if mq.TLO.Me.Class.ShortName() == 'BRD' then
    mq.cmd('/squelch /twist on')
    mq.delay(10)
   end
   mq.cmd('/squelch /boxr unpause')
   mq.delay(10)
end

local function on_load()
    local dsSpell = dsSpells[mq.TLO.Me.Class.ShortName()]
    Spellname = mq.TLO.Spell(tostring(dsSpell.name)).RankName()
    if dsSpell and dsSpell.type == 'spell' and XTarNr > 0 then
        if mq.TLO.Me.Gem(Spellname)() and mq.TLO.Me.Gem(Spellname)() > 0 then return end
        StopDPS()
        mq.cmdf('/memspell 13 "%s"', Spellname)
        mq.delay('4s')
        mq.TLO.Window('SpellBookWnd').DoClose()
        ResumeDPS()
    end
end

---@return boolean @Returns true if the action should fire, otherwise false.
local function condition()
---@diagnostic disable-next-line: undefined-field
    return mq.TLO.XAssist.XTFullHaterCount() > 0
    --return mq.TLO.Me.Combat() --or XTarget
end

local function target_Tank()
    if XTarNr > 0 then
        mq.cmdf('/xtar %i', XTarNr)
        mq.delay(20)
    end
end

local function cast(spell)
    mq.cmdf('/cast %s', spell)
    mq.delay(20)
    mq.doevents()
---@diagnostic disable-next-line: undefined-field
    mq.delay(20+mq.TLO.Me.CastTimeLeft.Raw)
   -- mq.delay(20+mq.TLO.Spell(spell).MyCastTime.Raw)
end

local function use_aa(aa)
    mq.cmdf('/alt activate %s', TLO.Me.AltAbility(aa).ID)
    mq.delay(20)
    mq.doevents()
---@diagnostic disable-next-line: undefined-field
    mq.delay(20+mq.TLO.Me.CastTimeLeft.Raw)
end

local function ds_ready(ds)
    if ds.type == 'spell' then
        return mq.TLO.Me.SpellReady(Spellname) and not mq.TLO.Me.Casting()
    elseif ds.type == 'aa' then
        return mq.TLO.Me.AltAbilityReady(tostring(ds.name)) and not mq.TLO.Me.Casting()
    end
end

local function action()
    local my_class = mq.TLO.Me.Class.ShortName()
    local ds = dsSpells[my_class]
    -- if not a ds class, return
    if not ds then return end
    -- if ds ability isn't ready, return
    if my_class ~= 'BRD' and not ds_ready(tostring(ds.name)) then return end
    StopDPS()
    target_Tank()
    if ds.type == 'spell' then
        cast(Spellname)
    else
        use_aa(tostring(ds.name))
    end
    while mq.TLO.Me.Casting() do
        mq.doevents()
        mq.delay(50)
    end
    ResumeDPS()
end

return {onload=on_load, condfunc=condition, actionfunc=action}



What if I would create a hotbutton on my tank like:

/dggae /lem event ChainDs off ## This will make shure, that all Mages will have this event disabled
/timed 400 /dex Mag1 /lem event ChainDs on
/timed 400 /dex Mag2 /lem event ChainDs on
/timed 400 /dex Mag3 /lem event ChainDs on
/dex Mag4 /lem event ChainDs on

where Mag1 .. Mag4 would be the names of my for mage
This will cause to run the event on 4 Mages, with a timeshift of 400 ms .....

During fighttime this timeshift would not stay fixed, as each mage works on its own ... but a simple click at the next start of a fight will sync them again with this timeshift
 
Last edited:
Conditional event: SHD disc 2-Hit Rune ... for lvl 120 "Repudiate"

Condition: If I have anything on aggro and I am not Invis
fire my 2 hit Rune "Repudiate" whenever possible on cooldown
as long as there is atleast 1 mob on aggro


Import Event
Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJMUzB0UUhSNWNHVWdUWEVLTFMwdFFIUjVjR1VnU1cxSGRXa0tDbXh2WTJGc0lHMXhJRDBnY21WeGRXbHlaU2duYlhFbktRcHNiMk5oYkNCRGIyMWlZWFJCWW1sc2FYUjVUbUZ0WlNBOUlDZFNaWEIxWkdsaGRHVW5DZ3BzYjJOaGJDQm1kVzVqZEdsdmJpQlRkRzl3UkZCVEtDa0tJQ0FnSUcxeExtTnRaQ2duTDNOeGRXVnNZMmdnTDIxeGNDQnZiaWNwQ2lBZ0lDQnRjUzVrWld4aGVTZ3hNQ2tLSUNBZ0lHMXhMbU50WkNnbkwzTnhkV1ZzWTJnZ0wySnZlSElnY0dGMWMyVW5LUW9nSUNBZ2JYRXVaR1ZzWVhrb01UQXBDaUFnSUNCM2FHbHNaU0J0Y1M1VVRFOHVUV1V1UTJGemRHbHVaeTVKUkNncElHUnZDaUFnSUNBZ0lDQnRjUzVrWld4aGVTZ3hNREFwQ2lBZ0lDQmxibVFLWlc1a0NncHNiMk5oYkNCbWRXNWpkR2x2YmlCU1pYTjFiV1ZFVUZNb0tRb2dJQ0J0Y1M1amJXUW9KeTl6Y1hWbGJHTm9JQzl0Y1hBZ2IyWm1KeWtLSUNBZ2JYRXVaR1ZzWVhrb01UQXBDaUFnSUcxeExtTnRaQ2duTDNOeGRXVnNZMmdnTDJKdmVISWdkVzV3WVhWelpTY3BDaUFnSUcxeExtUmxiR0Y1S0RFd0tRcGxibVFLQ214dlkyRnNJR1oxYm1OMGFXOXVJRTV2WmtoaGRHVnlLQ2tLTFMwdFFHUnBZV2R1YjNOMGFXTWdaR2x6WVdKc1pTMXVaWGgwTFd4cGJtVTZJSFZ1WkdWbWFXNWxaQzFtYVdWc1pBb2dJQ0FnY21WMGRYSnVJRzF4TGxSTVR5NVlRWE56YVhOMExsaFVSblZzYkVoaGRHVnlRMjkxYm5Rb0tRcGxibVFLQ214dlkyRnNJRU5CVW1GdWEyVmtJRDBnSWlJS2JHOWpZV3dnWm5WdVkzUnBiMjRnYjI1ZmJHOWhaQ2dwQ2lBZ0lDQkRRVkpoYm10bFpDQTlJRzF4TGxSTVR5NVRjR1ZzYkNnb1EyOXRZbUYwUVdKcGJHbDBlVTVoYldVcEtTNVNZVzVyVG1GdFpTZ3BDbVZ1WkFvS2JHOWpZV3dnWm5WdVkzUnBiMjRnWTI5dVpHbDBhVzl1S0NrS0lDQWdJR2xtSUc1dmRDQjBiM04wY21sdVp5aHRjUzVVVEU4dVRXVXVRMnhoYzNNdVUyaHZjblJPWVcxbEtDa3BJRDA5SUNkVFNFUW5JSFJvWlc0Z2NtVjBkWEp1SUdaaGJITmxJR1Z1WkNBZ0lDQWdJQ0FnSUNBZ0xTMGdibThnVTBoRUlHNXZJR1oxYmdvZ0lDQWdMUzB0UUdScFlXZHViM04wYVdNZ1pHbHpZV0pzWlMxdVpYaDBMV3hwYm1VNklIVnVaR1ZtYVc1bFpDMW1hV1ZzWkFvZ0lDQWdhV1lnVG05bVNHRjBaWElvS1NBK0lEQWdZVzVrSUc1dmRDQnRjUzVVVEU4dVRXVXVTVzUyYVhNb0tTQmhibVFnYlhFdVZFeFBMazFsTGtOdmJXSmhkRUZpYVd4cGRIbFNaV0ZrZVNoRFFWSmhibXRsWkNrZ2RHaGxiaUJ5WlhSMWNtNGdkSEoxWlNCbGJtUUtJQ0FnSUhKbGRIVnliaUJtWVd4elpRcGxibVFLQ214dlkyRnNJR1oxYm1OMGFXOXVJR0ZqZEdsdmJpZ3BDaUFnSUNCVGRHOXdSRkJUS0NrS0lDQWdJRzF4TG1SbGJHRjVLREV3S1FvZ0lDQWdiWEV1WTIxa1ppZ25MM054ZFdWc1kyZ2dMMlJwYzJNZ0pYTW5MQ0JEUVZKaGJtdGxaQ2tLSUNBZ0lHMXhMbVJsYkdGNUtERXdLUW9nSUNBZ1VtVnpkVzFsUkZCVEtDa0taVzVrQ2dweVpYUjFjbTRnZTI5dWJHOWhaRDF2Ymw5c2IyRmtMQ0JqYjI1a1puVnVZejFqYjI1a2FYUnBiMjRzSUdGamRHbHZibVoxYm1NOVlXTjBhVzl1ZlE9PSIsCiBjYXRlZ29yeSA9ICJnZW5lcmFsIiwKIHR5cGUgPSAiY29uZGl0aW9ucyIsCiBuYW1lID0gIlNoZDJIaXRSdW5lRGlzYyIsCn0=

This disc does not consume alot of Endurance, but for my feeling offers alot of defense, as it adsorbes upto 176k damage from the next 28 hits(full aa) . So my SHD likes it and want it always up when he has aggro.

Full ressource code
Code:
---@type Mq
---@type ImGui

local mq = require('mq')
local CombatAbilityName = 'Repudiate'

local function StopDPS()
    mq.cmd('/squelch /mqp on')
    mq.delay(10)
    mq.cmd('/squelch /boxr pause')
    mq.delay(10)
    while mq.TLO.Me.Casting.ID() do
       mq.delay(100)
    end
end

local function ResumeDPS()
   mq.cmd('/squelch /mqp off')
   mq.delay(10)
   mq.cmd('/squelch /boxr unpause')
   mq.delay(10)
end

local function NofHater()
---@diagnostic disable-next-line: undefined-field
    return mq.TLO.XAssist.XTFullHaterCount()
end

local CARanked = ""
local function on_load()
    CARanked = mq.TLO.Spell((CombatAbilityName)).RankName()
end

local function condition()
    if not tostring(mq.TLO.Me.Class.ShortName()) == 'SHD' then return false end           -- no SHD no fun
    ---@diagnostic disable-next-line: undefined-field
    if NofHater() > 0 and not mq.TLO.Me.Invis() and mq.TLO.Me.CombatAbilityReady(CARanked) then return true end
    return false
end

local function action()
    StopDPS()
    mq.delay(10)
    mq.cmdf('/squelch /disc %s', CARanked)
    mq.delay(10)
    ResumeDPS()
end

return {onload=on_load, condfunc=condition, actionfunc=action}


Idea for further improvements:
- extend for multiclass-support
 
Trying to figure out how to get this over to a LEM. Does anyone more intelligent than I have something like this done or know what I can do to get it to work?
[newtask]
trigger="You have been assigned the task '#1#'#*#"
command=/timed 10 /bc [+w+]New Task [+t+]${EventArg1} Step: [+o+]${Task[${EventArg1}].Step.Index} - [+w+]${Task[${EventArg1}].Step} [+p+]${Task[${EventArg1}].Step.Status}.



Lua:
local mq = require('mq')

local function event_handler()
    mq.cmd('/timed 10 /bc [+w+]New Task [+t+]${EventArg1} Step: [+o+]${Task[${EventArg1}].Step.Index} - [+w+]${Task[${EventArg1}].Step} [+p+]${Task[${EventArg1}].Step.Status}.')
end

return {eventfunc=event_handler}
 
Trying to figure out how to get this over to a LEM. Does anyone more intelligent than I have something like this done or know what I can do to get it to work?
[newtask]
trigger="You have been assigned the task '#1#'#*#"
command=/timed 10 /bc [+w+]New Task [+t+]${EventArg1} Step: [+o+]${Task[${EventArg1}].Step.Index} - [+w+]${Task[${EventArg1}].Step} [+p+]${Task[${EventArg1}].Step.Status}.



Lua:
local mq = require('mq')

local function event_handler()
    mq.cmd('/timed 10 /bc [+w+]New Task [+t+]${EventArg1} Step: [+o+]${Task[${EventArg1}].Step.Index} - [+w+]${Task[${EventArg1}].Step} [+p+]${Task[${EventArg1}].Step.Status}.')
end

return {eventfunc=event_handler}
Lua:
local function event_handler(line, taskName)
    local task = mq.TLO.Task(taskName)
    mq.cmdf('/timed 10 /bc [+w+]New Task [+t+]%s Step: [+o+]%s - [+w+]%s [+p+]%s.', taskName, task.Step.Index(), task.Step(), task.Step.Status())
end
 
Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENncHNiMk5oYkNCbWRXNWpkR2x2YmlCbGRtVnVkRjlvWVc1a2JHVnlLR3hwYm1Vc0lIUmhjMnRPWVcxbEtRb2dJQ0FnYkc5allXd2dkR0Z6YXlBOUlHMXhMbFJNVHk1VVlYTnJLSFJoYzJ0T1lXMWxLUW9nSUNBZ2JYRXVZMjFrWmlnbkwzUnBiV1ZrSURFd0lDOWlZeUJiSzNjclhVNWxkeUJVWVhOcklGc3JkQ3RkSlhNZ1UzUmxjRG9nV3l0dksxMGxjeUF0SUZzcmR5dGRKWE1nV3l0d0sxMGxjeTRuTENCMFlYTnJUbUZ0WlN3Z2RHRnpheTVUZEdWd0xrbHVaR1Y0S0Nrc0lIUmhjMnN1VTNSbGNDZ3BMQ0IwWVhOckxsTjBaWEF1VTNSaGRIVnpLQ2twQ21WdVpBb0tjbVYwZFhKdUlIdGxkbVZ1ZEdaMWJtTTlaWFpsYm5SZmFHRnVaR3hsY24wPSIsCiBjYXRlZ29yeSA9ICIiLAogdHlwZSA9ICJldmVudHMiLAogbmFtZSA9ICJOZXdfVGFzayIsCiBwYXR0ZXJuID0gIllvdSBoYXZlIGJlZW4gYXNzaWduZWQgdGhlIHRhc2sgJyMxIycjKiMiLAp9

This will update in EQBCS if you get task updates. Great for making sure all your boxes have the same task.
 
Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENteHZZMkZzSUhabGNuTnBiMjRnUFNBbk1TNHdKd3BzYjJOaGJDQnRaVjlqYkdGemN5QTlJRzF4TGxSTVR5NU5aUzVEYkdGemN5NVRhRzl5ZEU1aGJXVW9LUW9LYkc5allXd2dablZ1WTNScGIyNGdjSEpwYm5SbUtDNHVMaWtLSUNBZ0lIQnlhVzUwS0hOMGNtbHVaeTVtYjNKdFlYUW9MaTR1S1NrS0lDQmxibVFLQ214dlkyRnNJR1oxYm1OMGFXOXVJR1YyWlc1MFgyaGhibVJzWlhJb0tRb2dJQ0FnYlhFdVkyMWtLQ2N2Ym05dGIyUnJaWGtnTDJsMFpXMXViM1JwWm5rZ0lrMWxZMmhoYm1sNlpXUWdURzlqYTNCcFkydHpJaUJzWldaMGJXOTFjMlYxY0NjcENpQWdJQ0J0Y1M1amJXUW9KeTlrYjI5eWRHRnlaMlYwSnlrS0lDQWdJRzF4TG1OdFpDZ25MMk5zYVdOcklHeGxablFnWkc5dmNpY3BDaUFnSUNCdGNTNWtaV3hoZVNneE1EQXdLUW9nSUNBZ2JYRXVZMjFrS0NjdllYVjBiMmx1ZG1WdWRHOXllU2NwQ21WdVpBb0tjbVYwZFhKdUlIdGxkbVZ1ZEdaMWJtTTlaWFpsYm5SZmFHRnVaR3hsY24wPSIsCiBjYXRlZ29yeSA9ICIiLAogdHlwZSA9ICJldmVudHMiLAogbmFtZSA9ICJQaWNrIHRoZSBMb2NrIiwKIHBhdHRlcm4gPSAiIyojbG9ja2VkIGFuZCB5b3UncmUgbm90IGhvbGRpbmcgdGhlIGtleSMqIyIsCn0=

Automatically picking a locked door with mech lockpicks, if you are a rogue/bard.
 
Lua:
local function event_handler(line, taskName)
    local task = mq.TLO.Task(taskName)
    mq.cmdf('/timed 10 /bc [+w+]New Task [+t+]%s Step: [+o+]%s - [+w+]%s [+p+]%s.', taskName, task.Step.Index(), task.Step(), task.Step.Status())
end

#*#Your task '#1#' has been updated#*#

Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENncHNiMk5oYkNCbWRXNWpkR2x2YmlCbGRtVnVkRjlvWVc1a2JHVnlLR3hwYm1Vc0lIUmhjMnRPWVcxbEtRb2dJQ0FnYkc5allXd2dkR0Z6YXlBOUlHMXhMbFJNVHk1VVlYTnJLSFJoYzJ0T1lXMWxLUW9nSUNBZ2JYRXVZMjFrWmlnbkwzUnBiV1ZrSURFd0lDOWlZeUJiSzNjclhWUmhjMnNnV3l0MEsxMGxjeUJUZEdWd09pQmJLMjhyWFNWeklDMGdXeXQzSzEwbGN5QmJLM0FyWFNWekxpY3NJSFJoYzJ0T1lXMWxMQ0IwWVhOckxsTjBaWEF1U1c1a1pYZ29LU3dnZEdGemF5NVRkR1Z3S0Nrc0lIUmhjMnN1VTNSbGNDNVRkR0YwZFhNb0tTa0taVzVrQ2dweVpYUjFjbTRnZTJWMlpXNTBablZ1WXoxbGRtVnVkRjlvWVc1a2JHVnlmUT09IiwKIGNhdGVnb3J5ID0gIkdlbmVyYWwiLAogdHlwZSA9ICJldmVudHMiLAogbmFtZSA9ICJUYXNrX1VwZGF0ZWQiLAogcGF0dGVybiA9ICIjKiNZb3VyIHRhc2sgJyMxIycgaGFzIGJlZW4gdXBkYXRlZCMqIyIsCn0=

In theory this should work as well for updating tasks too.
 
Here is a LEM that is meant to emulate gtfo.mac . It should be running on your porter, and need to replace the spell_name variable with a spell you already have memmed to port out.

(The trigger condition assumes you have MQ2Posse loaded, enabled, and a radius set to detect strangers), you can test with /echo ${Posse.Strangers}

This will pause all macros, bring the group to the porter, then cast the spell.

(uses cast code from Dragonslayer's shei bane lem. Thank you!)

Edit: 11/20/2022 - Added a little loop to make sure the cast went off. Checks if you are in the zone you were planning to port to, if not, tries to port again

port out lem
Lua:
local mq = require('mq')
local function condition()
    return mq.TLO.Posse.Strangers() > 0
end
local function cast(spell)
    mq.cmdf('/cast %s', spell.RankName())
    mq.delay(50+spell.MyCastTime())
end
local function action()
    local spell_name =  mq.TLO.Spell('Succor: Butcher')
    mq.cmd('/mqp on')
    mq.delay(100)
    mq.cmd('/dgge /mqp on')
    mq.cmd('/dgze /nav id ${Me.ID}')
    mq.delay(5000)
    while mq.TLO.Zone.ShortName() ~= 'butcher' do
        cast(spell_name)
        --wait 45 seconds and check zone again
        mq.delay(45000)
    end
end
return {condfunc=condition, actionfunc=action}
 
Last edited:
Join_Raid
Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENncHNiMk5oYkNCbWRXNWpkR2x2YmlCbGRtVnVkRjlvWVc1a2JHVnlLQ2tLSUNBZ0lHMXhMbU50WkNnaUwySnZlSElnY0dGMWMyVWdiMjRpS1FvZ0lDQWdiWEV1WkdWc1lYa29NVEF3TUNrS0lDQWdJRzF4TG1OdFpDZ2lMMnh2WnlCdmJpSXBDaUFnSUNCdGNTNWtaV3hoZVNneE1EQXdLUW9nSUNBZ2JYRXVZMjFrS0NJdlpHOWpiMjF0WVc1a0lDOGtlMDFsTGtOc1lYTnpMbE5vYjNKMFRtRnRaWDBnY21GcFpHMXZaR1VnTVNJcENpQWdJQ0J0Y1M1a1pXeGhlU2d4TURBd0tRb2dJQ0FnYlhFdVkyMWtLQ0l2Wkc5amIyMXRZVzVrSUM4a2UwMWxMa05zWVhOekxsTm9iM0owVG1GdFpYMGdjbUZwWkdGemMybHpkQ0F4SWlrS0lDQWdJRzF4TG1SbGJHRjVLREV3TURBcENpQWdJQ0J0Y1M1amJXUW9JaTlzZFdFZ2MzUnZjQ0JzYjI5MGJIa2lLUW9nSUNBZ2JYRXVaR1ZzWVhrb01UQXdNQ2tLSUNBZ0lHMXhMbU50WkNnaUwyeDFZU0J6ZEc5d0lHOTJaWEp6WldWeUlpa0tJQ0FnSUcxeExtUmxiR0Y1S0RFd01EQXBDaUFnSUNCdGNTNWpiV1FvSWk5dWIzUnBabmtnVDNCMGFXOXVjMGRsYm1WeVlXeFFZV2RsSUU5RVVGOURiR2x3VUd4aGJtVlRiR2xrWlhJZ2JtVjNkbUZzZFdVZ05TSXBDaUFnSUNCdGNTNWtaV3hoZVNneE1EQXdLUW9nSUNBZ2JYRXVZMjFrS0NJdmFXWWdLQ0VrZTFkcGJtUnZkMXRQY0hScGIyNXpSMlZ1WlhKaGJGQmhaMlZkTGtOb2FXeGtXMDlIVUY5QmRYUnZRV05qWlhCMFMybGphMUpsY1hWbGMzUnpYUzVEYUdWamEyVmtmU2tnTDI1dmRHbG1lU0JQY0hScGIyNXpSMlZ1WlhKaGJGQmhaMlVnVDBkUVgwRjFkRzlCWTJObGNIUkxhV05yVW1WeGRXVnpkSE1nYkdWbWRHMXZkWE5sZFhBaUtRb2dJQ0FnYlhFdVpHVnNZWGtvTVRBd01Da0taVzVrQ2dweVpYUjFjbTRnWlhabGJuUmZhR0Z1Wkd4bGNnPT0iLAogY2F0ZWdvcnkgPSAiUmFpZCIsCiB0eXBlID0gImV2ZW50cyIsCiBuYW1lID0gIkpvaW5fUmFpZCIsCiBwYXR0ZXJuID0gIiMqI1lvdSBoYXZlIGpvaW5lZCB0aGUgcmFpZCMqIyIsCn0=

Code:
local mq = require('mq')

local function event_handler()
    mq.cmd("/boxr pause on")
    mq.delay(1000)
    mq.cmd("/log on")
    mq.delay(1000)
    mq.cmd("/docommand /${Me.Class.ShortName} raidmode 1")
    mq.delay(1000)
    mq.cmd("/docommand /${Me.Class.ShortName} raidassist 1")
    mq.delay(1000)
    mq.cmd("/lua stop lootly")
    mq.delay(1000)
    mq.cmd("/lua stop overseer")
    mq.delay(1000)
    mq.cmd("/notify OptionsGeneralPage ODP_ClipPlaneSlider newvalue 5")
    mq.delay(1000)
    mq.cmd("/if (!${Window[OptionsGeneralPage].Child[OGP_AutoAcceptKickRequests].Checked}) /notify OptionsGeneralPage OGP_AutoAcceptKickRequests leftmouseup")
    mq.delay(1000)
end

return event_handler

When you join a raid:
1. it will pause automation
2. turn your log on for Gina,
3. then set raid mode
4. raid assist to first MA.
5. Stop Lootly
6. Stop Overseer
7. Change Clip to 25%
8. Turn off Accept Kick requests.
 
Last edited:
Join_Raid
Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENncHNiMk5oYkNCbWRXNWpkR2x2YmlCbGRtVnVkRjlvWVc1a2JHVnlLQ2tLSUNBZ0lHMXhMbU50WkNnaUwySnZlSElnY0dGMWMyVWdiMjRpS1FvZ0lDQWdiWEV1WkdWc1lYa29NVEF3TUNrS0lDQWdJRzF4TG1OdFpDZ2lMMnh2WnlCdmJpSXBDaUFnSUNCdGNTNWtaV3hoZVNneE1EQXdLUW9nSUNBZ2JYRXVZMjFrS0NJdlpHOWpiMjF0WVc1a0lDOGtlMDFsTGtOc1lYTnpMbE5vYjNKMFRtRnRaWDBnY21GcFpHMXZaR1VnTVNJcENpQWdJQ0J0Y1M1a1pXeGhlU2d4TURBd0tRb2dJQ0FnYlhFdVkyMWtLQ0l2Wkc5amIyMXRZVzVrSUM4a2UwMWxMa05zWVhOekxsTm9iM0owVG1GdFpYMGdjbUZwWkdGemMybHpkQ0F4SWlrS0lDQWdJRzF4TG1SbGJHRjVLREV3TURBcENpQWdJQ0J0Y1M1amJXUW9JaTlzZFdFZ2MzUnZjQ0JzYjI5MGJIa2lLUW9nSUNBZ2JYRXVaR1ZzWVhrb01UQXdNQ2tLSUNBZ0lHMXhMbU50WkNnaUwyeDFZU0J6ZEc5d0lHOTJaWEp6WldWeUlpa0tJQ0FnSUcxeExtUmxiR0Y1S0RFd01EQXBDaUFnSUNCdGNTNWpiV1FvSWk5dWIzUnBabmtnVDNCMGFXOXVjMGRsYm1WeVlXeFFZV2RsSUU5RVVGOURiR2x3VUd4aGJtVlRiR2xrWlhJZ2JtVjNkbUZzZFdVZ05TSXBDaUFnSUNCdGNTNWtaV3hoZVNneE1EQXdLUW9nSUNBZ2JYRXVZMjFrS0NJdmFXWWdLQ0VrZTFkcGJtUnZkMXRQY0hScGIyNXpSMlZ1WlhKaGJGQmhaMlZkTGtOb2FXeGtXMDlIVUY5QmRYUnZRV05qWlhCMFMybGphMUpsY1hWbGMzUnpYUzVEYUdWamEyVmtmU2tnTDI1dmRHbG1lU0JQY0hScGIyNXpSMlZ1WlhKaGJGQmhaMlVnVDBkUVgwRjFkRzlCWTJObGNIUkxhV05yVW1WeGRXVnpkSE1nYkdWbWRHMXZkWE5sZFhBaUtRb2dJQ0FnYlhFdVpHVnNZWGtvTVRBd01Da0taVzVrQ2dweVpYUjFjbTRnWlhabGJuUmZhR0Z1Wkd4bGNnPT0iLAogY2F0ZWdvcnkgPSAiUmFpZCIsCiB0eXBlID0gImV2ZW50cyIsCiBuYW1lID0gIkpvaW5fUmFpZCIsCiBwYXR0ZXJuID0gIiMqI1lvdSBoYXZlIGpvaW5lZCB0aGUgcmFpZCMqIyIsCn0=

Code:
local mq = require('mq')

local function event_handler()
    mq.cmd("/boxr pause on")
    mq.delay(1000)
    mq.cmd("/log on")
    mq.delay(1000)
    mq.cmd("/docommand /${Me.Class.ShortName} raidmode 1")
    mq.delay(1000)
    mq.cmd("/docommand /${Me.Class.ShortName} raidassist 1")
    mq.delay(1000)
    mq.cmd("/lua stop lootly")
    mq.delay(1000)
    mq.cmd("/lua stop overseer")
    mq.delay(1000)
    mq.cmd("/notify OptionsGeneralPage ODP_ClipPlaneSlider newvalue 5")
    mq.delay(1000)
    mq.cmd("/if (!${Window[OptionsGeneralPage].Child[OGP_AutoAcceptKickRequests].Checked}) /notify OptionsGeneralPage OGP_AutoAcceptKickRequests leftmouseup")
    mq.delay(1000)
end

return event_handler


you might wanna say what it does lol
 
RogInvis
The following lem will keep your ROG always invis (hide + sneak)
Ontop, at a set aggrolvl (in %) it will trigger Escape, the line of code to set your value can be found at the top of the lem;
ESCSPE
Code:
local aggLvlPctEsc = 80
If ESCAPE is down, "hide" will be triggered.

NB: If you want to be able to be visible (i.e. to talk to quest-npc) you need to deactivate the lem, and cast anything like a clicky.

RogInvis
Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJMUzB0UUhSNWNHVWdUWEVLYkc5allXd2diWEVnUFNCeVpYRjFhWEpsS0NkdGNTY3BDZ290TFMxQWRIbHdaU0JKYlVkMWFRcHNiMk5oYkNCcFp5QTlJSEpsY1hWcGNtVW9KMGx0UjNWcEp5a0tDbXh2WTJGc0lHRm5aMHgyYkZCamRFVnpZeUE5SURnd0NncHNiMk5oYkNCbWRXNWpkR2x2YmlCVGRHOXdSRkJUS0NrS0lDQWdJRzF4TG1OdFpDZ25MM054ZFdWc1kyZ2dMMjF4Y0NCdmJpY3BDaUFnSUNCdGNTNWtaV3hoZVNneE1Da0tJQ0FnSUcxeExtTnRaQ2duTDNOeGRXVnNZMmdnTDJKdmVISWdjR0YxYzJVbktRb2dJQ0FnYlhFdVpHVnNZWGtvTVRBcENpQWdJQ0IzYUdsc1pTQnRjUzVVVEU4dVRXVXVRMkZ6ZEdsdVp5NUpSQ2dwSUdSdkNpQWdJQ0FnSUNCdGNTNWtaV3hoZVNneE1EQXBDaUFnSUNCbGJtUUtaVzVrQ2dwc2IyTmhiQ0JtZFc1amRHbHZiaUJTWlhOMWJXVkVVRk1vS1FvZ0lDQnRjUzVqYldRb0p5OXpjWFZsYkdOb0lDOXRjWEFnYjJabUp5a0tJQ0FnYlhFdVpHVnNZWGtvTVRBcENpQWdJRzF4TG1OdFpDZ25MM054ZFdWc1kyZ2dMMkp2ZUhJZ2RXNXdZWFZ6WlNjcENpQWdJRzF4TG1SbGJHRjVLREV3S1FwbGJtUUtDbXh2WTJGc0lHWjFibU4wYVc5dUlFNXZaa2hoZEdWeUtDa0tMUzB0UUdScFlXZHViM04wYVdNZ1pHbHpZV0pzWlMxdVpYaDBMV3hwYm1VNklIVnVaR1ZtYVc1bFpDMW1hV1ZzWkFvZ0lDQWdjbVYwZFhKdUlHMXhMbFJNVHk1WVFYTnphWE4wTGxoVVJuVnNiRWhoZEdWeVEyOTFiblFvS1FwbGJtUUtDbXh2WTJGc0lHWjFibU4wYVc5dUlGSmxZV1I1Um05eVNXNTJhWE1vS1FvZ0lDQWdhV1lnYm05MElHMXhMbFJNVHk1TlpTNUJZbWxzYVhSNVVtVmhaSGtvSjJocFpHVW5LU2dwSUhSb1pXNGdjbVYwZFhKdUlHWmhiSE5sSUdWdVpBb3RMU0FnSUNCcFppQnViM1FnYlhFdVZFeFBMazFsTGtGaWFXeHBkSGxTWldGa2VTZ25jMjVsWVdzbktTZ3BJSFJvWlc0Z2NtVjBkWEp1SUdaaGJITmxJR1Z1WkFvZ0lDQWdjbVYwZFhKdUlIUnlkV1VLWlc1a0NncHNiMk5oYkNCbWRXNWpkR2x2YmlCamIyNWthWFJwYjI0b0tRb2dJQ0FnYVdZZ2JtOTBJSFJ2YzNSeWFXNW5LRzF4TGxSTVR5NU5aUzVEYkdGemN5NVRhRzl5ZEU1aGJXVW9LU2tnUFQwZ0oxSlBSeWNnZEdobGJpQnlaWFIxY200Z1ptRnNjMlVnWlc1a0lDQWdJQ0FnSUNBZ0lDQWdJQzB0SUc1dklGSnZaeUJ1YnlCVFQxTUtJQ0FnSUhKbGRIVnliaUJTWldGa2VVWnZja2x1ZG1sektDa0taVzVrQ2dwc2IyTmhiQ0JtZFc1amRHbHZiaUJKYm5acGMwMWxLQ2tLSUNBZ0lHMXhMbU50WkNnbkwzTnhkV1ZzWTJnZ0wyUnZZV0pwYkdsMGVTQWljMjVsWVdzaUp5a0tJQ0FnSUcxeExtUmxiR0Y1S0RFd0tRb2dJQ0FnYlhFdVkyMWtLQ2N2YzNGMVpXeGphQ0F2Wkc5aFltbHNhWFI1SUNKb2FXUmxJaWNwQ2lBZ0lDQnRjUzVrWld4aGVTZ3hNQ2tLWlc1a0NncHNiMk5oYkNCbWRXNWpkR2x2YmlCSWFXUmxUV1VvS1FvZ0lDQWdhV1lnYm05MElHMXhMbFJNVHk1TlpTNUJZbWxzYVhSNVVtVmhaSGtvSjJocFpHVW5LU2dwSUhSb1pXNGdjbVYwZFhKdUlHVnVaQW9nSUNBZ2JYRXVZMjFrS0NjdmMzRjFaV3hqYUNBdlpHOWhZbWxzYVhSNUlDSm9hV1JsSWljcENtVnVaQW9LYkc5allXd2dablZ1WTNScGIyNGdZV04wYVc5dUtDa0tJQ0FnSUd4dlkyRnNJSE5CUVU1aGJXVWdQU0FuUlhOallYQmxKd29nSUNBZ2FXWWdUbTltU0dGMFpYSW9LU0ErSURBZ1lXNWtJRzF4TGxSTVR5NU5aUzVRWTNSQloyZHlieWdwSUQ0Z1lXZG5USFpzVUdOMFJYTmpJSFJvWlc0S0lDQWdJQ0FnSUNCcFppQnRjUzVVVEU4dVRXVXVRV3gwUVdKcGJHbDBlVkpsWVdSNUtITkJRVTVoYldVcEtDa2dkR2hsYmdvZ0lDQWdJQ0FnSUNBZ0lDQlRkRzl3UkZCVEtDa0tJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVkyMWtLQ2N2YzNGMVpXeGphQ0F2WVd4MElHRmpkQ0F4TURJbktTQWdJQzB0UlhOallYQmxDaUFnSUNBZ0lDQWdJQ0FnSUhCeWFXNTBLQ2RJYVdScGJtY2dkWE5wYm1jNklFVnpZMkZ3WlNjcENpQWdJQ0FnSUNBZ0lDQWdJQzB0SUdsbUlHMTVMblJoY21kbGREMU9VRU1nTFMwdElITm9iM1ZzWkNCaVpTQmhaR1JsWkFvZ0lDQWdJQ0FnSUNBZ0lDQnRjUzVqYldRb0p5OXpjWFZsYkdOb0lDOWhkSFJoWTJzZ2IyNG5LUW9nSUNBZ0lDQWdJQ0FnSUNCU1pYTjFiV1ZFVUZNb0tRb2dJQ0FnSUNBZ0lHVnNjMlVLSUNBZ0lDQWdJQ0FnSUNBZ1NHbGtaVTFsS0NrS0lDQWdJQ0FnSUNCbGJtUUtJQ0FnSUdWc2MyVUtJQ0FnSUNBZ0lDQkpiblpwYzAxbEtDa0tJQ0FnSUdWdVpBb2dJQ0FnYlhFdVpHVnNZWGtvTVRBcENtVnVaQW9LY21WMGRYSnVJSHRqYjI1a1puVnVZejFqYjI1a2FYUnBiMjRzSUdGamRHbHZibVoxYm1NOVlXTjBhVzl1ZlE9PSIsCiBjYXRlZ29yeSA9ICJST0ciLAogdHlwZSA9ICJjb25kaXRpb25zIiwKIG5hbWUgPSAiUm9nSW52aXMiLAp9

the full source:

Roginvis
Code:
---@type Mq
local mq = require('mq')
---@type ImGui
local ig = require('ImGui')
local aggLvlPctEsc = 80
local function StopDPS()
    mq.cmd('/squelch /mqp on')
    mq.delay(10)
    mq.cmd('/squelch /boxr pause')
    mq.delay(10)
    while mq.TLO.Me.Casting.ID() do
       mq.delay(100)
    end
end
local function ResumeDPS()
   mq.cmd('/squelch /mqp off')
   mq.delay(10)
   mq.cmd('/squelch /boxr unpause')
   mq.delay(10)
end
local function NofHater()
---@diagnostic disable-next-line: undefined-field
    return mq.TLO.XAssist.XTFullHaterCount()
end
local function ReadyForInvis()
    if not mq.TLO.Me.AbilityReady('hide')() then return false end
--    if not mq.TLO.Me.AbilityReady('sneak')() then return false end
    return true
end
local function condition()
    if not tostring(mq.TLO.Me.Class.ShortName()) == 'ROG' then return false end             -- no Rog no SOS
    return ReadyForInvis()
end
local function InvisMe()
    mq.cmd('/squelch /doability "sneak"')
    mq.delay(10)
    mq.cmd('/squelch /doability "hide"')
    mq.delay(10)
end
local function HideMe()
    if not mq.TLO.Me.AbilityReady('hide')() then return end
    mq.cmd('/squelch /doability "hide"')
end
local function action()
    local sAAName = 'Escape'
    if NofHater() > 0 and mq.TLO.Me.PctAggro() > aggLvlPctEsc then
        if mq.TLO.Me.AltAbilityReady(sAAName)() then
            StopDPS()
            mq.cmd('/squelch /alt act 102')   --Escape
            print('Hiding using: Escape')
            -- if my.target=NPC --- should be added
            mq.cmd('/squelch /attack on')
            ResumeDPS()
        else
            HideMe()
        end
    else
        InvisMe()
    end
    mq.delay(10)
end
return {condfunc=condition, actionfunc=action}
 
Last edited:
With SoF coming out tomorrow on Rizlona I will be exploring a way to have a macro or Lua event do the key manipulation for the mansion.

Hopefully I will get something figured out as I really dont want to do this on all of my toons!
 
Copying this over from the mission thread. This will get the "Hiding in Plain Sight" achievement by curing the adds in the "When One Door Opens" mission. It is written for a shaman as that is what I run, so adjust as needed based on the curer(s) in your group.

doorsham.lua
Lua:
local mq = require('mq')
local function condition()
    return mq.TLO.SpawnCount('whirling debris npc')() > 0
end
local function action()
    local cure = mq.TLO.Spell('Cure Corruption').RankName()
    mq.cmdf('/shm pause on')
    if mq.TLO.Target.CleanName() ~= 'whirling debris' then
        mq.cmd('/mqtar whirling debris npc')
        mq.delay(50)
    end
    if mq.TLO.Me.SpellReady(cure)() and not mq.TLO.Me.Casting() then
        mq.cmdf('/cast %s', cure)
        mq.delay(1000+mq.TLO.Spell(cure).MyCastTime())
    end
    mq.cmdf('/shm pause off')
end
return {condfunc=condition, actionfunc=action}
 
When One Door Opens: Multiclass Banishing the whirling debris.
It is desight to be able to be used by: BRD, CLR, PAL, SHM, DRU, RNG; but not limited to. If your class is not named but able to "cure corruption" you can extend the local table "banes" by your own.
Good for the achievement: "Hiding in Plain Sight and to get rid of the adds
NB: the "whirling debris" NPC cannot be banished within the first 10 to 15 seconds, after they spawned. On the other side, they spawn only any about 2 minutes.
Therefore there is a function included (SleepAWhile), which will delay the first attempt and any further attempts to banish by default by about 5 seconds. You can modifiy this by changing the value of "delayb4bane".
As this is done within a loop including "doevents", this time is used/can be used to do the usual business like healing, dpsing or alike in those times.

Attn: If the spell for your class is not aleady memmed, the lem will try to mem it. This may cause interferences with the used automation.
It is best to mem the spell defined within the table "banes" for your class, before you activate the lem and start the event.
Unless you are not within the right zone 'shadowhaventwo_mission', this lem should not do anything.

Attn2: You may avoid to be hit by the frequent stuns, if you face away from your tank until the mob is dead. The lem can't do the job, while you are stunned.

Import Event
Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJMUzB0UUhSNWNHVWdUWEVLYkc5allXd2diWEVnUFNCeVpYRjFhWEpsS0NkdGNTY3BDZ290TFMxQWRIbHdaU0JKYlVkMWFRcHNiMk5oYkNCcFp5QTlJSEpsY1hWcGNtVW9KMGx0UjNWcEp5a0tDbXh2WTJGc0lISmxjWFZwY21Wa1gzcHZibVVnUFNBbmMyaGhaRzkzYUdGMlpXNTBkMjlmYldsemMybHZiaWNLYkc5allXd2dZbUZ1WlY5dGIySmZibUZ0WlNBOUlDZDNhR2x5YkdsdVp5QmtaV0p5YVhNbkNteHZZMkZzSUdSbGJHRjVZalJpWVc1bElEMGdOVEF3TUNBZ0lDQWdJQ0FnSUMwdGRHRnJaWE1nYVc1MGJ5QmhZMk52ZFc1MExDQjBhR0YwSUhSb1pTQmlZVzVsYlc5aWN5QmhjbVVnTVRBdE1UVWdjMlZySUdsdVlXTjBhWFpoSUdGdVpDQnViM1FnSW1KaGJtVmhZbXhsSWlCaFpuUmxjaUJ6Y0dGM2JtbHVaeUFvYzI4Z1ltVnpkQ0IzYUdWdUlERXdNREF3TFRFMU1EQXdLUW9LYkc5allXd2dZbUZ1WlhNZ1BTQjdDaUFnSUNCQ1VrUTllMjVoYldVOUowRnlhV0VnYjJZZ1FXSnpiMngxZEdsdmJpY3NkSGx3WlQwbmMzQmxiR3duZlN3S0lDQWdJRU5NVWoxN2JtRnRaVDBuVTJGdVkzUnBabWxsWkNCQ2JHOXZaQ2NzZEhsd1pUMG5jM0JsYkd3bmZTd0tJQ0FnSUZCaGJEMTdibUZ0WlQwblEzVnlaU0JEYjNKeWRYQjBhVzl1Snl4MGVYQmxQU2R6Y0dWc2JDZDlMQW9nSUNBZ1UwaE5QWHR1WVcxbFBTZERkWEpsSUVOdmNuSjFjSFJwYjI0bkxIUjVjR1U5SjNOd1pXeHNKMzBzQ2lBZ0lDQkVVbFU5ZTI1aGJXVTlKMU5oYm1OMGFXWnBaV1FnUW14dmIyUW5MSFI1Y0dVOUozTndaV3hzSjMwc0NpQWdJQ0JTVGtjOWUyNWhiV1U5SjB4MWJtRnlJRUpoYkcwbkxIUjVjR1U5SjNOd1pXeHNKMzBLZlFvS2JHOWpZV3dnWm5WdVkzUnBiMjRnVTJ4bFpYQkJWMmhwYkdVb2JYTXBDaUFnSUd4dlkyRnNJR3h2YjNCMGFXMWxJRDBnTVRBS0lDQWdiRzlqWVd3Z2RHOTBkR2x0WlNBOUlEQUtJQ0FnZDJocGJHVWdkRzkwZEdsdFpTQThJRzF6SUdSdkNpQWdJQ0J0Y1M1a1pXeGhlU2hzYjI5d2RHbHRaU2tLSUNBZ0lHMXhMbVJ2WlhabGJuUnpLQ2tLSUNBZ0lIUnZkSFJwYldVZ1BTQjBiM1IwYVcxbElDc2diRzl2Y0hScGJXVUtJQ0FnWlc1a0NtVnVaQW9LYkc5allXd2dablZ1WTNScGIyNGdVM1J2Y0VSUVV5Z3BDaUFnSUNCdGNTNWpiV1FvSnk5emNYVmxiR05vSUM5dGNYQWdiMjRuS1FvZ0lDQWdiWEV1WkdWc1lYa29NVEFwQ2lBZ0lDQnBaaUJ0Y1M1VVRFOHVUV1V1UTJ4aGMzTXVVMmh2Y25ST1lXMWxLQ2tnUFQwZ0owSlNSQ2NnZEdobGJnb2dJQ0FnSUNBZ0lHMXhMbU50WkNnbkwzTnhkV1ZzWTJnZ0wzUjNhWE4wSUc5bVppY3BDaUFnSUNBZ0lDQWdiWEV1WkdWc1lYa29NVEFwQ2lBZ0lDQWdJQ0FnYlhFdVkyMWtLQ2N2YzNGMVpXeGphQ0F2YzNSdmNITnZibWNuS1FvZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RFd0tRb2dJQ0FnWlc1a0NpQWdJQ0F0TFcxeExtTnRaQ2duTDJGMGRHRmpheUJ2Wm1ZbktTQWdMaTR1SUcxaGVXSmxJR1JsWVdOMGFYWmhkR1VnWVhSMFlXTnJJR0oxZENCellYWmxJSE4wWVhSbElIUnZJSEpsWVdOMGFYWmhkR1VnWVhRZ1UzUmhjblJFY0hNS0lDQWdJQzB0YlhFdVpHVnNZWGtvTVRBcENpQWdJQ0J0Y1M1amJXUW9KeTl6Y1hWbGJHTm9JQzlpYjNoeUlIQmhkWE5sSnlrS0lDQWdJRzF4TG1SbGJHRjVLREV3S1FvZ0lDQWdkMmhwYkdVZ2JYRXVWRXhQTGsxbExrTmhjM1JwYm1jdVNVUW9LU0JrYndvZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTWpBd0tRb2dJQ0FnWlc1a0NtVnVaQXBzYjJOaGJDQm1kVzVqZEdsdmJpQlNaWE4xYldWRVVGTW9LUW9nSUNCdGNTNWpiV1FvSnk5emNYVmxiR05vSUM5dGNYQWdiMlptSnlrS0lDQWdiWEV1WkdWc1lYa29NVEFwQ2lBZ0lHbG1JRzF4TGxSTVR5NU5aUzVEYkdGemN5NVRhRzl5ZEU1aGJXVW9LU0E5UFNBblFsSkVKeUIwYUdWdUNpQWdJQ0J0Y1M1amJXUW9KeTl6Y1hWbGJHTm9JQzkwZDJsemRDQnZiaWNwQ2lBZ0lDQnRjUzVrWld4aGVTZ3hNQ2tLSUNBZ1pXNWtDaUFnSUcxeExtTnRaQ2duTDNOeGRXVnNZMmdnTDJKdmVISWdkVzV3WVhWelpTY3BDaUFnSUcxeExtUmxiR0Y1S0RFd0tRcGxibVFLYkc5allXd2dablZ1WTNScGIyNGdiMjVmYkc5aFpDZ3BDaUFnSUNCcFppQnRjUzVVVEU4dVdtOXVaUzVUYUc5eWRFNWhiV1VvS1NCK1BTQnlaWEYxYVhKbFpGOTZiMjVsSUhSb1pXNGdjbVYwZFhKdUlHVnVaQW9nSUNBZ2JHOWpZV3dnWW1GdVpTQTlJR0poYm1WelcyMXhMbFJNVHk1TlpTNURiR0Z6Y3k1VGFHOXlkRTVoYldVb0tWMEtJQ0FnSUd4dlkyRnNJSE53Wld4c2JtRnRaU0E5SUcxeExsUk1UeTVUY0dWc2JDaDBiM04wY21sdVp5aGlZVzVsTG01aGJXVXBLUzVTWVc1clRtRnRaU2dwQ2lBZ0lDQXRMWEJ5YVc1MEtITndaV3hzYm1GdFpTa0tJQ0FnSUdsbUlHSmhibVVnWVc1a0lHSmhibVV1ZEhsd1pTQTlQU0FuYzNCbGJHd25JSFJvWlc0S0lDQWdJQ0FnSUNCcFppQnRjUzVVVEU4dVRXVXVSMlZ0S0hOd1pXeHNibUZ0WlNrb0tTQStJREFnZEdobGJpQnlaWFIxY200Z1pXNWtJQ0F0TFNCVGFHOTFiR1FnWW1VZ2JXVnRiV1ZrSUdGc2NtVmhaSGtLSUNBZ0lDQWdJQ0JUZEc5d1JGQlRLQ2tLSUNBZ0lDQWdJQ0J0Y1M1amJXUm1LQ2N2YldWdGMzQmxiR3dnTVRNZ0lpVnpJaWNzSUhOd1pXeHNibUZ0WlNrS0lDQWdJQ0FnSUNCdGNTNWtaV3hoZVNnbk5ITW5LUW9nSUNBZ0lDQWdJRzF4TGxSTVR5NVhhVzVrYjNjb0oxTndaV3hzUW05dmExZHVaQ2NwTGtSdlEyeHZjMlVvS1FvZ0lDQWdJQ0FnSUZKbGMzVnRaVVJRVXlncENpQWdJQ0JsYm1RS1pXNWtDaTB0TFVCeVpYUjFjbTRnWW05dmJHVmhiaUJBVW1WMGRYSnVjeUIwY25WbElHbG1JSFJvWlNCaFkzUnBiMjRnYzJodmRXeGtJR1pwY21Vc0lHOTBhR1Z5ZDJselpTQm1ZV3h6WlM0S2JHOWpZV3dnWm5WdVkzUnBiMjRnWTI5dVpHbDBhVzl1S0NrS0lDQWdJSEpsZEhWeWJpQnRjUzVVVEU4dVdtOXVaUzVUYUc5eWRFNWhiV1VvS1NBOVBTQnlaWEYxYVhKbFpGOTZiMjVsSUdGdVpDQnRjUzVVVEU4dVUzQmhkMjVEYjNWdWRDZ29KeVZ6SUc1d1l5Y3BPbVp2Y20xaGRDaGlZVzVsWDIxdllsOXVZVzFsS1Nrb0tTQStJREFLSUNBZ0lDMHRjbVYwZFhKdUlIUnlkV1VLWlc1a0NteHZZMkZzSUdaMWJtTjBhVzl1SUhSaGNtZGxkRjlpWVc1bFgyMXZZaWdwQ2lBZ0lDQnBaaUJ0Y1M1VVRFOHVWR0Z5WjJWMExrTnNaV0Z1VG1GdFpTZ3BJSDQ5SUdKaGJtVmZiVzlpWDI1aGJXVWdkR2hsYmdvZ0lDQWdJQ0FnSUcxeExtTnRaR1lvSnk5dGNYUmhjaUFsY3lCdWNHTW5MQ0JpWVc1bFgyMXZZbDl1WVcxbEtRb2dJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEVXdLUW9nSUNBZ1pXNWtDbVZ1WkFwc2IyTmhiQ0JtZFc1amRHbHZiaUJqWVhOMEtITndaV3hzS1FvZ0lDQWdiWEV1WTIxa1ppZ25MMk5oYzNRZ0pYTW5MQ0J6Y0dWc2JDNVNZVzVyVG1GdFpTZ3BLUW9nSUNBZ2JYRXVaR1ZzWVhrb05UQXJjM0JsYkd3dVRYbERZWE4wVkdsdFpTZ3BLUXBsYm1RS2JHOWpZV3dnWm5WdVkzUnBiMjRnZFhObFgyRmhLR0ZoS1FvZ0lDQWdiWEV1WTIxa1ppZ25MMkZzZENCaFkzUnBkbUYwWlNBbGN5Y3NJR0ZoTGtsRUtDa3BDaUFnSUNCdGNTNWtaV3hoZVNnMU1DdGhZUzVUY0dWc2JDNURZWE4wVkdsdFpTZ3BLUXBsYm1RS2JHOWpZV3dnWm5WdVkzUnBiMjRnWW1GdVpWOXlaV0ZrZVNoaVlXNWxLUW9nSUNBZ2FXWWdZbUZ1WlM1MGVYQmxJRDA5SUNkemNHVnNiQ2NnZEdobGJnb2dJQ0FnSUNBZ0lISmxkSFZ5YmlCdGNTNVVURTh1VFdVdVUzQmxiR3hTWldGa2VTaGlZVzVsTG01aGJXVXBJR0Z1WkNCdWIzUWdiWEV1VkV4UExrMWxMa05oYzNScGJtY29LUW9nSUNBZ1pXeHpaV2xtSUdKaGJtVXVkSGx3WlNBOVBTQW5ZV0VuSUhSb1pXNEtJQ0FnSUNBZ0lDQnlaWFIxY200Z2JYRXVWRXhQTGsxbExrRnNkRUZpYVd4cGRIbFNaV0ZrZVNoaVlXNWxMbTVoYldVcElHRnVaQ0J1YjNRZ2JYRXVWRXhQTGsxbExrTmhjM1JwYm1jb0tRb2dJQ0FnWlc1a0NtVnVaQXBzYjJOaGJDQm1kVzVqZEdsdmJpQmhZM1JwYjI0b0tRb2dJQ0FnYkc5allXd2diWGxmWTJ4aGMzTWdQU0J0Y1M1VVRFOHVUV1V1UTJ4aGMzTXVVMmh2Y25ST1lXMWxLQ2tLSUNBZ0lHeHZZMkZzSUdKaGJtVWdQU0JpWVc1bGMxdHRlVjlqYkdGemMxMEtJQ0FnSUMwdElHbG1JRzV2ZENCaElHSmhibVVnWTJ4aGMzTXNJSEpsZEhWeWJnb2dJQ0FnYVdZZ2JtOTBJR0poYm1VZ2RHaGxiaUJ5WlhSMWNtNGdaVzVrQ2lBZ0lDQXRMU0JwWmlCaVlXNWxJR0ZpYVd4cGRIa2dhWE51SjNRZ2NtVmhaSGtzSUhKbGRIVnliZ29nSUNBZ2FXWWdiWGxmWTJ4aGMzTWdmajBnSjBKU1JDY2dZVzVrSUc1dmRDQmlZVzVsWDNKbFlXUjVLR0poYm1VcElIUm9aVzRnY21WMGRYSnVJR1Z1WkFvZ0lDQWdVMnhsWlhCQlYyaHBiR1VvWkdWc1lYbGlOR0poYm1VcENpQWdJQ0JUZEc5d1JGQlRLQ2tLSUNBZ0lIUmhjbWRsZEY5aVlXNWxYMjF2WWlncENpQWdJQ0JwWmlCaVlXNWxMblI1Y0dVZ1BUMGdKM053Wld4c0p5QjBhR1Z1Q2lBZ0lDQWdJQ0FnWTJGemRDaHRjUzVVVEU4dVUzQmxiR3dvWW1GdVpTNXVZVzFsS1NrS0lDQWdJR1ZzYzJVS0lDQWdJQ0FnSUNCMWMyVmZZV0VvYlhFdVZFeFBMazFsTGtGc2RFRmlhV3hwZEhrb1ltRnVaUzV1WVcxbEtTa0tJQ0FnSUdWdVpBb2dJQ0FnZDJocGJHVWdiWEV1VkV4UExrMWxMa05oYzNScGJtY29LU0JrYndvZ0lDQWdJQ0FnSUcxeExtUnZaWFpsYm5SektDa0tJQ0FnSUNBZ0lDQnRjUzVrWld4aGVTZzFNQ2tLSUNBZ0lHVnVaQW9nSUNBZ1VtVnpkVzFsUkZCVEtDa0taVzVrQ25KbGRIVnliaUI3YjI1c2IyRmtQVzl1WDJ4dllXUXNJR052Ym1SbWRXNWpQV052Ym1ScGRHbHZiaXdnWVdOMGFXOXVablZ1WXoxaFkzUnBiMjU5IiwKIGNhdGVnb3J5ID0gIk5vUyIsCiB0eXBlID0gImNvbmRpdGlvbnMiLAogbmFtZSA9ICJPbmVEb29yQmFuaXNoIiwKfQ==


full source code
Full Source Code
Lua:
---@type Mq
local mq = require('mq')

---@type ImGui
local ig = require('ImGui')

local required_zone = 'shadowhaventwo_mission'
local bane_mob_name = 'whirling debris'
local delayb4bane = 5000         --takes into account, that the banemobs are 10-15 sek inactive and not "baneable" after spawning (so best when 10000-15000)

local banes = {
    BRD={name='Aria of Absolution',type='spell'},
    CLR={name='Sanctified Blood',type='spell'},
    Pal={name='Cure Corruption',type='spell'},
    SHM={name='Cure Corruption',type='spell'},
    DRU={name='Sanctified Blood',type='spell'},
    RNG={name='Lunar Balm',type='spell'}
}

local function SleepAWhile(ms)
   local looptime = 10
   local tottime = 0
   while tottime < ms do
    mq.delay(looptime)
    mq.doevents()
    tottime = tottime + looptime
   end
end

local function StopDPS()
    mq.cmd('/squelch /mqp on')
    mq.delay(10)
    if mq.TLO.Me.Class.ShortName() == 'BRD' then
        mq.cmd('/squelch /twist off')
        mq.delay(10)
        mq.cmd('/squelch /stopsong')
        mq.delay(10)
    end
    --mq.cmd('/attack off')  ... maybe deactivate attack but save state to reactivate at StartDps
    --mq.delay(10)
    mq.cmd('/squelch /boxr pause')
    mq.delay(10)
    while mq.TLO.Me.Casting.ID() do
       mq.delay(200)
    end
end
local function ResumeDPS()
   mq.cmd('/squelch /mqp off')
   mq.delay(10)
   if mq.TLO.Me.Class.ShortName() == 'BRD' then
    mq.cmd('/squelch /twist on')
    mq.delay(10)
   end
   mq.cmd('/squelch /boxr unpause')
   mq.delay(10)
end
local function on_load()
    if mq.TLO.Zone.ShortName() ~= required_zone then return end
    local bane = banes[mq.TLO.Me.Class.ShortName()]
    local spellname = mq.TLO.Spell(tostring(bane.name)).RankName()
    --print(spellname)
    if bane and bane.type == 'spell' then
        if mq.TLO.Me.Gem(spellname)() > 0 then return end  -- Should be memmed already
        StopDPS()
        mq.cmdf('/memspell 13 "%s"', spellname)
        mq.delay('4s')
        mq.TLO.Window('SpellBookWnd').DoClose()
        ResumeDPS()
    end
end
---@return boolean @Returns true if the action should fire, otherwise false.
local function condition()
    return mq.TLO.Zone.ShortName() == required_zone and mq.TLO.SpawnCount(('%s npc'):format(bane_mob_name))() > 0
    --return true
end
local function target_bane_mob()
    if mq.TLO.Target.CleanName() ~= bane_mob_name then
        mq.cmdf('/mqtar %s npc', bane_mob_name)
        mq.delay(50)
    end
end
local function cast(spell)
    mq.cmdf('/cast %s', spell.RankName())
    mq.delay(50+spell.MyCastTime())
end
local function use_aa(aa)
    mq.cmdf('/alt activate %s', aa.ID())
    mq.delay(50+aa.Spell.CastTime())
end
local function bane_ready(bane)
    if bane.type == 'spell' then
        return mq.TLO.Me.SpellReady(bane.name) and not mq.TLO.Me.Casting()
    elseif bane.type == 'aa' then
        return mq.TLO.Me.AltAbilityReady(bane.name) and not mq.TLO.Me.Casting()
    end
end
local function action()
    local my_class = mq.TLO.Me.Class.ShortName()
    local bane = banes[my_class]
    -- if not a bane class, return
    if not bane then return end
    -- if bane ability isn't ready, return
    if my_class ~= 'BRD' and not bane_ready(bane) then return end
    SleepAWhile(delayb4bane)
    StopDPS()
    target_bane_mob()
    if bane.type == 'spell' then
        cast(mq.TLO.Spell(bane.name))
    else
        use_aa(mq.TLO.Me.AltAbility(bane.name))
    end
    while mq.TLO.Me.Casting() do
        mq.doevents()
        mq.delay(50)
    end
    ResumeDPS()
end
return {onload=on_load, condfunc=condition, actionfunc=action}
 
Last edited:
Hello LEM community!

The MQ2Grind plugin needs help pausing and resuming when group members run low on mana. Here is the mq2react config they provided. Can I get some assistance converting this to LEM?
Here is link to the original post: https://www.redguides.com/community/threads/mq2grind.75417/post-540616

mq2react ini
Code:
servername:
ShadowKnightName:
    GrindP: enabled
    GrindR: disabled

reacts:
GrindP:
    action: >-
      /multiline ; /shd mode 4; /grind pause; /react enable GrindR; /dex
      ClericName /clr mode 1; /react disable GrindP
    condition: >-
      ${Group.Member[ClericName].PctMana} < 20 && ${Grind.Active}
  GrindR:
    action: >-
      /multiline ; /shd mode 7; /grind resume; /react enable GrindP; /dex
      ClericName /clr mode 2; /stand; /react disable GrindR
    condition: >-
      ${Group.Member[ClericName].PctMana} > 95 && ${Grind.Paused}
 
Something like this might work as a combination of both of those, but also for whatever class the driver is, and any healer class (no, this is not even remotely tested)

Lua:
local mq = require('mq')

local myClass = mq.TLO.Me.Class.ShortName()
local healerName = ''

local function condition()
    local groupHealer = mq.TLO.Spawn('group healer')
    if not groupHealer() then return false end
    local healerName = groupHealer.CleanName()
    local healerMana = mq.TLO.Group.Member(healerName).PctMana() or 0
    if mq.TLO.Grind.Active() then
        return healerMana < 20
    elseif mq.TLO.Grind.Paused() then
        return healerMana > 95
    end
end

local function action()
    if mq.TLO.Grind.Active() then
        mq.cmdf('/%s mode 4', myClass)
        mq.cmd('/grind pause')
        mq.cmdf('/dex %s /$\{Me.Class.ShortName} mode 1', healerName)
    elseif mq.TLO.Grind.Paused() then
        mq.cmdf('/%s mode 7', myClass)
        mq.cmd('/grind resume')
        mq.cmdf('/dex %s /multiline ; /$\{Me.Class.ShortName} mode 2; /stand;', clericName)
    end
end

return {condfunc=condition, actionfunc=action}
 
Thanks for the fast reply @aquietone !

After some more work with the grind plugin, I think the condition should be switched to using this tlo Group.LowMana[20] so that all the group member's mana is factored, which includes the CC/Mezzer and DPS. Since grind can get the group into hairy situations with 3 or 4 adds, its not a bad thing to make sure the group has a full tank before hitting the next step/waypoint.
So how would this look inside Lua?


Condition Function
Lua:
local function condition()
    if mq.TLO.Grind.Active() then
        return mq.TLO.Group.LowMana[20]() > 1
    elseif mq.TLO.Grind.Paused() then
        return mq.TLO.Group.LowMana[95]() < 1
    end
end
 
Thanks for the fast reply @aquietone !

After some more work with the grind plugin, I think the condition should be switched to using this tlo Group.LowMana[20] so that all the group member's mana is factored, which includes the CC/Mezzer and DPS. Since grind can get the group into hairy situations with 3 or 4 adds, its not a bad thing to make sure the group has a full tank before hitting the next step/waypoint.
So how would this look inside LUA?


Condition Function
Lua:
local function condition()
    if mq.TLO.Grind.Active() then
        return mq.TLO.Group.LowMana[20]() > 1
    elseif mq.TLO.Grind.Paused() then
        return mq.TLO.Group.LowMana[95]() < 1
    end
end
Does not work... is the square brackets causing an issue?
 
I think I got it! Tested and functioning, but I am not a coder, so I invite all feedback to help make this more efficient. Thanks to aquietone for providing a starting point and examples I could learn from.
Grind LEM Event
Lua:
local mq = require('mq')

local function condition()
    if mq.TLO.Grind.Active() then
        if not mq.TLO.Grind.Paused() then
            return mq.TLO.Group.LowMana(20)() > 0
        elseif mq.TLO.Grind.Paused() then
            return mq.TLO.Group.LowMana(95)() < 1
        end
   end
end

local function action()
    if not mq.TLO.Grind.Paused() then
        mq.cmd('/grind pause')
    elseif mq.TLO.Grind.Paused() then
        mq.cmd('/grind resume')
    end
end

return {condfunc=condition, actionfunc=action}
 
HI all,

Trying to write a Lua for LEM. Specifically for the Grikaw Mission. I am "Lifting & Shifting" the Lua for the Aten Hen Ra Mission in TOL (i.e text is said and toon runs to set location) but I just tried and it failed. The toon called out didnt react. Could anyone please assist ?



"pattern" #*#Weakness Evinced devitalizes the skin of#1# #*#

local mq = require('mq')
local function event_handler(line, target)
local my_class = mq.TLO.Me.Class.ShortName()
local i_am_ma = mq.TLO.Group.Member(0).MainAssist()
local my_name = mq.TLO.Me.CleanName()
local ma_name = mq.TLO.Group.MainAssist.CleanName()
if not i_am_ma and (target == my_name or target == ma_name) then
if my_class == 'BER' and mq.TLO.Me.ActiveDisc.Name() == mq.TLO.Spell('Frenzied Resolve Discipline').RankName() then
mq.cmd('/stopdisc')
end
mq.cmdf('/%s mode 0', my_class)
mq.cmd('/mqp on')
mq.cmd('/twist off')
mq.cmd('/timed 5 /afollow off')
mq.cmd('/nav stop')
mq.cmd('/target clear')
mq.delay(100)
mq.cmd('/nav locxyz 832.08 -635.60 186.13')
mq.delay(15000)
mq.cmdf('/%s mode 2', my_class)
mq.cmd('/mqp off')
mq.cmd('/twist on')
end
end
return {eventfunc=event_handler}

Edit: I have a feeling the trigger may not be correct? I've tried in MQ2 Events and can't get them to move either.

1673464062258.png

The trigger (in my opinion or the react I want to happen) is on "Weakness Evinced Devitalizes the skin of (playername)" then upon this message, "playername" runs to location XYZ.


Thanks again..
 
Last edited:
I think I got it! Tested and functioning, but I am not a coder, so I invite all feedback to help make this more efficient. Thanks to aquietone for providing a starting point and examples I could learn from.
Grind LEM Event
Lua:
local mq = require('mq')

local function condition()
    if mq.TLO.Grind.Active() then
        if not mq.TLO.Grind.Paused() then
            return mq.TLO.Group.LowMana(20)() > 0
        elseif mq.TLO.Grind.Paused() then
            return mq.TLO.Group.LowMana(95)() < 1
        end
   end
end

local function action()
    if not mq.TLO.Grind.Paused() then
        mq.cmd('/grind pause')
    elseif mq.TLO.Grind.Paused() then
        mq.cmd('/grind resume')
    end
end

return {condfunc=condition, actionfunc=action}
So, this is a good start I guess, but the react you started from switched CWTN modes to take advantage of swift meditation, ensuring you are not sitting there for a long time regaining mana. Try this at level 95-100, and you will see what I mean with regards to how long it will take to med to 95, and how often you will pause.
 
I modified the monster mana controlling LEMs to just be a pause and wait in OOC for mages or other DPS casters. Thought I'd share.

Name: AllManaOn

Export string
Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENncHNiMk5oYkNCbWRXNWpkR2x2YmlCdmJsOXNiMkZrS0NrS0lDQWdJRzF4TG1OdFpDZ25MMmNnU0dWaFpITWdkWEFzSUdsbUlFa2daMlYwSUd4dmR5QnZiaUJ0WVc1aElFa2djM1JoY25RZ2JYVnlaR1Z5YVc1bklHMXZibk4wWlhKeklHWnZjaUJ0WVc1aExpY3BDbVZ1WkFvS0xTMHRRSEpsZEhWeWJpQmliMjlzWldGdUlFQlNaWFIxY201eklIUnlkV1VnYVdZZ2RHaGxJR0ZqZEdsdmJpQnphRzkxYkdRZ1ptbHlaU3dnYjNSb1pYSjNhWE5sSUdaaGJITmxMZ3BzYjJOaGJDQm1kVzVqZEdsdmJpQmpiMjVrYVhScGIyNG9LUW9nSUNBZ2NtVjBkWEp1SUcxeExsUk1UeTVOWlM1UVkzUk5ZVzVoS0NrZ1BDQXhNQ0JoYm1RZ2JYRXVWRXhQTGsxbExrTnZiV0poZEZOMFlYUmxLQ2tnZmowZ0owTlBUVUpCVkNjS1pXNWtDZ3BzYjJOaGJDQm1kVzVqZEdsdmJpQmhZM1JwYjI0b0tRb2dJQ0FnYlhFdVkyMWtaaWduTDJjZ1RYa2diV0Z1WVNCcGN5QmhkQ0FsY3lCemJ5QkpJR0Z0SUdkdmFXNW5JSEpsYzNRdUp5d2diWEV1VkV4UExrMWxMbEJqZEUxaGJtRW9LU2tLSUNBZ0lHMXhMbU50WkNnbkwyeGxiU0JqYjI1a0lFRnNiRTFoYm1GUGJpQXdKeWtLSUNBZ0lHMXhMbU50WkNnbkwyeGxiU0JqYjI1a0lFRnNiRTFoYm1GUFptWWdNU2NwQ2dvZ0lDQWdiWEV1WTIxa0tDY3ZjM0YxWld4amFDQXZaRzlqYjIxdFlXNWtJQzlpYjNoeUlIQmhkWE5sSnlrS0lDQWdJR2xtSUNodGNTNVVURTh1VFdVdVUzUmhibVJwYm1jb0tTQmhibVFnYm05MElHMXhMbFJNVHk1TlpTNURZWE4wYVc1bkxrbEVLQ2twSUhSb1pXNEtJQ0FnSUNBZ0lDQnRjUzVVVEU4dVRXVXVVMmwwS0NrS0lDQWdJR1Z1WkFwbGJtUUtDbkpsZEhWeWJpQjdiMjVzYjJGa1BXOXVYMnh2WVdRc0lHTnZibVJtZFc1alBXTnZibVJwZEdsdmJpd2dZV04wYVc5dVpuVnVZejFoWTNScGIyNTkiLAogY2F0ZWdvcnkgPSAiQWxsTWFuYSIsCiB0eXBlID0gImNvbmRpdGlvbnMiLAogbmFtZSA9ICJBbGxNYW5hT24iLAp9

AllManaOn
Lua:
local mq = require('mq')

local function on_load()
    mq.cmd('/g Heads up, if I get low on mana I get really tired.')
end

---@return boolean @Returns true if the action should fire, otherwise false.
local function condition()
    return mq.TLO.Me.PctMana() < 10 and mq.TLO.Me.CombatState() ~= 'COMBAT'
end

local function action()
    mq.cmdf('/g My mana is at %s so I am going rest.', mq.TLO.Me.PctMana())
    mq.cmd('/lem cond AllManaOn 0')
    mq.cmd('/lem cond AllManaOff 1')

    mq.cmd('/squelch /docommand /boxr pause')
    if (mq.TLO.Me.Standing() and not mq.TLO.Me.Casting.ID()) then
        mq.TLO.Me.Sit()
    end
end

return {onload=on_load, condfunc=condition, actionfunc=action}

Name: AllManaOff

Export String
Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENncHNiMk5oYkNCbWRXNWpkR2x2YmlCdmJsOXNiMkZrS0NrS0lDQWdJR2xtSUNodGNTNVVURTh1VFdVdVEyeGhjM011VTJodmNuUk9ZVzFsS0NrZ2ZqMGdKMDFCUnljcElIUm9aVzRLSUNBZ0lDQWdJQ0J0Y1M1amJXUW9KeTluSUVrZ1lXMGdibTkwSUdFZ2JXRm5aU0J6YnlCSklHTmhibTV2ZENCa2J5QjBhR0YwTGljcENpQWdJQ0FnSUNBZ2NtVjBkWEp1SUFvZ0lDQWdaVzVrQ2lBZ0lDQnRjUzVqYldRb0p5OW5JRmRoYVhScGJtY2dabTl5SUcxaGJtRWdkRzhnWW1VZ2IzWmxjaUE1TUNVdUp5a0taVzVrQ2dvdExTMUFjbVYwZFhKdUlHSnZiMnhsWVc0Z1FGSmxkSFZ5Ym5NZ2RISjFaU0JwWmlCMGFHVWdZV04wYVc5dUlITm9iM1ZzWkNCbWFYSmxMQ0J2ZEdobGNuZHBjMlVnWm1Gc2MyVXVDbXh2WTJGc0lHWjFibU4wYVc5dUlHTnZibVJwZEdsdmJpZ3BDaUFnSUNCeVpYUjFjbTRnYlhFdVZFeFBMazFsTGxCamRFMWhibUVvS1NBK0lEa3dJRzl5SUcxeExsUk1UeTVOWlM1RGIyMWlZWFJUZEdGMFpTZ3BJRDA5SUNkRFQwMUNRVlFuSUc5eUlHMXhMbFJNVHk1TlpTNVRkR0Z1WkdsdVp5Z3BDbVZ1WkFvS2JHOWpZV3dnWm5WdVkzUnBiMjRnWVdOMGFXOXVLQ2tLSUNBZ0lHbG1JQ2h0Y1M1VVRFOHVUV1V1VUdOMFRXRnVZU2dwSUQ0Z09UQWdiM0lnYlhFdVZFeFBMazFsTGtOdmJXSmhkRk4wWVhSbEtDa2dQVDBnSjBOUFRVSkJWQ2NwSUhSb1pXNEtJQ0FnSUNBZ0lDQnRjUzVqYldRb0p5OW5JRnAxWjNwMVp5QlhiM0pyWENkeklHUnZibVV1SnlrS0lDQWdJQ0FnSUNCdGNTNWpiV1FvSnk5c1pXMGdZMjl1WkNCQmJHeE5ZVzVoVDI0Z01TY3BDaUFnSUNBZ0lDQWdiWEV1WTIxa0tDY3ZiR1Z0SUdOdmJtUWdRV3hzVFdGdVlVOW1aaUF3SnlrS0lDQWdJQ0FnSUNCdGNTNWpiV1FvSnk5emNYVmxiR05vSUM5a2IyTnZiVzFoYm1RZ0wySnZlSElnZFc1d1lYVnpaU2NwQ2lBZ0lDQmxibVFLSUNBZ0lHbG1JQ2h0Y1M1VVRFOHVUV1V1VTNSaGJtUnBibWNvS1NCaGJtUWdibTkwSUcxeExsUk1UeTVOWlM1RFlYTjBhVzVuTGtsRUtDa3BJSFJvWlc0S0lDQWdJQ0FnSUNCdGNTNVVURTh1VFdVdVUybDBLQ2tLSUNBZ0lHVnVaQW9LWlc1a0NncHlaWFIxY200Z2UyOXViRzloWkQxdmJsOXNiMkZrTENCamIyNWtablZ1WXoxamIyNWthWFJwYjI0c0lHRmpkR2x2Ym1aMWJtTTlZV04wYVc5dWZRPT0iLAogY2F0ZWdvcnkgPSAiQWxsTWFuYSIsCiB0eXBlID0gImNvbmRpdGlvbnMiLAogbmFtZSA9ICJBbGxNYW5hT2ZmIiwKfQ==

AllManaOff
Lua:
local mq = require('mq')

local function on_load()
    if (mq.TLO.Me.Class.ShortName() ~= 'MAG') then
        mq.cmd('/g I am not a mage so I cannot do that.')
        return
    end
    mq.cmd('/g Waiting for mana to be over 90%.')
end

---@return boolean @Returns true if the action should fire, otherwise false.
local function condition()
    return mq.TLO.Me.PctMana() > 90 or mq.TLO.Me.CombatState() == 'COMBAT' or mq.TLO.Me.Standing()
end

local function action()
    if (mq.TLO.Me.PctMana() > 90 or mq.TLO.Me.CombatState() == 'COMBAT') then
        mq.cmd('/g Zugzug Work\'s done.')
        mq.cmd('/lem cond AllManaOn 1')
        mq.cmd('/lem cond AllManaOff 0')
        mq.cmd('/squelch /docommand /boxr unpause')
    end
    if (mq.TLO.Me.Standing() and not mq.TLO.Me.Casting.ID()) then
        mq.TLO.Me.Sit()
    end

end

return {onload=on_load, condfunc=condition, actionfunc=action}

The idea is that AllManaOn will wait for mana to get low enough, and then if it gets out of combat it will sit and pause macros/cwtn using Boxr and enable the AllManaOff and disable itself.

AllManaOff will watch for mana above 90 or combat getting initiated while paused. If fired it will unpause the macro, disable itself, and renable AllManaOn to reset the cycle.

The use case is purely for DPS caster classes I think that are in the 60-80s. I've had it running for 8 hours or so and no issues yet. Just don't try to move and it only works for groups doing the homesteading thing.
 
While Rizlona is in SoF and before we get AA mod rod, here is a LEM I am trying out.

If you are casting and get GoM it will pause CWTN and cast mass mod rod if you don't have one.

Name: ModRodGoM

Export String:
Export String
Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENnb3RMUzFBY21WMGRYSnVJR0p2YjJ4bFlXNGdRRkpsZEhWeWJuTWdkSEoxWlNCcFppQjBhR1VnWVdOMGFXOXVJSE5vYjNWc1pDQm1hWEpsTENCdmRHaGxjbmRwYzJVZ1ptRnNjMlV1Q214dlkyRnNJR1oxYm1OMGFXOXVJRzl1WDJ4dllXUW9LUW9nSUNBZ0xTMGdVR1Z5Wm05eWJTQmhibmtnYVc1cGRHbGhiQ0J6WlhSMWNDQm9aWEpsSUhkb1pXNGdkR2hsSUdWMlpXNTBJR2x6SUd4dllXUmxaQzRLWlc1a0NncHNiMk5oYkNCbWRXNWpkR2x2YmlCamIyNWthWFJwYjI0b0tRb2dJQ0FnY21WMGRYSnVJQ2dnYlhFdVZFeFBMazFsTGxOdmJtY29KMGRwWm5RZ2IyWWdUV0Z1WVNBb09EQXBKeWt1U1VRb0tTQmhibVFnYm05MElHMXhMbFJNVHk1R2FXNWtTWFJsYlNnblVtOWtJRzltSUZCeWFXMWxJRlJ5WVc1emRtVnlaMlZ1WTJVbktTZ3BJR0Z1WkNCdGNTNVVURTh1VFdVdVVHTjBUV0Z1WVNncElENGdNalVnS1FwbGJtUUtDbXh2WTJGc0lHWjFibU4wYVc5dUlHRmpkR2x2YmlncENpQWdJQ0JzYjJOaGJDQnRZWE56VW05a0lEMGdKMDFoYzNNZ1VISnBiV1VnVkhKaGJuTjJaWEpuWlc1alpTQlNheTRnU1VrbkNnb2dJQ0FnYVdZZ0tHMXhMbFJNVHk1RGRYSnpiM0l1U1VRb0tTa2dkR2hsYmdvZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDJGMWRHOXBiblpsYm5SdmNua25LUW9nSUNBZ0lDQWdJRzF4TG1SbGJHRjVLRElwQ2lBZ0lDQWdJQ0FnYlhFdVkyMWtLQ2N2WVhWMGIybHVkbVZ1ZEc5eWVTY3BDaUFnSUNCbGJtUUtDaUFnSUNBdExTQkpiWEJzWlcxbGJuUWdkR2hsSUdGamRHbHZiaUIwYnlCd1pYSm1iM0p0SUdobGNtVXVDaUFnSUNCdGNTNWpiV1FvSnk5bklGUmhhMlVnYlhrZ2NtOWtMaWNwQ2lBZ0lDQnRjUzVqYldRb0p5OWtiMk52YlcxaGJtUWdMMkp2ZUhJZ2NHRjFjMlVuS1FvZ0lDQWdiWEV1WkdWc1lYa29NVEFwQ2lBZ0lDQjNhR2xzWlNCdGNTNVVURTh1VFdVdVEyRnpkR2x1Wnk1SlJDZ3BJQ0J2Y2lCdWIzUWdiWEV1VkV4UExrMWxMbE53Wld4c1VtVmhaSGtvYldGemMxSnZaQ2tnWkc4S0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RJd01Da0tJQ0FnSUNBZ0lHMXhMbU50WkNnbkwyVmphRzhnVTNScGJHd2dibTkwSUhKbFlXUjVMaWNwQ2lBZ0lDQmxibVFLQ2lBZ0lDQnRjUzVrWld4aGVTZ3lNREF3S1FvZ0lDQWdiWEV1WTIxa0tDY3ZZMkZ6ZENBNUp5a0tJQ0FnSUcxeExtUmxiR0Y1S0RVd01EQXBDZ29nSUNBZ2FXWWdLRzF4TGxSTVR5NURkWEp6YjNJdVNVUW9LU2tnZEdobGJnb2dJQ0FnSUNBZ0lHMXhMbU50WkNnbkwyRjFkRzlwYm5abGJuUnZjbmtuS1FvZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RJcENpQWdJQ0FnSUNBZ2JYRXVZMjFrS0NjdllYVjBiMmx1ZG1WdWRHOXllU2NwQ2lBZ0lDQmxibVFLQ2lBZ0lDQnRjUzVqYldRb0p5OWtiMk52YlcxaGJtUWdMMkp2ZUhJZ2RXNXdZWFZ6WlNjcENpQWdJQ0FLWlc1a0NncHlaWFIxY200Z2UyOXViRzloWkQxdmJsOXNiMkZrTENCamIyNWtablZ1WXoxamIyNWthWFJwYjI0c0lHRmpkR2x2Ym1aMWJtTTlZV04wYVc5dWZRPT0iLAogY2F0ZWdvcnkgPSAiTWFnZU1hbmEiLAogdHlwZSA9ICJjb25kaXRpb25zIiwKIG5hbWUgPSAiTW9kUm9kR29NIiwKfQ==

ModRodGoM
Lua:
local mq = require('mq')

---@return boolean @Returns true if the action should fire, otherwise false.
local function on_load()
    -- Perform any initial setup here when the event is loaded.
end

local function condition()
    return ( mq.TLO.Me.Song('Gift of Mana (80)').ID() and not mq.TLO.FindItem('Rod of Prime Transvergence')() and mq.TLO.Me.PctMana() > 25 )
end

local function action()
    local massRod = 'Mass Prime Transvergence Rk. II'

    if (mq.TLO.Cursor.ID()) then
        mq.cmd('/autoinventory')
        mq.delay(2)
        mq.cmd('/autoinventory')
    end

    -- Implement the action to perform here.
    mq.cmd('/g Take my rod.')
    mq.cmd('/docommand /boxr pause')
    mq.delay(10)
    while mq.TLO.Me.Casting.ID()  or not mq.TLO.Me.SpellReady(massRod) do
       mq.delay(200)
       mq.cmd('/echo Still not ready.')
    end

    mq.delay(2000)
    mq.cmd('/cast 9')
    mq.delay(5000)

    if (mq.TLO.Cursor.ID()) then
        mq.cmd('/autoinventory')
        mq.delay(2)
        mq.cmd('/autoinventory')
    end

    mq.cmd('/docommand /boxr unpause')
    
end

return {onload=on_load, condfunc=condition, actionfunc=action}

CWTN right now doesn't use spot 9 so I put mass mod rod there and use /cast 9. Is there a better way to do it with spell name? Didn't want to do memorization and 'm not sure if mq2mage is going to keep a spot free up until we get HoT for the AA modrod.
 
So, I am interested in getting into this and replacing my HUGE react library with LEM. But it looks a lot harder than Yaml configuration.
I was wondering if some angel could maybe convert this react below into a Lua event? Just as an example for me to see how different it is, and to get an idea of how it's done.

Thanks!

Poison Apply
YAML:
globals:
    SafeToCast: >-
        !${Me.Song[Evader's Shroud of Stealth].ID} && !${Me.Song[Evader's
        Invisibility].ID} && !${Me.PctHPs} <=25 && !${Me.Moving} && !${Me.Casting.ID}
        && !${Me.Buff[Revival Sickness].ID} && ${SpawnCount[npc radius 60]}<1
        && ${Me.XTarget} < 1 && !${Me.Dead} && ${Me.State.NotEqual[FEIGN]}

reacts:
    RogPoisonApply:
        action: >-
          /multiline ; /react disable RogPoisonApply; /timed 25 /react enable
          RogPoisonApply; /useitem Consigned Bite of the Shissar XXI;
        condition: >-
          ${React.Global[SafeToCast]} && !${Me.Buff[Bite of the Shissar Poison
          XII].ID} && ${FindItemCount[=Consigned Bite of the Shissar XXI]}
          > 0
 
Release Lua Event Manager (LEM) Event Library

Users who are viewing this thread

Back
Top
Cart