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, confirm your email, resolve issues, 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.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUSHclient ➜ Lua ➜ Putting together a 3D view

Putting together a 3D view

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


Posted by Henry Tanner   Finland  (23 posts)  Bio
Date Fri 03 Sep 2010 09:33 AM (UTC)

Amended on Fri 03 Sep 2010 09:34 AM (UTC) by Henry Tanner

Message
For a good amount of time now I have worked on creating a plugin that will enhance the space battle experience in the MUD "Legends of the Jedi", and other similiar MUDs a great deal.

In the MUD the space is viewed through simple commands:
"proximity" for checking your distance from other stellar objects,
"proximity velocity" to check the objects' velocity
and "radar" or the more elaborate "fleetradar" for their x y z coordinates.

A sample of fleetradar output:

L[None    ]:P[Central ] Venator-Class Star Destroyer 'Resolute'  0 0 0
L[None    ]:P[Outer   ] G-Type Light Shuttle 'MatteBlackTaxi13'  0 0 0
L[None    ]:P[Outer   ] A Pirated Scurrg H-6 Bomber 'Krakana'  -1182 -1754 -446
L[None    ]:P[Outer   ] Mark I Bulk Freighter 'Imperceptus'  -231 -231 231
L[None    ]:P[Central ] Victory-Class Star Destroyer 'Exitus'  0 0 0
L[Victory-Class Star Destroyer 'Exitus']:P[Midguard] Victory-Class Star Destroyer 'Jomi'  0 0 0


In the script, the above is captured and turned into a visual representation: http://i.imgur.com/280X9.png
(If you have ever played Elite the image needs no explaining)

So far I've managed to automate listing new shiptypes (i.e Victory-Class Star Destroyer, Mark I Bulk Freighter and such) as the script comes across with them. It is also possible to change the color each shiptype is drawn in.

The table looks like this:

require "tprint"
tprint (shiptypes)
-->
"Venator-Class_Star_Destroyer"=16711680
"Victory-Class_Star_Destroyer"=16711680
"G-Type_Light_Shuttle"=16711680





Before I can move to other features of the script I will have to make the script capture the stellar objects into tables in a table that'd look something like this:

stellarobjects = {
1 = { "name"="resolute", "type"="Venator-Class Star Destroyer", ""leader"="None", "position"="Central", "x"="0", "y"="0", "z"="0"},
2 = { "name"="krakana", "type"="A pirated scurrg h-6 bomber", ""leader"="None", "position"="outer", "x"="-1182", "y"="-1754", "z"="-446"}
}


Despite studying the Tables guide, I haven't manged to figure out how to manage, delete, get and add entries in that table of tables.

Help?

I got this!
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #1 on Fri 03 Sep 2010 09:59 AM (UTC)
Message
Very briefly, for numbered tables (like in your example) - where the keys are just numbers starting at 1, you can use table.remove and table.insert.

For other keys (like names) you do something like this:


stellarobjects ["resolute"] = {   ... some stuff ...  }  -- add an item
stellarobjects ["resolute"] = nil  -- delete an item


For situations where you may have many things which are not otherwise unique (eg. multiple swords in an inventory) you probably want numeric keys, and you can just have item 1, item 2 etc.

For situations where everything has a unique name or identifier, then that unique thing is a sensible thing to use as the table key.

- Nick Gammon

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

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #2 on Fri 03 Sep 2010 10:07 AM (UTC)
Message
BTW I presume you just typed in your test data, it seems to have too many quotes in places, and also I personally would not put numbers in strings.

eg.

x="-1182"

might be better as

x = -1182

That saves converting them to numbers later to do things like addition, or comparison.

- Nick Gammon

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

Posted by Henry Tanner   Finland  (23 posts)  Bio
Date Reply #3 on Fri 03 Sep 2010 06:07 PM (UTC)
Message
I'm not quite that far yet.

In metacode i'm trying to do this:

output: L[None    ]:P[Central ] Venator-Class Star Destroyer 'Resolute'  0 0 0
trigger: L[*]:P[*] * '*'  * * *

check amount of tables within table StellarObjects
if StellarObjects has a table with a 'name' value that matches %4 in it
then
delete the whole old table and create a new one with the values that are in the wildcards
else
create a new table into the StellarObjects table


Does that make any sense at all?
I might be trying to swallow a too big bite again like I've done a dozen times before with this script before.

I've never played with tables within tables and I just can't figure out how to conveniently get information out of and in to a tabled table.

I've so far only managed to get that shiptypes table to work semi-conveniently.

Could I get some syntax? :/

I got this!
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #4 on Sat 04 Sep 2010 12:18 AM (UTC)
Message
Well that part is simple, since you want to add or replace based on a name. Something like:



StellarObjects ["%4"] = {  .... the data ..... }


With a table, inserting an entry replaces an existing one, if any.

- Nick Gammon

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

Posted by Henry Tanner   Finland  (23 posts)  Bio
Date Reply #5 on Mon 06 Sep 2010 07:05 AM (UTC)
Message

shiptype = string.gsub ("%3", " ", "_")
if not stellarobjects then
stellarobjects = {}
elseif StellarObjects ["%4"] then
stellarobjects["%4"] = { "type"="shiptype", "leader"="%1", "position"="%2", "x"="%5", "y"="%6", "z"="%7" }
else
stellarobjects.%4 = { "type"="shiptype", "leader"="%1", "position"="%2", "x"="%5", "y"="%6", "z"="%7" }
end


-->

Compile error
World: Legends of the Jedi
Immediate execution
[string "Trigger: "]:24: '}' expected near '='

with 24 being the 5th line in the pasted code


I can't see anything wrong with the syntax there, what am I doing wrong here? :S

I got this!
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #6 on Mon 06 Sep 2010 07:16 AM (UTC)

Amended on Mon 06 Sep 2010 07:26 AM (UTC) by Twisol

Message
Lua doesn't like using quotes around keynames. The "always works" syntax would be {["foo"] = 42, [100] = "a number"}, that is, with brackets around the key. Lua provides a shorthand that allows you to drop both the quotes and the brackets around a string key, so long as it's not something unreasonable like f$_!* or multiple words.

I'm also not sure what you're doing with the second and third branches of the if statement. The following statements are equivalent:

foo["bar"] = 42
foo.bar = 42


This goes back to what I was saying about Lua's special case for string keys. It's just syntatic sugar, they don't actually mean anything different. I think you're using one if the entry exists and one if it doesn't? It doesn't matter. :)

Lastly, you're defining a shiptype variable but you never use it. You do have type="shiptype", but that's a string literal. It won't pull the value out of the variable.

([EDIT]: Also, carefully consider what happens when there is no stellarobjects table. Only one branch of an if-statement is run every time it's executed, so when stellarobjects doesn't exist, it creates it, but doesn't add the current line to it.)

What I think you really want is this:

if not stellarobjects then
  stellarobjects = {}
end

stellarobjects["%4"] = {
  type = string.gsub ("%3", " ", "_"),
  leader = "%1",
  position = "%2",
  x = "%5",
  y = "%6",
  z = "%7",
}


Code styled for clarity. :)

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #7 on Mon 06 Sep 2010 07:57 AM (UTC)

Amended on Mon 06 Sep 2010 08:46 AM (UTC) by Nick Gammon

Message
Or to put it slightly differently, don't quote numbers, and don't quote keys.

So:


stellarobjects ["%4"] = { type=shiptype, leader="%1", position="%2", x=%5, y=%6, z=%7 }



[EDIT] Quoted position.

- Nick Gammon

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

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #8 on Mon 06 Sep 2010 08:14 AM (UTC)

Amended on Mon 06 Sep 2010 08:15 AM (UTC) by Twisol

Message
Nick Gammon said:
don't quote numbers

Strictly speaking, that's up to how you want to treat your data, rather than a syntax issue. ;) You're right that that's probably what he wants though.

Position isn't a number, by the way: see the first post.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #9 on Mon 06 Sep 2010 08:47 AM (UTC)
Message
OK I fixed that. As for the numbers, well, quoted numbers are generally not that useful. I mentioned it further up.

- Nick Gammon

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

Posted by Henry Tanner   Finland  (23 posts)  Bio
Date Reply #10 on Tue 07 Sep 2010 02:54 AM (UTC)
Message
Alright. I picked Twisol's layout because it is pretty and grabbed the xyz as values rather than strings, because they'll be used for calculating things rather than printing out to the output.

Now that stuff goes into the tables painlessly, I need to get them out of it too. I've never done "for blah blah do" sentences before and after checking out a few older posts I've managed to come up with this:

for t, x in stellarobjects do
print (stellarobjects.t [x])
end

-->

Run-time error
World: Legends of the Jedi
Immediate execution
[string "Trigger: "]:6: attempt to call a table value
stack traceback:
        [string "Trigger: "]:6: in main chunk


I am testing it out with a "print" for now to keep it simple until it works. What it should do is to get the xyz's out of the first entry, do calculations and draw and move on to the next one until the end of table.

I understand that "for t" means it does it until it comes across with a "nil", the x after it is used (?) as a variable in the syntax and "in stellarobjects" it is designated to work in that table. I couldn't find a good solid thread about "for" or anything else that I'd need to know in order to pull off this step. Ideas?

I got this!
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #11 on Tue 07 Sep 2010 03:03 AM (UTC)
Message
You want:


for t, x in pairs (stellarobjects) do
  print (t, x)
end


You don't need to mention stellarobjects inside the loop. The for loop is pulling out the key and value (t is the key, x is the value) for each item in the table.

- Nick Gammon

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

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #12 on Tue 07 Sep 2010 03:06 AM (UTC)
Message
And in your case the value is a table, so it would be something like:


for t, x in pairs (stellarobjects) do
  print (t, x.type, x.leader, x.position)
end


That is because the value "x" is really another table, so you can index into it to pull out the named items.

- Nick Gammon

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

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #13 on Tue 07 Sep 2010 03:21 AM (UTC)
Message
Here's how the generic-for works in a nutshell:

local t = {'a', 'b', 'c', 'd', 'e'}

for key, value in ipairs(t) do
  print(key, value)
end


A table is simply a set of key/value pairs. The generic for lets you access these pairs as you iterate over each pair in the table.

They key concept to understand here is that of an "iterator". Above, ipairs() is an iterator. You give it a table, it does some stuff (see non-nutshell explanation below), and it returns new values to your left-side variables for each iteration until you're done. ipairs() goes over consecutive integer keys (i.e. 1, 2, 3, 4) until there's no entry for that key (i.e. t[num] is nil). pairs() goes over absolutely every entry in a table, but you have no guarantee it will come out in any particular order.

Your code above would be:
for name, details in pairs(stellarobjects) do
  print(name, " -- ", details)
end

--[[ Output: (example)
Resolute -- table: 11111111
MatteBlackTaxi13 -- table: 222222
Krakana -- table: 33333333
--]]


Notice that it won't print out the contents of the details value. To inspect a table, I recommend using require("tprint") like so:
require("tprint")
tprint(stellarobjects)


Note that tprint() is not an iterator, so you don't use it as for k,v in tprint(t) do end. It's just a regular function, like print(). :)



If you're still reading and want more, here's an extended explanation. I suggest reading PiL chapter 7 for more details on iterators [1], but here's a cursory overview of the details.

An iterator like pairs() and ipairs() is really an iterator factory. Iterator factories return a function, and it's that function that's called every iteration by the generic-for loop. For example:
local iter, tbl, state = pairs(t)
for key, value in iter, tbl, state do
  print(key, value)
end


Now things are getting interesting, eh? An iterator factory return three values: an iterator function, the object being iterated over, and some state. Lets simulate what a loop that uses pairs() does:
-- pairs() returns a function that already exists, called next().

local t = {foo = 1, bar = 42, baz = 50}

local key, value = nil, nil
while true do
  key, value = next(t, key)
  if key == nil then
    break
  end
  
  print(key, value)
end


Do you see what's happening? This is almost exactly what happens inside the for-loop implementation, except it's not limited to next().

I highly recommend PiL if you want to learn more about iterators, or just Lua in general. :)

[1] http://www.lua.org/pil/7.html

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
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.


37,098 views.

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.