199 lines
6.1 KiB
Lua
199 lines
6.1 KiB
Lua
|
local modname = minetest.get_current_modname()
|
||
|
local modpath = minetest.get_modpath(modname)
|
||
|
local S = minetest.get_translator(modname)
|
||
|
local N = function(s) return s end
|
||
|
|
||
|
local mod_mcl_core = minetest.get_modpath("mcl_core")
|
||
|
local mod_mcl_banners = minetest.get_modpath("mcl_banners")
|
||
|
local mod_mcl_dye = minetest.get_modpath("mcl_wool")
|
||
|
local mod_mcl_dye = minetest.get_modpath("mcl_dye")
|
||
|
local mod_doc = minetest.get_modpath("doc")
|
||
|
|
||
|
local standing_banner_entity_offset = { x=0, y=-0.499, z=0 }
|
||
|
local hanging_banner_entity_offset = { x=0, y=-1.7, z=0 }
|
||
|
|
||
|
local inv
|
||
|
local base
|
||
|
local finished_banner
|
||
|
|
||
|
base = "mcl_banners_item_base.png^mcl_prideflags_item_overlay.png^[resize:32x32"
|
||
|
finished_banner = base
|
||
|
|
||
|
inv = finished_banner
|
||
|
groups = { banner = 1, deco_block = 1, flammable = -1 }
|
||
|
|
||
|
-- Helper function
|
||
|
local function round(num, idp)
|
||
|
local mult = 10^(idp or 0)
|
||
|
return math.floor(num * mult + 0.5) / mult
|
||
|
end
|
||
|
|
||
|
local function rotation_level_to_yaw(rotation_level)
|
||
|
return (rotation_level * (math.pi/8)) + math.pi
|
||
|
end
|
||
|
|
||
|
local function spawn_banner_entity(pos, hanging, itemstack)
|
||
|
local banner
|
||
|
if hanging then
|
||
|
banner = minetest.add_entity(pos, "mcl_banners:hanging_banner")
|
||
|
else
|
||
|
banner = minetest.add_entity(pos, "mcl_banners:standing_banner")
|
||
|
end
|
||
|
if banner == nil then
|
||
|
return banner
|
||
|
end
|
||
|
local imeta = itemstack:get_meta()
|
||
|
local layers = ""
|
||
|
local colorid = ""
|
||
|
banner:set_properties({textures = {"mcl_prideflags_base.png"}})
|
||
|
local mname = imeta:get_string("name")
|
||
|
if mname and mname ~= "" then
|
||
|
banner:get_luaentity()._item_name = mname
|
||
|
banner:get_luaentity()._item_description = imeta:get_string("description")
|
||
|
end
|
||
|
|
||
|
return banner
|
||
|
end
|
||
|
|
||
|
minetest.register_lbm({
|
||
|
label = "Respawn banner entities",
|
||
|
name = "mcl_prideflags:respawn_entities",
|
||
|
run_at_every_load = true,
|
||
|
nodenames = {"mcl_banners:standing_banner", "mcl_banners:hanging_banner"},
|
||
|
action = function(pos, node)
|
||
|
|
||
|
local hanging = node.name == "mcl_banners:hanging_banner"
|
||
|
local offset
|
||
|
if hanging then
|
||
|
offset = hanging_banner_entity_offset
|
||
|
else
|
||
|
offset = standing_banner_entity_offset
|
||
|
end
|
||
|
|
||
|
local bpos = vector.add(pos, offset)
|
||
|
local objects = minetest.get_objects_inside_radius(bpos, 0.5)
|
||
|
|
||
|
for _, v in ipairs(objects) do
|
||
|
local ent = v:get_luaentity()
|
||
|
if ent and (ent.name == "mcl_banners:standing_banner" or ent.name == "mcl_banners:hanging_banner") then
|
||
|
local meta = minetest.get_meta(pos)
|
||
|
if meta:get_int("pride") == 1 then
|
||
|
v:set_properties({textures = {"mcl_prideflags_base.png"}})
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end,
|
||
|
})
|
||
|
|
||
|
minetest.register_craftitem("mcl_prideflags:pride_flag", {
|
||
|
description = S("Pride Flag"),
|
||
|
_tt_help = S("Pride Flag decoration"),
|
||
|
_doc_items_create_entry = false,
|
||
|
inventory_image = inv,
|
||
|
wield_image = inv,
|
||
|
-- Banner group groups together the banner items, but not the nodes.
|
||
|
-- Used for crafting.
|
||
|
groups = groups,
|
||
|
stack_max = 16,
|
||
|
|
||
|
on_place = function(itemstack, placer, pointed_thing)
|
||
|
local above = pointed_thing.above
|
||
|
local under = pointed_thing.under
|
||
|
|
||
|
local node_under = minetest.get_node(under)
|
||
|
if placer and not placer:get_player_control().sneak then
|
||
|
-- Use pointed node's on_rightclick function first, if present
|
||
|
if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then
|
||
|
return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- Place the node!
|
||
|
local hanging = false
|
||
|
|
||
|
-- Standing or hanging banner. The placement rules are enforced by the node definitions
|
||
|
local _, success = minetest.item_place_node(ItemStack("mcl_banners:standing_banner"), placer, pointed_thing)
|
||
|
if not success then
|
||
|
-- Forbidden on ceiling
|
||
|
if pointed_thing.under.y ~= pointed_thing.above.y then
|
||
|
return itemstack
|
||
|
end
|
||
|
_, success = minetest.item_place_node(ItemStack("mcl_banners:hanging_banner"), placer, pointed_thing)
|
||
|
if not success then
|
||
|
return itemstack
|
||
|
end
|
||
|
hanging = true
|
||
|
end
|
||
|
local place_pos
|
||
|
if minetest.registered_nodes[node_under.name].buildable_to then
|
||
|
place_pos = under
|
||
|
else
|
||
|
place_pos = above
|
||
|
end
|
||
|
local bnode = minetest.get_node(place_pos)
|
||
|
if bnode.name ~= "mcl_banners:standing_banner" and bnode.name ~= "mcl_banners:hanging_banner" then
|
||
|
minetest.log("error", "[mcl_banners] The placed banner node is not what the mod expected!")
|
||
|
return itemstack
|
||
|
end
|
||
|
local meta = minetest.get_meta(place_pos)
|
||
|
local inv = meta:get_inventory()
|
||
|
inv:set_size("banner", 1)
|
||
|
local store_stack = ItemStack(itemstack)
|
||
|
store_stack:set_count(1)
|
||
|
inv:set_stack("banner", 1, store_stack)
|
||
|
|
||
|
-- Spawn entity
|
||
|
local entity_place_pos
|
||
|
if hanging then
|
||
|
entity_place_pos = vector.add(place_pos, hanging_banner_entity_offset)
|
||
|
else
|
||
|
entity_place_pos = vector.add(place_pos, standing_banner_entity_offset)
|
||
|
end
|
||
|
local banner_entity = spawn_banner_entity(entity_place_pos, hanging, itemstack)
|
||
|
-- Set rotation
|
||
|
local final_yaw, rotation_level
|
||
|
if hanging then
|
||
|
local pdir = vector.direction(pointed_thing.under, pointed_thing.above)
|
||
|
final_yaw = minetest.dir_to_yaw(pdir)
|
||
|
if pdir.x > 0 then
|
||
|
rotation_level = 4
|
||
|
elseif pdir.z > 0 then
|
||
|
rotation_level = 8
|
||
|
elseif pdir.x < 0 then
|
||
|
rotation_level = 12
|
||
|
else
|
||
|
rotation_level = 0
|
||
|
end
|
||
|
else
|
||
|
-- Determine the rotation based on player's yaw
|
||
|
local yaw = placer:get_look_horizontal()
|
||
|
-- Select one of 16 possible rotations (0-15)
|
||
|
rotation_level = round((yaw / (math.pi*2)) * 16)
|
||
|
if rotation_level >= 16 then
|
||
|
rotation_level = 0
|
||
|
end
|
||
|
final_yaw = rotation_level_to_yaw(rotation_level)
|
||
|
end
|
||
|
meta:set_int("rotation_level", rotation_level)
|
||
|
meta:set_int("pride", 1)
|
||
|
|
||
|
if banner_entity then
|
||
|
banner_entity:set_yaw(final_yaw)
|
||
|
end
|
||
|
|
||
|
if not minetest.is_creative_enabled(placer:get_player_name()) then
|
||
|
itemstack:take_item()
|
||
|
end
|
||
|
minetest.sound_play({name="default_place_node_hard", gain=1.0}, {pos = place_pos}, true)
|
||
|
|
||
|
return itemstack
|
||
|
end,
|
||
|
})
|
||
|
|
||
|
if mod_mcl_core then
|
||
|
minetest.register_craft({
|
||
|
output = "mcl_prideflags:pride_flag",
|
||
|
recipe = { {"mcl_wool:red", "mcl_wool:orange", "mcl_wool:yellow"}, {"mcl_wool:green", "mcl_wool:blue", "mcl_wool:purple"}, {"", "mcl_core:stick", ""} }
|
||
|
})
|
||
|
end
|