place_schematic replacements only works for the first time

Post Reply
Rochambeau
Member
Posts: 119
Joined: Tue Sep 23, 2014 11:37

place_schematic replacements only works for the first time

by Rochambeau » Post

Hi,

I'm playing with a mod, that places a schematic (built with cobble) several times. Each time it is placed, I want to have the walls to be built of another material.

The function looks like this:

Code: Select all

function settlements.build_schematic(pos)
  -- list of schematics, only one by now
  local schematic_table = {minetest.get_modpath("settlements").."/schems/hut.mts"}
  -- pick one of those schematics
  local schematic = schematic_table[math.random(1, #schematic_table)]
  -- pick random material for the walls
  local material = wallmaterial[math.random(1,#wallmaterial)]
  -- place schematic
  minetest.place_schematic(pos, schematic, "random", {["default:cobble"] = material}, true)
end
The replacement of the cobble walls only works for the first building. Every other building is made of the same material as the first one.

What am I doing wrong?

hajo
Member
Posts: 606
Joined: Thu Oct 13, 2016 10:45
Location: DE
Contact:

Re: place_schematic replacements only works for the first ti

by hajo » Post

Rochambeau wrote:places a schematic (built with cobble) several times.
Each time it is placed, I want to have the walls to be built of another material.

Code: Select all

function settlements.build_schematic(pos)
..
  -- pick one of those schematics
  local schematic = schematic_table[math.random(1, #schematic_table)]
  -- pick random material for the walls
  local material = wallmaterial[math.random(1,#wallmaterial)]
..
The replacement of the cobble walls only works for the first building.
Every other building is made of the same material as the first one.
I guess the same seed for your random numbers is used every time.

Sokomine
Member
Posts: 4290
Joined: Sun Sep 09, 2012 17:31
GitHub: Sokomine
IRC: Sokomine
In-game: Sokomine

Re: place_schematic replacements only works for the first ti

by Sokomine » Post

You are not doing anything wrong. The replacements are cached. I ran across that some time ago and eventually had to resort to my own placement function. Perhaps my handle_schematics and basic_houses mods can be of use to you.
A list of my mods can be found here.

Rochambeau
Member
Posts: 119
Joined: Tue Sep 23, 2014 11:37

Re: place_schematic replacements only works for the first ti

by Rochambeau » Post

Sokomine wrote:You are not doing anything wrong. The replacements are cached. I ran across that some time ago and eventually had to resort to my own placement function. Perhaps my handle_schematics and basic_houses mods can be of use to you.
Thank you for your helpful reply.

I'm still not perfectly satisfied ;-) and I'm trying a different approach:

- convert mts to lua

Code: Select all

local schem_lua = minetest.serialize_schematic(building, "lua", {lua_use_comments = false, lua_num_indent_spaces = 0}).." return(schematic)"
- replace material

Code: Select all

schem_lua = schem_lua:gsub("default:cobble", material)
  
- format schematic string

Code: Select all

local schematic = loadstring(schem_lua)()
- reconvert to mts

Code: Select all

local schem_mts = minetest.serialize_schematic(schematic, "mts", {})
My problem is, that when I call the function place_schematic like this, I get an error:

Code: Select all

minetest.place_schematic(pos, schem_mts, "random", nil, true)
The function expects a file-path as second parameter, instead of binary MTS data.

If I write schem_mts to a mts-file, and call the function with this file, it works, but the replacement only works once, because of caching.

Code: Select all

-- write file
  local file, err = io.open(schem_path.."temp.mts", "wb")
	file:write(schem_mts)
	file:flush()
	file:close()
  -- place schematic
  minetest.place_schematic(pos, schem_path.."temp.mts", "random", nil, true)
Maybe with random filenames, it would work, but there would be a huge amount of disk i/o.

Is it possible with lua to "fake" the existence of a file, that isn't physically there? Or modify the function place_schematic so it accepts binary MTS data?
Last edited by Rochambeau on Tue Jun 26, 2018 17:39, edited 1 time in total.

Rochambeau
Member
Posts: 119
Joined: Tue Sep 23, 2014 11:37

Re: place_schematic replacements only works for the first ti

by Rochambeau » Post

Yeehaaa, found a solution!

The reconversion to MTS wasn't necessary. This is the working code:

Code: Select all

function settlements.build_schematic(pos)
  -- list of schematics
  local schematic_table = {schem_path.."hut.mts"}
  -- pick one of those schematics
  local building = schematic_table[math.random(1, #schematic_table)]
   -- pick random material
  local material = wallmaterial[math.random(1,#wallmaterial)]
  -- schematic conversion to lua
  local schem_lua = minetest.serialize_schematic(building, "lua", {lua_use_comments = false, lua_num_indent_spaces = 0}).." return(schematic)"
  -- replace material
  schem_lua = schem_lua:gsub("default:cobble", material)
  -- format schematic string
  local schematic = loadstring(schem_lua)()
  -- place schematic
  minetest.place_schematic(pos, schematic, "random", nil, true)
end
Schematic can be an MTS file or a lua table. RTFM :-D

Sokomine
Member
Posts: 4290
Joined: Sun Sep 09, 2012 17:31
GitHub: Sokomine
IRC: Sokomine
In-game: Sokomine

Re: place_schematic replacements only works for the first ti

by Sokomine » Post

That's right. Lua tables work just as well. Paramat seems to even prefer them for things like trees. Probability of node generation/layer generation is tricky to do on .mts level.
A list of my mods can be found here.

Post Reply

Who is online

Users browsing this forum: shanish2 and 7 guests