Jump to content


Photo

lua code question


13 replies to this topic

#1 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 28 July 2005 - 08:58 AM

What's the difference between

  local num_items = table.getn( self.table )
   for i = 1, num_items, 1 do
      whatever( self.table[i])
    end

and

   for i in self.table do
        whatever( self.table[i])
    end

?

#2 Flenser

Flenser

    title available

  • Members
  • 316 posts
  • Location:Glasgow, Scotland
  • Projects:Dawn of War AI Skirmish

Posted 28 July 2005 - 10:30 AM

What's the difference between

  local num_items = table.getn( self.table )
   for i = 1, num_items, 1 do
      whatever( self.table[i])
    end

and

   for i in self.table do
        whatever( self.table[i])
    end

?

<{POST_SNAPBACK}>

I believe the former will only use items in self.table which have an integer key, whereas the latter will use all items in self.table regardless of what type of key they have.

Eg. self.table = {10, 20, 30; bob = "happy", 40 }

The former iterative function will only run through 10, 20, 30 and 40, since they have, by default, integer keys of 1, 2, 3 and 4 respectively (note: NOT 1, 2, 3 and 5). The value "happy" does not have an integer key (its key is 'bob').

The second function should also include the value "happy"

Flenser

Edited by Flenser, 28 July 2005 - 10:31 AM.


#3 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 28 July 2005 - 12:49 PM

I believe the former will only use items in self.table which have an integer key, whereas the latter will use all items in self.table regardless of what type of key they have.


If this is true then this shouldn't work as self.attack_units does not have an integer key, right ?

--run through tactics and remove those that are complete
	local num_items = table.getn( self.attack_units )
	for i = num_items, 1, -1 do
  if not self.attack_units[i]:IsValid() then
 	 Plan.UnlockResource( self, self.attack_units[i] )
 	 table.remove( self.attack_units, i )
  end
	end


#4 Flenser

Flenser

    title available

  • Members
  • 316 posts
  • Location:Glasgow, Scotland
  • Projects:Dawn of War AI Skirmish

Posted 28 July 2005 - 02:28 PM

If this is true then this shouldn't work as self.attack_units does not have an integer key, right ?

<{POST_SNAPBACK}>

It does. Integer keys are given by default if no key is specified. Units are added to self.attack_units as follows:-

table.insert( self.attack_units, attack_units[i] )
All that does is put the value 'attack_units[i]' at the end of the integer-keyed entries already in self.attack_units. Eg. if self.attack_units had no entries at all, then attack_units[i] would be inserted with a key of 1. LUA begins all tables at 1 and not zero. If self.attack_units had 3 units already added, then the new unit would be added at position 4, and automatically given key 4.

If you wanted to add attack_units with an non-integer key you would do something like this:-

self.attack_units["first_unit"] = attack_units[i]
The 'key' here is "first_unit" and the value is "attack_units[i]". (You could change "first_unit" to "1" and you would be expressly using an integer key. Not sure why you would do it this way, but it would work)

The problem with that, of course, is that non-integer keys are hard to use properly when you are iterating over numerous attack_units - how do you change the key to "second_unit", "third_unit" and so on? Best to stick to integer keys for tables where the contents change all the time.

It is worth noting that

table.insert( self.attack_units, attack_units[i] )
can be written as

self.attack_units[ ( table.getn( self.attack_units) + 1) ] = attack_units[i]

Flenser

Edited by Flenser, 28 July 2005 - 02:37 PM.


#5 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 28 July 2005 - 02:40 PM

Thanks for this table tutorial. I'm trying to hunt down a crash bug which does occur since I write dancing units to a table. Can you see any blunder here

function CpuManager:IsDancer( squad_id )

   dbAssert( squad_id ~= nil )

   --check if squad is dancing
   for i in self.no_move_tbl do
   if self.no_move_tbl[i]:IsValid() and
   self.no_move_tbl[i]:GetID() == squad_id then
   return true
   end
   end
   
   return false
end


function CpuManager:RemoveDancer( squad_ai )
  
   profile_start("RemoveDancer")

   dbAssert( squad_ai ~= nil )

   --remove dancing squad from table
   local num_items = table.getn( self.no_move_tbl )
   for i = num_items, 1, -1 do
   if not self.no_move_tbl[i]:IsValid() then
   table.remove( self.no_move_tbl, i ) --erase invalid from table
   elseif squad_ai ~= nil and self.no_move_tbl[i]:GetID() == squad_ai:GetID() then
   table.remove( self.no_move_tbl, i ) --erase specific ID from table
   end
   end

   profile_end("RemoveDancer")
end


function CpuManager:InsertDancer( squad_ai )

   dbAssert( squad_ai ~= nil )

   --insert dancing squad
   table.insert( self.no_move_tbl, squad_ai )
	
end


#6 Flenser

Flenser

    title available

  • Members
  • 316 posts
  • Location:Glasgow, Scotland
  • Projects:Dawn of War AI Skirmish

Posted 28 July 2005 - 02:59 PM

Hmmm. Not sure.

In function RemoveDancer() make sure that num_items ~= nil before proceeding (ie. make sure there actually are some entries in the table).

That should not be a problem in IsDancer() since if the table is empty the code after "do" and before "end" will simply not be executed at all.

If that doesn't work it is time for brute force! Aitrace your code from here to next week and see where it breaks.

Flenser

#7 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 29 July 2005 - 08:16 AM

I found where it breaks but I'm totally clueless why. Help !

  aitimelog("d:\\trace.log", "RemoveDancer 1: "..tostring(num_items)) --TP1
   for i = num_items, 1, -1 do
     dbAssert( self.no_move_tbl[i] ~= nil )
     dbAssert( self.no_move_tbl[i]:IsValid() ~= nil )
   if not self.no_move_tbl[i]:IsValid() then
     aitimelog("d:\\trace.log", "Remove Invalid "..tostring(i)) --TP2
   table.remove( self.no_move_tbl, i ) --erase invalid from table
   else
     aitimelog("d:\\trace.log", "Keep Valid "..tostring(i).." "..tostring(self.no_move_tbl[i]:GetID())) --TP3
   end
   end

   aitimelog("d:\\trace.log", "RemoveDancer 2: Count") --TP4  

It does reach trace point 1 (TP1) but crashes afterwards somewhere before TP4. num_items is 1. It crashes to desktop so dbAssert() didn't trigger anything.

The table does hold squad_ai of dancing squads. I found that it is possible
that self.no_move_tbl[i]:IsValid() can be tue BUT the squad_id is something like 478975677 ??? How this. Valid IDs start with 50000 and count upwards as squads are produced.

Is it possible that killed squads which are still in the table can't be erased as either IsValid() or GetID() access will crash the game ?

I've now wasted 16+ hours on this and are near a nervous breakdown.

#8 Flenser

Flenser

    title available

  • Members
  • 316 posts
  • Location:Glasgow, Scotland
  • Projects:Dawn of War AI Skirmish

Posted 29 July 2005 - 08:46 AM

1. You have TP2 and TP3 in your code. Does it reach either of these?

2. Are you sure you are using 'self' properly? Is self being passed to these functions when you call them, and is it the same self each time?

3. Take a look at my commented-out Ork CC code in Attackplan.ai - I implemented something very similar to this. I used self.enemy_ranged{} as a table to hold enemy squads and also which friendly squads were tasked with engaging them in CC. I have functions to add and remove both friendly and enemy squads from the table. That said Thud reported some crashes which he thought were caused by this code, so although the Ork CC runs, it is not 100%.

Squads can be deleted from the table whether they are dead or not - it makes no difference to the table. IsValid() should likewise be unbreakable - I have only known it to solve problems, not cause them. If a squad exists (is alive) it is Valid, if it does not exist then it is Not Valid. I cannot see any third alternative.

4. In function RemoveDancer() you do not check if the field squad_ai is valid or not. You check if the squad in the table is valid, but not the squad you are comparing it with. The dbAssert line will be insufficient since a squad_ai can be ~= nil but still be not Valid.

Flenser

#9 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 29 July 2005 - 09:45 AM

It does not reach TP2 or TP3.

I'm pretty sure I use the functions properly. I sense something rotten as I get IsValid() true for a squad with the ID of 424355455 whatever which should not be possible. IDs are 50000, 50001 etc pp.

My feeling is that I can't safely access squad_ai stored in a table in the long run. My code will work for 13+ minutes of excessive usage but will crash afterwards.

Thanks for your help but I decided to do it different. Now I just write ID to table, not the squad_ai. squad_ai is a pointer, right ? I fear it doesn't point to the right object if this squad was killed.

Whatever. Seems it works now with just ID instead of squad_ai.

I did send you my broken code (last night) + my new fixes (just now) by email so you can check it out while feeling investigative.

Edited by LarkinVB, 29 July 2005 - 09:47 AM.


#10 Flenser

Flenser

    title available

  • Members
  • 316 posts
  • Location:Glasgow, Scotland
  • Projects:Dawn of War AI Skirmish

Posted 29 July 2005 - 11:10 AM

Glad you got it fixed :w00t: I will remember that for the Ork CC code - use ID rather than squad_ai. Maybe that is what was causing the crashes Thud saw.

If I remember right, squad_ai is type Userdata in LUA terminology, meaning it is arbitrary C data. It is possible this gets changed in the main code which would then cause an error in LUA files if those files assumed no change over time. GetID() produces a simple Number type which is standard LUA data and probably does not get modified by the main code at all once assigned, hence the stability.

Who knows? It works = happy :lol:

Flenser

#11 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 09 August 2005 - 11:05 AM

Another question :

Whats the difference between

squad_ai:GetPosition()

and

squad_ai:GetSquad():GetPosition()

They are both used and I don't get it.

Sometimes it looks like this

for squad_ai in military_manager:GetUnlockedSquads() do

    local squad_pos = Vector3f( squad_ai:GetSquad():GetPosition() )
    local dist = distance_sqr( squad_pos, some_other_pos )

and another time like this

for squad_ai in military_manager:GetUnlockedSquads() do

    local squad_pos = squad_ai:GetPosition()
    local dist = distance_sqr( squad_pos, some_other_pos )


#12 Flenser

Flenser

    title available

  • Members
  • 316 posts
  • Location:Glasgow, Scotland
  • Projects:Dawn of War AI Skirmish

Posted 09 August 2005 - 01:50 PM

Heh - you actually asked this one before - ages ago! Can't remember what the answer was...

The best I can do is that one works on Entity- and the other on Squad- or SquadAI-type data. See the RDN AI Wiki for details. I think it is just redundant code.

In any event, the result is the same being a Vector3f output.

Flenser

#13 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 09 August 2005 - 02:05 PM

Yes. I asked this before but couldn't remember the answer. I wanted to simplify code, therefore I removed the entity stuff. Will see wether it wil crash this evening.

I was sceptical that it could be related to the no no to copy a Vector3d like this :

squad_pos = v3d_value

You have to do this :

squad_pos = Vector3d( v3d_value )

But it seems unrelated.

#14 thudo

thudo

    Wacko AI Guy!

  • Division Leaders
  • 12,164 posts
  • Location:Lemonville North, Canada
  • Projects:DoW AI Scripting Project
  • Division:DoW
  • Job:Division Leader

Posted 09 August 2005 - 02:46 PM

Original Thread:

Get Position Inquiry

Its funny looking at that old pre-v1.30 workaround thread as I understood your frustration with what we were dealing with at the time.

Edited by thudo, 09 August 2005 - 02:47 PM.

Advanced Skirmish AI Team Lead for the coolest Warhammer40k PC RTS out there:

Dawn of War Advanced AI Headquarters

Latest DoW Advanced AI Download!



Reply to this topic



  


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users