2023-04-23 14:17:16 -07:00

276 lines
9.1 KiB
Lua

ghost_blocks = {}
ghost_blocks.block_list = {
mcl_core = { --If this mod is defined, all blocks in the list will have ghost versions registered.
--"mcl_core:slimeblock",
},
--default = {}
}
ghost_blocks.group_list = {
"wood",
"tree",
"slab_wood",
"raw_meat_block",
"cooked_meat_block",
"burnt_meat_block",
"sand",
"soil",
"cobble",
"stone",
"wool",
"leaves",
"glass",
"shulker_box",
"baked_clay",
"pane",
"fence",
"tnt",
"anvil",
"solid",
"slab",
"stair",
"pickaxey",
"axey",
"shovely",
"handy",
"hoey",
"swordy"
}
ghost_blocks.block_map = {}
function ghost_blocks.register_ghost_block(block)
if not block then
return
end
local block_data = nil
pcall(function()
block_data = table.copy(minetest.registered_nodes[block])
end)
if not block_data then
minetest.log("error", "Could not create ghost block from "..block)
return
end
local _, _, new_name = string.find(block, ".+:(.+)")
if not new_name then
minetest.log("error", "Could not create ghost block from "..block)
return
end
new_name = "ghost_blocks:"..new_name
if block == "mcl_enchanting:table" then
new_name = "ghost_blocks:enchanting_table"
elseif block == "mcl_smithing_table:table" then
new_name = "ghost_blocks:smithing_table"
end
if block == "ghost_blocks:ghostifier" then
return
end
block_data.walkable = false
block_data.post_effect_color = "#00000000"
if not block_data.description then
block_data.description = "Ghost "..block
else
block_data.description = "Ghost "..block_data.description
end
block_data.groups.ghost_block = 1
block_data.groups.not_in_creative_inventory = 1
block_data.groups.not_in_craft_guide = 1
block_data.drop = new_name
block_data._mcl_silk_touch_drop = {new_name}
--override functions
--block_data.on_place = nil
--block_data.on_use = nil
--block_data.on_secondary_use = nil
--block_data.after_place_node = nil
block_data.on_construct = nil
--block_data.on_rightclick = nil
--block_data.on_click = nil --is this a thing? Or just on_punch?
--block_data.on_walk_over = nil
--block_data.on_punch = nil
--block_data.on_timer = nil
--block_data.groups.eatable = nil
--block_data._mcl_saturation = nil
block_data.after_dig_node = nil --fixes enchanting table duplication
if new_name == "ghost_blocks:ender_chest" then
block_data.groups.pickaxey = 1
end
if new_name == "ghost_blocks:chest" then
block_data.groups.axey = 1
end
if block_data.groups.shulker_box then
block_data.groups.pickaxey = 1
end
--minetest.log(tostring(new_name))
minetest.register_node(new_name, block_data)
ghost_blocks.block_map[block] = new_name
end
local ghostifier_formspec =
"size[9,7]"..
"label[0.3,0.3;"..minetest.formspec_escape(minetest.colorize("#313131", "Ghostifier")).."]"..
"list[context;src;1.5,1;1,1]"..
mcl_formspec.get_itemslot_bg(1.5,1,1,1)..
"list[context;dst;5,1;1,1]"..
mcl_formspec.get_itemslot_bg(5,1,1,1)..
"list[current_player;main;0,2.5;9,3;9]"..
mcl_formspec.get_itemslot_bg(0,2.5,9,3)..
"list[current_player;main;0,6;9,1;]"..
mcl_formspec.get_itemslot_bg(0,6,9,1)..
"listring[context;dst]"..
"listring[current_player;main]"..
"listring[context;src]"..
"listring[current_player;main]"
minetest.register_node("ghost_blocks:ghostifier", {
description = "Ghostifier",
hardness = 10,
walkable = false,
use_texture_alpha = "blend",
sunlight_propagates = true,
paramtype = "light",
drawtype = "allfaces",
tiles = {"ghost_blocks_ghostifier.png"},
groups = {ghost_block = 1, pickaxey = 1},
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if listname == "src" then
return stack:get_count()
elseif listname == "dst" then
return 0
end
end,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
local meta = minetest.get_meta(pos)
local meta2 = meta:to_table()
meta:from_table(oldmetadata)
local inv = meta:get_inventory()
for _, listname in ipairs({"src", "dst"}) do
local stack = inv:get_stack(listname, 1)
if not stack:is_empty() then
local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5}
minetest.add_item(p, stack)
end
end
meta:from_table(meta2)
end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
end,
on_timer = function(pos, elapsed)
--minetest.log("on_timer")
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local update = true
--minetest.log(elapsed)
while elapsed > 0 and update do
update = false
if not inv:is_empty("src") then
--minetest.log("src not empty")
local src_stack = inv:get_stack("src", 1)
local dst_stack = inv:get_stack("dst", 1)
local original_itemstring = src_stack:get_name()
local new_itemstring = ghost_blocks.block_map[original_itemstring]
if new_itemstring then
--minetest.log("Original: "..original_itemstring..", New: "..new_itemstring)
if not inv:is_empty("dst") then
if new_itemstring ~= dst_stack:get_name() then
--minetest.log("dst contains different block, stopping")
break --if dst is full of different block
end
--minetest.log("dst contains correct block, continuing.")
end
if dst_stack:is_empty() then
-- create a new stack
dst_stack = ItemStack(new_itemstring)
src_stack:set_count(src_stack:get_count() - 1)
--minetest.log("dst is empty, creating new itemstack")
elseif dst_stack:get_count() >= 64 then
--minetest.log("dst is full, stopping")
-- the max item count is limited to 64
break
else
-- add one node into stack
--minetest.log("dst++; src--")
dst_stack:set_count(dst_stack:get_count() + 1)
src_stack:set_count(src_stack:get_count() - 1)
end
--minetest.log("setting src and dst")
inv:set_stack("dst", 1, dst_stack)
inv:set_stack("src", 1, src_stack)
update = true
end
else
--minetest.log("src is empty")
end
end
minetest.get_node_timer(pos):stop()
return false
end,
on_metadata_inventory_move = function(pos)
minetest.get_node_timer(pos):start(1.0)
end,
on_metadata_inventory_put = function(pos)
minetest.get_node_timer(pos):start(1.0)
end,
on_metadata_inventory_take = function(pos)
minetest.get_node_timer(pos):start(1.0)
end,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size("src", 1)
inv:set_size("dst", 1)
meta:set_string("formspec", ghostifier_formspec)
--on_timer(pos, 0)
end
})
minetest.register_craft({
output = "ghost_blocks:ghostifier",
recipe = {
{"mcl_core:glass", "mcl_core:glass", "mcl_core:glass"},
{"mcl_core:glass", "mcl_mobitems:ghast_tear", "mcl_core:glass"},
{"mcl_core:glass", "mcl_core:glass", "mcl_core:glass"}
}
})
for dependency, block_list in pairs(ghost_blocks.block_list) do --Register indivdual blocks in block_list
if minetest.get_modpath(dependency) then
for _, block in ipairs(block_list) do
--minetest.log(block)
ghost_blocks.register_ghost_block(block)
end
end
end
local grouped_items = get_group_items(ghost_blocks.group_list)
for _, group in ipairs(ghost_blocks.group_list) do --Register all blocks in groups in group_list
for _, block in pairs(grouped_items[group]) do
ghost_blocks.register_ghost_block(block)
end
end