Compare commits
7 Commits
0bdbc5539a
...
f63f60a846
Author | SHA1 | Date |
---|---|---|
trans_soup | f63f60a846 | |
trans_soup | 41aa5536b0 | |
trans_soup | 1084214c10 | |
trans_soup | 512847f8f6 | |
trans_soup | 249a698b52 | |
trans_soup | 2de047d37a | |
trans_soup | 4436b9068a |
|
@ -1,7 +1,27 @@
|
|||
local function is_same_kind (pos, kindname)
|
||||
local node = minetest.get_node(pos)
|
||||
local node_kindname = minetest.registered_items[node.name].kindname
|
||||
return kindname == node_kindname
|
||||
return kindname and node_kindname and kindname == node_kindname
|
||||
end
|
||||
|
||||
local function transfer_levels (source, target, max)
|
||||
local max_diff = max - target
|
||||
local diff = math.min(max_diff, source)
|
||||
return source - diff, target + diff
|
||||
end
|
||||
|
||||
local function stack_attempt (pos, source_level)
|
||||
local node = minetest.get_node(pos)
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
if def.level == level_max then return source_level end
|
||||
|
||||
local level_max = def.level_max
|
||||
local kindname = def.kindname
|
||||
|
||||
local source_level, target_level = transfer_levels(source_level, def.level, level_max)
|
||||
|
||||
minetest.swap_node(pos, {name = kindname .. "_" .. (target_level)})
|
||||
return source_level
|
||||
end
|
||||
|
||||
function blockgame.check_for_stacking (pos)
|
||||
|
@ -11,21 +31,12 @@ function blockgame.check_for_stacking (pos)
|
|||
local kindname = def.kindname
|
||||
local level_max = def.level_max
|
||||
|
||||
local below = pos + blockgame.vector.dirs.down
|
||||
local below = pos:offset(0, -1, 0)
|
||||
if is_same_kind(below, kindname) then
|
||||
local below_node = minetest.get_node(below)
|
||||
local below_def = minetest.registered_nodes[below_node.name]
|
||||
local new_level = stack_attempt(below, def.level)
|
||||
|
||||
if below_def.level ~= level_max then
|
||||
local max_diff = level_max - below_def.level
|
||||
local diff = math.min(max_diff, def.level)
|
||||
|
||||
minetest.swap_node(below, {name = kindname .. "_" .. (below_def.level + diff)})
|
||||
if diff == def.level then
|
||||
minetest.remove_node(pos)
|
||||
else
|
||||
minetest.swap_node(pos, {name = kindname .. "_" .. (def.level - diff)})
|
||||
end
|
||||
if new_level ~= def.level then
|
||||
minetest.swap_node(pos, {name = kindname .. "_" .. new_level})
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -37,6 +48,39 @@ end
|
|||
|
||||
|
||||
|
||||
local function on_place (itemstack, placer, pointed)
|
||||
local function fallback_to_default ()
|
||||
return minetest.item_place(itemstack, placer, pointed)
|
||||
end
|
||||
|
||||
local placed_def = minetest.registered_items[itemstack:get_name()]
|
||||
if not placed_def.level_max then return fallback_to_default() end
|
||||
|
||||
if not is_same_kind(pointed.under, placed_def.kindname) then return fallback_to_default() end
|
||||
|
||||
if placer:is_player() and placer:get_player_control().sneak then return fallback_to_default() end
|
||||
|
||||
local above = pointed.under + vector.new(0, 1, 0)
|
||||
local above_node = minetest.get_node(above)
|
||||
|
||||
local target_node = minetest.get_node(pointed.under)
|
||||
local target_def = minetest.registered_items[target_node.name]
|
||||
if target_def.level_max == target_def.level then return fallback_to_default() end
|
||||
|
||||
local source_level, target_level = transfer_levels(placed_def.level, target_def.level, placed_def.level_max)
|
||||
if source_level > 0 and above_node.name ~= "air" then return fallback_to_default() end
|
||||
|
||||
local left_over = stack_attempt(pointed.under, placed_def.level)
|
||||
if above_node.name == "air" then
|
||||
minetest.set_node(pointed.above, {name = target_def.kindname .. "_" .. left_over})
|
||||
end
|
||||
itemstack:set_count(itemstack:get_count() - 1)
|
||||
|
||||
return itemstack
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function register_layer (kindname, def, level, modname)
|
||||
local def = blockgame.naive_deep_copy(def)
|
||||
def.level = level
|
||||
|
@ -53,10 +97,6 @@ local function register_layer (kindname, def, level, modname)
|
|||
}
|
||||
end
|
||||
|
||||
def.on_construct = blockgame.check_for_stacking
|
||||
def.after_place_node = blockgame.check_for_stacking
|
||||
def.after_land = blockgame.check_for_stacking
|
||||
|
||||
def.groups = def.groups or {}
|
||||
def.groups.leveled = level
|
||||
|
||||
|
@ -74,9 +114,17 @@ function blockgame.register_leveled_node (name, def)
|
|||
local basename, modname, fullname = blockgame.extract_id_parts(name)
|
||||
def.kindname = fullname
|
||||
|
||||
def.on_construct = blockgame.check_for_stacking
|
||||
def.on_place = on_place
|
||||
def.after_place_node = blockgame.check_for_stacking
|
||||
def.after_land = blockgame.check_for_stacking
|
||||
|
||||
def.node_placement_prediction = ""
|
||||
|
||||
for level=1, def.level_max do
|
||||
register_layer(basename, def, level, modname)
|
||||
end
|
||||
|
||||
minetest.register_alias(fullname, fullname .. "_" .. def.level_max)
|
||||
minetest.register_alias(fullname .. "_" .. 0, "air")
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue