#### Hail, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

#### Categories

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

# Quick Coding Questions

• Posts: 247Member ✭✭✭ - Distinguished
How do you add a background image to a label? Or, alternatively, move a label up/down a layer?
• Posts: 37Member ✭✭ - Stalwart
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]])
• Posts: 39Member ✭✭ - Stalwart
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"    endfunction targetaffreset()	targetafftable = {}	sysecho("green", " --- RESET ALL AFFLICTIONS --- ")	promptafftable = {}	darkshadecountdown = false	coagulating = falseendfunction targetaffadd(affliction)     if not table.contains(targetafftable, affliction) then           table.insert(targetafftable, affliction)     endend

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?
• Posts: 37Member ✭✭ - Stalwart
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 falseend

• Posts: 39Member ✭✭ - Stalwart
I'll give that a try!  Thanks!
• Posts: 1,197Member @ - Epic Achaean
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 toSendend
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).
• Posts: 409Member ✭✭✭✭ - Eminent
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.
• Posts: 39Member ✭✭ - Stalwart
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?
• Posts: 37Member ✭✭ - Stalwart
function targetaffadd(affliction)
targetafftable[affliction] = true
if affliction == "weariness" then
targetafftable.mighthavewearines = false
end
end

• Eye of the StormPosts: 2,763Member @@ - Legendary Achaean
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."
• Wherever I wanna bePosts: 3,370Member @@ - Legendary Achaean
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.
• Posts: 39Member ✭✭ - Stalwart
Jacero said:
function targetaffadd(affliction)
targetafftable[affliction] = true
if affliction == "weariness" then
targetafftable.mighthavewearines = false
end
end

• Posts: 73Member ✭✭✭ - Distinguished
Yes, it does need "'s, if you don't have them, then it is presumed to be a variable.
• Posts: 39Member ✭✭ - Stalwart
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?
• Posts: 4,412Member @@ - Legendary Achaean

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

• Posts: 39Member ✭✭ - Stalwart
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!
• Eye of the StormPosts: 2,763Member @@ - Legendary Achaean
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")endregisterAnonymousEventHandler("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."
• Posts: 37Member ✭✭ - Stalwart
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.
• Posts: 1,957Member @@ - Legendary Achaean
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

• Eye of the StormPosts: 2,763Member @@ - Legendary Achaean
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."
• PhD ScientologyPosts: 3,182Member @@ - Legendary Achaean
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

Has anyone else run into this problem?

[ SnB PvP Guide | Link ]

[ Runewarden Sparring Videos | Link ]
• Posts: 39Member ✭✭ - Stalwart
Is SnB Ferocity tracked in GMCP?  And if no one has the answer, how can I find out?
• Posts: 4,550Member, Secret Squirrel @@ - Legendary Achaean
{
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.

You hug Aurora compassionately.
• Posts: 3,257Member @@ - Legendary Achaean
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.

• PhD ScientologyPosts: 3,182Member @@ - Legendary Achaean
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 ]
• Eye of the StormPosts: 2,763Member @@ - Legendary Achaean
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."
• Posts: 9Member
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?

• Posts: 1,274Member @ - Epic Achaean
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.
• Posts: 4,412Member @@ - Legendary Achaean
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.