It works! I feel the need to give you a virtual hug or something.. It seems to be running the list slike curare gecko the whole time though, any idea why it's not starting with kalmia from the top?
Sorry to keep posting about this stuff, but I don't know where else to ask. I can now call these tables and change them up, add to them and it's all working really well, thanks for the huge help for that. Now I'm having trouble calling the script at the right time. To elaborate, when I execute my alias, it will set the venoms in the right order from top to bottom, but if I execute the alias it puts the throws into my queue and executes them on balance, meaning when I pushed SEND ALIAS the order was kalmia/gecko/slike, but if the target cures kalmia right after the venom hits them, it still goes on to gecko and slike though what it should be doing is going back and pick kalmia again from the top of the list. I don't know where I should make this table execute so that it stays constantly updated without me pushing any buttons and I want to be able to switch tables according to priorities as well. Would the prompt be the best place for that kind of thing? I've tried putting local venoms =venomprios() into triggers when the target cures something, but that has not worked at all either.. can it be called just by triggering something to go local venoms = venomprios()?
I believe you also have to resend the command to Achaea everytime you update the venoms. Otherwise Achaea will still run the command that contains previous evaluation.
This is so damn tricky, @Kayle thanks for the tip, it has made things a lot better and @Dochitha yeah you're right, the issue is not the script not working, the issue is the QUEUE, so the trouble I have is if I sent me command and they cure anything after I sent it and it's been added to the queue, it misses that important step. It's extremely close and works incredibly well, it's just that one extra boost that would make my life as jester so much easier if it worked faultless and I have no logical way of making it happen even if I could write code like a pro
This is so damn tricky, @Kayle thanks for the tip, it has made things a lot better and @Dochitha yeah you're right, the issue is not the script not working, the issue is the QUEUE, so the trouble I have is if I sent me command and they cure anything after I sent it and it's been added to the queue, it misses that important step. It's extremely close and works incredibly well, it's just that one extra boost that would make my life as jester so much easier if it worked faultless and I have no logical way of making it happen even if I could write code like a pro
Here's a rough outline of how you can do it, though it only queues a single throw at a time (i.e. you'd need to hit your key three times to throw all three juggled daggers):
function throwjuggled(queue)
local venoms = venomprios()
send("setalias jug throw dagger at " .. target .. " " .. venoms[1])
if queue then
send("queue addclear eqbal jug")
end
end
Your alias/keybinding calls throwjuggled(true). On cure lines, you call throwjuggled(false). It always updates the "jug" in-game alias to the correct command (the commands in the code above might not be correct, fix those). If queue is true, it will queue it. If queue is not true, it only updates the alias; if the command is queued from you hitting your keybinding, it runs the new command when you recover balance, otherwise you don't do any actual actions (avoids you throwing daggers when you don't want to just because they cured something).
EDIT: Ideally your affliction tracker would raise events when afflictions are gained or cured, so you don't have to update the actual triggers and instead just use an event handler to call that function.
@Antonius that's awesome, finally something that works, really cool! Event handlers? No idea what that is, and the only issue I have now is if I want to switch tables, lets say local venoms = venomprios2 and making a new function for it, and calling that function throwjuggled2(false) on the cure triggers is messing with the whole thing since now both tables get called every time. I'm assuming these event handlers have something to do with this?
@Dominius this is where the line for partially automated to full automated is drawn. You can either set an alias to reque your attacks if they cure something (partially automated) or add in your queue command to their cures if you have it queued up already (fully automated). Just make a variable to check if you have something queued and if they cure and that variable is set to true then the trigger checks venomprios() and reques the command automatically. When the command gets sent on queue you would set the variable to false
It looks like the code would work, depending on when you're calling it. However, there's an easier way to do it. If you look at the two functions you're defining there, the only difference between them is the "local venoms" line, so a lot of it is repeated (repeating code is usually bad). You could just declare the function a single time and check which function to call to get the venoms inside that, like this:
function throwjuggled(queue)
local venoms
if wanttolockslow then
venoms = venomprioslow()
else
venoms = venompriosrift()
end
send("setalias 1 throw axe at " .. target .. " " .. venoms[1])
if queue and juggling == true then
send("queue addclear eqbal 1")
elseif queue and juggling == nil then
send("unwield left;queue addclear eqbal juggle axe axe axe;1")
end
end
That will make it easier to make changes down the line - such as adding additional venom combinations - as you only need to do it in one place rather than several. Then you can have two keybindings/aliases/whatever that would look something like this:
So I wrote all of that, and it would work, but there's another way you could do this which may be even easier (but it's less obvious to beginners). Functions in Lua are stored as variables just like everything else, so there's a variable called 'throwjuggled' which points to your function. So just like you can have multiple references to the same table by doing something like a = {1, 2, 3}, b = a, you can have multiple references to the same function. If you introduce a third variable, let's call it juggledvenomfn, then your macros can just update that variable to reference one of your two functions to actually get a list of venoms.
-- slow keybinding/alias
juggledvenomfn = venomprioslow -- NOTE: No () because we want to set it to the reference to the function. We DON'T want to call the function and set the variable to whatever value is returned by it.
throwjuggled(true)
-- rift keybinding/alias
juggledvenomfn = venompriosrift
throwjuggled(true)
Then your throwjuggled function would look like this:
function throwjuggled(queue)
local venoms = juggledvenomfn() -- execute whatever function is referenced by juggledvenomfn and store the value returned in the local venoms variable
send("setalias 1 throw axe at " .. target .. " " .. venoms[1])
if queue and juggling == true then
send("queue addclear eqbal 1")
elseif queue and juggling == nil then
send("unwield left;queue addclear eqbal juggle axe axe axe;1")
end
end
This is the easiest option for adding additional venom combinations down the line, as you just create a new function to get the venoms, create a new keybinding or alias that sets juggledvenomfn to a reference to that new function, and call throwjuggled(true). No need to update the other macros, worry about making sure all of the mutually exclusive variables are set correctly, etc. Just make sure you're initialising juggledvenomfn to one of those two functions in a script (the same way you do in the macro, e.g. juggledvenomfn = venomprioslow), otherwise you'll get a load of errors when you see people cure if you haven't hit either of your macros yet and it runs the throwjuggled function.
is there a way I can have the timers be a variable? like
tempTimer("..matches[2])", [[ echo("this is timer #1 going off 3s after being made\n") ]])
I haven't been able to find a syntax that would make that work anywhere, all I can do is
tempTimer(5, [[ echo("this is timer #1 going off 3s after being made\n") ]])
but that doesn't help me in keeping track of anything is I can't trigger that into a changing number...
and while I'm at it, this trigger isn't working properly either, for harvesting
^A (.*) ((\w+))$
to send("harvest " ..matches[2])
how can I isolate the (\w+) to be captured in this case? apparently it's just capturing everything after "A" with the (.*) and not letting me pick up the word in the parantheses anymore..
(.*) matches anything. \w+ matches words. \d+ matches numbers. If you can, use \w+ or \d+, since .* matches literally everything. Also, you have an unneeded second set of parenthesis around your \w+, and you're only matching .* right now, not \w+.
^A (.*) (\w+)$
send("harvest "..matches[2]) <- matches[2] is just your .*. matches[3] would be \w+.
and the word in the parantheses is what I want to capture, that's why the doubles. using matches[3] somehow captures the moderate, spare, etc. bit at the end of that trigger line, because (.*) apparently included that as well..
I don't know the exact line you need to trigger off of or that would make it easier, but, it sounds like you just need to capture "coneflower" in that example.
If that's the case, you could just do..
^A \w+ (\w+)$
send("harvest "..matches[2])
Since the first \w+ isn't in parenthesis, it doesn't get built as a "matches" at all.
The text contains actual parentheses, so you need to escape them in your regex to make it clear you mean the literal character, not the start of a group. So:
^A (?:.+) \((\w+)\)$
The ?: means non-capturing, so it won't create an entry in the matches table. That means that matches[2] will be the bit between the brackets in the text, which is what you really care about. You could also just use .+ without any brackets at all, but this way I got to introduce non-capturing groups, which have some nice uses (e.g. (?:him|her) for matching either him or her without adding an unnecessary entry into the matches table).
is there a way I can have the timers be a variable? like
tempTimer("..matches[2])", [[ echo("this is timer #1 going off 3s after being made\n") ]])
I haven't been able to find a syntax that would make that work anywhere, all I can do is
tempTimer(5, [[ echo("this is timer #1 going off 3s after being made\n") ]])
but that doesn't help me in keeping track of anything is I can't trigger that into a changing number...
The first thing you need to know is that everything in the matches table is a string. Even if you use (\d+) to pull out a number, it's the string representation of that number. Depending on what you want to do with it, you may need to convert that string to a number. Lua has a function to do that, it's called tonumber, so you'd do something like: local delay = tonumber(matches[2]). If matches[2] contained the string "5" then delay would now be the number 5. If matches[2] contained something that can't be converted to a number then delay would be nil.
In terms of your code, you'd want to do something like this:
local delay = tonumber(matches[2])
tempTimer(delay, [[echo("This is a timer going off ]] .. delay .. [[ seconds after being made\n.")]])
The #1 part is a bit trickier, and it really depends exactly how you want it to work. You could just keep a running total of how many timers you've created - to do this you'd want to make a function that handles the timer creation so you can be sure you're always incrementing - and use that. But if you want the numbers to start from 1 again when you don't currently have any timers running, you'd need to keep track of your timers and reset your incremental counter when the last one finishes. That's non-trivial due to the way that timers work, and probably isn't worth the effort.
and the word in the parantheses is what I want to capture, that's why the doubles. using matches[3] somehow captures the moderate, spare, etc. bit at the end of that trigger line, because (.*) apparently included that as well..
If every line you want to pick up matches the pattern of "^A word1 word2 (word3)$" and all you want to do is capture word3, the pattern you want is this:
^A \w+ \w+ \((\w+)\)$
To match a ( or a ), you need to put a \ in front of it, to make it ignore the special meaning of the ()'s.
<...ue\.config\mudlet\profiles\Achaea\Bashing\script.lua:135: bad argument #2 to 'format' (string expected,
got nil)>
I'm trying to narrow why this is happening, from the script the variable passed to format that is does not like is 'requestSkillDetails[1]'
That variable's contents are supplied by keneanung.bashing.handleSkillList(), which is the callback for gmcp.Char.Skills.List. Maybe the table schema has changed since the script was last released. I'm having a hard time determining why this is coming back null and throwing errors every login. The bashing still seems to work but the error message is annoying.
that skill list function parses gmcp.Char.Skills.List. In my testing that table shows up as:
{
group = "battlerage",
descs = {
"A painful, choking cloud.",
"Weaken your enemy with cadmium.",
"A chemical that burns through denizen shields.",
"Ignite your victim's limbs with white-hot flames.",
"A chemical that tears your victims apart from within.",
"A chemical that dazes your victim into forgetfulness."
},
list = {
"Miasma",
"Cadmium",
"Caustic",
"Magnesium",
"Pathogen",
"Hypnotic"
}
}
Has anyone else seen this error? could you give me a clue for fixing it?
Comments
And in the alias you use:
GMCP documentation: https://github.com/keneanung/GMCPAdditions
svof github site: https://github.com/svof/svof and documentation at https://svof.github.io/svof
GMCP documentation: https://github.com/keneanung/GMCPAdditions
svof github site: https://github.com/svof/svof and documentation at https://svof.github.io/svof
send("setalias jug wipe axe/envenom axe with curare/throw axe at " ..target)
send("setalias jug1 wipe axe/envenom axe with curare/throw axe at " ..target)
send("setalias jug2 wipe axe/envenom axe with prefarar/throw axe at " ..target)
svo.doadd("queue add eqbal jug")
svo.doadd("queue add eqbal jug1")
svo.doadd("queue add eqbal jug2")
Only properly switched back to Jester yesterday, so still sorting these things out.
Your alias/keybinding calls throwjuggled(true). On cure lines, you call throwjuggled(false). It always updates the "jug" in-game alias to the correct command (the commands in the code above might not be correct, fix those). If queue is true, it will queue it. If queue is not true, it only updates the alias; if the command is queued from you hitting your keybinding, it runs the new command when you recover balance, otherwise you don't do any actual actions (avoids you throwing daggers when you don't want to just because they cured something).
EDIT: Ideally your affliction tracker would raise events when afflictions are gained or cured, so you don't have to update the actual triggers and instead just use an event handler to call that function.
Results of disembowel testing | Knight limb counter | GMCP AB files
Jeramun, the Flame of the World has loosed its full and unabated might upon Mosr, incinerating him
Jeramun, the Flame of the World has loosed its full and unabated might upon Kaden, incinerating him
Shrinking downwards with a last bellow of rage, the chains tighten into the shape of pitch-black
It looks like the code would work, depending on when you're calling it. However, there's an easier way to do it. If you look at the two functions you're defining there, the only difference between them is the "local venoms" line, so a lot of it is repeated (repeating code is usually bad). You could just declare the function a single time and check which function to call to get the venoms inside that, like this:
That will make it easier to make changes down the line - such as adding additional venom combinations - as you only need to do it in one place rather than several. Then you can have two keybindings/aliases/whatever that would look something like this:
So I wrote all of that, and it would work, but there's another way you could do this which may be even easier (but it's less obvious to beginners). Functions in Lua are stored as variables just like everything else, so there's a variable called 'throwjuggled' which points to your function. So just like you can have multiple references to the same table by doing something like a = {1, 2, 3}, b = a, you can have multiple references to the same function. If you introduce a third variable, let's call it juggledvenomfn, then your macros can just update that variable to reference one of your two functions to actually get a list of venoms.
Then your throwjuggled function would look like this:
This is the easiest option for adding additional venom combinations down the line, as you just create a new function to get the venoms, create a new keybinding or alias that sets juggledvenomfn to a reference to that new function, and call throwjuggled(true). No need to update the other macros, worry about making sure all of the mutually exclusive variables are set correctly, etc. Just make sure you're initialising juggledvenomfn to one of those two functions in a script (the same way you do in the macro, e.g. juggledvenomfn = venomprioslow), otherwise you'll get a load of errors when you see people cure if you haven't hit either of your macros yet and it runs the throwjuggled function.
Results of disembowel testing | Knight limb counter | GMCP AB files
I haven't been able to find a syntax that would make that work anywhere, all I can do is
tempTimer(5, [[ echo("this is timer #1 going off 3s after being made\n") ]])
but that doesn't help me in keeping track of anything is I can't trigger that into a changing number...
and while I'm at it, this trigger isn't working properly either, for harvesting
^A (.*) ((\w+))$
to send("harvest " ..matches[2])
how can I isolate the (\w+) to be captured in this case? apparently it's just capturing everything after "A" with the (.*) and not letting me pick up the word in the parantheses anymore..
(.*) matches anything. \w+ matches words. \d+ matches numbers. If you can, use \w+ or \d+, since .* matches literally everything. Also, you have an unneeded second set of parenthesis around your \w+, and you're only matching .* right now, not \w+.
^A (.*) (\w+)$
send("harvest "..matches[2]) <- matches[2] is just your .*. matches[3] would be \w+.
A purple coneflower (echinacea)
and the word in the parantheses is what I want to capture, that's why the doubles. using matches[3] somehow captures the moderate, spare, etc. bit at the end of that trigger line, because (.*) apparently included that as well..
I don't know the exact line you need to trigger off of or that would make it easier, but, it sounds like you just need to capture "coneflower" in that example.
If that's the case, you could just do..
^A \w+ (\w+)$
send("harvest "..matches[2])
Since the first \w+ isn't in parenthesis, it doesn't get built as a "matches" at all.
^A (?:.+) \((\w+)\)$
The ?: means non-capturing, so it won't create an entry in the matches table. That means that matches[2] will be the bit between the brackets in the text, which is what you really care about. You could also just use .+ without any brackets at all, but this way I got to introduce non-capturing groups, which have some nice uses (e.g. (?:him|her) for matching either him or her without adding an unnecessary entry into the matches table).
Results of disembowel testing | Knight limb counter | GMCP AB files
The first thing you need to know is that everything in the matches table is a string. Even if you use (\d+) to pull out a number, it's the string representation of that number. Depending on what you want to do with it, you may need to convert that string to a number. Lua has a function to do that, it's called tonumber, so you'd do something like: local delay = tonumber(matches[2]). If matches[2] contained the string "5" then delay would now be the number 5. If matches[2] contained something that can't be converted to a number then delay would be nil.
In terms of your code, you'd want to do something like this:
The #1 part is a bit trickier, and it really depends exactly how you want it to work. You could just keep a running total of how many timers you've created - to do this you'd want to make a function that handles the timer creation so you can be sure you're always incrementing - and use that. But if you want the numbers to start from 1 again when you don't currently have any timers running, you'd need to keep track of your timers and reset your incremental counter when the last one finishes. That's non-trivial due to the way that timers work, and probably isn't worth the effort.
Results of disembowel testing | Knight limb counter | GMCP AB files
^A \w+ \w+ \((\w+)\)$
To match a ( or a ), you need to put a \ in front of it, to make it ignore the special meaning of the ()'s.
Would be a bit easier to see the code 'cause it's not all green anymore.
Svof
Mudlet Discord join up
I'm trying to narrow why this is happening, from the script the variable passed to format that is does not like is 'requestSkillDetails[1]'
That variable's contents are supplied by keneanung.bashing.handleSkillList(), which is the callback for gmcp.Char.Skills.List. Maybe the table schema has changed since the script was last released. I'm having a hard time determining why this is coming back null and throwing errors every login. The bashing still seems to work but the error message is annoying.
that skill list function parses gmcp.Char.Skills.List. In my testing that table shows up as:
Has anyone else seen this error? could you give me a clue for fixing it?