Quick Coding Questions

13468924

Comments

  • How do you add a background image to a label? Or, alternatively, move a label up/down a layer? 
  • edited February 2016

    You need to create labels in a specific order. The first label is on the bottom, the next will be created on top of the first, and so on.

    Example label with a background image where the container is an HBox:

    tab_all = Geyser.Label:new({
       name = "all channels tab", x = 0, y = 0, height = 20
    }, tab_container)
    tab_all:setBackgroundImage([[C:\path\to\tab_all_inactive.png]])
  • edited February 2016
    function killthemded(limbtarget, aliasname)
    if not table.contains(targetafftable, "paralysis") then
    if not table.contains(targetafftable, "nausea") then
    snbcombo = "slice " .. limbtarget .. "euphorbia smash mid"
    elseif not table.contains(targetafftable, "clumsy") and not table.contains(targetafftable, "mighthaveclumsy") then
    snbcombo = "slice " .. limbtarget .. "xentio smash mid"
    elseif not table.contains(targetafftable, "weariness") and not table.contains(targetafftable, "mighthaveweariness") then
    snbcombo = "slice " .. limbtarget .. "vernalius smash mid"
    elseif not table.contains(targetafftable, "asthma") then
    snbcombo = "slice " .. limbtarget .. "curare drive"
    elseif not table.contains(targetafftable, "slickness") then
    snbcombo = "slice " .. limbtarget .. "gecko smash mid"
    elseif not table.contains(targetafftable, "anorexia") and not table.contains(targetafftable, "nofocus") then
    snbcombo = "slice " .. limbtarget .. "slike smash high"
    elseif not table.contains(targetafftable, "anorexia") then
    snbcombo = "slice " .. limbtarget .. "slike smash mid/shieldstrike &tar low"
    elseif not table.contains(targetafftable, "weariness") then
    snbcombo = "slice " .. limbtarget .. "vernalius smash mid/shieldstrike &tar low"
    else
    snbcombo = "slice " .. limbtarget .. "curare smash high/shieldstrike &tar low"
    end
    elseif not table.contains(targetafftable, "clumsy") and not table.contains(targetafftable, "mighthaveclumsy") then
    if not table.contains(targetafftable, "nausea") then
    snbcombo = "slice " .. limbtarget .. "euphorbia smash low"
    elseif not table.contains(targetafftable, "weariness") and not table.contains(targetafftable, "mighthaveweariness") then
    snbcombo = "slice " .. limbtarget .. "vernalius smash low"
    elseif not table.contains(targetafftable, "asthma") then
    snbcombo = "slice " .. limbtarget .. "xentio drive"
    elseif not table.contains(targetafftable, "slickness") then
    snbcombo = "slice " .. limbtarget .. "gecko smash low"
    elseif not table.contains(targetafftable, "anorexia") and table.contains(targetafftable, "nofocus") then
    snbcombo = "slice " .. limbtarget .. "slike smash high"
    elseif not table.contains(targetafftable, "anorexia") then
    snbcombo = "slice " .. limbtarget .. "slike smash low"
    elseif not table.contains(targetafftable, "weariness") then
    snbcombo = "slice " .. limbtarget .. "vernalius smash high/shieldstrike &tar low"
    else
    snbcombo = "slice " .. limbtarget .. "aconite smash high/shieldstrike &tar low"
    end
    elseif not table.contains(targetafftable, "asthma") then
    if not table.contains(targetafftable, "nausea") then
    snbcombo = "slice " .. limbtarget .. "euphorbia drive"
    elseif not table.contains(targetafftable, "weariness") and not table.contains(targetafftable, "mighthaveweariness") then
    snbcombo = "slice " .. limbtarget .. "vernalius drive"
    elseif not table.contains(targetafftable, "slickness") then
    snbcombo = "slice " .. limbtarget .. "gecko drive"
    elseif not table.contains(targetafftable, "anorexia") and not table.contains(targetafftable, "nofocus") then
    snbcombo = "slice " .. limbtarget .. "slike smash high"
    elseif not table.contains(targetafftable, "anorexia") then
    snbcombo = "slice " .. limbtarget .. "slike drive/shieldstrike &tar low"
    else
    snbcombo = "slice " .. limbtarget .. "kalmia smash high/shieldstrike &tar low"
    end
    elseif not table.contains(targetafftable, "slickness") then
    snbcombo = "slice " .. limbtarget .. "gecko smash high/shieldstrike &tar low"
    elseif not table.contains(targetafftable, "anorexia") then
    snbcombo = "slice " .. limbtarget .. "slike smash high/shieldstrike &tar low"
    elseif not table.contains(targetafftable, "weariness") then
    snbcombo = "slice " .. limbtarget .. "vernalius smash high/shieldstrike &tar low"
    elseif not table.contains(targetafftable, "weariness") then
    snbcombo = "slice " .. limbtarget .. "vernalius smash high/shieldstrike &tar low"
    else
    snbcombo = "slice " .. limbtarget .. "aconite smash high/shieldstrike &tar low"
    end


    function targetaffreset()
    targetafftable = {}
    sysecho("green", " --- RESET ALL AFFLICTIONS --- ")
    promptafftable = {}
    darkshadecountdown = false
    coagulating = false
    end


    function targetaffadd(affliction)

    if not table.contains(targetafftable, affliction) then

    table.insert(targetafftable, affliction)

    end
    end

    Above is my code.  I'm just learning, so it's pretty rudimentary, I know, but I'm having some serious problems.

    When I use the alias on a target that is not curing, it first gives then nausea/paralysis, then it does nothing.  Absolutely nothing.  If the target is curing, it does nothing when they have paralysis.  After fiddling around, I found that when the target has paralysis, the activated/deactivated box next the script's name is the ladybug, and this bug message appears:

    Lua syntax error: ./mudlet-lua/lua/TableUtils.lua:101:bad argument #1 to 'pairs' (table expected, got string)


    I have 0 idea what that means.  Any help?
  • edited February 2016
    That error means what it says. The pairs function expects a table, but your script is giving it a string somewhere.

    You'd be much better off using a table like this:
    targetafftable = {
    paralysis = false,
    ...
    }

    if targetafftable.paralysis then
    ...
    The table.contains function source:
    function table.contains(t, value)
    for k, v in pairs(t) do
    if v == value then
    return true
    elseif k == value then
    return true
    elseif type(v) == "table" then
    if table.contains(v, value) then return true end
    end
    end
    return false
    end


  • I'll give that a try!  Thanks!
  • edited February 2016
    Qwyn said:
    Question about scripts - you said they run at startup. Do all your scripts automatically run at startup? Can you reference a script to make it run again? Can you exclude a script from running at startup? Like, if I wanted to make a setup for milling inks or gathering herbs, could I write a script for the bulk of the work and just feed in values, and only run it when I tell it to run? I had assumed that's what they did, and now I'm a bit confused.
    Do all your scripts automatically run at startup?: Yes, if they're checked. They also run every time you edit them and save (this is one of the reasons to use the or thing - so if you edit a script and it runs again, it won't reset the variable to the default).

    Can you reference a script to make it run again?: No. Well, maybe (there's probably a function in Mudlet somewhere for it). But you shouldn't. If you want to run something in a script, have the script define a function that does that thing, then call the function from your trigger or alias or whatever. If you want whatever the function does to run at startup too, just call the function right after defining it in the script.

    Can you exclude a script from running at startup?: Just uncheck it.

    Like, if I wanted to make a setup for milling inks or gathering herbs, could I write a script for the bulk of the work and just feed in values, and only run it when I tell it to run?: What you are describing is a function, not a script.

    One thing that seems to be a really common hangup is thinking that your code and the stuff it produces are the same thing. They aren't. Your code is like a recipe and the computer is the cook that takes you recipe and produces some invisible state. Don't get the recipe and the dish it makes confused. When you say [target = "rat"], that isn't the variable itself, that's a recipe for the variable - you're saying "dear computer: set the contents of your invisible target variable to "rat"". When you reference your target variable later, you're saying "dear computer: please use whatever is contained in the variable called target".

    Defining a function is a way of saying "Dear computer: set the contents of an invisible variable named <function name> to this list of instructions that I don't want you to follow right now, but I want you to remember them under this name so I can tell you to follow them later". The script that defines your function isn't the instructions you want the computer to follow later, it's an instruction to remember those instructions (it's the recipe for a recipe). You usually want to put function definitions like this into Scripts in Mudlet because you want to get the functions set up as soon as possible, so they're ready to call whenever you need them.

    And "feeding in values" is exactly what functions let you do.

    So here's an example of a really simple function (note: any time I use brackets below, it's just to make it clear what is and isn't code):

    function helloName (name)
        send("say Hello " .. name)
    end
    Now if you just have this in your script, it doesn't do anything. All you've done is told the computer to store this list of instructions under the name helloName. When you want to actually use them, you do:
    helloName("Tael")
    Now that tells the computer: look for the function called helloName and run it. Notice how I passed the function the string "Tael" - that gets passed as the first argument to our helloName function which we called [name] (we could have called it anything we want, the point is that when it comes up again inside the function, it refers to the value of the argument - so name gets bound to "Tael" and when the function execution goes to see who to say hello to, it looks up the value of name, which is "Tael").

    In fact, functions are even neater - there are two other important things you can do with functions.

    The first is local variables. Let's say I want to say hello to two people:
    function helloName (nameOne, nameTwo)
        local toSend = "say Hello " .. nameOne .. " and " .. nameTwo
        send(toSend)
    end
    (I could have just done send("say Hello " .. nameOne .. " and " .. nameTwo), but bear with me.)

    The thing is, what if you have a variable named [toSend] somewhere else? Or some other function that uses a variable called [toSend]? You don't want those variables interfering with each other. Well, you don't have to worry: local variables only exist inside the function, so it won't matter. If you called this function then tried to print toSend, Mudlet would tell you it has no idea what toSend is. It's a good habit to keep as many variables local as you possibly can. Arguments are local variables too. If you run this function and then ask what nameOne or nameTwo is, the computer won't have any idea - it only knows about them while running the instructions inside the function.

    The other thing functions can do is return things.

    Let's say you want to remember the last message you sent. You could just save it to a normal global variable, but let's say you only want to save it sometimes. Or maybe you have two aliases that both call your helloName function, but you want to save the messages it sends independently. This is where return comes in.
    function helloName (nameOne, nameTwo)
        local toSend = "say Hello " .. nameOne .. " and " .. nameTwo
        send(toSend) return toSend
    end
    So now instead of your aliases both looking like [helloName(matches[2], matches[3])], one can look like [savedCommandOne = helloName(matches[2], matches[3])] and the other can look like [savedCommandTwo = helloName(matches[2], matches[3])]. These run the function, passing it the arguments, then save whatever was returned to a variable.

    The only thing to remember about this is that return must be the last thing in the function (the computer stops executing the function as soon as it hits a return).
  • I want to do two things, but don't know how to do them.

    1) Condense mindnet party announcing to do one line for multiple enemy entrances/departures instead of an announce for each individual person.

    2) I have a fullsense script that will announce all enemies in the area. What I want to do is to somehow include the room name with the area. I've already learned that gmcp.Room.Info.name does not do that, hehe.
    Give us -real- shop logs! Not another misinterpretation of features we ask for, turned into something that either doesn't help at all, or doesn't remotely resemble what we wanted to begin with.

    Thanks!

    Current position of some of the playerbase, instead of expressing a desire to fix problems:

    Vhaynna: "Honest question - if you don't like Achaea or the current admin, why do you even bother playing?"


  • function targetaffadd(affliction)
    	targetafftable.affliction = true
    		if affliction == "weariness" then
    			targetafftable.mighthavewearines = false
    		end
    end

    If I call targetaffadd("weariness"), will this function set

    targetafftable.weariness = true

    and

    targetafftable.mighthaveweariness = false

    ?

    Or do I need to do it another way?
  • function targetaffadd(affliction)
    	targetafftable[affliction] = true
    	if affliction == "weariness" then
    		targetafftable.mighthavewearines = false
    	end
    end

  • KlendathuKlendathu Eye of the Storm
    Ismay said:
    I want to do two things, but don't know how to do them.

    1) Condense mindnet party announcing to do one line for multiple enemy entrances/departures instead of an announce for each individual person.

    2) I have a fullsense script that will announce all enemies in the area. What I want to do is to somehow include the room name with the area. I've already learned that gmcp.Room.Info.name does not do that, hehe.
    1. Have a trigger to add the names to a table, eg mindnetNames, then have something run on prompt to table.concat(mindnetNames,", ") and announce that, also clearing the table.

    2. There's a function somewhere in the Mudlet mapper scripts you can steal borrow. Can't recall offhand the name though (mmp.locateandecho?), so you'll have to search for 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."
  • AhmetAhmet Wherever I wanna be
    Klendathu said:
    Ismay said:
    I want to do two things, but don't know how to do them.

    1) Condense mindnet party announcing to do one line for multiple enemy entrances/departures instead of an announce for each individual person.

    2) I have a fullsense script that will announce all enemies in the area. What I want to do is to somehow include the room name with the area. I've already learned that gmcp.Room.Info.name does not do that, hehe.
    1. Have a trigger to add the names to a table, eg mindnetNames, then have something run on prompt to table.concat(mindnetNames,", ") and announce that, also clearing the table.

    2. There's a function somewhere in the Mudlet mapper scripts you can steal borrow. Can't recall offhand the name though (mmp.locateandecho?), so you'll have to search for it.
    Fullsense only finds people in your current area, so gmcp.Room.Info.area will always contain what area you're fullsensing. To pull the room name, you'll have to set up a trigger for the fullsense.
    Huh. Neat.
  • Jacero said:
    function targetaffadd(affliction)
    	targetafftable[affliction] = true
    	if affliction == "weariness" then
    		targetafftable.mighthavewearines = false
    	end
    end

    Does "affliction" need quotes?  Ex: targetaffadd("weariness")  or targetaffadd(weariness)
  • Yes, it does need "'s, if you don't have them, then it is presumed to be a variable.
  • Matias said:
    Yes, it does need "'s, if you don't have them, then it is presumed to be a variable.
    It's a variable in a table.

    targetafftable = {
         paralysis = false
         }

    Still need quotes?
  • In the definition of the function, you don't use quotes. You're declaring a parameter for the function - or, in other words, you're defining the name of a variable (locally-scoped to the function) to be created when that function is called. When calling that function, you'd want double quotes (because you want the affliction variable inside the function to have the actual string value "weariness"). Calling targetaddaff("weariness") would essentially make the body of the function (for that specific call) the same as this:

    
    targetafftable["weariness"] = true
    if "weariness" == "weariness" then
    	targetafftable.mighthavewearines = false
    end
    
  • Antonius said:

    In the definition of the function, you don't use quotes. You're declaring a parameter for the function - or, in other words, you're defining the name of a variable (locally-scoped to the function) to be created when that function is called. When calling that function, you'd want double quotes (because you want the affliction variable inside the function to have the actual string value "weariness"). Calling targetaddaff("weariness") would essentially make the body of the function (for that specific call) the same as this:

    targetafftable["weariness"] = true
    if "weariness" == "weariness" then
    	targetafftable.mighthavewearines = false
    end
    
    I think I actually understand that.  Thank you!
  • KlendathuKlendathu Eye of the Storm
    I must be missing something bloody obvious, but can't see it for the life of me. I want the script to fire when there's change in max hp (dragonforming, changing artefacts, etc), but it steadfastedly refuses to fire... HAAAALP!

    kln.resetSipThresholds = function()
    print("Resetting sip thresholds")
    end
    registerAnonymousEventHandler("gmcp.Char.Vitals.maxhp","kln.resetSipThresholds")



    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."
  • edited February 2016
    The server sends Char.Vitals to the client (which is then processed and put into the gmcp table), not Char.Vitals.maxhp. Your function will never be called as it is currently.
  • Maxhp changing won't fire a maxhp event it'll fire the char.vitals event where you'll have to check if something has changed inside on your own
    image
  • KlendathuKlendathu Eye of the Storm
    Told you it would be something simple! Will have to modify my function to trigger off gmcp.Char.Vitals with the argument maxhp. Thanks both.

    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."
  • Did some testing earlier. Seems like burn salve prios aren't syncing with serverside and svof?

    With serverside turned on : https://ada-young.appspot.com/pastebin/197c7382
    With serverside turned off : https://ada-young.appspot.com/pastebin/041eef99
    Salve prios : https://ada-young.appspot.com/pastebin/ba496169

    Has anyone else run into this problem?

    [ SnB PvP Guide | Link ]

    [ Runewarden Sparring Videos | Link ]
  • Is SnB Ferocity tracked in GMCP?  And if no one has the answer, how can I find out?
  • {
      wp = "20600",
      eq = "1",
      ep = "28175",
      charstats = {
        "Bleed: 0",
        "Rage: 0",
        "Devotion: 94%",
        "Spec: Sword and Shield"
      },
      maxhp = "6418",
      hp = "6418",
      nl = "48.4",
      maxep = "28175",
      maxmp = "4752",
      mp = "4752",
      maxwp = "20600",
      string = "H:6418/6418 M:4752/4752 E:28175/28175 W:20600/20600 NL:48.4/100 ",
      vote = "1",
      bal = "1"


    That's gmcp.Char.Vitals

    If it was tracked, it would be somewhere in this (I believe), so I would have to assume that it isn't listed in gmcp.




    Penwize has cowardly forfeited the challenge to mortal combat issued by Atalkez.
  • It's not, yeah. Can always msg Makarios/Tecton to ask if it can! I'm pretty sure they were looking for ideas of what else to put in it. Just gotta capture the lines after each combo you do.

  • If I were to create a function that just loops restoration on legs to prevent dying to axekick spam, is there a way to get it to terminate on a torso break(via diagnose) or a limb break then restart once that is cured?

    [ SnB PvP Guide | Link ]

    [ Runewarden Sparring Videos | Link ]
  • KlendathuKlendathu Eye of the Storm
    If I were to create a function that just loops restoration on legs to prevent dying to axekick spam, is there a way to get it to terminate on a torso break(via diagnose) or a limb break then restart once that is cured?
    Somewhere in your loop you'd need a check for the affliction with the option to escape the loop.


    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."
  • edited February 2016
    1. Starting a System from scratch? How would I do that? I hear namespaces are the way to go but I never know how to code efficiently/neatly so that I can begin my own system. Now so much curing right now but offense/queuing/hunting/general stuff.


    --I'd like a categorized list if plausible to note the very basics/foundation of a system.--


    2. Making an affliction tracker, what do I need to account for? timers, etc.


    3. How would someone track smart afflictions(i.e smash high, sicken) I'll use sicken - it gives paralysis > manaleech > slickness. For any means of writing an affliction tracker - how would someone account for the ability giving different afflictions and more importantly how would they use that logic in the selection of afflictions?

  • Klendathu said:
    If I were to create a function that just loops restoration on legs to prevent dying to axekick spam, is there a way to get it to terminate on a torso break(via diagnose) or a limb break then restart once that is cured?
    Somewhere in your loop you'd need a check for the affliction with the option to escape the loop.

    Yeah it is abusable. Maybe cripple axk cripple axk, still looks scary. 
  • Namespacing is important if you want to write clean, readable code that has no chance of conflicting with anything else you might install from other people. You can code everything you need to without using namespaces, but it's not a really a good idea; your code will be messy as hell and a lot harder to write and maintain.

    The very basic foundation of a system is the list of requirements for what you need it to do. If you don't have that you shouldn't really be writing any code. You can always change or add requirements later on, but you have to have an initial list of things you want to accomplish. If you're wanting us to provide that, the absolute basics:
    an alias to store a target in a variable
    aliases for all of your attacks which use that variable

    How complicated you want to get is up to you, and will to some degree be dictated by how competent you are as a coder, but the first thing you need to decide is what you want/need.
Sign In or Register to comment.