update boost carts, mesecons, moreblocks, moretrees, unified inventory,
and worldedit
@ -157,6 +157,29 @@ function boost_cart:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
|
||||
return {x=0, y=0, z=0}
|
||||
end
|
||||
|
||||
function boost_cart:pathfinder(pos_, expected_pos, old_dir, ctrl, pf_switch, railtype)
|
||||
local pos = vector.round(pos_)
|
||||
local pf_pos = vector.round(expected_pos)
|
||||
local pf_dir = vector.new(old_dir)
|
||||
|
||||
for i = 1, 3 do
|
||||
if vector.equals(pf_pos, pos) then
|
||||
-- Success! Cart moved on correctly
|
||||
return true
|
||||
end
|
||||
|
||||
pf_dir, pf_switch = boost_cart:get_rail_direction(pf_pos, pf_dir, ctrl, pf_switch, railtype)
|
||||
if vector.equals(pf_dir, {x=0, y=0, z=0}) then
|
||||
-- No way forwards
|
||||
return false
|
||||
end
|
||||
|
||||
pf_pos = vector.add(pf_pos, pf_dir)
|
||||
end
|
||||
-- Cart not found
|
||||
return false
|
||||
end
|
||||
|
||||
function boost_cart:boost_rail(pos, amount)
|
||||
minetest.get_meta(pos):set_string("cart_acceleration", tostring(amount))
|
||||
for _,obj_ in ipairs(minetest.get_objects_inside_radius(pos, 0.5)) do
|
||||
|
@ -4,7 +4,7 @@ boost_cart.modpath = minetest.get_modpath("boost_cart")
|
||||
|
||||
-- Maximal speed of the cart in m/s
|
||||
boost_cart.speed_max = 10
|
||||
-- Set to nil to disable punching the cart from inside
|
||||
-- Set to nil to disable punching the cart from inside (min = -1)
|
||||
boost_cart.punch_speed_min = 7
|
||||
|
||||
|
||||
@ -103,6 +103,7 @@ function boost_cart.cart:on_punch(puncher, time_from_last_punch, tool_capabiliti
|
||||
end
|
||||
|
||||
if puncher:get_player_control().sneak then
|
||||
-- Pick up cart: Drop all attachments
|
||||
if self.driver then
|
||||
if self.old_pos then
|
||||
self.object:setpos(self.old_pos)
|
||||
@ -124,10 +125,9 @@ function boost_cart.cart:on_punch(puncher, time_from_last_punch, tool_capabiliti
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local vel = self.object:getvelocity()
|
||||
if puncher:get_player_name() == self.driver then
|
||||
if math.abs(vel.x + vel.z) > (boost_cart.punch_speed_min or -1) then
|
||||
if math.abs(vel.x + vel.z) > boost_cart.punch_speed_min then
|
||||
return
|
||||
end
|
||||
end
|
||||
@ -162,40 +162,44 @@ function boost_cart.cart:on_step(dtime)
|
||||
return
|
||||
end
|
||||
|
||||
local dir, last_switch = nil, nil
|
||||
-- dir: New moving direction of the cart
|
||||
-- last_switch: Currently pressed L/R key, used to ignore the key on the next rail node
|
||||
local dir, last_switch
|
||||
local pos = self.object:getpos()
|
||||
|
||||
if self.old_pos and not self.punched then
|
||||
local flo_pos = vector.floor(pos)
|
||||
local flo_old = vector.floor(self.old_pos)
|
||||
local flo_pos = vector.round(pos)
|
||||
local flo_old = vector.round(self.old_pos)
|
||||
if vector.equals(flo_pos, flo_old) then
|
||||
-- Do not check one node multiple times
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local ctrl, player = nil, nil
|
||||
local ctrl, player
|
||||
|
||||
-- Get player controls
|
||||
if self.driver then
|
||||
player = minetest.get_player_by_name(self.driver)
|
||||
if player then
|
||||
ctrl = player:get_player_control()
|
||||
end
|
||||
end
|
||||
|
||||
if self.old_pos then
|
||||
local diff = vector.subtract(self.old_pos, pos)
|
||||
for _,v in ipairs({"x","y","z"}) do
|
||||
if math.abs(diff[v]) > 1.1 then
|
||||
local expected_pos = vector.add(self.old_pos, self.old_dir)
|
||||
dir, last_switch = boost_cart:get_rail_direction(pos, self.old_dir, ctrl, self.old_switch, self.railtype)
|
||||
if vector.equals(dir, {x=0, y=0, z=0}) then
|
||||
dir = false
|
||||
pos = vector.new(expected_pos)
|
||||
update.pos = true
|
||||
end
|
||||
break
|
||||
end
|
||||
-- Detection for "skipping" nodes
|
||||
local expected_pos = vector.add(self.old_pos, self.old_dir)
|
||||
local found_path = boost_cart:pathfinder(pos, expected_pos, self.old_dir, ctrl, self.old_switch, self.railtype)
|
||||
|
||||
if not found_path then
|
||||
-- No rail found: reset back to the expected position
|
||||
pos = expected_pos
|
||||
update.pos = true
|
||||
end
|
||||
end
|
||||
|
||||
if vel.y == 0 then
|
||||
-- Stop cart completely (do not swing)
|
||||
for _,v in ipairs({"x", "z"}) do
|
||||
if vel[v] ~= 0 and math.abs(vel[v]) < 0.9 then
|
||||
vel[v] = 0
|
||||
@ -213,6 +217,8 @@ function boost_cart.cart:on_step(dtime)
|
||||
local new_acc = {x=0, y=0, z=0}
|
||||
if vector.equals(dir, {x=0, y=0, z=0}) then
|
||||
vel = {x=0, y=0, z=0}
|
||||
pos = vector.round(pos)
|
||||
update.pos = true
|
||||
update.vel = true
|
||||
else
|
||||
-- If the direction changed
|
||||
@ -248,7 +254,8 @@ function boost_cart.cart:on_step(dtime)
|
||||
end
|
||||
end
|
||||
end
|
||||
acc = acc + (speed_mod * 8)
|
||||
-- Try to make it similar to the original carts mod
|
||||
acc = acc + (speed_mod * 10)
|
||||
else
|
||||
acc = acc - 0.4
|
||||
-- Handbrake
|
||||
@ -261,21 +268,23 @@ function boost_cart.cart:on_step(dtime)
|
||||
end
|
||||
|
||||
if mesecon then
|
||||
boost_cart:signal_detector_rail(vector.floor(pos))
|
||||
boost_cart:signal_detector_rail(vector.round(pos))
|
||||
end
|
||||
|
||||
self.object:setacceleration(new_acc)
|
||||
self.old_pos = vector.new(pos)
|
||||
self.old_dir = vector.new(dir)
|
||||
self.old_switch = last_switch
|
||||
|
||||
-- Limits
|
||||
for _,v in ipairs({"x","y","z"}) do
|
||||
if math.abs(vel[v]) > max_vel then
|
||||
vel[v] = boost_cart:get_sign(vel[v]) * max_vel
|
||||
new_acc[v] = 0
|
||||
update.vel = true
|
||||
end
|
||||
end
|
||||
|
||||
self.object:setacceleration(new_acc)
|
||||
self.old_pos = vector.new(pos)
|
||||
self.old_dir = vector.new(dir)
|
||||
self.old_switch = last_switch
|
||||
|
||||
|
||||
if self.punched then
|
||||
-- Collect dropped items
|
||||
|
@ -87,10 +87,6 @@ end
|
||||
|
||||
|
||||
mesecon.queue:add_function("cooldown", function (pos)
|
||||
if minetest.get_item_group(minetest.get_node(pos).name, "overheat") == 0 then
|
||||
return -- node has been moved, this one does not use overheating - ignore
|
||||
end
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local heat = meta:get_int("heat")
|
||||
|
||||
|
@ -93,9 +93,22 @@ local function receive_fields(pos, formname, fields, sender)
|
||||
end
|
||||
|
||||
local function resolve_commands(commands, pos)
|
||||
local players = minetest.get_connected_players()
|
||||
|
||||
-- No players online: remove all commands containing
|
||||
-- @nearest, @farthest and @random
|
||||
if #players == 0 then
|
||||
commands = commands:gsub("[^\r\n]+", function (line)
|
||||
if line:find("@nearest") then return "" end
|
||||
if line:find("@farthest") then return "" end
|
||||
if line:find("@random") then return "" end
|
||||
return line
|
||||
end)
|
||||
return commands
|
||||
end
|
||||
|
||||
local nearest, farthest = nil, nil
|
||||
local min_distance, max_distance = math.huge, -1
|
||||
local players = minetest.get_connected_players()
|
||||
for index, player in pairs(players) do
|
||||
local distance = vector.distance(pos, player:getpos())
|
||||
if distance < min_distance then
|
||||
|
@ -19,6 +19,8 @@ minetest.register_alias("moreblocks:stone_bricks", "default:stonebrick")
|
||||
minetest.register_alias("moreblocks:stonebrick", "default:stonebrick")
|
||||
minetest.register_alias("moreblocks:junglewood", "default:junglewood")
|
||||
minetest.register_alias("moreblocks:jungle_wood", "default:junglewood")
|
||||
minetest.register_alias("moreblocks:fence_jungle_wood", "default:fence_junglewood")
|
||||
minetest.register_alias("moreblocks:jungle_stick", "default:stick")
|
||||
|
||||
for _, t in pairs(circular_saw.names) do
|
||||
minetest.register_alias("moreblocks:" .. t[1] .. "_jungle_wood" .. t[2],
|
||||
|
@ -239,21 +239,6 @@ local nodes = {
|
||||
sounds = sound_glass,
|
||||
no_stairs = true,
|
||||
},
|
||||
["fence_jungle_wood"] = {
|
||||
description = S("Jungle Wood Fence"),
|
||||
drawtype = "fencelike",
|
||||
tiles = {"default_junglewood.png"},
|
||||
inventory_image = "default_fence_overlay.png^default_junglewood.png^default_fence_overlay.png^[makealpha:255,126,126",
|
||||
wield_image = "default_fence_overlay.png^default_junglewood.png^default_fence_overlay.png^[makealpha:255,126,126",
|
||||
paramtype = "light",
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
|
||||
},
|
||||
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
|
||||
sounds = sound_wood,
|
||||
no_stairs = true,
|
||||
},
|
||||
["all_faces_tree"] = {
|
||||
description = S("All-faces Tree"),
|
||||
tiles = {"default_tree_top.png"},
|
||||
@ -364,12 +349,6 @@ minetest.register_craftitem("moreblocks:sweeper", {
|
||||
inventory_image = "moreblocks_sweeper.png",
|
||||
})
|
||||
|
||||
minetest.register_craftitem("moreblocks:jungle_stick", {
|
||||
description = S("Jungle Stick"),
|
||||
inventory_image = "moreblocks_junglestick.png",
|
||||
groups = {stick= 1},
|
||||
})
|
||||
|
||||
minetest.register_craftitem("moreblocks:nothing", {
|
||||
inventory_image = "invisible.png",
|
||||
on_use = function() end,
|
||||
|
@ -45,56 +45,3 @@ minetest.register_craft({
|
||||
type = "toolrepair",
|
||||
additional_wear = -0.10, -- Tool repair buff (10% bonus instead of 2%).
|
||||
})
|
||||
|
||||
-- Redefinitions of some default nodes
|
||||
-- ===================================
|
||||
|
||||
-- Let there be light. This makes some nodes let light pass through:
|
||||
minetest.override_item("default:ladder", {
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
|
||||
minetest.override_item("default:sapling", {
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
|
||||
minetest.override_item("default:dry_shrub", {
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
|
||||
minetest.override_item("default:papyrus", {
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
|
||||
minetest.override_item("default:fence_wood", {
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
|
||||
minetest.override_item("default:junglegrass", {
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
|
||||
minetest.override_item("default:junglesapling", {
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
|
||||
minetest.override_item("default:grass_1", {
|
||||
inventory_image = "default_grass_3.png", -- Use a bigger inventory image.
|
||||
wield_image = "default_grass_3.png",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
|
||||
for i = 2, 5 do
|
||||
minetest.override_item("default:grass_" ..i, {
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
})
|
||||
end
|
||||
|
@ -77,7 +77,7 @@ function stairsplus:register_micro(modname, subname, recipeitem, fields)
|
||||
def.on_place = minetest.rotate_node
|
||||
def.groups = stairsplus:prepare_groups(fields.groups)
|
||||
def.description = desc
|
||||
if fields.drop and not type(fields.drop) == "table" then
|
||||
if fields.drop and not (type(fields.drop) == "table") then
|
||||
def.drop = modname.. ":micro_" ..fields.drop..alternate
|
||||
end
|
||||
minetest.register_node(":" ..modname.. ":micro_" ..subname..alternate, def)
|
||||
|
@ -77,7 +77,7 @@ function stairsplus:register_panel(modname, subname, recipeitem, fields)
|
||||
def.on_place = minetest.rotate_node
|
||||
def.description = desc
|
||||
def.groups = stairsplus:prepare_groups(fields.groups)
|
||||
if fields.drop and not type(fields.drop) == "table" then
|
||||
if fields.drop and not (type(fields.drop) == "table") then
|
||||
def.drop = modname.. ":panel_" ..fields.drop..alternate
|
||||
end
|
||||
minetest.register_node(":" ..modname.. ":panel_" ..subname..alternate, def)
|
||||
|
@ -48,7 +48,7 @@ function stairsplus:register_slab(modname, subname, recipeitem, fields)
|
||||
def.on_place = minetest.rotate_node
|
||||
def.description = ("%s (%d/16)"):format(desc_base, num)
|
||||
def.groups = stairsplus:prepare_groups(fields.groups)
|
||||
if fields.drop and not type(fields.drop) == "table" then
|
||||
if fields.drop and not (type(fields.drop) == "table") then
|
||||
def.drop = modname.. ":slab_" .. fields.drop .. alternate
|
||||
end
|
||||
minetest.register_node(":" .. modname .. ":slab_" .. subname .. alternate, def)
|
||||
|
@ -231,7 +231,7 @@ function stairsplus:register_slope(modname, subname, recipeitem, fields)
|
||||
def.on_place = minetest.rotate_node
|
||||
def.description = desc
|
||||
def.groups = stairsplus:prepare_groups(fields.groups)
|
||||
if fields.drop and not type(fields.drop) == "table" then
|
||||
if fields.drop and not (type(fields.drop) == "table") then
|
||||
def.drop = modname.. ":slope_" ..fields.drop..alternate
|
||||
end
|
||||
minetest.register_node(":" ..modname.. ":slope_" ..subname..alternate, def)
|
||||
|
@ -117,7 +117,7 @@ function stairsplus:register_stair(modname, subname, recipeitem, fields)
|
||||
def.on_place = minetest.rotate_node
|
||||
def.description = desc
|
||||
def.groups = stairsplus:prepare_groups(fields.groups)
|
||||
if fields.drop and not type(fields.drop) == "table" then
|
||||
if fields.drop and not (type(fields.drop) == "table") then
|
||||
def.drop = modname .. ":stair_" .. fields.drop .. alternate
|
||||
end
|
||||
minetest.register_node(":" .. modname .. ":stair_" .. subname .. alternate, def)
|
||||
|
@ -7,13 +7,14 @@ All source code:
|
||||
Date & cocos palm code (date_palm.lua, cocos_palm.lua)
|
||||
© 2016, Rogier <rogier777@gmail.com>
|
||||
Published under the terms and conditions of the WTFPL.
|
||||
All date & date palm textures, date-based food, cocos flower & green coconuts:
|
||||
All date & date palm textures, date-based food, cocos flower & green coconuts,
|
||||
and all poplar textures:
|
||||
© 2016, Rogier <rogier777@gmail.com>
|
||||
Published under the terms and conditions of CC-BY-SA-3.0 Unported.
|
||||
- Three of the date palm textures are modifications of existing moretrees textures
|
||||
- The green coconuts are a modification of the brown coconut
|
||||
- The date cake batter is a modification of the acorn muffin batter
|
||||
All sapling textures (textures/*_sapling.png):
|
||||
All other sapling textures (textures/*_sapling.png):
|
||||
© 2013, Tim Huppertz <mitroman@naturalnet.de>
|
||||
Published under the terms and conditions of CC-BY-SA-3.0 Unported.
|
||||
All other textures:
|
||||
|
@ -196,6 +196,97 @@ moretrees.cedar_biome = {
|
||||
max_count = 10,
|
||||
}
|
||||
|
||||
|
||||
-- Poplar requires a lot of water.
|
||||
moretrees.poplar_biome = {
|
||||
surface = "default:dirt_with_grass",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 6,
|
||||
seed_diff = 341,
|
||||
min_elevation = 0,
|
||||
max_elevation = 50,
|
||||
near_nodes = {"default:water_source"},
|
||||
near_nodes_size = 15,
|
||||
near_nodes_vertical = 5,
|
||||
near_nodes_count = 1,
|
||||
humidity_min = -0.7,
|
||||
humidity_max = -1,
|
||||
rarity = 50,
|
||||
max_count = 15,
|
||||
}
|
||||
|
||||
-- The humidity requirement it quite restrictive (apparently).
|
||||
-- Spawn an occasional poplar elsewhere.
|
||||
moretrees.poplar_biome_2 = {
|
||||
surface = "default:dirt_with_grass",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 6,
|
||||
seed_diff = 341,
|
||||
min_elevation = 0,
|
||||
max_elevation = 50,
|
||||
near_nodes = {"default:water_source"},
|
||||
near_nodes_size = 15,
|
||||
near_nodes_vertical = 4,
|
||||
near_nodes_count = 10,
|
||||
humidity_min = 0.1,
|
||||
humidity_max = -0.6,
|
||||
rarity = 50,
|
||||
max_count = 1,
|
||||
}
|
||||
|
||||
-- Subterranean lakes provide enough water for poplars to grow
|
||||
moretrees.poplar_biome_3 = {
|
||||
surface = "default:dirt_with_grass",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 6,
|
||||
seed_diff = 342,
|
||||
min_elevation = 0,
|
||||
max_elevation = 50,
|
||||
near_nodes = {"default:water_source"},
|
||||
near_nodes_size = 1,
|
||||
near_nodes_vertical = 25,
|
||||
near_nodes_count = 1,
|
||||
humidity_min = -0.5,
|
||||
humidity_max = -1,
|
||||
rarity = 0,
|
||||
max_count = 30,
|
||||
}
|
||||
|
||||
moretrees.poplar_small_biome = {
|
||||
surface = "default:dirt_with_grass",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 4,
|
||||
seed_diff = 343,
|
||||
min_elevation = 0,
|
||||
max_elevation = 50,
|
||||
near_nodes = {"default:water_source"},
|
||||
near_nodes_size = 10,
|
||||
near_nodes_vertical = 5,
|
||||
near_nodes_count = 1,
|
||||
humidity_min = -0.7,
|
||||
humidity_max = -1,
|
||||
rarity = 50,
|
||||
max_count = 10,
|
||||
}
|
||||
|
||||
moretrees.poplar_small_biome_2 = {
|
||||
surface = "default:dirt_with_grass",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 4,
|
||||
seed_diff = 343,
|
||||
min_elevation = 0,
|
||||
max_elevation = 50,
|
||||
near_nodes = {"default:water_source"},
|
||||
near_nodes_size = 10,
|
||||
near_nodes_vertical = 4,
|
||||
near_nodes_count = 5,
|
||||
humidity_min = 0.1,
|
||||
humidity_max = -0.6,
|
||||
rarity = 50,
|
||||
max_count = 3,
|
||||
}
|
||||
|
||||
|
||||
moretrees.fir_biome = {
|
||||
surface = "default:dirt_with_grass",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
|
@ -15,6 +15,7 @@ moretrees.enable_birch = true
|
||||
moretrees.enable_spruce = true
|
||||
moretrees.enable_jungle_tree = true
|
||||
moretrees.enable_fir = true
|
||||
moretrees.enable_poplar = true
|
||||
moretrees.enable_beech = false
|
||||
|
||||
-- set this to true to make moretrees spawn saplings at mapgen time instead
|
||||
|
@ -97,6 +97,8 @@ if moretrees.spawn_saplings then
|
||||
moretrees.spawn_jungletree_object = "moretrees:jungletree_sapling_ongen"
|
||||
moretrees.spawn_fir_object = "moretrees:fir_sapling_ongen"
|
||||
moretrees.spawn_fir_snow_object = "snow:sapling_pine"
|
||||
moretrees.spawn_poplar_object = "moretrees:poplar_sapling_ongen"
|
||||
moretrees.spawn_poplar_small_object = "moretrees:poplar_small_sapling_ongen"
|
||||
else
|
||||
moretrees.spawn_beech_object = moretrees.beech_model
|
||||
moretrees.spawn_apple_tree_object = moretrees.apple_tree_model
|
||||
@ -113,6 +115,8 @@ else
|
||||
moretrees.spawn_jungletree_object = "moretrees.grow_jungletree"
|
||||
moretrees.spawn_fir_object = "moretrees.grow_fir"
|
||||
moretrees.spawn_fir_snow_object = "moretrees.grow_fir_snow"
|
||||
moretrees.spawn_poplar_object = moretrees.poplar_model
|
||||
moretrees.spawn_poplar_small_object = moretrees.poplar_small_model
|
||||
end
|
||||
|
||||
if moretrees.enable_beech then
|
||||
@ -175,6 +179,14 @@ if moretrees.enable_fir then
|
||||
end
|
||||
end
|
||||
|
||||
if moretrees.enable_poplar then
|
||||
biome_lib:register_generate_plant(moretrees.poplar_biome, moretrees.spawn_poplar_object)
|
||||
biome_lib:register_generate_plant(moretrees.poplar_biome_2, moretrees.spawn_poplar_object)
|
||||
biome_lib:register_generate_plant(moretrees.poplar_biome_3, moretrees.spawn_poplar_object)
|
||||
biome_lib:register_generate_plant(moretrees.poplar_small_biome, moretrees.spawn_poplar_small_object)
|
||||
biome_lib:register_generate_plant(moretrees.poplar_small_biome_2, moretrees.spawn_poplar_small_object)
|
||||
end
|
||||
|
||||
-- Code to spawn a birch tree
|
||||
|
||||
function moretrees.grow_birch(pos)
|
||||
|
@ -12,6 +12,8 @@ moretrees.treelist = {
|
||||
{"date_palm", "Date Palm Tree", "date_palm_fruit_trunk", "Date Palm Tree", {0, 0, 0, 0, 0, 0}, 0.0 },
|
||||
{"spruce", "Spruce Tree", "spruce_cone", "Spruce Cone", {-0.2, -0.5, -0.2, 0.2, 0, 0.2}, 0.8 },
|
||||
{"cedar", "Cedar Tree", "cedar_cone", "Cedar Cone", {-0.2, -0.5, -0.2, 0.2, 0, 0.2}, 0.8 },
|
||||
{"poplar", "Poplar Tree"},
|
||||
{"poplar_small", "Poplar Tree"},
|
||||
{"willow", "Willow Tree"},
|
||||
{"rubber_tree", "Rubber Tree"},
|
||||
{"fir", "Douglas Fir", "fir_cone", "Fir Cone", {-0.2, -0.5, -0.2, 0.2, 0, 0.2}, 0.8 },
|
||||
@ -72,6 +74,7 @@ for i in ipairs(moretrees.treelist) do
|
||||
|
||||
if treename ~= "jungletree" -- the default game provides jungle tree, acacia, and pine trunk/planks nodes.
|
||||
and treename ~= "acacia"
|
||||
and treename ~= "poplar_small"
|
||||
and treename ~= "pine" then
|
||||
|
||||
saptex = "moretrees_"..treename.."_sapling.png"
|
||||
@ -273,6 +276,43 @@ for i in ipairs(moretrees.treelist) do
|
||||
end
|
||||
end
|
||||
|
||||
-- Add small poplar saplings
|
||||
|
||||
local poplar_sapling = minetest.registered_nodes["moretrees:poplar_sapling"]
|
||||
local poplar_sapling_ongen = minetest.registered_nodes["moretrees:poplar_sapling_ongen"]
|
||||
local poplar_small_sapling = {}
|
||||
local poplar_small_sapling_ongen = {}
|
||||
for k,v in pairs(poplar_sapling) do
|
||||
poplar_small_sapling[k] = v
|
||||
end
|
||||
for k,v in pairs(poplar_sapling_ongen) do
|
||||
poplar_small_sapling_ongen[k] = v
|
||||
end
|
||||
poplar_small_sapling.tiles = {"moretrees_poplar_small_sapling.png"}
|
||||
poplar_small_sapling.inventory_image = "moretrees_poplar_small_sapling.png"
|
||||
poplar_small_sapling_ongen.tiles_ongen = {"moretrees_poplar_small_sapling.png"}
|
||||
poplar_small_sapling_ongen.inventory_image_ongen = "moretrees_poplar_small_sapling.png"
|
||||
poplar_small_sapling_ongen.drop = "moretrees:poplar_small_sapling"
|
||||
minetest.register_node("moretrees:poplar_small_sapling", poplar_small_sapling)
|
||||
minetest.register_node("moretrees:poplar_small_sapling_ongen", poplar_small_sapling_ongen)
|
||||
if moretrees.spawn_saplings then
|
||||
table.insert(moretrees.avoidnodes, "moretrees:poplar_sapling")
|
||||
table.insert(moretrees.avoidnodes, "moretrees:poplar_small_sapling_ongen")
|
||||
end
|
||||
|
||||
local poplar_leaves_drop = minetest.registered_nodes["moretrees:poplar_leaves"].drop
|
||||
minetest.override_item("moretrees:poplar_leaves", {
|
||||
drop = {
|
||||
max_items = poplar_leaves_drop.maxitems,
|
||||
items = {
|
||||
{items = {"moretrees:poplar_sapling"}, rarity = 1.33 * poplar_leaves_drop.items[1].rarity },
|
||||
{items = {"moretrees:poplar_small_sapling"}, rarity = 1.33 * poplar_leaves_drop.items[1].rarity },
|
||||
{items = {"moretrees:poplar_leaves"} }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
-- Extra nodes for jungle trees:
|
||||
|
||||
local jungleleaves = {"yellow","red"}
|
||||
|
168
moretrees/screenshot.lua
Normal file
@ -0,0 +1,168 @@
|
||||
-- Usage:
|
||||
-- - Create a new world
|
||||
-- - Set world mapgen: v6
|
||||
-- - Set world seed: 2625051331357512570
|
||||
-- - Enable the moretrees mod
|
||||
-- - Edit the moretrees source
|
||||
-- - Disable all trees in default_settings.lua
|
||||
-- - Recommended: make saplings grow fast in default_settings.lua:
|
||||
-- sapling_interval = 5
|
||||
-- sapling_chance = 1
|
||||
-- - Apply the patch below to moretrees
|
||||
-- (so that jungle trees are always large, and differently-colored):
|
||||
-- use 'git apply --ignore-space-change'
|
||||
-- - Make sure this file (you are reading) will be loaded when minetest starts !
|
||||
-- (e.g. add 'dofile(modpath.."/screenshot.lua")' to init.lua)
|
||||
-- - Start minetest
|
||||
-- - Goto 700,y,-280 (approximately)
|
||||
-- - Make sure the world is loaded between x = 650 .. 780 and z = -350 .. -180
|
||||
-- - Give the chat command '/make-scene'
|
||||
-- - Wait & walk/fly around until all trees have grown
|
||||
-- - goto the platform at 780, 30, -277
|
||||
-- - Set the viewing range to 300, with fog enabled
|
||||
-- - Take a screenshot.
|
||||
|
||||
-- Patch to apply to moretrees
|
||||
--[[
|
||||
diff --git a/init.lua b/init.lua
|
||||
index 8189ffd..afd4644 100644
|
||||
--- a/init.lua
|
||||
+++ b/init.lua
|
||||
@@ -225,9 +225,12 @@ moretrees.ct_rules_b1 = "[-FBf][+FBf]"
|
||||
moretrees.ct_rules_a2 = "FF[FF][&&-FBF][&&+FBF][&&---FBF][&&+++FBF]F/A"
|
||||
moretrees.ct_rules_b2 = "[-fB][+fB]"
|
||||
|
||||
+local jleaves = 1
|
||||
function moretrees.grow_jungletree(pos)
|
||||
local r1 = math.random(2)
|
||||
local r2 = math.random(3)
|
||||
+ r1 = jleaves
|
||||
+ jleaves = jleaves % 2 + 1
|
||||
if r1 == 1 then
|
||||
moretrees.jungletree_model.leaves2 = "moretrees:jungletree_leaves_red"
|
||||
else
|
||||
@@ -235,6 +238,7 @@ function moretrees.grow_jungletree(pos)
|
||||
end
|
||||
moretrees.jungletree_model.leaves2_chance = math.random(25, 75)
|
||||
|
||||
+ r2=3
|
||||
if r2 == 1 then
|
||||
moretrees.jungletree_model.trunk_type = "single"
|
||||
moretrees.jungletree_model.iterations = 2
|
||||
]]
|
||||
|
||||
|
||||
minetest.register_chatcommand("make-scene", {
|
||||
func = function()
|
||||
minetest.place_node({x=780, y=30, z=-277}, {name="default:obsidian"})
|
||||
minetest.place_node({x=780, y=30, z=-278}, {name="default:obsidian"})
|
||||
minetest.place_node({x=781, y=30, z=-277}, {name="default:obsidian"})
|
||||
minetest.place_node({x=781, y=30, z=-278}, {name="default:obsidian"})
|
||||
minetest.place_node({x=781, y=30, z=-276}, {name="default:obsidian"})
|
||||
minetest.place_node({x=780, y=30, z=-276}, {name="default:obsidian"})
|
||||
|
||||
for z = -360, -300 do
|
||||
dy=2
|
||||
for x = 630 + (-z - 360)/3, 660 + (-z - 300)/3 do
|
||||
for y = 5, 22 do
|
||||
minetest.place_node({x=x, y=y, z=z}, {name="default:desert_stone"})
|
||||
end
|
||||
for y = 23, 25 + dy do
|
||||
minetest.place_node({x=x, y=y, z=z}, {name="default:desert_sand"})
|
||||
end
|
||||
dy = 0
|
||||
end
|
||||
end
|
||||
|
||||
minetest.place_node({x=717, y=2, z=-298}, {name = "moretrees:palm_sapling"})
|
||||
minetest.place_node({x=713, y=2, z=-302}, {name = "moretrees:palm_sapling"})
|
||||
minetest.place_node({x=713, y=2, z=-307}, {name = "moretrees:palm_sapling"})
|
||||
minetest.place_node({x=717, y=2, z=-318}, {name = "moretrees:palm_sapling"})
|
||||
minetest.place_node({x=723, y=2, z=-320}, {name = "moretrees:palm_sapling"})
|
||||
|
||||
minetest.place_node({x=645, y=26, z=-314}, {name="moretrees:date_palm_sapling"})
|
||||
minetest.place_node({x=653, y=26, z=-322}, {name="moretrees:date_palm_sapling"})
|
||||
minetest.place_node({x=649, y=26, z=-334}, {name="moretrees:date_palm_sapling"})
|
||||
minetest.place_node({x=662, y=26, z=-342}, {name="moretrees:date_palm_sapling"})
|
||||
|
||||
minetest.place_node({x=672, y=5, z=-305}, {name="moretrees:oak_sapling"})
|
||||
minetest.place_node({x=690, y=6, z=-322}, {name="moretrees:oak_sapling"})
|
||||
minetest.place_node({x=695, y=7, z=-335}, {name="moretrees:oak_sapling"})
|
||||
minetest.place_node({x=699, y=4, z=-301}, {name="moretrees:oak_sapling"})
|
||||
|
||||
minetest.place_node({x=751, y=5, z=-254}, {name="moretrees:apple_tree_sapling"})
|
||||
minetest.place_node({x=729, y=3, z=-275}, {name="moretrees:apple_tree_sapling"})
|
||||
minetest.place_node({x=747, y=4, z=-270}, {name="moretrees:apple_tree_sapling"})
|
||||
|
||||
minetest.place_node({x=671, y=5, z=-283}, {name="default:junglesapling"})
|
||||
minetest.place_node({x=680, y=4, z=-287}, {name="default:junglesapling"})
|
||||
minetest.place_node({x=702, y=4, z=-288}, {name="default:junglesapling"})
|
||||
|
||||
minetest.place_node({x=646, y=12, z=-199}, {name="moretrees:spruce_sapling"})
|
||||
minetest.place_node({x=644, y=14, z=-177}, {name="moretrees:spruce_sapling"})
|
||||
minetest.place_node({x=678, y=9, z=-211}, {name="moretrees:spruce_sapling"})
|
||||
minetest.place_node({x=663, y=10, z=-215}, {name="moretrees:spruce_sapling"})
|
||||
|
||||
minetest.place_node({x=637, y=3, z=-263}, {name="moretrees:sequoia_sapling"})
|
||||
minetest.place_node({x=625, y=3, z=-250}, {name="moretrees:sequoia_sapling"})
|
||||
minetest.place_node({x=616, y=3, z=-233}, {name="moretrees:sequoia_sapling"})
|
||||
minetest.place_node({x=635, y=3, z=-276}, {name="moretrees:sequoia_sapling"})
|
||||
minetest.place_node({x=681, y=11, z=-260}, {name="moretrees:sequoia_sapling"})
|
||||
minetest.place_node({x=682, y=10, z=-247}, {name="moretrees:sequoia_sapling"})
|
||||
|
||||
minetest.place_node({x=737, y=7, z=-195}, {name="moretrees:cedar_sapling"})
|
||||
minetest.place_node({x=720, y=8, z=-189}, {name="moretrees:cedar_sapling"})
|
||||
minetest.place_node({x=704, y=7, z=-187}, {name="moretrees:cedar_sapling"})
|
||||
|
||||
minetest.place_node({x=731, y=2, z=-227}, {name="moretrees:poplar_sapling"})
|
||||
minetest.place_node({x=721, y=2, z=-233}, {name="moretrees:poplar_sapling"})
|
||||
minetest.place_node({x=712, y=1, z=-237}, {name="moretrees:poplar_sapling"})
|
||||
minetest.place_node({x=743, y=3, z=-228}, {name="moretrees:poplar_small_sapling"})
|
||||
minetest.place_node({x=750, y=3, z=-230}, {name="moretrees:poplar_small_sapling"})
|
||||
minetest.place_node({x=731, y=5, z=-233}, {name="moretrees:poplar_small_sapling"})
|
||||
|
||||
minetest.place_node({x=702, y=2, z=-274}, {name="moretrees:birch_sapling"})
|
||||
minetest.place_node({x=697, y=2, z=-271}, {name="moretrees:birch_sapling"})
|
||||
minetest.place_node({x=696, y=2, z=-264}, {name="moretrees:birch_sapling"})
|
||||
minetest.place_node({x=710, y=2, z=-265}, {name="moretrees:birch_sapling"})
|
||||
|
||||
minetest.place_node({x=707, y=8, z=-247}, {name="moretrees:fir_sapling"})
|
||||
minetest.place_node({x=699, y=10, z=-254}, {name="moretrees:fir_sapling"})
|
||||
minetest.place_node({x=729, y=5, z=-261}, {name="moretrees:fir_sapling"})
|
||||
minetest.place_node({x=732, y=5, z=-252}, {name="moretrees:fir_sapling"})
|
||||
minetest.place_node({x=741, y=4, z=-262}, {name="moretrees:fir_sapling"})
|
||||
|
||||
minetest.place_node({x=751, y=2, z=-286}, {name="moretrees:willow_sapling"})
|
||||
|
||||
minetest.place_node({x=760, y=5, z=-223}, {name="moretrees:rubber_tree_sapling"})
|
||||
minetest.place_node({x=762, y=5, z=-230}, {name="moretrees:rubber_tree_sapling"})
|
||||
minetest.place_node({x=766, y=5, z=-243}, {name="moretrees:rubber_tree_sapling"})
|
||||
minetest.place_node({x=764, y=6, z=-252}, {name="moretrees:rubber_tree_sapling"})
|
||||
end
|
||||
})
|
||||
|
||||
--[[
|
||||
The following is a search/replace command suitable for vi (/vim) or sed, to convert minetest log
|
||||
messages to equivalent lua commands:
|
||||
|
||||
s/.*\(\(moretrees\|default\)[^ ]*\) at (\([-0-9]\+\),\([-0-9]\+\),\([-0-9]\+\)).*/\t\tminetest.place_node({x=\3, y=\4, z=\5}, {name="\1"})/
|
||||
|
||||
E.g. a minetest log line of the following kind:
|
||||
2016-07-03 11:30:50: ACTION[Server]: singleplayer places node moretrees:rubber_tree_sapling at (760,5,-223)
|
||||
Becomes:
|
||||
minetest.place_node({x=760, y=5, z=-223}, {name="moretrees:rubber_tree_sapling"})
|
||||
(Except that the example log line above has an extra space added, so it won't be converted)
|
||||
|
||||
vi/vim users: Add the minetest log lines to this file, then enter the following command, with
|
||||
<expression> replaced with the search/replace expression above.
|
||||
:%<expression>
|
||||
|
||||
sed users: Add the minetest log lines to this file, then execute the following command at the shell
|
||||
prompt with <expression> replaced by the search/replace expression above. Don't forget the
|
||||
single-quotes.
|
||||
sed '<expression>' < screenshot.lua > screenshot-new.lua
|
||||
|
||||
Windows users: You're probably out of luck. And the effort of doing such a thing is probably
|
||||
larger anyway than the effort of copying an existing line and typing things manually.
|
||||
]]
|
||||
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 101 KiB |
BIN
moretrees/textures/moretrees_poplar_leaves.png
Normal file
After Width: | Height: | Size: 563 B |
BIN
moretrees/textures/moretrees_poplar_sapling.png
Normal file
After Width: | Height: | Size: 447 B |
BIN
moretrees/textures/moretrees_poplar_small_sapling.png
Normal file
After Width: | Height: | Size: 347 B |
BIN
moretrees/textures/moretrees_poplar_trunk-1.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
moretrees/textures/moretrees_poplar_trunk.png
Normal file
After Width: | Height: | Size: 980 B |
BIN
moretrees/textures/moretrees_poplar_trunk_top.png
Normal file
After Width: | Height: | Size: 751 B |
BIN
moretrees/textures/moretrees_poplar_wood.png
Normal file
After Width: | Height: | Size: 726 B |
@ -18,6 +18,7 @@ willow - 5 to + 5 n/a water, 15 5 dirt_with grass 337 20
|
||||
acacia n/a n/a n/a n/a dirt_with_grass,
|
||||
desert_sand n/a 15
|
||||
rubber - 5 to + 5 above +32 water, 15 10 dirt_with_grass 338 20
|
||||
poplar n/a -10 to +26 water, 15h,5v 1 dirt_with_grass 341,342,343 10
|
||||
|
||||
beech n/a n/a n/a n/a dirt_with_grass 2 10
|
||||
|
||||
|
@ -43,6 +43,37 @@ moretrees.oak_model={
|
||||
fruit_chance=3,
|
||||
}
|
||||
|
||||
moretrees.poplar_model={
|
||||
axiom="TTTaaBCCCCCCCCCCCcccBBB[[f]&&G++f++Gf++Gf++Gf++G--]G[[f]&&G++f++Gf++Gf++Gf++G--]Gff",
|
||||
rules_a="T",
|
||||
rules_b="[[T]&&G++f++ff++ff++ff++f--]G",
|
||||
rules_c="[[T]&&G++f++ff++ff++ff++f--G++[d]G[d]G++G[d]G[d]G[d]G++G[d]G[d]G[d]G++G[d]G[d]G[d]G++G[d]G]G",
|
||||
rules_d="f",
|
||||
trunk="air",
|
||||
trunk="moretrees:poplar_trunk",
|
||||
leaves="moretrees:poplar_leaves",
|
||||
angle=45,
|
||||
iterations=0,
|
||||
random_level=0,
|
||||
trunk_type="single",
|
||||
thin_branches=false,
|
||||
}
|
||||
|
||||
moretrees.poplar_small_model={
|
||||
axiom="TT[T]BCCCCccBBff",
|
||||
rules_a="T",
|
||||
rules_b="[[f]&&G++f++Gf++Gf++Gf++G--]G",
|
||||
rules_c="[[T]&&G++f++[d]Gf++[d]Gf++[d]Gf++[d]G--]G",
|
||||
rules_d="f",
|
||||
trunk="moretrees:poplar_trunk",
|
||||
leaves="moretrees:poplar_leaves",
|
||||
angle=45,
|
||||
iterations=0,
|
||||
random_level=0,
|
||||
trunk_type="single",
|
||||
thin_branches=false,
|
||||
}
|
||||
|
||||
moretrees.sequoia_model={
|
||||
axiom="FFFFFFFFFFddccA///cccFddcFA///ddFcFA/cFFddFcdBddd/A/ccdcddd/ccAddddcFBcccAccFdFcFBcccc/BFdFFcFFdcccc/B",
|
||||
rules_a="[&&&GGF[++^FFdd][--&Fddd]//Fdd[+^Fd][--&Fdd]]////[&&&GGF[++^FFdd][--&Fddd]//Fdd[+^Fd][--&Fdd]]////[&&&GGF[++^FFdd][--&Fddd]//Fdd[+^Fd][--&Fdd]]",
|
||||
|
@ -25,7 +25,8 @@ minetest.after(0.01, function()
|
||||
for _,chk in pairs(recipe.items) do
|
||||
local groupchk = string.find(chk, "group:")
|
||||
if (not groupchk and not minetest.registered_items[chk])
|
||||
or (groupchk and not unified_inventory.get_group_item(string.gsub(chk, "group:", "")).item) then
|
||||
or (groupchk and not unified_inventory.get_group_item(string.gsub(chk, "group:", "")).item)
|
||||
or minetest.get_item_group(chk, "exclude_from_craft_guide") ~= 0 then
|
||||
unknowns = true
|
||||
end
|
||||
end
|
||||
|
1
unified_inventory/description.txt
Normal file
@ -0,0 +1 @@
|
||||
Unified Inventory replaces the default survival and creative inventory. It adds a nicer interface and a number of features, such as a crafting guide.
|
1
unified_inventory/mod.conf
Normal file
@ -0,0 +1 @@
|
||||
name = unified_inventory
|
BIN
unified_inventory/screenshot.png
Normal file
After Width: | Height: | Size: 149 KiB |
258
worldedit/cuboid.lua
Normal file
@ -0,0 +1,258 @@
|
||||
-- Expands or contracts the cuboid in all axes by amount (positive or negative)
|
||||
worldedit.cuboid_volumetric_expand = function(name, amount)
|
||||
local pos1 = worldedit.pos1[name]
|
||||
local pos2 = worldedit.pos2[name]
|
||||
|
||||
if pos1 == nil or pos2 == nil then
|
||||
return false, "Undefined cuboid"
|
||||
end
|
||||
|
||||
local delta1 = vector.new()
|
||||
local delta2 = vector.new()
|
||||
local delta_dir1
|
||||
local delta_dir2
|
||||
|
||||
delta1 = vector.add(delta1, amount)
|
||||
delta2 = vector.add(delta2, amount)
|
||||
delta_dir1, delta_dir2 = worldedit.get_expansion_directions(pos1, pos2)
|
||||
delta1 = vector.multiply(delta1, delta_dir1)
|
||||
delta2 = vector.multiply(delta2, delta_dir2)
|
||||
worldedit.pos1[name] = vector.add(pos1, delta1)
|
||||
worldedit.pos2[name] = vector.add(pos2, delta2)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
-- Expands or contracts the cuboid in a single axis by amount (positive or negative)
|
||||
worldedit.cuboid_linear_expand = function(name, axis, direction, amount)
|
||||
local pos1 = worldedit.pos1[name]
|
||||
local pos2 = worldedit.pos2[name]
|
||||
|
||||
if pos1 == nil or pos2 == nil then
|
||||
return false, "undefined cuboid"
|
||||
end
|
||||
|
||||
if direction ~= 1 and direction ~= -1 then
|
||||
return false, "invalid marker"
|
||||
end
|
||||
|
||||
local marker = worldedit.marker_get_closest_to_axis(name, axis, direction)
|
||||
local deltavect = vector.new()
|
||||
|
||||
if axis == 'x' then
|
||||
deltavect.x = amount * direction
|
||||
elseif axis == 'y' then
|
||||
deltavect.y = amount * direction
|
||||
elseif axis == 'z' then
|
||||
deltavect.z = amount * direction
|
||||
else
|
||||
return false, "invalid axis"
|
||||
end
|
||||
|
||||
worldedit.marker_move(name, marker, deltavect)
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
-- Shifts the cuboid by '+-amount' in axis 'axis'
|
||||
worldedit.cuboid_shift = function(name, axis, amount)
|
||||
local pos1 = worldedit.pos1[name]
|
||||
local pos2 = worldedit.pos2[name]
|
||||
|
||||
if pos1 == nil or pos2 == nil then
|
||||
return false, "undefined cuboid"
|
||||
end
|
||||
|
||||
if axis == 'x' then
|
||||
worldedit.pos1[name].x = pos1.x + amount
|
||||
worldedit.pos2[name].x = pos2.x + amount
|
||||
elseif axis == 'y' then
|
||||
worldedit.pos1[name].y = pos1.y + amount
|
||||
worldedit.pos2[name].y = pos2.y + amount
|
||||
elseif axis == 'z' then
|
||||
worldedit.pos1[name].z = pos1.z + amount
|
||||
worldedit.pos2[name].z = pos2.z + amount
|
||||
else
|
||||
return false, "invalid axis"
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
-- Moves the location of a single marker by adding deltavector
|
||||
worldedit.marker_move = function(name, marker, deltavector)
|
||||
if marker ~= 1 and marker ~= 2 then
|
||||
return false
|
||||
end
|
||||
|
||||
if marker == 1 then
|
||||
local pos = worldedit.pos1[name]
|
||||
worldedit.pos1[name] = vector.add(deltavector, pos)
|
||||
else
|
||||
local pos = worldedit.pos2[name]
|
||||
worldedit.pos2[name] = vector.add(deltavector, pos)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- Updates the location ingame of the markers
|
||||
worldedit.marker_update = function(name, marker)
|
||||
if marker == nil then
|
||||
worldedit.mark_pos1(name)
|
||||
worldedit.mark_pos2(name)
|
||||
elseif marker == 1 then
|
||||
worldedit.mark_pos1(name)
|
||||
elseif marker == 2 then
|
||||
worldedit.mark_pos2(name)
|
||||
else
|
||||
minetest.debug(
|
||||
"worldedit: Invalid execution of function update_markers")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Returns two vectors with the directions for volumetric expansion
|
||||
worldedit.get_expansion_directions = function(mark1, mark2)
|
||||
if mark1 == nil or mark2 == nil then
|
||||
return
|
||||
end
|
||||
local dir1 = vector.new()
|
||||
local dir2 = vector.new()
|
||||
|
||||
if mark1.x < mark2.x then
|
||||
dir1.x = -1
|
||||
dir2.x = 1
|
||||
else
|
||||
dir1.x = 1
|
||||
dir2.x = -1
|
||||
end
|
||||
if mark1.y < mark2.y then
|
||||
dir1.y = -1
|
||||
dir2.y = 1
|
||||
else
|
||||
dir1.y = 1
|
||||
dir2.y = -1
|
||||
end
|
||||
if mark1.z < mark2.z then
|
||||
dir1.z = -1
|
||||
dir2.z = 1
|
||||
else
|
||||
dir1.z = 1
|
||||
dir2.z = -1
|
||||
end
|
||||
return dir1, dir2
|
||||
end
|
||||
|
||||
|
||||
-- Return the marker that is closest to the player
|
||||
worldedit.marker_get_closest_to_player = function(name)
|
||||
local playerpos = minetest.get_player_by_name(name):getpos()
|
||||
local dist1 = vector.distance(playerpos, worldedit.pos1[name])
|
||||
local dist2 = vector.distance(playerpos, worldedit.pos2[name])
|
||||
|
||||
if dist1 < dist2 then
|
||||
return 1
|
||||
else
|
||||
return 2
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Returns the closest marker to the specified axis and direction
|
||||
worldedit.marker_get_closest_to_axis = function(name, axis, direction)
|
||||
local pos1 = vector.new()
|
||||
local pos2 = vector.new()
|
||||
|
||||
if direction ~= 1 and direction ~= -1 then
|
||||
return nil
|
||||
end
|
||||
|
||||
if axis == 'x' then
|
||||
pos1.x = worldedit.pos1[name].x * direction
|
||||
pos2.x = worldedit.pos2[name].x * direction
|
||||
if pos1.x > pos2.x then
|
||||
return 1
|
||||
else
|
||||
return 2
|
||||
end
|
||||
elseif axis == 'y' then
|
||||
pos1.y = worldedit.pos1[name].y * direction
|
||||
pos2.y = worldedit.pos2[name].y * direction
|
||||
if pos1.y > pos2.y then
|
||||
return 1
|
||||
else
|
||||
return 2
|
||||
end
|
||||
elseif axis == 'z' then
|
||||
pos1.z = worldedit.pos1[name].z * direction
|
||||
pos2.z = worldedit.pos2[name].z * direction
|
||||
if pos1.z > pos2.z then
|
||||
return 1
|
||||
else
|
||||
return 2
|
||||
end
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Translates up, down, left, right, front, back to their corresponding axes and
|
||||
-- directions according to faced direction
|
||||
worldedit.translate_direction = function(name, direction)
|
||||
local axis, dir = worldedit.player_axis(name)
|
||||
local resaxis, resdir
|
||||
|
||||
if direction == "up" then
|
||||
return 'y', 1
|
||||
end
|
||||
|
||||
if direction == "down" then
|
||||
return 'y', -1
|
||||
end
|
||||
|
||||
if direction == "front" then
|
||||
if axis == "y" then
|
||||
resaxis = nil
|
||||
resdir = nil
|
||||
else
|
||||
resaxis = axis
|
||||
resdir = dir
|
||||
end
|
||||
end
|
||||
|
||||
if direction == "back" then
|
||||
if axis == "y" then
|
||||
resaxis = nil
|
||||
resdir = nil
|
||||
else
|
||||
resaxis = axis
|
||||
resdir = -dir
|
||||
end
|
||||
end
|
||||
|
||||
if direction == "left" then
|
||||
if axis == 'x' then
|
||||
resaxis = 'z'
|
||||
resdir = dir
|
||||
elseif axis == 'z' then
|
||||
resaxis = 'x'
|
||||
resdir = -dir
|
||||
end
|
||||
end
|
||||
|
||||
if direction == "right" then
|
||||
if axis == 'x' then
|
||||
resaxis = 'z'
|
||||
resdir = -dir
|
||||
elseif axis == 'z' then
|
||||
resaxis = 'x'
|
||||
resdir = dir
|
||||
end
|
||||
end
|
||||
|
||||
return resaxis, resdir
|
||||
end
|
@ -37,6 +37,7 @@ load_module(path .. "/serialization.lua")
|
||||
load_module(path .. "/code.lua")
|
||||
load_module(path .. "/compatibility.lua")
|
||||
load_module(path .. "/wand.lua")
|
||||
load_module(path .. "/cuboid.lua")
|
||||
|
||||
|
||||
if minetest.setting_getbool("log_mods") then
|
||||
|
240
worldedit_commands/cuboid.lua
Normal file
@ -0,0 +1,240 @@
|
||||
minetest.register_chatcommand("/outset", {
|
||||
params = "[h|v] <amount>",
|
||||
description = "outset the selection",
|
||||
privs = {worldedit=true},
|
||||
func = function(name, param)
|
||||
local find, _, dir, amount = param:find("(%a*)%s*([+-]?%d+)")
|
||||
|
||||
if find == nil then
|
||||
return false, "invalid usage: " .. param
|
||||
end
|
||||
|
||||
local pos1 = worldedit.pos1[name]
|
||||
local pos2 = worldedit.pos2[name]
|
||||
|
||||
if pos1 == nil or pos2 == nil then
|
||||
return false,
|
||||
"Undefined region. Region must be defined beforehand."
|
||||
end
|
||||
|
||||
local hv_test = dir:find("[^hv]+")
|
||||
|
||||
if hv_test ~= nil then
|
||||
return false, "Invalid direction."
|
||||
end
|
||||
|
||||
if dir == "" or dir == "hv" or dir == "vh" then
|
||||
assert(worldedit.cuboid_volumetric_expand(name, amount))
|
||||
elseif dir == "h" then
|
||||
assert(worldedit.cuboid_linear_expand(name, 'x', 1, amount))
|
||||
assert(worldedit.cuboid_linear_expand(name, 'x', -1, amount))
|
||||
assert(worldedit.cuboid_linear_expand(name, 'z', 1, amount))
|
||||
assert(worldedit.cuboid_linear_expand(name, 'z', -1, amount))
|
||||
elseif dir == "v" then
|
||||
assert(worldedit.cuboid_linear_expand(name, 'y', 1, amount))
|
||||
assert(worldedit.cuboid_linear_expand(name, 'y', -1, amount))
|
||||
else
|
||||
return false, "Invalid number of arguments"
|
||||
end
|
||||
|
||||
worldedit.marker_update(name)
|
||||
return true, "Region outset by " .. amount .. " blocks"
|
||||
end,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
minetest.register_chatcommand("/inset", {
|
||||
params = "[h|v] <amount>",
|
||||
description = "inset the selection",
|
||||
privs = {worldedit=true},
|
||||
func = function(name, param)
|
||||
local find, _, dir, amount = param:find("(%a*)%s*([+-]?%d+)")
|
||||
|
||||
if find == nil then
|
||||
return false, "invalid usage: " .. param
|
||||
end
|
||||
|
||||
local pos1 = worldedit.pos1[name]
|
||||
local pos2 = worldedit.pos2[name]
|
||||
|
||||
if pos1 == nil or pos2 == nil then
|
||||
return false,
|
||||
"Undefined region. Region must be defined beforehand."
|
||||
end
|
||||
|
||||
local hv_test = dir:find("[^hv]+")
|
||||
|
||||
if hv_test ~= nil then
|
||||
return false, "Invalid direction."
|
||||
end
|
||||
|
||||
if dir == "" or dir == "vh" or dir == "hv" then
|
||||
assert(worldedit.cuboid_volumetric_expand(name, -amount))
|
||||
elseif dir == "h" then
|
||||
assert(worldedit.cuboid_linear_expand(name, 'x', 1, -amount))
|
||||
assert(worldedit.cuboid_linear_expand(name, 'x', -1, -amount))
|
||||
assert(worldedit.cuboid_linear_expand(name, 'z', 1, -amount))
|
||||
assert(worldedit.cuboid_linear_expand(name, 'z', -1, -amount))
|
||||
elseif dir == "v" then
|
||||
assert(worldedit.cuboid_linear_expand(name, 'y', 1, -amount))
|
||||
assert(worldedit.cuboid_linear_expand(name, 'y', -1, -amount))
|
||||
else
|
||||
return false, "Invalid number of arguments"
|
||||
end
|
||||
|
||||
worldedit.marker_update(name)
|
||||
return true, "Region inset by " .. amount .. " blocks"
|
||||
end,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
minetest.register_chatcommand("/shift", {
|
||||
params = "[x|y|z|?|up|down|left|right|front|back] [+|-]<amount>",
|
||||
description = "Moves the selection region. Does not move contents.",
|
||||
privs = {worldedit=true},
|
||||
func = function(name, param)
|
||||
local pos1 = worldedit.pos1[name]
|
||||
local pos2 = worldedit.pos2[name]
|
||||
local find, _, direction, amount = param:find("([%?%l]+)%s*([+-]?%d+)")
|
||||
|
||||
if find == nil then
|
||||
worldedit.player_notify(name, "invalid usage: " .. param)
|
||||
return
|
||||
end
|
||||
|
||||
if pos1 == nil or pos2 == nil then
|
||||
worldedit.player_notify(name,
|
||||
"Undefined region. Region must be defined beforehand.")
|
||||
return
|
||||
end
|
||||
|
||||
local axis, dir
|
||||
if direction == "x" or direction == "y" or direction == "z" then
|
||||
axis, dir = direction, 1
|
||||
elseif direction == "?" then
|
||||
axis, dir = worldedit.player_axis(name)
|
||||
else
|
||||
axis, dir = worldedit.translate_direction(name, direction)
|
||||
end
|
||||
|
||||
if axis == nil or dir == nil then
|
||||
return false, "Invalid if looking straight up or down"
|
||||
end
|
||||
|
||||
assert(worldedit.cuboid_shift(name, axis, amount * dir))
|
||||
worldedit.marker_update(name)
|
||||
|
||||
return true, "Region shifted by " .. amount .. " nodes"
|
||||
end,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
minetest.register_chatcommand("/expand", {
|
||||
params = "[+|-]<x|y|z|?|up|down|left|right|front|back> <amount> [reverse-amount]",
|
||||
description = "expand the selection in one or two directions at once",
|
||||
privs = {worldedit=true},
|
||||
func = function(name, param)
|
||||
local find, _, sign, direction, amount,
|
||||
rev_amount = param:find("([+-]?)([%?%l]+)%s*(%d+)%s*(%d*)")
|
||||
|
||||
if find == nil then
|
||||
worldedit.player_notify(name, "invalid use: " .. param)
|
||||
return
|
||||
end
|
||||
|
||||
if worldedit.pos1[name] == nil or worldedit.pos2[name] == nil then
|
||||
worldedit.player_notify(name,
|
||||
"Undefined region. Region must be defined beforehand.")
|
||||
return
|
||||
end
|
||||
|
||||
local absolute = direction:find("[xyz?]")
|
||||
local dir, axis
|
||||
|
||||
if rev_amount == "" then
|
||||
rev_amount = 0
|
||||
end
|
||||
|
||||
if absolute == nil then
|
||||
axis, dir = worldedit.translate_direction(name, direction)
|
||||
|
||||
if axis == nil or dir == nil then
|
||||
return false, "Invalid if looking straight up or down"
|
||||
end
|
||||
else
|
||||
if direction == "?" then
|
||||
axis, dir = worldedit.player_axis(name)
|
||||
else
|
||||
axis = direction
|
||||
dir = 1
|
||||
end
|
||||
end
|
||||
|
||||
if sign == "-" then
|
||||
dir = -dir
|
||||
end
|
||||
|
||||
worldedit.cuboid_linear_expand(name, axis, dir, amount)
|
||||
worldedit.cuboid_linear_expand(name, axis, -dir, rev_amount)
|
||||
worldedit.marker_update(name)
|
||||
return true, "Region expanded by " .. (amount + rev_amount) .. " nodes"
|
||||
end,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
minetest.register_chatcommand("/contract", {
|
||||
params = "[+|-]<x|y|z|?|up|down|left|right|front|back> <amount> [reverse-amount]",
|
||||
description = "contract the selection in one or two directions at once",
|
||||
privs = {worldedit=true},
|
||||
func = function(name, param)
|
||||
local find, _, sign, direction, amount,
|
||||
rev_amount = param:find("([+-]?)([%?%l]+)%s*(%d+)%s*(%d*)")
|
||||
|
||||
if find == nil then
|
||||
worldedit.player_notify(name, "invalid use: " .. param)
|
||||
return
|
||||
end
|
||||
|
||||
if worldedit.pos1[name] == nil or worldedit.pos2[name] == nil then
|
||||
worldedit.player_notify(name,
|
||||
"Undefined region. Region must be defined beforehand.")
|
||||
return
|
||||
end
|
||||
|
||||
local absolute = direction:find("[xyz?]")
|
||||
local dir, axis
|
||||
|
||||
if rev_amount == "" then
|
||||
rev_amount = 0
|
||||
end
|
||||
|
||||
if absolute == nil then
|
||||
axis, dir = worldedit.translate_direction(name, direction)
|
||||
|
||||
if axis == nil or dir == nil then
|
||||
return false, "Invalid if looking straight up or down"
|
||||
end
|
||||
else
|
||||
if direction == "?" then
|
||||
axis, dir = worldedit.player_axis(name)
|
||||
else
|
||||
axis = direction
|
||||
dir = 1
|
||||
end
|
||||
end
|
||||
|
||||
if sign == "-" then
|
||||
dir = -dir
|
||||
end
|
||||
|
||||
worldedit.cuboid_linear_expand(name, axis, dir, -amount)
|
||||
worldedit.cuboid_linear_expand(name, axis, -dir, -rev_amount)
|
||||
worldedit.marker_update(name)
|
||||
return true, "Region contracted by " .. (amount + rev_amount) .. " nodes"
|
||||
end,
|
||||
}
|
||||
)
|
@ -10,6 +10,7 @@ if minetest.place_schematic then
|
||||
worldedit.prob_list = {}
|
||||
end
|
||||
|
||||
dofile(minetest.get_modpath("worldedit_commands") .. "/cuboid.lua")
|
||||
dofile(minetest.get_modpath("worldedit_commands") .. "/mark.lua")
|
||||
local safe_region, check_region = dofile(minetest.get_modpath("worldedit_commands") .. "/safe.lua")
|
||||
|
||||
@ -1181,4 +1182,4 @@ minetest.register_chatcommand("/clearobjects", {
|
||||
local count = worldedit.clear_objects(worldedit.pos1[name], worldedit.pos2[name])
|
||||
worldedit.player_notify(name, count .. " objects cleared")
|
||||
end),
|
||||
})
|
||||
})
|