2021-05-25 12:52:25 +02:00
local modname = minetest.get_current_modname ( )
local S = minetest.get_translator ( modname )
local modpath = minetest.get_modpath ( modname )
mcl_structures = { }
2021-02-22 00:15:32 +01:00
local rotations = {
" 0 " ,
" 90 " ,
" 180 " ,
" 270 "
}
local function ecb_place ( blockpos , action , calls_remaining , param )
if calls_remaining >= 1 then return end
2021-02-24 22:03:41 +01:00
minetest.place_schematic ( param.pos , param.schematic , param.rotation , param.replacements , param.force_placement , param.flags )
2021-02-22 00:15:32 +01:00
if param.after_placement_callback and param.p1 and param.p2 then
2021-04-07 01:34:15 +02:00
param.after_placement_callback ( param.p1 , param.p2 , param.size , param.rotation , param.pr , param.callback_param )
2021-02-22 00:15:32 +01:00
end
end
2021-05-25 12:52:25 +02:00
function mcl_structures . place_schematic ( pos , schematic , rotation , replacements , force_placement , flags , after_placement_callback , pr , callback_param )
2021-05-25 10:56:06 +02:00
local s = loadstring ( minetest.serialize_schematic ( schematic , " lua " , { lua_use_comments = false , lua_num_indent_spaces = 0 } ) .. " return schematic " ) ( )
2021-02-22 00:15:32 +01:00
if s and s.size then
local x , z = s.size . x , s.size . z
if rotation then
if rotation == " random " and pr then
rotation = rotations [ pr : next ( 1 , # rotations ) ]
end
if rotation == " random " then
x = math.max ( x , z )
z = x
elseif rotation == " 90 " or rotation == " 270 " then
x , z = z , x
end
end
local p1 = { x = pos.x , y = pos.y , z = pos.z }
local p2 = { x = pos.x + x - 1 , y = pos.y + s.size . y - 1 , z = pos.z + z - 1 }
2021-05-29 16:12:33 +02:00
minetest.log ( " verbose " , " [mcl_structures] size= " .. minetest.pos_to_string ( s.size ) .. " , rotation= " .. tostring ( rotation ) .. " , emerge from " .. minetest.pos_to_string ( p1 ) .. " to " .. minetest.pos_to_string ( p2 ) )
2022-10-24 04:09:08 +02:00
local param = { pos = vector.new ( pos ) , schematic = s , rotation = rotation , replacements = replacements , force_placement = force_placement , flags = flags , p1 = p1 , p2 = p2 , after_placement_callback = after_placement_callback , size = vector.new ( s.size ) , pr = pr , callback_param = callback_param }
2021-02-22 00:15:32 +01:00
minetest.emerge_area ( p1 , p2 , ecb_place , param )
2022-06-24 23:24:51 +02:00
return true
2021-02-22 00:15:32 +01:00
end
end
2015-07-03 06:58:45 +02:00
2021-05-25 12:52:25 +02:00
function mcl_structures . get_struct ( file )
2021-05-29 16:12:33 +02:00
local localfile = modpath .. " /schematics/ " .. file
2015-07-03 06:58:45 +02:00
local file , errorload = io.open ( localfile , " rb " )
2021-05-29 16:12:33 +02:00
if errorload then
minetest.log ( " error " , " [mcl_structures] Could not open this struct: " .. localfile )
2021-02-22 00:15:32 +01:00
return nil
2015-07-03 06:58:45 +02:00
end
2021-02-22 00:15:32 +01:00
local allnode = file : read ( " *a " )
file : close ( )
2015-07-03 06:58:45 +02:00
2021-02-22 00:15:32 +01:00
return allnode
2015-07-03 06:58:45 +02:00
end
2019-02-28 18:19:57 +01:00
-- Call on_construct on pos.
-- Useful to init chests from formspec.
2021-05-25 12:52:25 +02:00
local function init_node_construct ( pos )
2019-02-28 18:19:57 +01:00
local node = minetest.get_node ( pos )
local def = minetest.registered_nodes [ node.name ]
if def and def.on_construct then
def.on_construct ( pos )
return true
end
return false
end
2022-06-24 02:11:24 +02:00
mcl_structures.init_node_construct = init_node_construct
2019-02-28 18:19:57 +01:00
2022-10-24 04:09:08 +02:00
local function dir_to_rotation ( dir )
local ax , az = math.abs ( dir.x ) , math.abs ( dir.z )
if ax > az then
if dir.x < 0 then
return " 270 "
2017-12-09 16:50:32 +01:00
end
2022-10-24 04:09:08 +02:00
return " 90 "
2017-12-09 16:50:32 +01:00
end
2022-10-24 04:09:08 +02:00
if dir.z < 0 then
return " 180 "
2017-12-09 02:05:41 +01:00
end
2022-10-24 04:09:08 +02:00
return " 0 "
2020-10-14 15:23:39 +02:00
end
2022-06-06 03:34:31 +02:00
dofile ( modpath .. " /api.lua " )
2022-06-25 00:31:28 +02:00
dofile ( modpath .. " /shipwrecks.lua " )
2022-06-24 02:11:24 +02:00
dofile ( modpath .. " /desert_temple.lua " )
dofile ( modpath .. " /jungle_temple.lua " )
2022-06-24 03:09:50 +02:00
dofile ( modpath .. " /ocean_ruins.lua " )
2022-06-24 21:47:44 +02:00
dofile ( modpath .. " /witch_hut.lua " )
dofile ( modpath .. " /igloo.lua " )
2022-07-01 04:25:34 +02:00
dofile ( modpath .. " /woodland_mansion.lua " )
2022-07-10 02:32:37 +02:00
dofile ( modpath .. " /ruined_portal.lua " )
2022-06-24 23:24:51 +02:00
dofile ( modpath .. " /geode.lua " )
2022-08-08 04:50:26 +02:00
dofile ( modpath .. " /pillager_outpost.lua " )
2022-09-10 21:39:56 +02:00
dofile ( modpath .. " /end_spawn.lua " )
2022-08-31 11:41:04 +02:00
dofile ( modpath .. " /end_city.lua " )
2022-06-24 17:54:34 +02:00
2022-06-25 00:31:28 +02:00
2022-06-24 02:11:24 +02:00
mcl_structures.register_structure ( " desert_well " , {
place_on = { " group:sand " } ,
2022-06-24 21:10:52 +02:00
fill_ratio = 0.01 ,
2022-06-24 02:11:24 +02:00
flags = " place_center_x, place_center_z " ,
not_near = { " desert_temple_new " } ,
solid_ground = true ,
sidelen = 4 ,
2022-06-25 06:16:43 +02:00
chunk_probability = 600 ,
2022-06-24 02:11:24 +02:00
y_max = mcl_vars.mg_overworld_max ,
y_min = 1 ,
y_offset = - 2 ,
biomes = { " Desert " } ,
filenames = { modpath .. " /schematics/mcl_structures_desert_well.mts " } ,
} )
2022-06-06 03:34:31 +02:00
2022-06-24 21:47:44 +02:00
mcl_structures.register_structure ( " fossil " , {
2022-06-25 06:16:43 +02:00
place_on = { " group:material_stone " , " group:sand " } ,
2022-06-24 21:47:44 +02:00
fill_ratio = 0.01 ,
flags = " place_center_x, place_center_z " ,
solid_ground = true ,
sidelen = 13 ,
2022-06-25 06:16:43 +02:00
chunk_probability = 1000 ,
y_offset = function ( pr ) return ( pr : next ( 1 , 16 ) * - 1 ) - 16 end ,
y_max = 15 ,
y_min = mcl_vars.mg_overworld_min + 35 ,
2022-06-24 21:47:44 +02:00
biomes = { " Desert " } ,
filenames = {
modpath .. " /schematics/mcl_structures_fossil_skull_1.mts " , -- 4× 5× 5
modpath .. " /schematics/mcl_structures_fossil_skull_2.mts " , -- 5× 5× 5
modpath .. " /schematics/mcl_structures_fossil_skull_3.mts " , -- 5× 5× 7
modpath .. " /schematics/mcl_structures_fossil_skull_4.mts " , -- 7× 5× 5
modpath .. " /schematics/mcl_structures_fossil_spine_1.mts " , -- 3× 3× 13
modpath .. " /schematics/mcl_structures_fossil_spine_2.mts " , -- 5× 4× 13
modpath .. " /schematics/mcl_structures_fossil_spine_3.mts " , -- 7× 4× 13
modpath .. " /schematics/mcl_structures_fossil_spine_4.mts " , -- 8× 5× 13
} ,
} )
2022-06-24 17:54:34 +02:00
mcl_structures.register_structure ( " boulder " , {
filenames = {
modpath .. " /schematics/mcl_structures_boulder_small.mts " ,
modpath .. " /schematics/mcl_structures_boulder_small.mts " ,
modpath .. " /schematics/mcl_structures_boulder_small.mts " ,
modpath .. " /schematics/mcl_structures_boulder.mts " ,
2022-06-24 21:10:52 +02:00
-- small boulder 3x as likely
2022-06-24 17:54:34 +02:00
} ,
} , true ) --is spawned as a normal decoration. this is just for /spawnstruct
mcl_structures.register_structure ( " ice_spike_small " , {
filenames = {
modpath .. " /schematics/mcl_structures_ice_spike_small.mts "
} ,
} , true ) --is spawned as a normal decoration. this is just for /spawnstruct
mcl_structures.register_structure ( " ice_spike_large " , {
sidelen = 6 ,
filenames = {
modpath .. " /schematics/mcl_structures_ice_spike_large.mts "
} ,
} , true ) --is spawned as a normal decoration. this is just for /spawnstruct
2022-06-15 04:48:26 +02:00
-- Debug command
minetest.register_chatcommand ( " spawnstruct " , {
2022-10-24 04:09:08 +02:00
params = " dungeon " ,
2022-06-15 04:48:26 +02:00
description = S ( " Generate a pre-defined structure near your position. " ) ,
privs = { debug = true } ,
func = function ( name , param )
local player = minetest.get_player_by_name ( name )
if not player then return end
local pos = player : get_pos ( )
if not pos then return end
pos = vector.round ( pos )
local dir = minetest.yaw_to_dir ( player : get_look_horizontal ( ) )
local rot = dir_to_rotation ( dir )
local pr = PseudoRandom ( pos.x + pos.y + pos.z )
local errord = false
local message = S ( " Structure placed. " )
2022-10-24 04:09:08 +02:00
if param == " dungeon " and mcl_dungeons and mcl_dungeons.spawn_dungeon then
2022-06-15 04:48:26 +02:00
mcl_dungeons.spawn_dungeon ( pos , rot , pr )
elseif param == " " then
message = S ( " Error: No structure type given. Please use “/spawnstruct <type>”. " )
errord = true
else
for n , d in pairs ( mcl_structures.registered_structures ) do
if n == param then
2022-07-02 03:44:13 +02:00
mcl_structures.place_structure ( pos , d , pr , math.random ( ) )
2022-06-15 04:48:26 +02:00
return true , message
2022-06-10 02:40:33 +02:00
end
end
2022-06-15 04:48:26 +02:00
message = S ( " Error: Unknown structure type. Please use “/spawnstruct <type>”. " )
errord = true
end
minetest.chat_send_player ( name , message )
if errord then
minetest.chat_send_player ( name , S ( " Use /help spawnstruct to see a list of avaiable types. " ) )
2022-06-10 02:40:33 +02:00
end
2022-06-15 04:48:26 +02:00
end
} )
minetest.register_on_mods_loaded ( function ( )
local p = " "
for n , _ in pairs ( mcl_structures.registered_structures ) do
p = p .. " | " .. n
end
minetest.registered_chatcommands [ " spawnstruct " ] . params = minetest.registered_chatcommands [ " spawnstruct " ] . params .. p
2022-06-10 02:40:33 +02:00
end )