miniwindow updating from variables

Posted by Krae on Sun 12 Sep 2010 06:02 PM — 13 posts, 46,188 views.

Netherlands #0
Alright the title might be vague but I am trying to make something but I am not quite sure how to handle this yet.

For this Iron Realms MUD I want to have a miniwindow created that will track which afflictions my enemy has. I already have triggers set up which will detect which affliction has been inflicted, I just need to find a way to set it up so these variables will be picked up and placed in the miniwindow and then also a way so that if my enemy cures the affliction that it is taken off again.

Now the way I -thought- I might do this is to have each affliction have its own variable such as if @enemydizzy == "1" then 'bladibla put in window' and enemy eats herb = SetVariable @enemydizzy == "0". Something to that extent, but to do this it would either need a timer or the miniwindow would have to be deleted and recreated every time (probably a wrong assumption) because of its importance it has to be updated as soon as any affliction variable changes.
USA #1
You can clear a miniwindow pretty easily by using WindowRectOp to fill the whole window with a flat color. If you need to resize the miniwindow, use WindowResize (assuming a recent version of MUSHclient).

As for how you'd update the miniwindow, you'll probably want to do it immediately once a variable changes. There's no way to "track" a change to a variable.
Australia Forum Administrator #2
In the trigger here:

http://www.gammon.com.au/forum/?id=9626

... I remake the mininwindow every time you change rooms. It's no big deal.
Netherlands #3
Aha yes, okay thank you. And yes I have seen that tutorial and used it before, thanks.

So basically it wouldn't matter if I would have it create a window every single time the variable changes.. thereby creating a REALLY big script.


if GetVariable ("venom1hit") == "yes" then
   if GetVariable ("venom1") == "xentio" then
      Note ("target has clumsiness - KELP/EYEBALL")
   elseif GetVariable ("venom1") == "eurypteria" then
      Note ("target has recklessness - LOBELIA/TESTIS")

I would have to create a new window at each note here,

And when it's cured:

if GetVariable ("herbeaten") == "goldenseal" then
	if GetVariable ("stupidity") == "1" then
		SetVariable ("stupidity", "0")
		Note ("Target Cured Stupidity!")
	elseif GetVariable ("dizziness") == "1" then
		SetVariable ("dizziness", "0")
		Note ("Target Cured Dizziness!")

And so on and so forth. And then after each Note I would have to go through the steps of erasing the windows.

So I would have to make a separate window for every single variable/affliction.
I thought/hoped there would be a simpler or easier way to do this and have it all displayed in one single window.

Edit: And/or alternatively I could create a separate alias that will run through all the variables when I afflict or the enemy eats a herb and then create a window out of the activated variables, how would I display variables in a miniwindow exactly?


WindowText (win, font, "GetVariable("dizziness")", 5, 10, 0, 0, ColourNameToRGB ("yellow"))

Is probably wrong.
Or how would I call all variables beforehand and then display the output in the miniwindow?
Amended on Sun 12 Sep 2010 10:56 PM by Krae
USA #4
Well, everything doesn't have to be self-contained within the alias/trigger send text. You can define shared functions in your script file - or the <script> section of a plugin - and call them from your triggers/aliases. For example, you can put all of your window drawing code in one function, and call it each time you have new variable data.
Netherlands #5
How would I create shared functions like that? I am not -that- well versed in lua on that department.
Australia Forum Administrator #6
OK, here is what I would do. Certainly not create hundreds of windows, that would be a major pain.

Let's say we start off with no afflictions (bear in mind I don't play the IRE MUDs regularly). So we have:


afflictions = {}  -- empty table


That might be in the plugin install part.

Now you get an affliction, in a trigger:


Match: You are dizzy.

Script:

afflictions.dizzy = true
ShowAfflictions ()


You are no longer dizzy:


Match: You are no longer dizzy.

Script:

afflictions.dizzy = false
ShowAfflictions ()



So you have lots of triggers that simply turn on/off each affliction (there may be an easier way, I am just showing the idea).

Now you have one spot - ShowAfflictions () - that is responsible for showing your afflictions.

In that you might count how many you have:


count = 0
for k, v in pairs (afflictions) do
  count = count + 1
end -- for


That gives you the size of the window (vertically). You then remake the window of the correct size (similar to my tutorial on doing an inventory window).

Then you, for each affliction line, draw a line to the window. Put a title on the top, draw a nice border, and there you are!

Really it is similar in many ways to the inventory miniwindow.

Amended on Sun 12 Sep 2010 11:10 PM by Nick Gammon
Netherlands #7
Aha! Yes I had been viewing the tutorials on miniwindows both the inventory and the exits on a few times but eventually I ended up lost.
Note: I am not going to track what -I- get afflicted with, but what I am afflicting someone else with (which is the tricky part!)

Okay so I'm going to try and write up something according to that and post part of what I think it might be, a lot of that lua just explained is new to me especially the table stuff but I'll try and punch through!

Thanks much for the support!
USA #8
([EDIT] Ninja'd big time...)

In Lua, one of the value types a variable may contain is the 'function'. The simplest function you can possibly define is "foo = function() end". When you want to run the function, you place () after the variable containing a function, i.e. foo().

A function can take many arguments, and return many(!) values. For example:
MyNote = function(text)
  Note("From MyNote: " .. text)
end

Numbers = function()
  return 1, 2, 3, 4
end

MyNote("Hello, world!")
-- From MyNote: Hello, world!
print(Numbers())
-- 1 2 3 4


There's also a shorthand for writing functions:
function Foo()
end

Personally, I like to make it very explicit that a function is just another value, so I don't use this form much. It's just personal taste.

Maybe now you can see how you'd define a function for your window drawing. Now where would you put it? Not in a trigger/alias - it would be redefined every time, and it wouldn't really be "shared" either. MUSHclient lets you create a "script file", which you can put scripts in that will be run as soon as the world is loaded (i.e. even before connecting) and when it's explicitly reloaded.

You can create one by going to Game -> Configure -> Scripting, clicking New File in the "External Script File" section, and creating your file. I personally also uncheck "use inbuilt notepad to edit scripts", because I like to use Notepad++ or Komodo Edit, and I can alt-tab back and forth. You can then edit it either from your favorite editor, or by going to Game -> Edit Script File.
Netherlands #9
Aha! Wow I had never discovered that whole external script file thing! Thank you for pointing that out.

So I can just start out straight away with coding no things needed to open it?

I just started with something not quite sure if this is possible since I'm not sure if I'm doing it right;


--mw = {}

--function enemaff()
--	win = "enemaff"
--	WindowCreate (win, 700, 0 ,170, 145, 6, 2, ColourNameToRGB("green"))
--	WindowRectOp (win, 1, 700, 0, 145, 0, ColourNameToRGB("tan"))
--	WindowShow (win, true)
--	WindowFont (win, "f", "Trebuchet MS", 14, true, false, false, false)
--	WindowText (win, "f", ("Target is: "..GetVariable("target")), 4, 0, 0, 0, ColourNameToRGB ("darkred"), false)


--afflictions = {} -- empty table
--	if GetVariable("dizziness") == "1" then
--      Note ("Dizzy!"
--	GetVariable ("stupidity") == "1" then
--      Note ("Stupid!")
--      end
--	count = 0
--	for k, v in pairs (afflictions) do
--	count = count + 1
--end


Just putting the '--' in to make it not affect anything just yet.

This is the whole script file right now, am I on the right track here or not quite?
As an addendum, sorry for continuously bugging you guys! I can understand it must be annoying to have to break things down.
USA #10
Krae said:
Aha! Wow I had never discovered that whole external script file thing! Thank you for pointing that out.

No problem.

Krae said:
So I can just start out straight away with coding no things needed to open it?

Once MUSHclient knows the name of the file, it'll automatically run it. You can even set it to reload it whenever the file changes; check out the options in the Scripting configuration.

Krae said:
I just started with something not quite sure if this is possible since I'm not sure if I'm doing it right;


--mw = {}

--function enemaff()
--	win = "enemaff"
--	WindowCreate (win, 700, 0 ,170, 145, 6, 2, ColourNameToRGB("green"))
--	WindowRectOp (win, 1, 700, 0, 145, 0, ColourNameToRGB("tan"))
--	WindowShow (win, true)
--	WindowFont (win, "f", "Trebuchet MS", 14, true, false, false, false)
--	WindowText (win, "f", ("Target is: "..GetVariable("target")), 4, 0, 0, 0, ColourNameToRGB ("darkred"), false)


--afflictions = {} -- empty table
--	if GetVariable("dizziness") == "1" then
--      Note ("Dizzy!"
--	GetVariable ("stupidity") == "1" then
--      Note ("Stupid!")
--      end
--	count = 0
--	for k, v in pairs (afflictions) do
--	count = count + 1
--end


Just putting the '--' in to make it not affect anything just yet.

This is the whole script file right now, am I on the right track here or not quite?


All things considered, yes, you're on the right track. I suggest using indentation heavily though, because you're missing an 'end' and it's not immediately obvious. Conventional Lua indentation, by the way, is two spaces. Lastly, you can do a multiline comment with "--[[ ]]".

You don't really need to comment this stuff out, though. Functions are inert until you call them, so unless you're worried about using the variable name or the code is syntactically broken, there's no need.

mw = {}
win = "enemaff" -- Moved out of the function since it's constant

-- Don't worry too much about short names; enemy_aff would be clearer.
-- draw_enemy_affs would be perfect.
function enemaff()
  WindowCreate (win, 700, 0 ,170, 145, 6, 2, ColourNameToRGB("green"))
  WindowRectOp (win, 1, 700, 0, 145, 0, ColourNameToRGB("tan"))
  WindowShow (win, true)
  WindowFont (win, "f", "Trebuchet MS", 14, true, false, false, false)
  WindowText (win, "f", "Target is: " .. GetVariable("target"), 4, 0, 0, 0, ColourNameToRGB ("darkred"), false)

  -- This table will always be empty, because it's created every time in the function.
  -- Is this what you wanted? If not, consider putting it outside the function instead.
  afflictions = {} -- empty table

  if GetVariable("dizziness") == "1" then
    Note ("Dizzy!") -- You forgot a ) here.
  end -- You forgot this 'end'.

  if GetVariable ("stupidity") == "1" then
    Note ("Stupid!")
  end

  local count = 0 -- Making this local.
  for k, v in pairs (afflictions) do
    count = count + 1
  end
end -- You forgot this 'end'.


Krae said:
As an addendum, sorry for continuously bugging you guys! I can understand it must be annoying to have to break things down.

What's annoying is that everyone who actually deserves our help thinks they're bugging us. ;) It's really no big deal, you're obviously taking our advice and trying things on your own.
Amended on Mon 13 Sep 2010 09:09 AM by Twisol
Australia Forum Administrator #11
Template:scripting
Scripting tutorial

There is extensive information about scripting in MUSHclient at http://mushclient.com/scripting. This includes screen shots and examples.

Finland #12
I feel the same way (that I'm being a bugger) evey time I post a question.

What I can do to ease my concience is to:

1) Make the title something that I did a forum search with so people with the same question find their way to the post.

2) And ofcourse eventually when the problem is solved turn the question into a tutorial of sorts (basically adding a summa summarum to the end of the thread when needed)

3) Obviously helping out people with their issues when ever possible is a good thing to do too.