Okay, so I have Geyser for Mudlet, and I can't get the gauges on the gui to attach to my stats. I'm not sure what I'm supposed to be doing to make it grab the values for my health.
This is what is in the Gauges script folder. I have GMCP enabled, but I don't know how to make it grab the values. When I take damage, the bar doesn't move, for example.
Char
Sent by server:
- Char.Vitals
* Basic character attributes such as health, mana, etc.
* Message body is an object containing several variables
* Additionally, each variable is included in a string, in the format name:cur/max
* Interpretation of the variables is game specific
* It is generally safe to assume that the values are numbers (even though encoded as strings)
* Example: Char.Vitals { "hp": "4500", "maxhp": "4800", "mp": "1200", "maxmp": "2500", "ep": "15000", "maxep": "16000", "wp": "14000", "maxwp": "15000", "nl": "10", "string": "H:4500/4800 M:1200/2500 E:15000/16000 W:14000/15000 NL:10/100" }
tl;dr: hp is current hp, mp is current mp.
EDIT: My last gmcp.char.vitals looks like this:
{"bal":"1","maxmp":"6710","maxhp":"5720","string":"H:5720\/5720 M:6710\/6710 NL:44\/100 ","nl":"44","mp":"6710","hp":"5720","eq":"1","deaf":"1","salve":"0","blind":"1"}
I am the righteous one... the claims are stated - it's the world I've created
Bear in mind I don't use geyser but this would appear to be the correct solution based on your previous code which I'm assuming was copied from some template. For the gauge you'd need both the value and it's maximum range.
Okay i will try that this weekend when i get on the laptop. That makes a lot of sense, looking at it. I tried reading the manual, and got more confused.DX I'll let you know if it works.
This is kind of a minor thing because it's a niche thing that really only matters in content heavy RP or PK discussions where I need to say a lot at one time, but I use the Vyzor map window and whenever the resolution of the window things it needs to change - it really lags pretty bad, it usually recovers after about 30 seconds, but I was wondering if anyone had a quick fix for that?
I'd like to figure out how to build an affliction tracker.
I have the knowledge of how to fight and score a kill, I know how to stack affs and everything, but the biggest problem for me is tracking it. I don't have the mental reflexes to actually manually track it, even with big flashy echoes, so I need to code a tracker that can tell me what affs someone has, and then a queue to apply affs based on that tracking.
I know how to create aff variables and use aff/cure messages to set those variables, but I don't know how to add those afflictions to a table and then display that table on-screen so I know what to afflict with next. That's what I'm stuck at.
It'd also be nice if I could figure out how to set up a window or a GUI or something that could tell me what a person's herb/salve/smoke/tree/purge balances are on and have timers for them, or at the very least an 'on' or 'off'.
Tracking what you give is easy (see Iniar's stuff above). Probably your most complex function will be the one that determines what they just cured. There are a ton of ways to go about that (ranging from just guess at an aff of the herb type and remove it to Kyrock math). That's typically what makes the difference between people who track well and badly though, if you're doubling up affs you're killing your progress.
This is kind of a minor thing because it's a niche thing that really only matters in content heavy RP or PK discussions where I need to say a lot at one time, but I use the Vyzor map window and whenever the resolution of the window things it needs to change - it really lags pretty bad, it usually recovers after about 30 seconds, but I was wondering if anyone had a quick fix for that?
Just loaded up Vyzor, having no dramas with it - what are you doing specifically when it happens? Resizing the main Mudlet application, resizing the frame, receiving new data from the server?
Does it pretty much when any resize happens - if I try to change the main Mudlet application window, if I get to typing a conversation, when the input line wraps the text over to a second line, etc.
Quick question, I didn't see any mention of balances and how to use GMCP to keep track of them, anyone mind giving me an example of how to do it or explain it a bit to me?
char.vitals has bal and eq keys that swap between 1 and 0 (also blind, deaf, prone, stun, bleed, etc)
If you have existing things that work off GMCP, these work the same way. The best way of using GMCP that I can teach you is to uninstall mudlet (lua ftl) and use cmud (cmud admittedly is pretty terrible too, especially when it comes to GMCP).
You find all the GMCP data in Mudlet in the table named "gmcp". So for example gmcp.Char.Vitals is where you find balances, health, mana and so on. So checking if you're on balance is as easy as "if gmcp.Char.Vitals.bal == "1" then echo("I have balance") end". If you want to show the whole table you can type "lua display(gmcp)" in your command prompt - assuming you have the lua alias that should be standard today. If not, you find it on the Mudlet forum.
If you want to bind a script to a gmcp event, you'll be able to find out when GMCP events are ran if you turn on Debug mode. This is commonly done to update all your balances, health etc each time it's updated, instead of binding a script to every prompt, which I believe is a slower process. This is of course a bit more advanced, but it's a tip.
Does it pretty much when any resize happens - if I try to change the main Mudlet application window, if I get to typing a conversation, when the input line wraps the text over to a second line, etc.
"Unfortunately, any time Vyzor.HUD:Draw()is called, whatever it is that causes the slow-down occurs. I experimented with using the Draw() function directly on the frames I want to resize (in the instances when I am only adjusting specific portions of my gui rather than the entire thing) but with mixed success."
Thanks for digging that up... you think there'd be any way to at least keep that function from being called when my input line gets longer than 1 line... I get that it will probably have to happen when I resize the window, but it gets to be a pain in the ass when I am typing a sentence and am limited to 140 characters, Twitter-style without having to have the slow-down hit me like a truck.
Probably not. Vyzor is overly complicated, especially for what we (or I) use it for. See http://forums.mudlet.org/viewtopic.php?f=7&t=3481&p=17155&hilit=command+line#p17155 seems they are aware of it and want to squish it at some point. Haven't actually tested the script in that thread but might be worth looking into (instead of Vyzor).
eden.overmind.update() -- this draws a simple box, use this as a real-time guide
if not eden.resizing then -- this is a lockout flag, start drawing if it's false
eden.resizing = true -- enable your lockout
if eden.resizeTimer then killTimer(eden.resizeTimer) end -- reset the timer
eden.resizeTimer = tempTimer( 2, function() eden.ui.draw() end ) -- make a timer to execute all your main drawing stuff only at t=2
tempTimer( 3, function() if eden.resizeTimer and eden.resizing then killTimer( eden.resizeTimer) eden.resizing = false end end ) -- reset your lockout and kill your timer at t=3
end
end
I imagine you would end up placing something like Vyzor's main Draw() function where I have eden.ui.draw()
I've hit a problem with the mud let mapper. I updated the mapper, but now none of the aliases for using it are working (mc, rl, goto, etc.,). Nor does the mapper even seem to know where I am. it's stuck on one room and when I pass through that room it doesn't start tracking me either. Any ideas how to fix this?
I want to write a little mini guide for Mudlet that's suited to someone with 0 experience in coding, sort of hashed this out in about 30 minutes, just wanted to chuck it someplace safe.
A Baby's Guide to Mudlet
=====================================
1) Definitions
'server' - where Imperian is hosted
'client' - where you receive information from Imperian, this could be programs like Mudlet or CMUD
'serverside' - this happens on Imperian's end, and has nothing to do with your computer, Mudlet/CMUD, or internet connection
'clientside' - this happens on your end, and -usually- means Mudlet/CMUD
'alias' - a word or pattern you key in that represents something else, for example typing in 'pg' would become 'put gold in pack' and then sent to the server
'macro' - similar to 'alias' but is instantly sent without you hitting the 'Enter' key or 'Return' key
'variable' - a container for your client (Mudlet/CMUD) to hold information
'trigger' - a pattern for your client to react to, for example, someone smiling at me could be triggered so I say hi! to the person in response
'table' - a collection of 'variables', for example, 200 maidenhair, 100 kelp, 50 toadstool
'function' - a machine that interprets some data and returns you something else, for example, your ATM machine processes your card and gives you your money
'event listener' - a machine that waits for some specific data and then returns you something else, for example, -when- the clock hits ten AM, the bell rings (to signal recess!), for this to work, someone (or something) needs to pay attention to the clock... this is what we call an event listener (the person who watches the clock!)
'pseudo-code' - the lazy man's way of trying to show the ideas behind a code, that is, it won't run, but the general idea is there!
2) Navigating Mudlet
Picture 1:
if you click this button here and click 'Add Item' (see below), you will create a new trigger
Picture 2:
1 - this is your new trigger
2 - see how one trigger has a little ladybug over it? This means there is something wrong with the trigger. You'll need to fix it before it works! This little ladybug is generally true for all the other things like scripts/aliases as well! Also see how the trigger above it has a little green tick? This means the trigger is turned on! If the box is not ticked, it may not work! So if something's not working, check to see if this tick is present.
3 - this is what I call the 'code box'! This is where all the special stuff goes in to make it all work! That is, when the pattern is received, this is what the machine runs (executes)
4 - this is the 'name box'! You can name your triggers what ever you like. There are only very few circumstances where names actually matter: a) when you want to turn them on/off with code, b) for 'event listeners'
5 - this is the 'pattern box'! Here is where you put in your 'triggers'
6 - this is the 'trigger type box'! Here is where you decide what kind of 'trigger' your trigger grows up to be! They can meet very different conditions, so you'll want to learn to play with this!
7 - this is the multiline tick box, which we'll explain a little later
Let's make a really basic trigger!
We met a crazy woman named Aleutia, and she often smiles (wickedly) at you! What you see in your screen is something like this:
Aleutia rubs her hands together and grins evilly at you.
If you put this line in the 'pattern box' (5), you'll now respond to Aleutia grinning at you evilly.
What shall we do?
Let us stick our tongue out at her!
See that 'code box'? (3)
In it, type:
send("tongue Aleutia")
Hit Save Item, and make sure your box is checked green.
Now everytime Aleutia grins evilly at you, you will stick your tongue out at her!
'trigger types'
- there are several types of trigger types, and the ones I use the most are 'regex', 'Lua function' and the occasional 'color trigger'
- the default substring type is otherwise very useful
'regex'
- 'regex' stands for 'regular expression' but that doesn't really mean anything
- let's take for example our basic trigger from earlier! What if we meet this really sweet woman named Aulani and she loves to grin evilly too? What if we want to stick out our tongue at her too? We could make another copy of the same trigger, except for swapping Aleutia with Aulani.
- the other way we could work it is to use 'regex'.
- the concept is this: we replace changeable words and symbols with our own special symbols so the machine can accept more than one correct answer!
- for example, instead of 'Aleutia rubs her hands together and grins evilly at you.', we now have '\w+ rubs her hands together and grins evilly at you.'
- now our machine will accept both 'Aleutia rubs her hands together and grins evilly at you.' and 'Aulani rubs her hands together and grins evilly at you.' and send 'tongue Aleutia' when this happens!
- how does this happen? the symbol '\w+' is interpreted by our machine as a 'word'! So any word would be 'OK' with it and it would run the stuff in the 'code box'! So instead of two patterns, we now have 1 pattern that will fit two (and more!) situations!
- but do we really want to stick our tongue out at Aleutia when it's Aulani grinning at us??
'captures'
- in comes the concept of captures!
- we now change our pattern from 'Aleutia rubs her hands together and grins evilly at you.' to '\w+ rubs her hands together and grins evilly at you.'
- let's change that to '(\w+) rubs her hands together and grins evilly at you.'
- we put in parentheses '()'
- what does this do? this 'captures', that is, it 'saves' or 'remembers' this information! Remember that \w+ represents a word, any word. Now the word that matches the pattern is remembered!
- how can we access this 'capture'? By using the Mudlet-only 'matches' command
- In this situation, if 'Iniar rubs her hands together and grins evilly at you.' is sent to you by the Imperian server, it will 'trigger' off the pattern '(\w+) rubs her hands together and grins evilly at you.' and the name 'Iniar' will be saved! To use this information, use: matches[2]
- matches[2] is the first capture in the trigger, matches[3] is the second capture and so on and so forth
- now we can stick our tongue back at the right person! How?
- look at your 'code box' (3); let's change the code to:
send("tongue "..matches[2])
- this will now send 'tongue Aulani' when Aulani grins evilly at you, 'tongue Aleutia' when Aleutia grins evilly at you, and in fact, any female that grins evilly at you, you can stick your tongue out at them!
- something very important happened here!
- see how we did "tongue Aleutia" earlier, and now we did "tongue "..matches[2]?
- why can't we do "tongue matches[2]" ??
'variables'
- we come to variables. Remember that variables are 'a container for your client (Mudlet/CMUD) to hold information'
- take for example the word 'name'. In Lua (the language of Mudlet) if we did "name", this would literally mean 'name' as you and I understand it
- now if we did name, by itself, without the "" (apostrophes), it is basically a pointer telling the machine about information you and I can't see!
- so, because of this, send("name") and send(name) are two very different things!
- if for example, earlier on in some other random script, we did this:
name = "Ozreas"
then when we do send(name), it will be changed into send("Ozreas") and this will send the word "Ozreas" to the 'server'
on the other hand, send("name") will send the word "name" to the 'server'
- this is the basic concept of a variable!
- to join "name" and name, you'll want to do this! send("name"..name), or better yet, send("say my name is "..name)!
- so you can see, because the earlier example 'captured' Aulani's name in matches[2], we can do send("tongue "..matches[2]), which will become send("tongue Aulani") which will send 'tongue Aulani' to the 'server'
'permission lists!'
- what if you only want to tongue certain people??
- let's look at tables!
- tables are essentially like a shopping list
- on it, you can put almost -anything-
- in Lua (the language of Mudlet), a table looks like this:
- notice how we took out Svorai and added Aulani/Aleutia in?
- where do I put this table, you say? Go to your code box (3), and above send("tongue "..matches[2]), paste it in!
- now we have a list of people we want to respond to, ooer!
- let us now change the code in our code box (3) to only respond to the people on our awesome list
- delete send("tongue "..matches[2])
- in its place, put this:
if table.contains( this_awesome_table, matches[2] ) then
send("tongue "..matches[2])
end
- simply put, this checks the table for the 'capture' and then responds if it is present!
'if!'
- the IF!
- IF is amazing.
- it lets us check things before running our code!
- IF I am on fire, THEN stop-drop-and-roll END
- that is the basic pattern of the IF
- let's look at a practical example!
- IF my_health < 100 THEN send("eat toadstool") END
- but we can't eat toadstool without a balance, correct?
- IF my_health < 100 AND toadstool_balance == true THEN send("eat toadstool") END
- you can also specify what to do if you don't fulfil the condition!
- IF (I am awesome) THEN send("scream I am awesome!") ELSE send("say I'm sadly not awesome") END
- take a look at these:
- IF rebounding == true THEN send("rsl "..target) ELSE send("dsl "..target) END
- IF shield == true THEN send("touch hammer "..target) ELSE send("kill "..target) END
- IF wielding == "tablet" AND class == "Deathknight" THEN send("wield sabre") END
- so IFs are really powerful when you check the right 'variables'! and you'll get the right 'variables' if you 'capture' them properly!
'functions'
- notice in our earlier example, we did; if table.contains( this_awesome_table, matches[2] ) then etc. etc.
- what is table.contains()?
- this is a 'function'
- remember, a function is: a machine that interprets some data and returns you something else
- in this case, table.contains( A, B ) checks to see if table A, contains variable B. If it does, it sends 'true' otherwise it sends 'false'!
- let's look at a quick example of a function:
function my_awesome_function( argument_one, argument_two )
if argument_one == "Iniar" and argument_two == "awesome" then
send("say Iniar is awesome")
else
send("say Iniar is "..argument_two)
end
end
- we can now 'use' our function like this:
my_awesome_function( "Aulani", "awesomest" ) <- this would send 'say Iniar is awesomest'
my_awesome_function( "Iniar", "cheesy" ) <- this would send 'say Iniar is cheesy'
my_awesome_function( "Iniar", "awesome" ) <- this would send 'say Iniar is awesome'
- finally, we can get functions to return values into 'variables'
- for example,
function is_potato( name )
if name == "Ahkan" then
return true
else
return "No potatoes here"
end
end
- 'return' stops the 'function' cold, and can send a value back, so we could use our new function like this:
my_potato = is_potato("Iluv")
send(my_potato) would expand into send("No potatoes here")
my_potato = is_potato("Ahkan")
send(my_potato) would expand into send(true)
So, I hope this helps those who understand almost nothing about Mudlet, Lua and coding, and I hope I've made it clear as mud. Feel free to hit me up with any questions in-game or on the forums PM system if you have any questions!
Comments
This is what is in the Gauges script folder. I have GMCP enabled, but I don't know how to make it grab the values. When I take damage, the bar doesn't move, for example.
GUI.Footer = Geyser.HBox:new({
name = "GUI.Footer",
x = 0, y = 0,
width = "100%",
height = "100%",
},GUI.Bottom)
GUI.LeftColumn = Geyser.VBox:new({
name = "GUI.LeftColumn",
},GUI.Footer)
GUI.RightColumn = Geyser.VBox:new({
name = "GUI.RightColumn",
},GUI.Footer)
GUI.GaugeBackCSS = CSSMan.new([[
background-color: rgba(0,0,0,0);
border-style: solid;
border-color: white;
border-width: 1px;
border-radius: 5px;
margin: 5px;
]])
GUI.GaugeFrontCSS = CSSMan.new([[
background-color: rgba(0,0,0,0);
border-style: solid;
border-color: white;
border-width: 1px;
border-radius: 5px;
margin: 5px;
]])
GUI.Health = Geyser.Gauge:new({
name = "Health",
},GUI.LeftColumn)
GUI.Health.back:setStyleSheet(GUI.GaugeBackCSS:getCSS())
GUI.GaugeFrontCSS:set("background-color","red")
GUI.Health.front:setStyleSheet(GUI.GaugeFrontCSS:getCSS())
GUI.Health:setValue(math.random(100),100)
GUI.Health.front:echo("Health")
GUI.Mana = Geyser.Gauge:new({
name = "Mana",
},GUI.LeftColumn)
GUI.Mana.back:setStyleSheet(GUI.GaugeBackCSS:getCSS())
GUI.GaugeFrontCSS:set("background-color","blue")
GUI.Mana.front:setStyleSheet(GUI.GaugeFrontCSS:getCSS())
GUI.Mana:setValue(math.random(100),100)
GUI.Mana.front:echo("Mana")
GUI.Endurance = Geyser.Gauge:new({
name = "Endurance",
},GUI.RightColumn)
GUI.Endurance.back:setStyleSheet(GUI.GaugeBackCSS:getCSS())
GUI.GaugeFrontCSS:set("background-color","yellow")
GUI.Endurance.front:setStyleSheet(GUI.GaugeFrontCSS:getCSS())
GUI.Endurance:setValue(math.random(100),100)
--GUI.Endurance.front:echo("Endurance")
GUI.Endurance.front:echo([[<span style = "color: black">Endurance</span>]])
GUI.Willpower = Geyser.Gauge:new({
name = "Willpower",
},GUI.RightColumn)
GUI.Willpower.back:setStyleSheet(GUI.GaugeBackCSS:getCSS())
GUI.GaugeFrontCSS:set("background-color","purple")
GUI.Willpower.front:setStyleSheet(GUI.GaugeFrontCSS:getCSS())
GUI.Willpower:setValue(math.random(100),100)
GUI.Willpower.front:echo("Willpower")
Anyone have any Ideas?GUI.Mana:setValue(math.random(100),100)
GUI.Mana:setValue(gmcp.Char.Vitals.mp)
the claims are stated - it's the world I've created
the claims are stated - it's the world I've created
I'll let you know if it works.
eden.thing = Geyser.MiniConsole:new({
name="affbox",
x= -0.1*width,
y= 440,
width= 0.1*width, height="40c",
})
eden.thing:setFontSize(10)
eden.thing:setColor(20,20,20,10)
end
To push something into it, do:
// Clear it first
clearWindow("affbox")
// Then push
cecho("affbox", "\nhemotoxin")
So, use your iterator:
selectString(matches[1], 1)
setUnderline(true)
setLink([[openUrl("]]..matches[1]..[[")]], "Click to open in browser")
resetFormat()