• You've discovered RedGuides, an EverQuest multi-boxing and scripting community 🧙‍♀️⚙️. We want you to play several EQ characters at once, come join us and say hello! 👋

  • A TLP without truebox has thawed (Very Vanilla ready)
    Frostreaver
(Mighty) Lua Event Manager

Release (Mighty) Lua Event Manager 12/13/2024

No permission to download
Doing my first test of this on an easy fight....what could possibly go wrong..

The event fails to load...

View attachment 40743

And I get an Error in the Chat. Event Registration Failed: Griklor

Not sure if its a syntax error or do i need to reload something?
I made the changes suggested below the post. Where do I put the
#*#Griklor the Restless roars and points at#1#.
I am just trying to learn Lua coding and having a hard time.
 
Feature extension request:
I would like to have 2 commands extended.
/lem event <eventname> - toggle text event enabled/disabled
/lem cond <eventname> - toggle condition event enabled/disabled
Each one extended with 2 additional options: "on" and "off" in order to be able to set their state without the need to know the actual state
afterwards the two commands would be extended to six possible commands as follows:
/lem event <eventname> - toggle text event enabled/disabled
/lem event <eventname> on - text event enabled indipended from the former state
/lem event <eventname> off - text event disabled indipended from the former state
/lem cond <eventname> - toggle condition event enabled/disabled
/lem cond <eventname> on - condition event enabled indipended from the former state
/lem cond <eventname> off - condition event disabled indipended from the former state

I would like to activate/deactivate events from hotbuttons or even other Luas and would like to be sure, I achieve the intended state in any case, without the need to create a construct to memorize the actual state when calling the toggle.
 
Feature extension request:
I would like to have 2 commands extended.

Each one extended with 2 additional options: "on" and "off" in order to be able to set their state without the need to know the actual state
afterwards the two command would be extended to six possible commands as follows:







I would like to activate/deactivate events from hotbuttons or even other Luas and would like to be sure, I achieve the intended state in any case, without the need to create a construct to memorize the actual state when calling the toggle.
Should already be there, maybe just not doc'd. any of /lem cond eventname on|off|0|1|true|false
 
@Myysterio you may want to click „Overview“ to find the instructions of how to use it.
First samples if events can be found at the library
I went totally through it, I am not a programmer however, i know kinda how stuff goes, but not how this thing works. There was a video for setting up events, just wondering if there's something else.
 
@aquietone : I am going to create a somewhat more complex event and would like an answer to the following questions beforehand:
Are the events singletons? What If I create an event which needs more processing time than the set cycletime (250 ms).
Will lem prevent to start another event, when the last event is still processing while a new cycle of checking the events conditions starts?
 
Last edited:
Text events are processed by calling mq.doevents on every loop. The 250ms is the default delay between loop iterations.

Condition events are called directly from the main while loop, iterating over them to check the condition and then call the action.

The expectation is that the events all run synchronously to completion before moving on.

The event callbacks for text events are called from the mq c++ side and should pull as many events off the queue and run them synchronously as it can before yielding to the frame. Any delay call also causes a yield. If it's a long running text event with delays, afaik it'd still run that event to completion before moving on as well but not positive if it wouldn't just get cut off by mq forcing it to yield then just going back to the main loop next frame. I don't think that is what happens but it's recommended not to do long running things in event callbacks.
 
This seems awesome but I struggled to get it to work because of syntax. I don't know if it's possible but if someone could make a converter for mq conditions into mlem, that would be awesome.
 
Some examples..

1. ${Me.Something} becomes mq.TLO.Me.Something()
2. ${Me.Something[somethingelse]} becomes mq.TLO.Me.Something('somethingelse')
3. if (${Me.PctHPs} > 70 && ${Me.PctMana} < 50) { becomes if mq.TLO.Me.PctHPs() > 70 and mq.TLO.Me.PctMana() < 50 then

macro ||, Lua or
macro &&, Lua and
macro !, Lua not or ~=

if (!${Pet.ID}) {
if mq.TLO.Pet.ID() == 0 then

if (!${Spawn[npc fippy].ID}) {
if not mq.TLO.Spawn('npc fippy')() then

As far as event pattern syntax, it is the same as mq2events mostly, but without the TLO matches. For example, an mq2event pattern could be like "Looks at |${Me.CleanName}|#*#" but in LEM you would have "Looks at #1#" and then have to compare name to mq.TLO.Me.CleanName()

I had started on a converter one day but then didn't feel like rewriting the macro parser as soon as I started considering nested TLOs and stuff.
 
possible feature Request for lem events:

Motivation:
Yesterday I took some time to read the Lua Wiki. After some while I passed also the section garbage collector.
If I understood well, the garbage collertor does it's job best, if all references to tables are set to nil, before a Lua is finalized.
I am not sure, if the GC will eventually find the table and recycle it (together with the memory used to hold the reference to it), if not all references to the trable are set to nil.


If there is the possibillity to create an overloaded funkion of the last line:
return {onload=on_load, condfunc=condition, actionfunc=action}
and add the reference to an unload-function like
return {onload=on_load, condfunc=condition, actionfunc=action, onunload=on_unload}
all existing events should run as usual but one could decide to create a destructor-function to eliminate all the references to tables bei setting them to nil.

[CODE title="Event using table"]local dsSpells = {
MAG={name='Scorching Skin',type='spell'},
DRU={name='Daggerthorn',type='spell'}
}

local function on_load()
my_class = mq.TLO.Me.Class.ShortName()
dsSpell = dsSpells[my_class]
Spellname = mq.TLO.Spell(dsSpell.name).RankName()
print('ds= ', Spellname)
end

- added new function do delete references to the table(s)
local function on_unload()
dsSpells = nil
end

.
.
. ... rest of the event
[/CODE]

Today I tried to find the same chapter of garbage-collection in Lua, but could not find any more the suggestion to set all references to tables to nil, when they are no longer needed.
As today I could not find anymore the suggestion to set all references to tables to nil, when they are no longer needed, I am not sure how useful it may be to add this feature.

Maybe someone of deeper knowledge of Lua could chime in and tell, if my finding is still valid.
If there is a likehood of tables remaining uncollected in memory, the addition of a desctructor could help to keep the ressource-footprint of the running code as small as possible.
 
With some help from @toadwart (initial idea and react) and @aquietone (formatting and understanding lem lua) here is an event for maxing your toons to max level for the expansions you have, and then altering AA exp % to keep you pushing to 99.99% into max level, while also gaining AA at the same time based on your current exp% level. For example, if you are 15% into 120, this will apply 15% into AA exp gains. Once you hit 16% into level, changes to 16% AA exp, and so on.

This requires you create a Category named "Character", without quotations.

Here is the Import Code:

[CODE title="AAXPOn Import Code"]cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENncHNiMk5oYkNCelpYUmhZWEJqZENBOUlEQUtDbXh2WTJGc0lHWjFibU4wYVc5dUlHTnZibVJwZEdsdmJpZ3BDaUFnSUNCc2IyTmhiQ0JzWlhabGJDQTlJRzF4TGxSTVR5NU5aUzVNWlhabGJDZ3BDaUFnSUNCc2IyTmhiQ0J0WVhoc1pYWmxiQ0E5SUcxeExsUk1UeTVOWlM1TllYaE1aWFpsYkNncENpQWdJQ0JzYjJOaGJDQmxlSEJ3WTNRZ1BTQnRjUzVVVEU4dVRXVXVVR04wUlhod0tDa0tJQ0FnSUd4dlkyRnNJR1Y0Y0hCamRHbHVkQ0E5SUcxeExsUk1UeTVOWlM1UVkzUkZlSEF1U1c1MEtDa0tJQ0FnSUd4dlkyRnNJR1Y0Y0hCamRHbHVkREVnUFNCdGNTNVVURTh1VFdVdVVHTjBSWGh3TGtsdWRDZ3BJQ3NnTVFvZ0lDQWdiRzlqWVd3Z1lXRndZM1FnUFNCdGNTNVVURTh1VFdVdVVHTjBSWGh3Vkc5QlFTZ3BDaUFnSUNBS0lDQWdJR2xtSUd4bGRtVnNJSDQ5SUcxaGVHeGxkbVZzSUdGdVpDQmhZWEJqZENBK0lEQWdkR2hsYmdvZ0lDQWdJQ0FnSUhObGRHRmhjR04wSUQwZ01Bb2dJQ0FnSUNBZ0lISmxkSFZ5YmlCMGNuVmxDaUFnSUNCbGJtUUtJQ0FnSUdsbUlHeGxkbVZzSUQwOUlHMWhlR3hsZG1Wc0lHRnVaQW9nSUNBZ0lDQWdJR1Y0Y0hCamRDQStJREV3SUdGdVpBb2dJQ0FnSUNBZ0lHVjRjSEJqZENBOFBTQTVPUzQ1T0NCaGJtUUtJQ0FnSUNBZ0lDQmxlSEJ3WTNScGJuUWdmajBnWVdGd1kzUWdkR2hsYmdvZ0lDQWdJQ0FnSUNBZ0lDQnpaWFJoWVhCamRDQTlJR1Y0Y0hCamRHbHVkQW9nSUNBZ0lDQWdJSEpsZEhWeWJpQjBjblZsQ2lBZ0lDQmxibVFLSUNBZ0lHbG1JR3hsZG1Wc0lEMDlJRzFoZUd4bGRtVnNJR0Z1WkFvZ0lDQWdJQ0FnSUdWNGNIQmpkQ0ErSURrNUxqazRJR0Z1WkNBS0lDQWdJQ0FnSUNCbGVIQndZM1JwYm5ReElINDlJR0ZoY0dOMElIUm9aVzRLSUNBZ0lDQWdJQ0FnSUNBZ2MyVjBZV0Z3WTNRZ1BTQmxlSEJ3WTNScGJuUXhDaUFnSUNBZ0lDQWdjbVYwZFhKdUlIUnlkV1VLSUNBZ0lHVnVaQW9LSUNBZ0lISmxkSFZ5YmlCbVlXeHpaUXBsYm1RS0NteHZZMkZzSUdaMWJtTjBhVzl1SUdGamRHbHZiaWdwQ2lBZ0lDQnBaaUJ6WlhSaFlYQmpkQ0E5UFNBd0lIUm9aVzRLSUNBZ0lDQWdJQ0J0Y1M1amJXUW9KeTloYkhRZ2IyWm1KeWtLSUNBZ0lHVnNjMlVLSUNBZ0lDQWdJQ0J0Y1M1amJXUm1LQ2N2WVd4MElHOXVJQ1Z6Snl3Z2MyVjBZV0Z3WTNRcENpQWdJQ0JsYm1RS1pXNWtDZ3B5WlhSMWNtNGdlMk52Ym1SbWRXNWpQV052Ym1ScGRHbHZiaXdnWVdOMGFXOXVablZ1WXoxaFkzUnBiMjU5IiwKIGNhdGVnb3J5ID0gIkNoYXJhY3RlciIsCiB0eXBlID0gImNvbmRpdGlvbnMiLAogbmFtZSA9ICJBQVBDVCIsCn0=[/CODE]

Here is the Verbose Code:

[CODE title="AAXPOn Verbose Code"]local mq = require('mq')

local setaapct = 0
local function condition()
local level = mq.TLO.Me.Level()
local maxlevel = mq.TLO.Me.MaxLevel()
local exppct = mq.TLO.Me.PctExp()
local exppctint = mq.TLO.Me.PctExp.Int()
local exppctint1 = mq.TLO.Me.PctExp.Int() + 1
local aapct = mq.TLO.Me.PctExpToAA()

if level ~= maxlevel and aapct > 0 then
setaapct = 0
return true
end
if level == maxlevel and
exppct > 10 and
exppct <= 99.98 and
exppctint ~= aapct then
setaapct = exppctint
return true
end
if level == maxlevel and
exppct > 99.98 and
exppctint1 ~= aapct then
setaapct = exppctint1
return true
end
return false
end
local function action()
if setaapct == 0 then
mq.cmd('/alt off')
else
mq.cmdf('/alt on %s', setaapct)
end
end
return {condfunc=condition, actionfunc=action}
[/CODE]

[CODE title="StopAA_XP"]cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENncHNiMk5oYkNCbWRXNWpkR2x2YmlCbGRtVnVkRjlvWVc1a2JHVnlLQ2tLSUNBZ0lDMHRJRWx0Y0d4bGJXVnVkQ0IwYUdVZ2FHRnVaR3hwYm1jZ1ptOXlJSFJvWlNCbGRtVnVkQ0JvWlhKbExnb2dJQ0FnYlhFdVkyMWtLQ2N2YkdWdElHTnZibVFnUVVGUVExUWdiMlptSnlrS1pXNWtDZ3B5WlhSMWNtNGdlMlYyWlc1MFpuVnVZejFsZG1WdWRGOW9ZVzVrYkdWeWZRPT0iLAogY2F0ZWdvcnkgPSAiIiwKIHR5cGUgPSAiZXZlbnRzIiwKIG5hbWUgPSAiU3RvcEFBX1hQIiwKIHBhdHRlcm4gPSAiIyojWW91IGFyZSBjdXJyZW50bHkgb3ZlciB0aGUgZWFybmVkIEFkdmFuY2VtZW50IHBvaW50IGxpbWl0IyojIiwKfQ==[/CODE]


Quick little LEM to stop your AAXP if you get over 240.
 
[CODE title="StopAA_XP"]cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENncHNiMk5oYkNCbWRXNWpkR2x2YmlCbGRtVnVkRjlvWVc1a2JHVnlLQ2tLSUNBZ0lDMHRJRWx0Y0d4bGJXVnVkQ0IwYUdVZ2FHRnVaR3hwYm1jZ1ptOXlJSFJvWlNCbGRtVnVkQ0JvWlhKbExnb2dJQ0FnYlhFdVkyMWtLQ2N2YkdWdElHTnZibVFnUVVGUVExUWdiMlptSnlrS1pXNWtDZ3B5WlhSMWNtNGdlMlYyWlc1MFpuVnVZejFsZG1WdWRGOW9ZVzVrYkdWeWZRPT0iLAogY2F0ZWdvcnkgPSAiIiwKIHR5cGUgPSAiZXZlbnRzIiwKIG5hbWUgPSAiU3RvcEFBX1hQIiwKIHBhdHRlcm4gPSAiIyojWW91IGFyZSBjdXJyZW50bHkgb3ZlciB0aGUgZWFybmVkIEFkdmFuY2VtZW50IHBvaW50IGxpbWl0IyojIiwKfQ==[/CODE]


Quick little LEM to stop your AAXP if you get over 240.
Shouldn't that be 2*level?
 
LEM failing to load... Can not open... Permission denied...
yes known issue


will be fixed with next rebuild
 
the question was already qualified by Lua scripts that have a folder structure, so I wasn't sure what the question was leading towards..
 
Is this how all lua scripts will be that have a folder structure?
No. There is nothing stopping you from continuing to have something like:
myscript.lua and myscript/utils-for-myscript.lua where users would do /lua run myscript

or
myscript/start.lua where users would do /lua run myscript/start

The latest builds just added a new option where you can use a folder name to run a Lua script, so if you have
myscript/init.lua
then you can just do /lua run myscript
and MQ will know to run myscript/init.lua
 
you really want to follow this format though, because it means that "myscript/" will now be in the search path for your requires, which gives you the advantage of not requiring a specific folder name (you can rename it, for example if you want multiple versions i.e. for stable and dev, etc)
 
So I am trying to learn this with something easy. I was trying to set up a condition event that checks if the character is a mage and its mana is under 15%, and if so to run the Lua mm, which is the mage mana Lua from roundeq. What am I missing or need to change to make this wor? Once I get this one figured out I want to set up one for my bard to fire up his epic when my shaman does.

Lua:
local mq = require('mq')
local my_class = mq.TLO.Me.Class.ShortName()
local my_mana = mq.TLO.Me.PctMana()


---@return boolean @Returns true if the action should fire, otherwise false.
local function condition()
    If my_class == MAG and my_mana < 15 then
    mq.cmd('/lua run mm')
end

end
 
So I am trying to learn this with something easy. I was trying to set up a condition event that checks if the character is a mage and its mana is under 15%, and if so to run the lua mm, which is the mage mana lua from roundeq. What am I missing or need to change to make this wor? Once I get this one figured out I want to set up one for my bard to fire up his epic when my shaman does.

Lua:
local mq = require('mq')
local my_class = mq.TLO.Me.Class.ShortName()
local my_mana = mq.TLO.Me.PctMana()


---@return boolean @Returns true if the action should fire, otherwise false.
local function condition()
    If my_class == MAG and my_mana < 15 then
    mq.cmd('/lua run mm')
end

end
I really don't know why I didn't catch this the first time you asked me about it. Sometimes the derp is strong. Change to if my_class == "MAG" and my_mana < 15 then
 
Thank you rouneq; sadly that didn't do it. I am still getting a "Failed to Load" error

EDIT: I also found the If is supposed to be if - still no beans
 
Last edited:
Sorry if this question is a bit silly or stupid, but didnt really see anywhere that it was exactly address. I know with MQ2events you need to have that running on each toon. Does Lem need to be running on each toon with the script in there, or running it on the driver sufficient?
 
Sorry if this question is a bit silly or stupid, but didnt really see anywhere that it was exactly address. I know with MQ2events you need to have that running on each toon. Does Lem need to be running on each toon with the script in there, or running it on the driver sufficient?
In general, you would run it on every toon so that it can respond to events on each toon its running on. Look at it the same way as mq2events and mq2react, except you can write more complex Lua code to handle the events, opposed to a giant multiline like in the two plugins.
It could also depend on the event, technically you could write an event that runs on the driver and coordinates things to other toons.
 
In general, you would run it on every toon so that it can respond to events on each toon its running on. Look at it the same way as mq2events and mq2react, except you can write more complex lua code to handle the events, opposed to a giant multiline like in the two plugins.
It could also depend on the event, technically you could write an event that runs on the driver and coordinates things to other toons.
Thank you
 
So I am trying to learn this with something easy. I was trying to set up a condition event that checks if the character is a mage and its mana is under 15%, and if so to run the lua mm, which is the mage mana lua from roundeq. What am I missing or need to change to make this wor? Once I get this one figured out I want to set up one for my bard to fire up his epic when my shaman does.

Lua:
local mq = require('mq')
local my_class = mq.TLO.Me.Class.ShortName()
local my_mana = mq.TLO.Me.PctMana()


---@return boolean @Returns true if the action should fire, otherwise false.
local function condition()
    if my_class == MAG and my_mana < 15 then
    mq.cmd('/lua run mm')
end

end
Can any of you folks good with Lua tell me why this is not working? For the life of me, I can't figure it out
 
Can any of you folks good with LUA tell me why this is not working? For the life of me, I can't figure it out

my_mana would need to be inside the condition function otherwise its only reading your mana once when the script loads.
MAG needs quotes around it as it is a string and not a variable.
It needs to return a table with condfunc which points to the condition function (whether to take an action) and actionfunc which points to the action function (what action to take).

Lua:
local mq = require('mq')

---@return boolean @Returns true if the action should fire, otherwise false.
local function condition()
    local my_class = mq.TLO.Me.Class.ShortName()
    local my_mana = mq.TLO.Me.PctMana()
    local mm_status = mq.TLO.Lua.Script('mm').Status()
    return my_class == 'MAG' and my_mana < 15 and mm_status ~= 'RUNNING'
end

local function action()
    mq.cmd('/lua run mm')
end

return {condfunc=condition, actionfunc=action}

If mm script is something simple, you might also consider having the
 
[CODE title="StopAA_XP"]cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENncHNiMk5oYkNCbWRXNWpkR2x2YmlCbGRtVnVkRjlvWVc1a2JHVnlLQ2tLSUNBZ0lDMHRJRWx0Y0d4bGJXVnVkQ0IwYUdVZ2FHRnVaR3hwYm1jZ1ptOXlJSFJvWlNCbGRtVnVkQ0JvWlhKbExnb2dJQ0FnYlhFdVkyMWtLQ2N2YkdWdElHTnZibVFnUVVGUVExUWdiMlptSnlrS1pXNWtDZ3B5WlhSMWNtNGdlMlYyWlc1MFpuVnVZejFsZG1WdWRGOW9ZVzVrYkdWeWZRPT0iLAogY2F0ZWdvcnkgPSAiIiwKIHR5cGUgPSAiZXZlbnRzIiwKIG5hbWUgPSAiU3RvcEFBX1hQIiwKIHBhdHRlcm4gPSAiIyojWW91IGFyZSBjdXJyZW50bHkgb3ZlciB0aGUgZWFybmVkIEFkdmFuY2VtZW50IHBvaW50IGxpbWl0IyojIiwKfQ==[/CODE]


Quick little LEM to stop your AAXP if you get over 240.

There is a small issue with this, if you have over 240aa, it will spam non-stop that you must use all your aa before you can get more.
 
The AAXP LEM will spam you. That’s why StopAA_XP exists. It should stop the AAXP LEM.
 
Release (Mighty) Lua Event Manager

Users who are viewing this thread

Back
Top
Cart