Skip to content

Mudlet Scripting

1101113151618

Comments

  • Oh, I thought we had to specify open tattoo slots. Thanks for the tip!
  • It will also automatically OUTR the appropriate inks, so that is not an issue anymore either. 

    "On the battlefield I am a god. I love war. The steel, the smell, the corpses. I wish there were more. On the first day I drove the Northmen back alone at the ford. Alone! On the second I carried the bridge! Me! Yesterday I climbed the Heroes! I love war! I… I wish it wasn’t over."

  • Imperian has a lot of QoL features like that :)
    currently tentatively active
    (may vanish for periods of time)
  • A few people may know Vadi, but as Imperian is not one of the IRE games he's ever played seriously, it seems like most of us actually don't know him here unless we've played either Achaea or Lusternia.  I can't overemphasize the impact his client (he's the head guy behind mudlet) and his system (svo) have had.  And now, svo has gone open source, which means that we (and especially those of you who have greater aptitude at this sort of thing) can mine the hell out of it, and I also think a lot of it would be very useful in any MUD.  One thing about svo was that in the past, a great deal of its guts were "under the hood".  So with that, have a look here.  I really think a lot of you are going to be interested:


  • I was actually considering buying it for a different IRE mud at some point just so I could look in it. What great news! =D
    image
  • Jules said:
    A few people may know Vadi, but as Imperian is not one of the IRE games he's ever played seriously, it seems like most of us actually don't know him here unless we've played either Achaea or Lusternia.  I can't overemphasize the impact his client (he's the head guy behind mudlet) and his system (svo) have had.  And now, svo has gone open source, which means that we (and especially those of you who have greater aptitude at this sort of thing) can mine the hell out of it, and I also think a lot of it would be very useful in any MUD.  One thing about svo was that in the past, a great deal of its guts were "under the hood".  So with that, have a look here.  I really think a lot of you are going to be interested:


    http://www.achaea.com/game/news/Achaea/Announce/4398



    Definitely have Svo, had no idea he made it open source. He's a great coder, and now I intend on digging through his stuff.

  • edited September 2015
    Heh, so.  I got a good reminder of how rare it is for someone who does understand coding to be able to work with someone who doesn't just "get it".  It was pretty awful.  There were tables involved.  To someone who just "gets" everything about coding, it tends to be inconceivable that what they just said isn't completely clear and obvious, and you can see that they are pretty much convinced you're being willfully stupid.  He was so mad.  If I ever want to to troll someone, I should probably ask them to help me with tables.  

    So before all of that happened, I had been playing around last night and I did finally get a sort of handle on some gmcp stuff (on my own, even), which for me, was huge, because I just haven't been able to work with the event handler, which you really do need to be able to do things with gmcp.  And absolutely everything about these things is horribly alien and strange and non-intuitive.  Part of why it was so hard, is that most people who have made stuff that uses gmcp have done it in the fanciest way possible, with all sorts of extra code I do not understand how to pick out yet.  And also, because of the very strange way that the event handler itself needs "hooks".  There is this incredibly strange circular logic of "dependency" that I still can't quite hold on to.  So anyway, then I was able to get specific gmcp values I want into tables, and echo those new tables with a newline between each thing.  

    What I can't do (and how this whole debacle came up) is make those new values echo in the way I'd want.  And of course what I would want is, if I have a "name" that is say "fenugreek" from my rift stuff, and then an "amount" of "345" I would want to be able to print those two values on a single line and then go to the next "name" and "amount" values.  I literally drove a guy to go get a drink trying to make this happen :(  I am absolutely positive it is some small snippet of code I can't quite find/figure out.  My current table looks like so:  http://hastebin.com/bibowajibi   This table is not particularly useful or important, but if I could just understand the process, I might be able to make something that IS useful.  At this point, I just need to understand "thing that manipulates table into strings the way I want" (but that is proving to be even more insanely hard than the other stuff).  
  • @Jules. I totally feel your pain ... 
  • IniarIniar Australia
    edited September 2015
    From your table.

    newTable = {}
    for i=1,#myTable,2 do
    local item = myTable[i]
    local count = myTable[i+1]

    newTable[item] = count
    end

    for key,value in pairs(newTable) do

    cecho("\n"..key..": ("..value..")")

    value = tonumber(value)
    -- example code for specific threshold found
    if type(value) == "number" and value < 20 then
    cecho(" ... Running out of "..key.."!")
    end

    -- example code for specific item found etc
    if key == "mandrake" then -- do something
    cecho("\n I found "..key.."!")
    end
    end
    wit beyond measure is a Sidhe's greatest treasure
  • edited September 2015
    Iniar said:
    From your table.

    newTable = {}
    for i=1,#myTable,2 do
    local item = myTable[i]
    local count = myTable[i+1]

    newTable[item] = count
    end

    for key,value in pairs(newTable) do

    cecho("\n"..key..": ("..value..")")

    value = tonumber(value)
    -- example code for specific threshold found
    if type(value) == "number" and value < 20 then
    cecho(" ... Running out of "..key.."!")
    end

    -- example code for specific item found etc
    if key == "mandrake" then -- do something
    cecho("\n I found "..key.."!")
    end
    end
    Oh god I am glad I came back to refresh this.  I felt like there has to be maybe a tonumber in there or something but wasn't sure about that, or where to put it.  It werrrrrks.  And now I have two different versions that sort of deal with this to look at because someone else came through with a version as well, which is:


    str = ""

    tick = 1

    for i in ipairs(my_rift) do

    num = tonumber(my_rift[i].amount)/10

    color = mtw.coloring(num)

    if tick <= 3 then

    str = str.." \n<khaki>"..my_rift[i].name..": "..color..my_rift[i].amount

    tick = tick +1

    else

    str = str.."\n<khaki>"..my_rift[i].name..": "..color..my_rift[i].amount

    tick = 1

    end

    end

    cecho(str)


    ^^^^ EDIT:  Oops, this is the alias... ^^^^




    and then:    my_rift = gmcp.IRE.Rift.List

    ^^^^ put that in a script box with the event handler gmcp.IRE.Rift

    If I were really serious about rifts in particular I would probably stick with actually requesting the whole rift and updating the contents that way, and use Iniar's method of dealing with the table contents, and use the pretty color thing to organize them (the pretty table version does not update as is).  
  • Did they give that to you all on one line to troll you or is this some sneaky Jules plot to make us all cry.
  • I think I hopefully fixed that now, before edit time closes.  
  • edited October 2015
    1. My mudlet map, which I usually keep hidden, started to pop up with every line of input from me. This started happening at complete random, since it began the tail end of a hunting trip. After I got frustrated at this, I left-clicked the map button and selected the empty space below.

    2. So now my toolbar is missing, and I have no idea how to get it back. And my map is still there, mocking me.

    Also, is anyone able to add me to the 'mudlet chat' clan in game, or at least refer me to the short list of people I can ask questions on the fly?

    Thanks for the help. =D
     You say, "This is much harder than just being a normal person."
  • I'll add you if you haven't been already
  • IniarIniar Australia
    Ive been getting a lot of garbled GMCP info lately... so much so that I have to log/relog repeatedly. Cant even tell if its on my end or from Imperian. :(
    wit beyond measure is a Sidhe's greatest treasure
  • edited October 2015

    An info grabber from the website honors. Honorable mention to @Iniar for halpings



    function trueHonours(target)

    local path = "http://www.imperian.com/game/honors/Imperian/"..target

    local saveto = getMudletHomeDir().."/page.html"


    downloadFile(saveto,path)


    io.input(saveto)

    local s = io.read("*all")


    -----Change the sys.profiler mentioned here to wherever you want to store the captured data

    if not sys.profiler[target] then sys.profiler[target] = {} end

    sys.profiler[target].name = string.match(s,"Name: (%a+)")

    sys.profiler[target].fullname = string.match(s,"Full name: (.-)[%<]")

    sys.profiler[target].class = string.match(s,"Profession: (%a+)")

    sys.profiler[target].level = string.match(s,"Level: (%d+)")

    sys.profiler[target].city = string.match(s,"City: (%a+)")

    sys.profiler[target].guild = string.match(s,"Guild: (%a+)")

    sys.profiler[target].desc = string.match(s,"Description: (.-)[%<]")



    io.open():close()

    os.remove(saveto)


    end

  • Imo, use the API accessible json pages: http://api.imperian.com/characters/kabaal.json
    image

  • local herb = matches[2]

    local herbLeft = matches[4]


    if not herbTable then herbTable = {} end


    table.insert(herbTable.herb,herbLeft)


    if tonumber(herbLeft) < 50 then

    cecho("\n<red>Running low on " .. herb .. "!")

    end



    Hey guys, I'm trying to insert to herbTable so that I could call on herbTable.kelp and it will show the amount left.  The variables I am catching from a trigger are good, so the problem is the bolded.  If anyone could give me some insight, I would appreciate it!

  • local herb = matches[2]

    local herbLeft = matches[4]


    if not herbTable then herbTable = {} end


    if tonumber(herbLeft) < 50 then

    cecho("\n<red>Running low on " .. herb .. "!")

    herbTable[herb] = herbLeft

    table.insert(herbTable.herb,herbLeft)

    end


    So i've made the following changes in bold, and it is working nicely.  The problem I have now, is that if the plant has two names.  for instance violet root.  It is storing it in the table like this.


    {

      toadstool = "49",

      kelp = "18",

      ["violet root"] = "23",

      linseed = "29"

    }



  • The problem is that your trigger pattern is capturing both words.

    Two solutions:

    1. Modify the trigger pattern so it does not pick up the root/flower/leaf/gum/seed/etc after the plant name, or the 'prickly' before prickly pear. 

    2. Alternatively, you can do string manipulation after the fact to discard the extra stuff. Split it on a space, if the second word is "pear" then herb is pear, else herb is the first word, etc. 

    The first solution is the more elegant solution, but the latter involves less finicky regex if that's an issue for you(though learning regex is always good!). Either solution would be adequate here, so this is really down to personal preference. 

    "On the battlefield I am a god. I love war. The steel, the smell, the corpses. I wish there were more. On the first day I drove the Northmen back alone at the ford. Alone! On the second I carried the bridge! Me! Yesterday I climbed the Heroes! I love war! I… I wish it wasn’t over."

  • Could also use something like the following for Khizan's Solution #2:


    plantlist = {"endive", "fenugreek", "galingale", "ginger",

     "hyssop", "juniper", "kelp", "laurel", "linseed", "lovage",

     "maidenhair", "mandrake", "myrrh", "nightshade", "orphine", "pear",

     "primrose", "quince", "toadstool", "violet", "weed", "wormwood"}


    function getPlantShortName(fullName)

      for i, v in ipairs(plantlist) do

        if fullName:match(v) then

          return v

        end

      end

      return "unknown"

    end

    image
  • Here's another one.

    What would a function look like that sorts a table to echo each string value back in the order it was originally inserted?

    For instance:

    If I create a table and insert strings "one" "two" "three" "four", how would I retain that order when looping the table to echo?


    Thank you!
  • edited October 2015
    There are places online that might do a better job explaining this, but I'll give it a try...

    Example one(how you probably want to do ordered arrays):

    listOfStrings = {}
    table.insert(listOfStrings, "one")
    table.insert(listOfStrings, "two")
    table.insert(listOfStrings, "three")
    table.insert(listOfStrings, "four")

    echo("List: " .. table.concat(listOfStrings, ", "))
    -- List: one, two, three, four

    for i, v in ipairs(listOfStrings) do
      echo(i .. ": " .. v .. "\n")
    end
    -- 1: one
    -- 2: two
    -- 3: three
    -- 4: four

    table.remove(listOfStrings, 3)

    for i, v in ipairs(listOfStrings) do
      echo(i .. ": " .. v .. "\n")
    end
    -- 1: one
    -- 2: two
    -- 3: four


    Example two(what to be wary of):

    listOfStrings = {}
    listOfStrings[1] = "one"
    listOfStrings[2] = "two"
    listOfStrings[3] = "three"
    listOfStrings[4] = "four"

    --everything still looking good at this point

    listOfStrings[3] = nil

    display(listOfStrings)
    --{
    -- 1, "one"
    -- 2, "two"
    -- 4, "four"
    --}
    --note that when you remove the entry by assigning it to nil, it does NOT automatically adjust like it does with table.remove on an ordered index
    --this leads to the part that I think trips most people up the first few times

    for i, v in ipairs(listOfStrings) do
      echo(i .. ": " .. v .. "\n")
    end
    -- 1: one
    -- 2: two

    --when you use ipairs(and table.concat, which AFAIK utilizes ipairs), it only lists off ordered numeric entries until it hits a nil entry
    --this means when you break the consecutive entries(like we did by nilling out that entry), ipairs will NOT see past that missing entry

    tl;dr: if your table is a consecutive list of numeric-indexed entries, use ipairs and table.concat; for everything else, use pairs(which will always give you ever entry, but does not return them in a specific order(despite what it might look like))

    More reading by people more qualified than me:

    image
  • Dicene thank you so much!

    If you could shed some insight on this... 
    What if I wanted to create a function that would pull the first value of my table (as it was originally inserted) then on it's next iteration, it would pull the second value, then the third, et cetra... without deleting any value of the table.

    I know this is quite a choir, and making it elegant is tricky.  Thank you in advance for any tips.
  • It's not quite gonna be elegant but...

    exampleList = exampleList --already defined, cause I'm lazy

    currentIndex = 0

    function nextIndex()

      currentIndex = currentIndex + 1

      if currentIndex > #exampleList then
        currentIndex = 1
      end

      return exampleList[currentIndex]

    end



    If you're looking to have the index self-contained in the function, that's a little beyond me. Never really had a situation where I HAD to do it that way, so I've never actually done it that way.
    image
  • Is there any way to use
    table.remove(sampleTable, key)

    but call a value rather than it's position in the table?

    I'm trying to track defences in a table and I'm not sure how I'd go about removing one without being able to call the defence from a "You have lost xxx" trigger
  • edited October 2015
    If you're tracking them like: defences["fitness"] then you can simply do:

    defences["fitness"] = false


    If you're tracking them with table.insert(defences, "fitness") (which probably isn't the easiest way to track it) you can do:

    table.remove(defences, table.index_of(defences, "fitness"))


    Edit: Another option if you're feeling frisky would be to use a meta-table to replace table.remove with a function that can accept strings to do the above for you, instead of erroring when a string is received.
    image
  • IniarIniar Australia
    edited October 2015
    image

    Fixt.

    Kind of.

    image

    Time to show off:

    image

    Etc:

    image
    wit beyond measure is a Sidhe's greatest treasure
  • I'm stuck here.  I'm looking to create a "countdown" function that will iterate through a table and create a variable that I can then display in a status type window.

    For example.

    table = { buffOne = 50, buffTwo = 40, buffThree = 30 }

    So I'm thinking:

    function countDown()
    for k,v in pairs(table) do
    local timeLeft = tonumber(v)
    tempTimer(1,[[timeLeft = timeLeft - 1;countDown()]])
    end
    end

    Kinda gets me close.. but what I need is for the countdown timers to be unique for each key,value pair in "Table".  They need to countdown independently from each other.

    Dicene I need your wizardry...

  • @Mirrors

    Just woke up, so everything below may be utterly incorrect.

    I'd probably just run the countDown through a perma timer. 

    This is the script I use for my tracker collection on a 3s timer 


    So, just make the 1s timer, then throw in something like


    It could maybe work! Or blow up your computer. One of the two.

    ((Also, square brackets are a pain for passing functions along. Use

     function () <code here> end 

    instead.))
Sign In or Register to comment.