Page 1 of 1

[Resolved] Reading values into table. Export Table

Posted: Tue Jun 27, 2017 8:08 pm
by TheSAguy
Hi,

I have a table that lists terain type and tree type that I want to use per terrain type.
How do I randomly select if I have more than 1 tree type.

In my table below, "grass-dry" has two tree types, "sand" has three.
How can I randomly choose one of these tree types each time I hit the table?

Code: Select all

Bi_Industries.tree_type = {  
	-- Vanilla
	["grass-medium"]    = "tree-04", 
	["grass"]           = "tree-05", 
	["grass-dry"]       = "tree-01",
	["grass-dry"]       = "tree-02",
	["dirt"]            = "tree-06",
	["dirt"]            = "tree-07",
	["dirt-dark"]       = "tree-06",
	["dirt-dark"]       = "tree-07",
	["sand"]            = "tree-03",
	["sand"]            = "tree-08",
	["sand"]            = "tree-09",
	["sand-dark"]       = "tree-03",
	["sand-dark"]       = "tree-08",
	["sand-dark"]       = "tree-09",
	["red-desert"]      = "tree-06",
	["red-desert"]      = "tree-07",
	["red-desert-dark"] = "tree-06",
	["red-desert-dark"] = "tree-07",

}
Thanks.

Re: Random Table Select

Posted: Tue Jun 27, 2017 8:49 pm
by darkfrei
Something like this:

Code: Select all

function get_random_tree_for_terrain (terrain_name) -- text
	-- local terrain_names = {"grass-medium", "grass", "grass-dry", "dirt", "dirt-dark", "sand", "sand-dark", "red-desert", "red-desert-dark"}
	local terrains = {}
	terrains["grass-medium"] = {name = "grass-medium", trees = {"tree-04"}}
	terrains["grass"] = {name = "grass", trees = {"tree-05"}}
	terrains["grass-dry"] = {name = "grass-dry", trees = {"tree-01", "tree-02"}}
	terrains["dirt"] = {name = "dirt", trees = {"tree-06", "tree-07"}}
	terrains["dirt-dark"] = {name = "dirt-dark", trees = {"tree-06", "tree-07"}}
	terrains["sand"] = {name = "sand", trees = {"tree-03", "tree-08", "tree-09"}}
	terrains["sand-dark"] = {name = "sand-dark", trees = {"tree-03", "tree-08", "tree-09"}}
	terrains["red-desert"] = {name = "red-desert", trees = {"tree-06", "tree-07"}}
	terrains["red-desert-dark"] = {name = "red-desert-dark", trees = {"tree-06", "tree-07"}}

	for i, terrain in pairs (terrains) do
		if (terrain.name == terrain_name) then 
			return get_random_from_table (terrain.trees)
		end
	end
end
or just

Code: Select all

	return get_random_from_table (terrains[terrain_name].trees)

Re: Random Table Select

Posted: Tue Jun 27, 2017 9:14 pm
by darkfrei
The second function is something like this.

Code: Select all

function get_random_from_table (table)
	-- compressed table if some elements was deleted and we have {[1] = value1, [3] = value3}
	local compressed_table = {}
	for i, value in pairs (table) do
		if value then 
			compressed_table[#compressed_table+1] = value
		end
	end
	return compressed_table[math.random(1,#compressed_table)]
end
For sure, somebody can write it easy, just with return table[math.random(1,#table)], but I'm not sure that it always works.

Re: Random Table Select

Posted: Tue Jun 27, 2017 9:43 pm
by TheSAguy
This works perfectly!
Thanks a lot Darkfrei!!

Re: Random Table Select

Posted: Tue Jun 27, 2017 10:06 pm
by darkfrei
I don't know if it works (or correct, I can't .lua not very good), but you can use it by your code:

Code: Select all

function add_tree_name_to_terrain_table (table, tree_name, terrain_name)
	-- table must be global.terrains or what you use
	if table[terrain_name] then
		add_tree_name_to_table_as_last (table[terrain_name].trees, tree_name) -- (table, value)
	else	
		table[terrain_name] = {name = terrain_name, trees = {tree_name}}
	end
end

function add_tree_name_to_table_as_last (table, value)
	local cash_i = 0
	for i, v in pairs (table) do
		cash_i = i
		if v == value then
			return -- we have this already!
		end
	end
	table[cash_i + 1] = value
end

Re: Random Table Select

Posted: Wed Jun 28, 2017 7:07 pm
by TheSAguy
Hey Darkfrei,
I need some assistance please. I know you've already done 95%, but I still can't get that last 5% down...

So my idea is to create some large maps and read in all tree names and terrain types to create a static table that I'll use for choosing the tree type based on the terrain type.

I was not sure if I should do it on "on_chunk_generated"
Something like: (this is not correct, but I'm trying...

Code: Select all

local function onChunkGenerated(event)
	
	local radius = 10
	local trees			
	local area = {{pos.x - radius, pos.y - radius}, {pos.x + radius, pos.y + radius}}
	
	
	trees = game.surfaces[1].find_entities_filtered{area = area, type= "tree"}
	
	if #trees > 0 then
	
	for _,target in pairs(trees) do
	
		local position = target.position
		local currentTilename = surface.get_tile(position.x, position.y).name
		local tree_name = target.name
		
	end


	add_tree_name_to_terrain_table (global.bi.terrains, tree_name, currentTilename)
end



script.on_event(defines.events.on_chunk_generated, onChunkGenerated)

Then, how do I print this table, preferably to a file.

Thanks.

Re: Random Table Select

Posted: Wed Jun 28, 2017 7:25 pm
by darkfrei
The code wasn't tested, but looks like:

Code: Select all

script.on_init(function ()
	if not global then global = {} end
	if not global.terrains then global.terrains = {} end
	if not global.terrain_names then global.terrain_names = {} end
	if not global.tree_names then global.tree_names = {} end
end)

script.on_event(defines.events.on_chunk_generated, function (event)
	chunk_generated_handler(event)
end)

function chunk_generated_handler(event)
	--area :: BoundingBox: Area of the chunk
	--surface :: LuaSurface: The surface the chunk is on
	--Area example: {{-2, -3}, {5, 8}} is left_top and right_bottom position
	local area = event.area
	local surface = event.surface
	local entities = surface.find_entities_filtered{area=area, type="tree"} -- don't forget surface!
	if (not entities) or (#entities == 0) then return end
	for i, entity in pairs (entities) do
		--search_tiles_by_this_entity_handler(entity)
	end
end

Re: Random Table Select

Posted: Wed Jun 28, 2017 8:47 pm
by darkfrei
So, result is here: 112 lines after 15 minutes exploring.
All pairs terrain-tree from vanilla
:arrow: :arrow: :arrow: Find this file!
control.lua
version_001
(3.41 KiB) Downloaded 76 times

:arrow: :arrow: :arrow: Find this file!

Re: Random Table Select

Posted: Wed Jun 28, 2017 9:13 pm
by TheSAguy
Okay, I have the following. I believe it's now writing it into the table.
Can I output the table to a file?

Code: Select all

local QC_Mod = true

script.on_init(function ()
   if not global then global = {} end
   if not global.terrains then global.terrains = {} end
   if not global.terrain_names then global.terrain_names = {} end
   if not global.tree_names then global.tree_names = {} end
end)

script.on_event(defines.events.on_chunk_generated, function (event)
   chunk_generated_handler(event)
end)

function chunk_generated_handler(event)
   --area :: BoundingBox: Area of the chunk
   --surface :: LuaSurface: The surface the chunk is on
   --Area example: {{-2, -3}, {5, 8}} is left_top and right_bottom position
   local area = event.area
   local surface = event.surface
   local entities = surface.find_entities_filtered{area=area, type="tree"} -- don't forget surface!
   if (not entities) or (#entities == 0) then return end
   for i, entity in pairs (entities) do
      --search_tiles_by_this_entity_handler(entity)
	 local tree_name = entity.name
	 local pos = entity.position
	 local terrain_name = surface.get_tile(pos.x, pos.y).name
	 writeDebug("The Tree is: ".. tree_name)
	 writeDebug("The Tile is: ".. terrain_name)
	  
	 add_tree_name_to_terrain_table (global.terrains, tree_name, terrain_name)
	 
   end
end



--- Need your help here.

function add_tree_name_to_terrain_table (table, tree_name, terrain_name)
   -- table must be global.terrains or what you use
   if table[terrain_name] then
      add_tree_name_to_table_as_last (table[terrain_name].trees, tree_name) -- (table, value)
   else   
      table[terrain_name] = {name = terrain_name, trees = {tree_name}}
   end
end

function add_tree_name_to_table_as_last (table, value)
   local cash_i = 0
   for i, v in pairs (table) do
      cash_i = i
      if v == value then
         return -- we have this already!
      end
   end
   table[cash_i + 1] = value
end






--------------------------------------------------------------------
--- DeBug Messages 
--------------------------------------------------------------------
function writeDebug(message)
	if QC_Mod == true then 
		for i, player in pairs(game.players) do
			player.print(tostring(message))
		end
	end
end


Re: Random Table Select

Posted: Wed Jun 28, 2017 9:18 pm
by darkfrei
You can find file in one post before.
This script export this to the file in Factorio\script-output\terrains.txt

The file is now 128 lines, I think there is nothing more. I have found first sand biome after 100 000 chunks!

Re: [Resolved] Reading values into table. Export Table

Posted: Thu Jun 29, 2017 4:10 pm
by TheSAguy
Hey Darkfrei,
It worked perfectly, thanks so much for your help with this!

Re: [Resolved] Reading values into table. Export Table

Posted: Wed Dec 20, 2017 10:48 pm
by darkfrei
Updated version with weights.

The result table looks like:
code
TreesAndTerrains_0.0.1.zip
For 0.16
(1.83 KiB) Downloaded 67 times