Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to "verify" your details, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ MUSHclient ➜ General ➜ changing variables with new data

changing variables with new data

It is now over 60 days since the last post. This thread is closed.     Refresh page


Pages: 1 2  

Posted by Zack   (23 posts)  Bio
Date Sat 05 Feb 2022 07:30 PM (UTC)
Message
Hey all!
I'm currently playing around on a mud that displays NPC's on a grid. Not the typical north east south west type of thing. I'm at like (2, 5) and there's all sorts of enemy around me at different points. Each unit has 2 numbers representing their position. It looks like this
Soldiers: (1, 5) (4, 6) (15, 12) (12, 2)
And if you are flying it'll add a third number for altitude. Fighters: (1, 15, 11) etc
I can create a second script for the map with 3 numbers not a problem. I just need to know how to write this out at all.
You see this information with a quick command and I want to have each set of numbers be placed into a variable so I can run a script to evaluate which one is closest to me at any given moment as I move around on the map.
Being blind it's kind of hard to swift through all the numbers. It doesn't exactly break them up real well with the screen reader it just sounds like 12, 15, 2, 3, 12, 5, 6 and it's hard to figure out while in combat.
So is there a way I can write a script that create a set of variables that collects the data? Is there away to have mush client stick to a naming convention while auto generating variables?
I was thinking like enemy_1, if enemy_1 is full create enemy_2 with this data.
I don't exactly no how to work this out. I'm quite familiar with SetVariable and GetVariable with Lua.
I would also need a way to count how many variables the script needs to look at as well. So if there's 30 it doesn't just look at the first ten.
As far as the script that evaluates who's closest to me I figured that'd just be a lone list of elseif statements.
thanks for any help and I appreciate the hell out of this site and mush client.
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #1 on Sun 06 Feb 2022 06:11 AM (UTC)
Message
It sounds like this is a job for ... Table Man!

Tables are a fundamental part of Lua, and Lua is a great scripting language. :)

Rather than trying to create variables with names, how about just shoving the information into a table? It's a bit unclear from your description whether or not you might have multiple mobs at the same location.

Assuming you don't, for the moment, then the problem becomes simple. Just make the coordinate the key. So, for example:


mobs = {}   -- create the table (once only)

mobs [ "5,6" ] = true  -- there is a mob here


Once the mob is in the table you can iterate over the table (that is, see what is in it).

Read this for stuff about tables: http://www.gammon.com.au/forum/?id=4903

Another way of doing this, which would also handle multiple mobs at one location, is to push stuff into a numbered table. So in this case, you would do something like:



mobs = {}   -- create the table (once only)

table.insert (mobs, "5,6")  -- there is a mob here


In this case the mobs table now has an entry (number 1) with the value "5,6" which is the coordinate of the mob.

The nice thing about this, from your point of view, is that the entries are now simply numbered. So you have mob 1, mob 2, and so on.

The fact that it is in the table means it exists, and its value tells you its location.

Example code:


mobs = {}   -- create the table (once only)

table.insert (mobs, "5,6") 
table.insert (mobs, "2,1") 
table.insert (mobs, "4,2") 


print ("There are", #mobs, "enemies")

for k,v in ipairs (mobs) do
  print ("Mob number", k, "is at location", v)
end


Output:


There are 3 enemies 
Mob number 1 is at location 5,6 
Mob number 2 is at location 2,1 
Mob number 3 is at location 4,2 

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #2 on Sun 06 Feb 2022 06:32 AM (UTC)

Amended on Sun 06 Feb 2022 06:35 AM (UTC) by Nick Gammon

Message
As for proximity, let's assume you know where the mobs are (using triggers, for example).

This example code shows how you can work out which one is closer. I amended my earlier example to have a table within a table (which is perfectly fine), where the sub-table has the x and y coordinate as two items. I'll let you work out how to do the Z coordinate as well. :)


mobs = {}   -- create the table (once only)

table.insert (mobs, {x=5,y=6}) 
table.insert (mobs, {x=2,y=1}) 
table.insert (mobs, {x=4,y=2}) 

print ("There are", #mobs, "enemies")

for k,v in ipairs (mobs) do
  print ("Mob number", k, "is at location", v.x, ",", v.y)
end -- for

me = {x=4,y=3}

-- find closest

closest_distance = nil
closest_mob = nil

for k, v in ipairs (mobs) do
  
  -- calculate distance to me

  distance = math.sqrt ((me.x - v.x)^2 + (me.y - v.y)^2)
  if not closest_distance then
    -- first time
    closest_distance = distance
    closest_mob = k
  else
    -- record this if it is closer
    if distance < closest_distance then
      closest_distance = distance
      closest_mob = k
    end -- if
  end -- if
  print (string.format ("Mob %i is %0.1f away", k, distance))
end -- for

print ("Closest mob is number", closest_mob, "at", 
       mobs [closest_mob].x, "," , mobs [closest_mob].y)


This calculates the distance between you (hardcoded here) and the various mobs, and tells you which is closest. In this example the output was:


There are 3 enemies 
Mob number 1 is at location 5 , 6 
Mob number 2 is at location 2 , 1 
Mob number 3 is at location 4 , 2 
Mob 1 is 3.2 away 
Mob 2 is 2.8 away 
Mob 3 is 1.0 away 
Closest mob is number 3 at 4 , 2 

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #3 on Sun 06 Feb 2022 06:37 AM (UTC)
Message
Just to explain "k,v". In my mind they stand for "key,value" where the key is "where it is" and the value is "what is there".

So, for example, the key might be "Number 10 Downing Street" and the value might be "Boris Johnson". However that might change. :)

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Zack   (23 posts)  Bio
Date Reply #4 on Mon 14 Feb 2022 03:46 PM (UTC)
Message
thank you so much, for some reason I didn't get notified of responses to this thread so sorry it took so long. I appreciate your help with this and I'll sit down today and try to add this in.
I understand it from a read through point of view so we'll see what happens when I start to put it in the world.
As always thank you and you're the best.
Top

Posted by Zack   (23 posts)  Bio
Date Reply #5 on Mon 14 Feb 2022 05:45 PM (UTC)

Amended on Tue 15 Feb 2022 04:39 AM (UTC) by Zack

Message
Okay I have no clue what I'm doing I guess.
So in order to generate the table I need to place it in a trigger that's pulling the coordinates of the enemy right?
I read on the page about tables the table doesn't go in the trigger so how do I populate the table with the info?
Note: I'll clean up the trigger and turn it into a reg-exp once I have it all working.
Trigger is:
<triggers>
<trigger
enabled="y"
group="test"
match="*(*, *, *)*"
send_to="12"
sequence="100"
>
<send>mobs = {} -- create the table (once only)

table.insert (mobs, {x=%2,y=%3,z=%4})
table.insert (mobs, {x=%2,y=%3,z=%4})

table.insert (mobs, {x=%2,y=%3,z=%4})

table.insert (mobs, {x=%2,y=%3,z=%4})

table.insert (mobs, {x=%2,y=%3,z=%4})

table.insert (mobs, {x=%2,y=%3,z=%4})

table.insert (mobs, {x=%2,y=%3,z=%4})

table.insert (mobs, {x=%2,y=%3,z=%4})




print ("There are", #mobs, "enemies")

for k,v in ipairs (mobs) do
print ("Mob number", k, "is at location", v.x, ",", v.y)
end -- for

me = {x=4,y=3}

-- find closest

closest_distance = nil
closest_mob = nil

for k, v in ipairs (mobs) do

-- calculate distance to me

distance = math.sqrt ((me.x - v.x)^2 + (me.y - v.y)^2)
if not closest_distance then
-- first time
closest_distance = distance
closest_mob = k
else
-- record this if it is closer
if distance &lt; closest_distance then
closest_distance = distance
closest_mob = k
end -- if
end -- if
print (string.format ("Mob %i is %0.1f away", k, distance))
end -- for

print ("Closest mob is number", closest_mob, "at",
mobs [closest_mob].x, "," , mobs [closest_mob].y)
</send>
</trigger>
</triggers>

So a few problems I'm getting is it generates 8 mobs when there's only 5.
Anytime I try to add a Z value to me it throws up there needs to be a ) error.
It also repeats itself 8 times with all the enemies. Here's a sample of just one. It throws all this out 7 more times.
I understand it's creating 8 mobs because there is 8 table.inserts but if I don't have 8 it only fills the table in with one. So how do I have it fill in with the right amount with out over populating or under populating?
Also the mobs locations aren't exactly right you'll notice that it repeats the same mob at the same coordinates a bunch.

There are 8 enemies
Mob number 1 is at location 10 , 20
Mob number 2 is at location 10 , 20
Mob number 3 is at location 10 , 20
Mob number 4 is at location 10 , 20
Mob number 5 is at location 10 , 20
Mob number 6 is at location 10 , 20
Mob number 7 is at location 10 , 20
Mob number 8 is at location 10 , 20
Mob 1 is aircraft: bomber 1 (10, 20, 18), bomber 2 (6, 20, 20), bomber 3 (3, 12, 15), bomber 4 (2, 10, 13), and bomber 5 (20, 13, 4).1f away
Mob 2 is aircraft: bomber 1 (10, 20, 18), bomber 2 (6, 20, 20), bomber 3 (3, 12, 15), bomber 4 (2, 10, 13), and bomber 5 (20, 13, 4).1f away
Mob 3 is aircraft: bomber 1 (10, 20, 18), bomber 2 (6, 20, 20), bomber 3 (3, 12, 15), bomber 4 (2, 10, 13), and bomber 5 (20, 13, 4).1f away
Mob 4 is aircraft: bomber 1 (10, 20, 18), bomber 2 (6, 20, 20), bomber 3 (3, 12, 15), bomber 4 (2, 10, 13), and bomber 5 (20, 13, 4).1f away
Mob 5 is aircraft: bomber 1 (10, 20, 18), bomber 2 (6, 20, 20), bomber 3 (3, 12, 15), bomber 4 (2, 10, 13), and bomber 5 (20, 13, 4).1f away
Mob 6 is aircraft: bomber 1 (10, 20, 18), bomber 2 (6, 20, 20), bomber 3 (3, 12, 15), bomber 4 (2, 10, 13), and bomber 5 (20, 13, 4).1f away
Mob 7 is aircraft: bomber 1 (10, 20, 18), bomber 2 (6, 20, 20), bomber 3 (3, 12, 15), bomber 4 (2, 10, 13), and bomber 5 (20, 13, 4).1f away
Mob 8 is aircraft: bomber 1 (10, 20, 18), bomber 2 (6, 20, 20), bomber 3 (3, 12, 15), bomber 4 (2, 10, 13), and bomber 5 (20, 13, 4).1f away
Closest mob is number 1 at 10 , 20
aircraft: bomber 1 (10, 20, 18), bomber 2 (6, 20, 20), bomber 3 (3, 12, 15), bomber 4 (2, 10, 13), and bomber 5 (20, 13, 4)
There are 8 enemies
Mob number 1 is at location 3 , 2
Mob number 2 is at location 3 , 2
Mob number 3 is at location 3 , 2
Mob number 4 is at location 3 , 2
Mob number 5 is at location 3 , 2
Mob number 6 is at location 3 , 2
Mob number 7 is at location 3 , 2
Mob number 8 is at location 3 , 2
Mob 1 is Current Coordinates: (3, 2, 13).1f away
Mob 2 is Current Coordinates: (3, 2, 13).1f away
Mob 3 is Current Coordinates: (3, 2, 13).1f away
Mob 4 is Current Coordinates: (3, 2, 13).1f away
Mob 5 is Current Coordinates: (3, 2, 13).1f away
Mob 6 is Current Coordinates: (3, 2, 13).1f away
Mob 7 is Current Coordinates: (3, 2, 13).1f away
Mob 8 is Current Coordinates: (3, 2, 13).1f away
Closest mob is number 1 at 3 , 2
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #6 on Tue 15 Feb 2022 03:53 AM (UTC)
Message

table.insert (mobs, {x=%2,y=%3,z=%4}) 
table.insert (mobs, {x=%2,y=%3,z=%4}) 
table.insert (mobs, {x=%2,y=%3,z=%4}) 
table.insert (mobs, {x=%2,y=%3,z=%4}) 
table.insert (mobs, {x=%2,y=%3,z=%4}) 
table.insert (mobs, {x=%2,y=%3,z=%4}) 
table.insert (mobs, {x=%2,y=%3,z=%4}) 
table.insert (mobs, {x=%2,y=%3,z=%4}) 


When you find a mob you insert it into the table 8 times, so I'm not sure why you are surprised that you are seeing 8 of everything. Why not do it once?





  print (string.format ("Mob %i is %0.1f away", k, distance))


Inside a trigger, %0 means the entire matching line, so you need to double the percent symbols. My example was not written for inside a trigger so I didn't to that.

In other words:


  print (string.format ("Mob %%i is %%0.1f away", k, distance))






mobs = {}   -- create the table (once only)


This isn't once only, that is doing it every time the trigger fires. Unless this is what you want (like, you refresh the list every time) you really want:


if not mobs then
  mobs = {}   -- create the table (once only)
end -- if no mobs table yet

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Zack   (23 posts)  Bio
Date Reply #7 on Tue 15 Feb 2022 04:50 AM (UTC)
Message
I'm a tad confused. So the way the map works is it gives you all of the mobs with one command.
I type map and it gives me
Aircraft: (1, 5, 3) (4, 5, 5) and so on.
Their positions are random and the amount of aircraft can change as you move.
So every few kills I pull up the map again to see mob location.
It's not one trigger every time I encounter a mob. So I'm not sure if I've got the table set up right. It needs to automatically add the different mobs from one trigger.
I hope I'm explaining this well.
I thought that by adding a bunch of table.inserts it would just fill in the mobs positions and not add in the amount of table.inserts I had. So if there was 5 mobs it'd stop at 5.
I appreciate your help.
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #8 on Tue 15 Feb 2022 05:49 AM (UTC)

Amended on Tue 15 Feb 2022 05:50 AM (UTC) by Nick Gammon

Message
It would certainly help if you actually copy/pasted MUD output. It is hard to work from:


 Aircraft: (1, 5, 3) (4, 5, 5) and so on.


Surely you can just give two or three examples? It seems you have clarified that a single trigger tells you about a lot of mobs, is that right? And you don't need to remember them, next time they will be in different positions?

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Zack   (23 posts)  Bio
Date Reply #9 on Tue 15 Feb 2022 06:02 AM (UTC)
Message
Okay so mobs move randomly sorry I didn't make that super clear. So while I might be at 15, 12, 11 killing a mob the other ones might be moving towards me or away from me. to check this I just type map to see their coordinates.

Mud output:

Combat Zone Alpha: Enemy alert!
Aircraft: Bomber 1 (10, 5, 1), Bomber 6 (15, 4, 5), Bomber 3 (5, 5, 10), Bomber 20 (12, 8, 6)
Current position: (6, 6, 1)
With your examples for the closest mob I wasn't sure if it was looking at all of them and just showing the closest one or if it was only looking at one and showing me that one. That's why I was confused on how many times I needed to use table.insert.
From what I've seen there can be 30 or more mobs or 5 it just depends on if people have been killing in the area.
Tables are a great way to look at this data I'm just so new to how they work I got lost.
I apologize for not being clear.
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #10 on Wed 16 Feb 2022 08:16 AM (UTC)

Amended on Wed 16 Feb 2022 08:24 AM (UTC) by Nick Gammon

Message
Some real-life data always helps.

So you have two events there. One announces where the bombers are, which we can use to save in a table, as I said.

The second event is finding your own location. That is where we can compare that to the previously-remembered aircraft locations.

Like this:



<triggers>
  <trigger
   enabled="y"
   match="Aircraft: *"
   send_to="12"
   sequence="100"
  >
  <send>

mobs = { }  -- table of mobs

function processMob (name, x, y, z)
  -- get rid of comma from previous mob
  name = string.gsub (name, "^, ", "")
  -- insert into table
  table.insert (mobs, { name = name, x = x, y = y, z = z } )
end -- processMob 

-- split wildcard into individual mobs
string.gsub ("%1", "(.-) %((%d+), (%d+), (%d+)%)", processMob)


</send>
  </trigger>


  <trigger
   enabled="y"
   match="Current position: (*, *, *)"
   send_to="12"
   sequence="100"
  >
  <send>

me = { x = %1, y = %2, z = %3 }
mobs = mobs or { }  -- in case no mobs

-- find closest

closest_distance = nil
closest_mob = nil

for k, v in ipairs (mobs) do
  
  -- calculate distance to me

  distance = math.sqrt ((me.x - v.x)^2 + (me.y - v.y)^2 + (me.z - v.z)^2)
  if not closest_distance then
    -- first time
    closest_distance = distance
    closest_mob = v
  else
    -- record this if it is closer
    if distance &lt; closest_distance then
      closest_distance = distance
      closest_mob = v
    end -- if
  end -- if
  print (string.format ("%%s is %%0.1f km away", v.name, distance))
end -- for

if closest_mob then
  print (string.format ("Closest is %%s at (%%i, %%i, %%i)",
         closest_mob.name, closest_mob.x, closest_mob.y, closest_mob.z))
else
  print ("No aircraft nearby")
end -- if

</send>
  </trigger>
</triggers>




Template:pasting For advice on how to copy the above, and paste it into MUSHclient, please see Pasting XML.


Example output from your test data:


Bomber 1 is 4.1 km away
Bomber 6 is 10.0 km away
Bomber 3 is 9.1 km away
Bomber 20 is 8.1 km away
Closest is Bomber 1 at (10, 5, 1)


The code above takes into account the Z location.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Zack   (23 posts)  Bio
Date Reply #11 on Wed 16 Feb 2022 10:42 PM (UTC)
Message
Awesome, I appreciate the fact you can just throw this all together.
On the second trigger it spits this out twice.
Compile error
World: Zack
Immediate execution
[string "Trigger: "]:20: 'then' expected near '&'
Compile error
World: Zack
Immediate execution
[string "Trigger: "]:20: 'then' expected near '&'
I'm not exactly sure what it wants me to do to fix it. Also I can't remember if blank lines count as line numbers.
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #12 on Thu 17 Feb 2022 05:51 AM (UTC)
Message
Did you follow this link?

Template:pasting For advice on how to copy the above, and paste it into MUSHclient, please see Pasting XML.


Or did you ignore it?

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Zack   (23 posts)  Bio
Date Reply #13 on Thu 17 Feb 2022 11:54 PM (UTC)
Message
Yep I've read how to copy xml a few times. I tried it and was getting this error as well.
[WARNING] Clipboard
Line 24: Unexpected end-of-file while looking for </triggers> (Cannot load)
I made a blank world file and tried pasting it there as well and still got the same error.
I then selected and pasted the send to script information into a trigger to see if it would work that way. It didn't throw up an error.
The second trigger was throwing up the errors no matter what I did.
I have it working now. Not sure what happened but I created a new world file and the second trigger started working after closing mush client and a restart of my computer.
I typically don't ignore documentation as I'm doing everything I can to understand the best practices for mush client. I only make a thread if I can't figure this stuff out. I've been working on this for a few weeks now.
I appreciate your help.
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #14 on Fri 18 Feb 2022 12:15 AM (UTC)
Message
Quote:

Unexpected end-of-file while looking for </triggers>


Sounds like you didn't copy all of the text. It is in a box with a scrollbar, so you may have missed some.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


29,267 views.

This is page 1, subject is 2 pages long: 1 2  [Next page]

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.