Welcome to the Achaea Forums! Please be sure to read the Forum Rules.

Quick Coding Questions

11415161820

Comments

  • DominiusDominius Posts: 116Member ✭✭✭ - Distinguished
    and no error message, it's just not executing at all the alias
  • KeneanungKeneanung Posts: 598Member ✭✭✭✭ - Eminent
    edited December 2017
    The code is in the alias? The issue is that "venoms" is a local table and it's not defined at that place anymore. You can adapt with the following:

    function venomprio()
      local venoms = {}
      local affVenomPrio = {
        {
          affliction = "asthma", 
          venom = "kalmia"
        },     {
          affliction = "anorexia",
          venom = "slike"
        },
        {
          affliction = "paralysis",
          venom = "curare"
        },
        {
          affliction = "slickness",
          venom = "gecko"
        }
      }
      local i = 0
      for _, affVenomPair in ipairs(affVenomPrio) do  -- for each affliction/venom in order
        if affstrack.score[affVenomPair.affliction] < 100 then -- if aff is < 100, choose that venom
          venoms[i] = affVenomPair.venom
          i = i + 1
          if i > 3 then break end -- once we've gotten 3 venoms, we're through
        end
      end
      return venoms
    end


    And in the alias you use:

    local venoms = venomprio()
    send("queue add eqbal throw axe at " .. target .." ".. venoms[1]..";queue add eqbal throw axe at " .. target .." ".. venoms[2]..";queue add eqbal throw axe at " .. target .." ".. venoms[3])
    Dochitha
  • DominiusDominius Posts: 116Member ✭✭✭ - Distinguished
    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?
  • DominiusDominius Posts: 116Member ✭✭✭ - Distinguished
    ok kalmia is not being included at all in the list, any idea why? 
  • KeneanungKeneanung Posts: 598Member ✭✭✭✭ - Eminent
    Oh, you should start the variable i at 1, instead of 0
  • DominiusDominius Posts: 116Member ✭✭✭ - Distinguished
    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()?
  • KayleKayle Posts: 81Member ✭✭✭ - Distinguished
    Try putting just venomprios() in the triggers for cures. That should update the order every time they cure something
  • DochithaDochitha Posts: 1,356Member @ - Epic Achaean
    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. 
    ShirszaeKayle
  • SobriquetSobriquet Posts: 2,154Member @@ - Legendary Achaean
    Shout out to @Jonathin for giving me the building blocks for a fashion counter. Learnt some stuff today
    image
    JonathinZekeros
  • DominiusDominius Posts: 116Member ✭✭✭ - Distinguished
    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
  • DominiusDominius Posts: 116Member ✭✭✭ - Distinguished
    @sobriquet, any ideas? How do you handle it as Jester?

  • SobriquetSobriquet Posts: 2,154Member @@ - Legendary Achaean
    I'm old school, I have F keys set up with predefined venom combo's and use that:

    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.

    image
  • AntoniusAntonius Posts: 4,674Member @@ - Legendary Achaean
    edited December 2017
    Dominius said:
    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.

  • DominiusDominius Posts: 116Member ✭✭✭ - Distinguished
    @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? 
  • DominiusDominius Posts: 116Member ✭✭✭ - Distinguished
    @sobriquet throw axe at dominius curare is now a thing!!
  • KayleKayle Posts: 81Member ✭✭✭ - Distinguished
    edited December 2017
    @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
  • DominiusDominius Posts: 116Member ✭✭✭ - Distinguished
    New tendrils of raging fire twist about him, shaping itself into the form of incandescent, aurulent
    chains, reaching up from deep within Hthrak to enshroud Jeramun's wildfire.

    Jeramun, the Flame of the World has loosed its full and unabated might upon Mosr, incinerating him
    until naught but ashes remain.

    Jeramun, the Flame of the World has loosed its full and unabated might upon Kaden, incinerating him
    until naught but ashes remain.

    Shrinking downwards with a last bellow of rage, the chains tighten into the shape of pitch-black
    armour, encasing the Flame of the World within the confining grip of their metallic embrace as the 
    conduit is returned, at long last, to slumber.

    The caustic voice of Khalasian Wanderer, Asmodron Dicondron sizzles through the air, "Well done all."

    A soldier of Kkractle shouts, "Your world's Fire knows once more the embrace of Kkractle, fuel."
  • DominiusDominius Posts: 116Member ✭✭✭ - Distinguished
    wrong thread
  • DominiusDominius Posts: 116Member ✭✭✭ - Distinguished
    how does this code look? haven't been able to test it properly..

    if wanttolockslow == true then
    wanttolockrift = nil
    function throwjuggled(queue)
    local venoms = venomprioslow()
    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
    elseif wanttolockrift == true then
    wanttolockslow = nil
    function throwjuggled(queue)
    local venoms = venompriosrift()
    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


    end
  • AntoniusAntonius Posts: 4,674Member @@ - Legendary Achaean
    edited December 2017

    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:

    -- slow
    wanttolockslow = true
    wanttolockrift = false
    throwjuggled(true)
    
    -- rift
    wanttolockslow = false
    wanttolockrift = true
    throwjuggled(true)
    

    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.

    Shirszae
  • DominiusDominius Posts: 116Member ✭✭✭ - Distinguished
    MARRY ME!?!?
  • DominiusDominius Posts: 116Member ✭✭✭ - Distinguished
    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..




  • SolnirSolnir Posts: 749Member ✭✭✭✭✭ - Grand Achaean

    (.*) 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+.

  • DominiusDominius Posts: 116Member ✭✭✭ - Distinguished
    well the trigger is supposed to run off of:

    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..
  • SolnirSolnir Posts: 749Member ✭✭✭✭✭ - Grand Achaean

    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.

  • AntoniusAntonius Posts: 4,674Member @@ - Legendary Achaean
    edited December 2017
    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).
  • AntoniusAntonius Posts: 4,674Member @@ - Legendary Achaean
    Dominius said:
    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.

  • NazihkNazihk Posts: 993Member @ - Epic Achaean
    Dominius said:
    well the trigger is supposed to run off of:

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

  • VadimusesVadimuses Posts: 1,095Member @ - Epic Achaean
    edited December 2017
    By the way! You can also do this now:

    local delay = tonumber(matches[2])
    tempTimer(delay, function() echo("This is a timer going off " .. delay .. " seconds after being made\n.") end)
    Would be a bit easier to see the code 'cause it's not all green anymore.
    Tysandr
  • ShubShub Posts: 56Member ✭✭ - Stalwart
    edited December 2017
    Attempting to use @Keneanung ;'s bashing script. I get the following error every log in:

    [  LUA  ] - object:<event handler function> function:<keneanung.bashing.handleSkillInfo>
                <...ue\.config\mudlet\profiles\Achaea\Bashing\script.lua:135: bad argument #2 to 'format' (string expected, 
    got nil)>
    You can purchase 5 available credits in a City credit sale.
    5487h, 6066m, 22760e, 25340w ex-
    [  LUA  ] - object:<event handler function> function:<keneanung.bashing.handleSkillInfo>
                <...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?
Sign In to Comment.