Identifying Active World

Posted by Balerion on Fri 26 Jan 2007 11:24 PM — 6 posts, 20,148 views.

#0
I've just started digging into MUSHclient's scripting capabilities after a number of years of using it. I started with VBScript, but given Nick's recommendation of LUA for scripting novices, it seemed the wiser choice. I've managed quite a few of the things I wanted to do, but I'd like to refine it if possible.

I've got a trigger that ends up sending a message to all open worlds (I always run several) when it's run -- basically, notifying me that I've been contacted on said world. What I'd like to do is have it send only to the active world. What I'm using to send to all worlds is this:

function SendToAllWorlds (message)

for k, v in pairs (GetWorldIdList ()) do
GetWorldById (v):ColourNote ("red","white,",message)
end

What I'd like to do is something like this instead:

function SendToActiveWorld (message)

for k, v in pairs (GetWorldIdList ()) do
if GetWorldById (v):isActive() then
GetWorldById (v):ColourNote ("red","white,",message)
end
end

Where isActive() is something that uses GetInfo(113), I guess (I suspect this may be a place where I'm going wrong):

function isActive ()

GetInfo(113)
end

What's happening right now is that I get this error message when the trigger's script tries to execute:

[string "Script file"]:676: attempt to call method `isActive' (a nil value)
stack traceback:
[string "Script file"]:676: in function `SendToActiveWorld'
[string "Trigger: "]:2: in main chunk

Any pointers much appreciated.
Australia Forum Administrator #1
This test routine worked for me. For all open worlds it displays a message showing the world name, and whether it is active or not:


message = "test"
for k, v in pairs (GetWorldIdList ()) do
  w = GetWorldById (v)  -- world userdatum
  w:Tell (w:WorldName() .. ": ")
  w:Tell (tostring (w:GetInfo (113)) .. ": ")
  w:ColourNote ("red", "white", message)
end -- for


I would also take the the comma you have in "white,".

Now using that idea, we can write the loop like this:


message = "test"

for k, v in pairs (GetWorldIdList ()) do
  w = GetWorldById (v) -- world userdatum
  if w:GetInfo (113) then  -- is it active?
    w:ColourNote ("red", "white", message)
  end -- if
end -- for


If you want to keep your separate isActive function, you could write it like this:


function isActive (w)
  if w then
    return w:GetInfo (113)
  else
    return GetInfo (113)
  end -- if
end -- function isActive 

message = "test"

for k, v in pairs (GetWorldIdList ()) do
  w = GetWorldById (v)  -- world userdatum
  if isActive (w) then  -- is it active?
    w:ColourNote ("red", "white", message)
  end -- if
end -- for


You have to pass down to isActive which world is the one whose activity you are testing for.
Amended on Sat 27 Jan 2007 03:45 AM by Nick Gammon
#2
Thanks, Nick. That's done the trick. I realize that I need one more wrinkle in there: how do I have it _not_ send the notice if I receive the message in the active world? No real point for it to notify me if I'm looking right at it.

I figured something of this sort might work, but it doesn't for some reason:

local foo
foo = GetWorldID ()
for k, v in pairs (GetWorldIdList ()) do
w = GetWorldById (v) -- world userdatum
if isActive (w) then -- is it active?
if w ~= foo then
w:ColourNote ("red", "white", message)
end -- if
end -- if
end -- for

Nothing seems to break, but it seems to always come out that w (active world) and foo ('current world', which I'm assuming is the world triggering the script?) are not equal even when this is not true.
Australia Forum Administrator #3
You are comparing two different types of things here, one is a world userdatum, one is the world ID. For example:


foo = GetWorldID ()
print (foo) --> ba5f85fd5e7c9ab5a8f62f3d


You want to change:


if w ~= foo then


to:


if v ~= foo then


In this case "v" is the ID from GetWorldIdList, so you are now comparing an ID to an ID.
#4
Thanks again, Nick. That was silly of me, heh. I think I'm getting more of a grasp of LUA now. Will have to ponder what sort of nifty things I'll want to do with it.
Australia Forum Administrator #5
Quote:

I've got a trigger that ends up sending a message to all open worlds ...


In case you haven't done so already, this is a good candidate for a small plugin. That way, if you make amendments, you only have to make them once.

Then you could go to Global Preference -> Plugins, and make that a global plugin, so it is automatically loaded into every world.