Vyzor, UI Manager for Mudlet

Share your scripts and packages with other Mudlet users.
User avatar
Akaya
Posts: 414
Joined: Thu Apr 19, 2012 1:36 am

Re: Vyzor, UI Manager for Mudlet

Post by Akaya »

I don't mind at all. Enjoy.

User avatar
Nioki
Posts: 10
Joined: Tue Feb 04, 2014 7:59 am

Re: Vyzor, UI Manager for Mudlet

Post by Nioki »

So I tried using Both VyzorGaugeUpdate() and individual gauge updates (for health and mana gauges), through both regular gui timers and temporal timers (both mudlet base ones) but still couldn't manage to get anything to update :/ just constantly at full. I'm also getting the following error every time the timer timer ticks -

Code: Select all

[ERROR:] object:<MainGauges Update> function:<Timer5>
         <...config/mudlet/profiles/Kash/vyzor\compound\gauge.lua:240: attempt to perform 
arithmetic on upvalue 'current_stat' (a string value)>
MainGauges is the frame that contains the gauges.
Can anyone give me a working vyzor code example perhaps? Or any other help would be nice as well :\ :P

Drevarr
Posts: 43
Joined: Tue Aug 06, 2013 12:07 am
Location: GA, USA

Re: Vyzor, UI Manager for Mudlet

Post by Drevarr »

Make sure you are converting the captured data to a numeric.

Code: Select all

--example
current_stat=tonumber(matches[2])

User avatar
Oneymus
Posts: 321
Joined: Thu Sep 17, 2009 5:24 am

Re: Vyzor, UI Manager for Mudlet

Post by Oneymus »

The variable current_stat holds the value of the address you passed in the Gauge constructor.

By reading the error message, we can clearly see that current_stat is not, in fact, a number. It's a string. Hence why the error message reads "attempt to perform arithmetic on upvalue 'current_stat' (a string value)".

What this means is that, whatever address you passed to the Gauge constructor is pointing at a string variable. Perhaps, when you get your current health or whatever, you're storing it as a string. For instance, all triggers pass matches as strings; this means you have to call tonumber() to actually get a number.

So, as Drevarr suggested, in order to store a number from a trigger, you need to do something like this:
Code: [show] | [select all] lua
local MySystem.currentHealth = tonumber(matches[2])
Then, when you pass "MySystem.currentHealth" to the Gauge constructor, it'll actually pull out a number instead of a string.

The fact that this error pops up when you try to update your gauges is a pretty good indication that something is wrong. Use the error dialog. Read the error dialog. It's not there just to be copy/pasted into the forums for someone else to read. The best way to get better at programming of any kind is to embrace error reporting; as a programmer, I am confident saying that more of your time is spent testing for and deciphering errors than actually writing code.

Jor'Mox
Posts: 1142
Joined: Wed Apr 03, 2013 2:19 am

Re: Vyzor, UI Manager for Mudlet

Post by Jor'Mox »

As a side note, any string that can be directly converted to a number via tonumber() can have math performed on it. "10" + "5" works just fine. So there is something other than just numbers in the value it is referencing, and consequently, tonumber(value) is going to return nil, not a number that can be worked with.

User avatar
Nioki
Posts: 10
Joined: Tue Feb 04, 2014 7:59 am

Re: Vyzor, UI Manager for Mudlet

Post by Nioki »

But how do you guys handle the delay for gmcp data from when a mudlet profile gets started up and connection is finished?
Judging by the error I'm receiving of Char of Vitals being nil both only being mentioned in things like

Code: Select all

NioSys.currentHP = tonumber(gmcp.Char.Vitals.hp)
( I guess Jor'Mox's post above is talking about that, but I'm not sure I'm reading the last part right..)
Anyway I'm guessing that its related to the fact that the script is still not receiving values from mudlet. I tried using a temporal timer, a normal mudlet timer a trigger to delay it but those didn't help, and a loop set up to check if the values are loaded up before going on just freezes and then crashes mudlet.

And I am reading the error logs, just that they do not always help out that much. I have been working on even these probably 'simple' hp and mana gauges for over a week now :/ and that does make me feel a bit pathetic :'|

User avatar
Oneymus
Posts: 321
Joined: Thu Sep 17, 2009 5:24 am

Re: Vyzor, UI Manager for Mudlet

Post by Oneymus »

I can't say I'm too clear on your problem. Are you never getting values from GMCP? May be a settings problem. Is it that 'delay' that's throwing you for a loop? It should be irrelevant, because your MUD will send those values again later.

And, as a safeguard, why not just do something like:
Code: [show] | [select all] lua
local hp = gmcp.Char.Vitals.hp
if hp then -- Make sure we got something from the MUD.
  NioSys.currentHP = tonumber(hp)

  if NioSys.currentHP then -- Make sure that something from the MUD was cast correctly.
    VyzorUpdateGauges()
  end
end
I need more details on what, exactly, is going wrong in the data flow before I could give you a solution. It looks like, at some point in your flow, the data is either missing or the wrong format.

User avatar
Nioki
Posts: 10
Joined: Tue Feb 04, 2014 7:59 am

Re: Vyzor, UI Manager for Mudlet

Post by Nioki »

Okay, I'm doing a full backtracking to my last "Working" code, when it at least displayed everything.
Just in case giving more info: GMCP Is activated in the client + I have both drawing the borders and frames in one function and on one script with the gauges, mapper and etc. Only separate script is the colors, but that should be fine. considering all of the colors are getting passed to the frames properly in this last working version.



I'm omitting frame and border construction.
Code: [show] | [select all] lua
			
function Layout()
..
..
..
			--Exp Gauge
	NioSys["ExpFront"] = Vyzor.Frame( "ExpFront" )
	NioSys.ExpFront:Add( NioSys.BrightWhiteBG )
	NioSys["ExpBack"] = Vyzor.Frame( "ExpBack" )
	NioSys.ExpBack:Add( NioSys.DarkWhiteBG )
	NioSys["ExpGauge"] = Vyzor.Gauge( "ExpGauge", "gmcp.Char.Vitals.nl", "100", NioSys.ExpBack, NioSys.ExpFront )
	NioSys.ExpFrame:Add( NioSys.ExpGauge ) 

			--Hp Gauge
	NioSys["HpFront"] = Vyzor.Frame( "HpFront" )
	NioSys.HpFront:Add( NioSys.BrightRedBG )
	NioSys["HpBack"] = Vyzor.Frame( "HpBack" )
	NioSys.HpBack:Add( NioSys.DarkRedBG )
	NioSys["HpGauge"] = Vyzor.Gauge( "HpGauge", "gmcp.Char.Vitals.hp", "gmcp.Char.Vitals.maxhp", NioSys.HpBack, NioSys.HpFront )
	NioSys.HpFrame:Add( NioSys.HpGauge )

			--Mana Gauge
	NioSys["MpFront"] = Vyzor.Frame( "MpFront" )
	NioSys.MpFront:Add( NioSys.BrightBlueBG )
	NioSys["MpBack"] = Vyzor.Frame( "MpBack" )
	NioSys.MpBack:Add( NioSys.DarkBlueBG )
	NioSys["MpGauge"] = Vyzor.Gauge( "MpGauge", "gmcp.Char.Vitals.mp", "gmcp.Char.Vitals.maxmp", NioSys.MpBack, NioSys.MpFront )
	NioSys.MpFrame:Add( NioSys.MpGauge )

			--Endurance Gauge
	NioSys["EndFront"] = Vyzor.Frame( "EndFront" )
	NioSys.EndFront:Add( NioSys.BrightGoldBG )
	NioSys["EndBack"] = Vyzor.Frame( "EndBack" )
	NioSys.EndBack:Add( NioSys.DarkGoldBG )
	NioSys["EndGauge"] = Vyzor.Gauge( "EndGauge", "gmcp.Char.Vitals.ep", "gmcp.Char.Vitals.maxep", NioSys.EndBack, NioSys.EndFront )
	NioSys.EndFrame:Add( NioSys.EndGauge )

			--Willpower Gauge
	NioSys["WillFront"] = Vyzor.Frame( "WillFront" )
	NioSys.WillFront:Add( NioSys.BrightPurpleBG )
	NioSys["WillBack"] = Vyzor.Frame( "WillBack" )
	NioSys.WillBack:Add( NioSys.DarkPurpleBG )
	NioSys["WillGauge"] = Vyzor.Gauge( "WillGauge", "gmcp.Char.Vitals.wp", "gmcp.Char.Vitals.maxwp", NioSys.WillBack, NioSys.WillFront )
	NioSys.WillFrame:Add( NioSys.WillGauge )

	Vyzor.HUD:Draw()	
end
This was the version pre my inclusion of the following just before the previous lines of code while still logged into the game
Code: [show] | [select all] lua
	NioSys.currentHP = tonumber(gmcp.Char.Vitals.hp)
	NioSys.totalHP = tonumber(gmcp.Char.Vitals.maxhp)
        NioSys.currentMP = tonumber(gmcp.Char.Vitals.mp)
	NioSys.totalMP = tonumber(gmcp.Char.Vitals.maxmp)
	NioSys.currentEND = tonumber(gmcp.Char.Vitals.ep)
	NioSys.totalEND = tonumber(gmcp.Char.Vitals.maxep)
	NioSys.currentWILL = tonumber(gmcp.Char.Vitals.wp)
	NioSys.totalWILL = tonumber(gmcp.Char.Vitals.maxwp)
	NioSys.currentEXP = tonumber(gmcp.Char.Vitals.nl)
giving me essentially this:
Code: [show] | [select all] lua
function Layout()
..
..
..
			--Grabbing Vitals
	NioSys.currentHP = tonumber(gmcp.Char.Vitals.hp)
	NioSys.totalHP = tonumber(gmcp.Char.Vitals.maxhp)
        NioSys.currentMP = tonumber(gmcp.Char.Vitals.mp)
	NioSys.totalMP = tonumber(gmcp.Char.Vitals.maxmp)
	NioSys.currentEND = tonumber(gmcp.Char.Vitals.ep)
	NioSys.totalEND = tonumber(gmcp.Char.Vitals.maxep)
	NioSys.currentWILL = tonumber(gmcp.Char.Vitals.wp)
	NioSys.totalWILL = tonumber(gmcp.Char.Vitals.maxwp)
	NioSys.currentEXP = tonumber(gmcp.Char.Vitals.nl)

			--Exp Gauge
	NioSys["ExpFront"] = Vyzor.Frame( "ExpFront" )
	NioSys.ExpFront:Add( NioSys.BrightWhiteBG )
	NioSys["ExpBack"] = Vyzor.Frame( "ExpBack" )
	NioSys.ExpBack:Add( NioSys.DarkWhiteBG )
	NioSys["ExpGauge"] = Vyzor.Gauge( "ExpGauge", "currentEXP", "100", NioSys.ExpBack, NioSys.ExpFront )
	NioSys.ExpFrame:Add( NioSys.ExpGauge ) 

			--Hp Gauge
	NioSys["HpFront"] = Vyzor.Frame( "HpFront" )
	NioSys.HpFront:Add( NioSys.BrightRedBG )
	NioSys["HpBack"] = Vyzor.Frame( "HpBack" )
	NioSys.HpBack:Add( NioSys.DarkRedBG )
	NioSys["HpGauge"] = Vyzor.Gauge( "HpGauge", "currentHP", "totalHP", NioSys.HpBack, NioSys.HpFront )
	NioSys.HpFrame:Add( NioSys.HpGauge )

			--Mana Gauge
	NioSys["MpFront"] = Vyzor.Frame( "MpFront" )
	NioSys.MpFront:Add( NioSys.BrightBlueBG )
	NioSys["MpBack"] = Vyzor.Frame( "MpBack" )
	NioSys.MpBack:Add( NioSys.DarkBlueBG )
	NioSys["MpGauge"] = Vyzor.Gauge( "MpGauge", "currentMP", "totalMP", NioSys.MpBack, NioSys.MpFront )
	NioSys.MpFrame:Add( NioSys.MpGauge )

			--Endurance Gauge
	NioSys["EndFront"] = Vyzor.Frame( "EndFront" )
	NioSys.EndFront:Add( NioSys.BrightGoldBG )
	NioSys["EndBack"] = Vyzor.Frame( "EndBack" )
	NioSys.EndBack:Add( NioSys.DarkGoldBG )
	NioSys["EndGauge"] = Vyzor.Gauge( "EndGauge", "currentEND", "totalEND", NioSys.EndBack, NioSys.EndFront )
	NioSys.EndFrame:Add( NioSys.EndGauge )

			--Willpower Gauge
	NioSys["WillFront"] = Vyzor.Frame( "WillFront" )
	NioSys.WillFront:Add( NioSys.BrightPurpleBG )
	NioSys["WillBack"] = Vyzor.Frame( "WillBack" )
	NioSys.WillBack:Add( NioSys.DarkPurpleBG )
	NioSys["WillGauge"] = Vyzor.Gauge( "WillGauge", "currentWILL", "totalWILL", NioSys.WillBack, NioSys.WillFront )
	NioSys.WillFrame:Add( NioSys.WillGauge )

	Vyzor.HUD:Draw()	
end
All works perfectly at this stage, well aside from my xp bar which displays 83/1 instead of 83/100, and a weird error
Code: [show] | [select all] lua
[ERROR:] object:<event handler function> function:<VyzorInitializeGauges>
         <...config/mudlet/profiles/Kash/vyzor\compound\gauge.lua:228: attempt to index local 'v' 
(a nil value)>
but that is not the issue right now. Bad things start to happen as soon as save, close and restart the profile:

Nothing draws at all, only borders and this pops up, and whichever method I use to update gauges, it just stumbles at the first variable using gmcp on line 82 { NioSys.currentHP = tonumber(gmcp.Char.Vitals.hp) } and says that its nil:
Code: [show] | [select all] lua
[ERROR:] object:<event handler function> function:<Layout>
         <[string "function Layout()..."]:82: attempt to index field 'Char' (a nil value)>

User avatar
Oneymus
Posts: 321
Joined: Thu Sep 17, 2009 5:24 am

Re: Vyzor, UI Manager for Mudlet

Post by Oneymus »

I see a couple of things that could cause problems. First, the GMCP thing. Your scripts fire when Mudlet loads the profile, not when you connect to the MUD. This means, of course, that you won't have any GMCP data to use at load time. The simplest solution for you in this case is to initially fill your variables with dummy values.

Like so:
Code: [show] | [select all] lua
NioSys.currentHP = gmcp and tonumber(gmcp.Char.Vitals.hp) or 100
NioSys.totalHP = gmcp and tonumber(gmcp.Char.Vitals.maxhp) or 100
...
Basically, this says "If the gmcp variable is not nil, then use this value. Else, use 100." It's not strictly necessary here, since we know that the GMCP table doesn't exist yet. But it's a good practice to learn and use elsewhere.

Now, the next thing I see is the way you're passing your addresses to the Gauge constructor. Vyzor uses a function that iteratively tracks through the global variable table (in Lua, this is _G) using the string you passed in, period delimited.

When you pass in something like "totalHP", it's actually looking in _G["totalHP"] (_G.totalHP) and finding nothing. It finds nothing, of course, because you actually stored that value in the variable NioSys.totalHP. Therefore, you want to pass in the address "NioSys.totalHP". This translates to _G["NioSys"]["totalHP"] (_G.NioSys.totalHP).

And, finally, the reason that your XP gauge maximum is 1 is because you passed in "100". This means that Vyzor is looking for a value stored at _G["100"]. Obviously, it doesn't find it, and Vyzor defaults the value to 1. Looking at it now, it may be a nice feature to allow you to pass numbers directly. However, for the foreseeable future, you'll want to make a variable to store that 100 in; something like NioSys.totalXP, to follow your naming convention.

So, to recap, you want something that looks vaguely like...
Code: [show] | [select all] lua
NioSys.currentHP = 100
NioSys.totalHP = 100
...
NioSys.currentXP = 100
NioSys.totalXP = 100
...

NioSys.HpGauge = Vyzor.Gauge("HpGauge", "NioSys.currentHP", "NioSys.totalHP", ...)
NioSys.ExpGauge = Vyzor.Gauge("ExpGauge", "NioSys.currentXP", "NioSys.totalXP", ...)
Hell, just as a bonus, here's how you could turn the whole thing into one loop, since there's a lot of repetition (disclaimer: written in browser):
Code: [show] | [select all] lua
local gaugesToMake = {
  "Hp",
  "Mp",
  "End",
  "Will",
  "Exp"
}

for _, gaugeToMake in ipairs( gaugesToMake ) do
  local current = "current" .. gaugeToMake
  NioSys[current] = 100

  local total = "total" .. gaugeToMake
  NioSys["total" .. gaugeToMake] = 100

  local front = gaugeToMake .. "Front"
  NioSys[front] = Vyzor.Frame(front)

  local back = gaugeToMake .. "Back"
  NioSys[back] = Vyzor.Frame(back)

  local gauge = gaugeToMake .. "Gauge"
  NioSys[gauge] = Vyzor.Gauge(gauge,
    NioSys[current],
    NioSys[total],
    NioSys[back],
    NioSys[front])

  local frame = gaugeToMake .. "Frame"
  NioSys[frame]:Add(NioSys[gauge])
end
I'll leave the colours as an exercise for you, if you choose to go down this route. But it may involve tables or functions. As a general practice, it's always helpful to identify areas of repetition, as these areas are usually great candidates for loops; cutting down on the sheer number of lines in your code makes it easier to modify and maintain over time.

User avatar
Nioki
Posts: 10
Joined: Tue Feb 04, 2014 7:59 am

Re: Vyzor, UI Manager for Mudlet

Post by Nioki »

Okay, managed to get it to work.

All that still didn't help, was just resetting it to the alternative value of '100'
and normally resetting the gauges didn't help. Solved it by using my Gauge reset script grab new values from gmcp every single time. Thanks a lot for you patience everybody.

As for the chat compound though, I guess there are no ways to make them flash like in YATCO implemented yet?




P.S. Did I misunderstand the init_back in the gauge component? I thought it was supposed to be the background of the gauge, but it isn't drawing. Not that much of a problem but it is slightly annoying.

Post Reply