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

Quick Coding Questions

11617182022

Comments

  • NazihkNazihk Member Posts: 993 @ - Epic Achaean
    Keep track of the size of the table of emotes. When you randomly select an emote from the table, move that emote to the last slot of the table and reduce your table size by one.  

    Example:
    • You have a table A B C D E. Size of 5. 
    • You select a random number 1 through 5, you get 3. 
    • You use C and then you move C to the end of the table, so it is now A B D E C. Record the table size as 4.
    • Now you select a number 1 through 4. You get 3 again, which is D
    • Use D, and move it to the end of the table. A B E C D. Table size 3. 
    • Random number between 1 and 3, etc, etc.
    To reset it, all you need to do is reset the table size variable back to number of items that are actually in the table. 

    Here's some code that uses the same principles: https://repl.it/repls/SameGruesomeLamp
    t = {"run", "hop", "dance", "skip", "leap", "bounce", "hug", "frolic", "potato", "tomato", "boom"}
    tsize = #t
    print(table.concat(t, ','))
    for i = tsize, 1, -1
      do
      rn = math.random(tsize)
      print(t[rn])
      table.insert(t, tsize, table.remove(t,rn))
      tsize = tsize -1
      end
    Riell
  • RiellRiell Member Posts: 209 ✭✭✭ - Distinguished
    Thank you guys so much! With your help, and some additional digging, I got everything up and running. I AM SO EXCITED!!
  • AntoniusAntonius Member Posts: 4,917 @@ - Legendary Achaean
    Pyori said:
    --Initialise the tables here; again, have something to revert back to this state.
    emoteTable = { "hi", "wavehi", "hello", "greet", "smile" }
    usedEmotes = {}

    --Separate alias for sending the emote itself.
    emoteSend = false
    while emoteSend == false do
    emNum = math.random(1, #emoteTable)
    if not table.contains(usedEmotes, emoteTable[emNum]) then
    emoteSend = emoteTable[emNum]
    end
    end

    table.insert(usedEmotes, emoteSend)
    send(emoteSend, false)
    The way that works is that it'll continuously create a random number, until it meets a value that hasn't been used yet (isn't in the usedEmotes table). Once it does, it breaks the 'while' loop, and sends it, then adds that emote to the usedEmotes table until you reset it. The first one is probably the easiest.

    Changing the type of a variable - even if it's just local to an alias/function (which yours isn't!) - is a great way to make your code more prone to errors, especially if you're new to coding. Lua will let you do it (that's the beauty of a dynamically typed language) but it's generally not a good idea unless you really know what you're doing (I'm sure you do, but Riell doesn't).
  • PyoriPyori Member Posts: 1,796 @ - Epic Achaean
    Antonius said:
    Pyori said:
    --Initialise the tables here; again, have something to revert back to this state.
    emoteTable = { "hi", "wavehi", "hello", "greet", "smile" }
    usedEmotes = {}

    --Separate alias for sending the emote itself.
    emoteSend = false
    while emoteSend == false do
    emNum = math.random(1, #emoteTable)
    if not table.contains(usedEmotes, emoteTable[emNum]) then
    emoteSend = emoteTable[emNum]
    end
    end

    table.insert(usedEmotes, emoteSend)
    send(emoteSend, false)
    The way that works is that it'll continuously create a random number, until it meets a value that hasn't been used yet (isn't in the usedEmotes table). Once it does, it breaks the 'while' loop, and sends it, then adds that emote to the usedEmotes table until you reset it. The first one is probably the easiest.

    Changing the type of a variable - even if it's just local to an alias/function (which yours isn't!) - is a great way to make your code more prone to errors, especially if you're new to coding. Lua will let you do it (that's the beauty of a dynamically typed language) but it's generally not a good idea unless you really know what you're doing (I'm sure you do, but Riell doesn't).
    It's perfectly fine when you only have that one thing calling the variable. I tried to make the variable name obscure for that very reason.

  • ZerisZeris Member Posts: 70 ✭✭ - Stalwart
    edited July 2018
    So I'm trying to use the gmcp.Comm dealio for a chat capture script and I figured out how to convert the ANSI data, but I can't figure out how to strip out the backslashes. I don't want to do a general replace in the event that someone, for some reason, uses backslashes in speech, but leaving them in is annoying. Anyone know how I can accomplish this?

     text = "[0;1;32m(Market): Kriex says, \"Also buying a winductter!\"[0;37m",

  • NazihkNazihk Member Posts: 993 @ - Epic Achaean
    IMO, regardless of the whole variable retyping issue, it's bad form to suggest the "keep track of your random numbers and keep randoming until you get one you haven't gotten yet" method of random selection. It's hugely inefficient and subject to massive RNG tailing problems, and you're better off implementing another solution.
    Tvistor
  • PyoriPyori Member Posts: 1,796 @ - Epic Achaean
    @Zeris do it like this:
    local text = ansi2decho(gmcp.Comm.Channel.Text.text)
    <miniconsole to echo to>:decho(text.."\n")

    That'll take out all that extra stuff.


    Zeris
  • IvisIvis Member Posts: 5
    I've recently returned after a three year hiatus, and in the time away have forgotten the little bit of coding knowledge I had gained before... But what I'm basically trying to do is make a script to pick two random limbs, and also add in the ability to expend or not. 

    Something like: doublewhirl (target) (limb1) (limb2) (expend) 

    I know it requires tables of some sort, and that the alias should look something like ^d(\w)(\w)(\w)$
    but beyond that, I'm at a loss. 
  • ThaisenThaisen Member Posts: 127 ✭✭✭ - Distinguished
    Ivis said:
    I've recently returned after a three year hiatus, and in the time away have forgotten the little bit of coding knowledge I had gained before... But what I'm basically trying to do is make a script to pick two random limbs, and also add in the ability to expend or not. 

    Something like: doublewhirl (target) (limb1) (limb2) (expend) 

    I know it requires tables of some sort, and that the alias should look something like ^d(\w)(\w)(\w)$
    but beyond that, I'm at a loss. 

    I'm kind of confused. Do you want it to pick random limbs, or do you want to be able to specify limbs. You say random, but then your alias makes it seem like it should be specified. :)

    Also, mudlet?
  • CaelanCaelan Member Posts: 1,922 @ - Epic Achaean
    edited September 2018
    He/She can do both.  something like "if matches[3] == "" and matches[4] == "" then <random> else <not random>.

    And you probably don't need the mention of target in there since it is kind of a given and would require less typing in a fight.

    And to make it random, you really only need the expend option.

    Something like ^dw(?: |e)$

    local commands = {"hi", "wave", "bye"}
    local which = math.random(#commands)
    
    send(commands[which])


    You'd need to iterate over it a couple times filling in gaps. I use something similar where if one variable is empty, it fills it.  If it isn't, it moves to the next, then executes the command.

    Then add something like if matches[2] == "e" then <append the expend command>


  • IvisIvis Member Posts: 5
    Thaisen said:
    Ivis said:
    I've recently returned after a three year hiatus, and in the time away have forgotten the little bit of coding knowledge I had gained before... But what I'm basically trying to do is make a script to pick two random limbs, and also add in the ability to expend or not. 

    Something like: doublewhirl (target) (limb1) (limb2) (expend) 

    I know it requires tables of some sort, and that the alias should look something like ^d(\w)(\w)(\w)$
    but beyond that, I'm at a loss. 

    I'm kind of confused. Do you want it to pick random limbs, or do you want to be able to specify limbs. You say random, but then your alias makes it seem like it should be specified. :)

    Also, mudlet?
    Sorry, I meant to specify limbs. Not sure what that looks like though. Is the alias for that, that I had, correct? 
    I'm unsure of how to form the tables for those specific limbs. 

    Caelan said:
    He/She can do both.  something like "if matches[3] == "" and matches[4] == "" then <random> else <not random>.

    And you probably don't need the mention of target in there since it is kind of a given and would require less typing in a fight.

    And to make it random, you really only need the expend option.

    Something like ^dw(?: |e)$

    local commands = {"hi", "wave", "bye"}
    local which = math.random(#commands)
    
    send(commands[which])


    You'd need to iterate over it a couple times filling in gaps. I use something similar where if one variable is empty, it fills it.  If it isn't, it moves to the next, then executes the command.

    Then add something like if matches[2] == "e" then <append the expend command>

    The ability to pick random limbs also seems like an interesting option. Would that be: 

    local commands = {"head", "torso", "right arm", "left arm", "right leg", "left leg"}
    local which = math.random(#commands)

    send("doublewhirl "..target..[which]) 

    ??

    I'm not really sure of any of this, so I apologize if I'm butchering your suggestions. 
  • NazihkNazihk Member Posts: 993 @ - Epic Achaean
    local limbs = {"left leg", "right leg", "left arm", "right arm", "head", "torso"}
    math.randomseed(os.time())
    tsize = #limbs
    rn = math.random(tsize)limb1 = limbs[rn]
    --Uncomment the following two lines to ensure you don't pick the same limb twice
    --table.insert(limbs, tsize, table.remove(limbs,rn))
    --tsize = tsize -1rn = math.random(tsize)
    limb2 = limbs[rn]
    print("doublewhirl target "..limb1.." "..limb2)
    https://repl.it/repls/SillyFortunateWebsites

    There's some code that will select two random limbs, with an option to avoid picking the same limb twice.

    However, dwhirling random limbs is, generally speaking, a bad idea and you shouldn't do it. You want to plan when you break limbs and which limbs you are breaking, even when you're just rolling damage on somebody. 
    Caelan
  • KrizalKrizal Member Posts: 47 ✭✭✭ - Distinguished
    Alias: ^d([rfthli])(|x)([rfthli])(|x)$
    In this alias, matches[1] is the whole alias (you won't be needing this), matches[2] is one of "rfthli", same for matches[4], and matches[3] and matches[5] are either "" or "x".
    You can then hit left leg + right leg with "dfr", head+expend on right leg with "dhrx", expend on left arm+right leg with "dlxr".

    Script for the alias:
    local limbtable = {
    r = "right leg",
    f = "left leg",
    h = "head",
    t = "torso",
    l = "left arm",
    i = "right arm",
    }
    local firstlimb = limbtable[matches[2]]
    local secondlimb = limbtable[matches[4]]
    local expendfirst = matches[3]
    local expendsecond = matches[5]
    
    if expendfirst == "x" then --this will expend on the first limb you specify, eg. drxf
    send("doublewhirl "..target.. " "..firstlimb.. " expend "..secondlimb)
    elseif expendsecond == "x" then --will expend on the second limb, eg. drfx
    send("doublewhirl "..target.. " "..firstlimb.. " "..secondlimb.." expend")
    else --no expend
    send("doublewhirl "..target.. " "..firstlimb.." "..secondlimb)
    end
    
    

    Sobriquet
  • PyoriPyori Member Posts: 1,796 @ - Epic Achaean
    You could simplify that if block to just
    send( "doublewhirl "..target.." "..firstlimb..(expendfirst == "x" and " expend " or " ")..secondlimb..(expendsecond == "x" and " expend " or "") )


    KrizalCaelanDochitha
  • NazihkNazihk Member Posts: 993 @ - Epic Achaean
    Could do that, but shouldn't do that.

    It's a bad idea in general to sacrifice readability for decreased linecount and no measurable gain in performance, but espe[cially so when you're giving advice to non-coders.
    UtianimaTaryiusLeffe
  • KresslackKresslack Florida, United StatesMember Posts: 6,268 @@ - Legendary Achaean
    If I wanted to make a list of some items I use frequently, to reference them across multiple triggers and aliases, would the best way be to make a table to house the variables? Sort of like an equipment list is what I'm going for.


  • AccipiterAccipiter Member Posts: 462 ✭✭✭✭ - Eminent
    Depends on how you want to reference them.
    Equipment = {sword = "bastard1234", hat = "hat5678"} then call it with Equipment.sword
    Equipment = {sword = {desc = "An old rusty bastard sword", ID = "sword1234"}, hat = {desc = "a cute hat", ID = "hat5678"}} and call it with Equipment.sword.ID


    Mudlet can save variables across sessions now, or you could hard code it into a script.
    KresslackUtianima
  • KresslackKresslack Florida, United StatesMember Posts: 6,268 @@ - Legendary Achaean
    Accipiter said:
    Depends on how you want to reference them.
    Equipment = {sword = "bastard1234", hat = "hat5678"} then call it with Equipment.sword
    Equipment = {sword = {desc = "An old rusty bastard sword", ID = "sword1234"}, hat = {desc = "a cute hat", ID = "hat5678"}} and call it with Equipment.sword.ID


    Mudlet can save variables across sessions now, or you could hard code it into a script.
    Thank you, I'll give that a try.


  • KlendathuKlendathu Eye of the StormMember Posts: 3,178 @@ - Legendary Achaean
    The above image illustrates my issue. I want to have a big echo when the wind has blown me in a direction, but NOT if there is a wall blocking.

    Here's the trigger. What am I doing wrong?
    Actually, I think I know what's wrong - it's matching "A shrill wind blows you northeast." against the first line and the second line, then it's checking the next line, but it's already matched the first line twice and fired the trigger - but not how to fix it






    Tharos, the Announcer of Delos shouts, "It's near the end of the egghunt and I still haven't figured out how to pronounce Clean-dat-hoo."
  • KlendathuKlendathu Eye of the StormMember Posts: 3,178 @@ - Legendary Achaean
    Sorted it... I changed the trigger to just have the first line as regex:
    ^A shrill wind blows you (\w+).\$

    Then used the following code:
    blownDir = matches[2]
    tempLineTrigger(
      1,
      1,
      [[
        if not (line == "A wall blocks your way.") then
            guac.alert("BLOWN " .. blownDir:upper(),1)
        end
    ]]
    )



    Tharos, the Announcer of Delos shouts, "It's near the end of the egghunt and I still haven't figured out how to pronounce Clean-dat-hoo."
  • AccipiterAccipiter Member Posts: 462 ✭✭✭✭ - Eminent
    If I remember correctly, you want to have a gate trigger and have the second line in there with logic if you don't match. Cause everything in the triggers will try to match on each line, even if you have match all selected.
  • PyoriPyori Member Posts: 1,796 @ - Epic Achaean
    Would also work.


    KrizalVadimuses
  • VadimusesVadimuses Member Posts: 1,117 @ - Epic Achaean
    That
    1
    should be a line spacer pattern, for anyone looking
  • AntoniusAntonius Member Posts: 4,917 @@ - Legendary Achaean
    That (.*) should also just be ^ if you want to match literally anything, then use the line variable to do the comparison.
  • HolsteinHolstein Member Posts: 93 ✭✭✭ - Distinguished
    Had a chat about this with a few people and we never really found a true answer so I figure I will post it here.
     
    I want to use gmcp.Room.Info.exits to grab the first exit in the room and store it in a variable so that when I fire my pinshot alias it will grab an exit (makes absolutely no difference what exit) and will toss a lightwall there along with the pinshot on my target. gmcp.Room.Info.exits looks like this:

    {
      ne = 11104,
      u = 11095,
      e = 12453,
      d = 11089,
      w = 13229,
      nw = 11142
    }

    All I would want to do if I were in that room, would be grab "ne," the key in the first pair. The first thing I tried was to grab it by index, but gmcp.Room.Info.exits[1] didn't work, which I didn't think it would. Moving on from that, the only way I knew how to manipulate a k,v pair is with a for loop. Now the for loop worked, and it tossed a lightwall NE, but it obviously goes through the rest of the pairs and that can be spammy in a room with a bunch of exits such as the room this example is from. 

    My question is, is there a way to just grab the key from the first pair in that array without running through the whole array and spamming myself?
    Roll the windows down
    This cool night air is curious
    Let the whole world look in
    Who cares who sees anything?
  • CyrCyr Member Posts: 168 ✭✭✭ - Distinguished
    edited November 2018
    for k,v in pairs(gmcp.Room.Info.exits) do
     send("conjure lightwall " ..k)
    end
    or write a function that does that with a return so it only ever sends once

    Dunn tells you, "I hate you."
    (Party): You say, "Bad plan coming right up."
  • CyrCyr Member Posts: 168 ✭✭✭ - Distinguished
    There's meant to be a break in that loop. Whups
    For k, v in pairs (gmcp.Room.Info.exits) do
           Send("conjure lightwall "..k)
           Break
    End

    Dunn tells you, "I hate you."
    (Party): You say, "Bad plan coming right up."
    Holstein
  • HolsteinHolstein Member Posts: 93 ✭✭✭ - Distinguished
    Cyr said:
    There's meant to be a break in that loop. Whups
    For k, v in pairs (gmcp.Room.Info.exits) do
           Send("conjure lightwall "..k)
           Break
    End
    Awesome, thank you!
    Roll the windows down
    This cool night air is curious
    Let the whole world look in
    Who cares who sees anything?
  • RiellRiell Member Posts: 209 ✭✭✭ - Distinguished


    HELP WHY IS EVERYTHING GRAYED OUT
  • VadimusesVadimuses Member Posts: 1,117 @ - Epic Achaean
    Update Mudlet? That looks wrong.
Sign In to Comment.