Added in display item rotation

Updated the Readme. Added in the ability to rotate the displayed item with a screwdriver. Made the Screwdriver mod required, due to rotating the item being fundamental behavoir.

Finalized a few bug fixes... still have to remove the all of the forced debug code, and move the item frames and glow frames over to the new api, and do a final test.
This commit is contained in:
Michieal 2022-11-02 06:14:09 +00:00 committed by cora
parent 8a21b9e99c
commit 18e83e5763
3 changed files with 158 additions and 79 deletions

View File

@ -1,4 +1,13 @@
This mod is originally by Zeg9, but heavily modified for MineClone 2. This mod has been rewritten and revamped by Michieal / Faerraven. Based on the code originally done by Zeg9, and then
heavily modified by the Mineclone 2 dev team.
This mod now supports all the base item frame functions, like rotating the displayed item, which it didn't do before it
was rewritten. Additionally, Glow Frames have been added in, and item frames now has an API to allow new item frames to
be created in other modules.
Now requires the Screwdriver to have full functionality.
The code is licenced under the standard MineClone 2 license for usage, with the requirement that this readme is
included in the code / module.
Model created by 22i, licensed under the Model created by 22i, licensed under the
GNU GPLv3 <https://www.gnu.org/licenses/gpl-3.0.html>. GNU GPLv3 <https://www.gnu.org/licenses/gpl-3.0.html>.

View File

@ -33,12 +33,105 @@ local glow_amount = 6 -- LIGHT_MAX is 15, but the items aren't supposed to be a
local frame_item_base = {} local frame_item_base = {}
local map_item_base = {} local map_item_base = {}
-- Time to Fleckenstein! (it just sounds cool lol)
--- self: the object to roll.
local function update_roll(self, pos)
-- get the entity's metadata.
local meta = minetest.get_meta(pos)
-- using an integer, as it's the number of 45 degree turns. ie, 0 to 7
local current_roll = meta:get_int("roll", 0)
local new_roll = current_roll + 1
if new_roll == 8 then
new_roll = 0
end
meta:set_int("roll", new_roll)
local new_roll_deg = new_roll * 45
-- * `get_rotation()`: returns the rotation, a vector (radians)
local rot = self:get_rotation()
local Radians = 0
-- Radians = Degrees * (pi / 180) degrees to radian formula
-- Radian quick chart
-- One full revolution is equal to 2π rad (or) 360°.
-- 1° = 0.017453 radians and 1 rad = 57.2958°.
-- To convert an angle from degrees to radians, we multiply it by π/180°.
-- To convert an angle from radians to degrees, we multiply it by 180°/π.
Radians = new_roll_deg * (pi / 180)
rot.z = Radians
self:set_rotation(rot)
end
--- self: the object to roll.
--- faceDeg: 0-7, inclusive.
local function set_roll(self, faceDeg)
-- get the entity's metadata.
local meta = minetest.get_meta(self:get_pos())
-- using an integer, as it's the number of 45 degree turns. ie, 0 to 7
local new_roll = faceDeg
if new_roll >= 8 then
new_roll = 7
end
if new_roll <= 0 then
new_roll = 0
end
meta:set_int("roll", new_roll)
local new_roll_deg = new_roll * 45
-- * `get_rotation()`: returns the rotation, a vector (radians)
local rot = self:get_rotation()
local Radians = 0
-- Radians = Degrees * (pi / 180) degrees to radian formula
-- Radian quick chart
-- One full revolution is equal to 2π rad (or) 360°.
-- 1° = 0.017453 radians and 1 rad = 57.2958°.
-- To convert an angle from degrees to radians, we multiply it by π/180°.
-- To convert an angle from radians to degrees, we multiply it by 180°/π.
Radians = new_roll_deg * (pi / 180)
rot.z = Radians
self:set_rotation(rot)
end
local function update_map_texture (self, staticdata)
self.id = staticdata
local result = true
result = mcl_maps.load_map(self.id, function(texture)
-- will not crash even if self.object is invalid by now
-- update... quite possibly will screw up with each version of Minetest. >.<
if not texture then
minetest.log("error", "Failed to load the map texture using mcl_maps.")
end
self.object:set_properties({ textures = { texture } })
end)
if result ~= nil and result == false then
mintest.log("error", "[mcl_itemframes] Error setting up Map Item.")
end
end
local remove_item_entity = function(pos, node) local remove_item_entity = function(pos, node)
local name_found = false local name_found = false
local found_name_to_use = "" local found_name_to_use = ""
for k,v in pairs(mcl_itemframes.frames_registered.glowing) do for k, v in pairs(mcl_itemframes.frames_registered.glowing) do
if node.name == v then if node.name == v then
name_found = true name_found = true
found_name_to_use = v found_name_to_use = v
@ -48,7 +141,7 @@ local remove_item_entity = function(pos, node)
-- try to cut down on excess looping, if possible. -- try to cut down on excess looping, if possible.
if name_found == false then if name_found == false then
for k,v in pairs(mcl_itemframes.frames_registered.standard) do for k, v in pairs(mcl_itemframes.frames_registered.standard) do
if node.name == v then if node.name == v then
name_found = true name_found = true
found_name_to_use = v found_name_to_use = v
@ -57,8 +150,8 @@ local remove_item_entity = function(pos, node)
end end
end end
if 1==1 then if 1 == 1 then
minetest.log("action","mcl_itemframes] remove_item_entity: " .. found_name_to_use .. "'s displayed item." ) minetest.log("action", "mcl_itemframes] remove_item_entity: " .. found_name_to_use .. "'s displayed item.")
end end
if node.name == "mcl_itemframes:item_frame" or node.name == "mcl_itemframes:glow_item_frame" or node.name == found_name_to_use then if node.name == "mcl_itemframes:item_frame" or node.name == "mcl_itemframes:glow_item_frame" or node.name == found_name_to_use then
@ -69,8 +162,8 @@ local remove_item_entity = function(pos, node)
entity.name == "mcl_itemframes:glow_item" or entity.name == "mcl_itemframes:glow_map" then entity.name == "mcl_itemframes:glow_item" or entity.name == "mcl_itemframes:glow_map" then
obj:remove() obj:remove()
elseif entity.name == found_name_to_use .. "_item" or entity.name == found_name_to_use .. "_map" then elseif entity.name == found_name_to_use .. "_item" or entity.name == found_name_to_use .. "_map" then
if 1==1 then if 1 == 1 then
minetest.log("action","mcl_itemframes] remove_item_entity: " .. entity.name .. "-- the item." ) minetest.log("action", "mcl_itemframes] remove_item_entity: " .. entity.name .. "-- the item.")
end end
obj:remove() obj:remove()
end end
@ -133,6 +226,11 @@ mcl_itemframes.update_item_entity = function(pos, node, param2)
end end
map_id_entity:set_yaw(yaw) map_id_entity:set_yaw(yaw)
end end
-- finally, set the rotation (roll) of the displayed object.
local roll = meta:get_int("roll", 0)
set_roll(map_id_entity, roll)
end end
end end
@ -151,7 +249,7 @@ mcl_itemframes.update_generic_item_entity = function(pos, node, param2)
local found_name_to_use = "" local found_name_to_use = ""
local has_glow = false local has_glow = false
for k,v in pairs(mcl_itemframes.frames_registered.glowing) do for k, v in pairs(mcl_itemframes.frames_registered.glowing) do
if node.name == v then if node.name == v then
name_found = true name_found = true
has_glow = true has_glow = true
@ -162,7 +260,7 @@ mcl_itemframes.update_generic_item_entity = function(pos, node, param2)
-- try to cut down on excess looping, if possible. -- try to cut down on excess looping, if possible.
if name_found == false then if name_found == false then
for k,v in pairs(mcl_itemframes.frames_registered.standard) do for k, v in pairs(mcl_itemframes.frames_registered.standard) do
if node.name == v then if node.name == v then
name_found = true name_found = true
has_glow = false has_glow = false
@ -173,8 +271,8 @@ mcl_itemframes.update_generic_item_entity = function(pos, node, param2)
end end
if name_found == false then if name_found == false then
minetest.log("error","[mcl_itemframes] Update_Generic_Item:\nFailed to find registered node:\nNode name - " .. node.name) minetest.log("error", "[mcl_itemframes] Update_Generic_Item:\nFailed to find registered node:\nNode name - " .. node.name)
minetest.log("error","[mcl_itemframes] Update_Generic_Item:\nRegistry definition:" .. dump(mcl_itemframes.frames_registered)) minetest.log("error", "[mcl_itemframes] Update_Generic_Item:\nRegistry definition:" .. dump(mcl_itemframes.frames_registered))
return return
end end
@ -250,6 +348,10 @@ mcl_itemframes.update_generic_item_entity = function(pos, node, param2)
minetest.log("error", "[mcl_itemframes] Update_Generic_Item: Failed to set Map Item in " .. found_name_to_use .. "'s frame.") minetest.log("error", "[mcl_itemframes] Update_Generic_Item: Failed to set Map Item in " .. found_name_to_use .. "'s frame.")
end end
end end
-- finally, set the rotation (roll) of the displayed object.
local roll = meta:get_int("roll", 0)
set_roll(map_id_entity, roll)
end end
end end
@ -269,6 +371,7 @@ local drop_item = function(pos, node, meta, clicker)
end end
meta:set_string("infotext", "") meta:set_string("infotext", "")
meta:set_int("roll", 0)
remove_item_entity(pos, node) remove_item_entity(pos, node)
end end
@ -276,7 +379,7 @@ function mcl_itemframes.drop_generic_item(pos, node, meta, clicker)
local name_found = false local name_found = false
local found_name_to_use = "" local found_name_to_use = ""
for k,v in pairs(mcl_itemframes.frames_registered.glowing) do for k, v in pairs(mcl_itemframes.frames_registered.glowing) do
if node.name == v then if node.name == v then
name_found = true name_found = true
found_name_to_use = v found_name_to_use = v
@ -286,7 +389,7 @@ function mcl_itemframes.drop_generic_item(pos, node, meta, clicker)
-- try to cut down on excess looping, if possible. -- try to cut down on excess looping, if possible.
if name_found == false then if name_found == false then
for k,v in pairs(mcl_itemframes.frames_registered.standard) do for k, v in pairs(mcl_itemframes.frames_registered.standard) do
if node.name == v then if node.name == v then
name_found = true name_found = true
found_name_to_use = v found_name_to_use = v
@ -474,17 +577,16 @@ mcl_itemframes.item_frame_base = {
end, end,
on_rotate = function(pos, node, user, mode, param2) on_rotate = function(pos, node, user, mode, param2)
if mode == screwdriver.ROTATE_FACE then
-- Rotate face
--local meta = minetest.get_meta(pos) --local meta = minetest.get_meta(pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local objs = nil local objs = nil
local name_found = false local name_found = false
local found_name_to_use = "" local found_name_to_use = ""
name_found = false
found_name_to_use = ""
for k,v in pairs(mcl_itemframes.frames_registered.glowing) do for k, v in pairs(mcl_itemframes.frames_registered.glowing) do
if node.name == v then if node.name == v then
name_found = true name_found = true
found_name_to_use = v found_name_to_use = v
@ -494,7 +596,7 @@ mcl_itemframes.item_frame_base = {
-- try to cut down on excess looping, if possible. -- try to cut down on excess looping, if possible.
if name_found == false then if name_found == false then
for k,v in pairs(mcl_itemframes.frames_registered.standard) do for k, v in pairs(mcl_itemframes.frames_registered.standard) do
if node.name == v then if node.name == v then
name_found = true name_found = true
found_name_to_use = v found_name_to_use = v
@ -505,46 +607,34 @@ mcl_itemframes.item_frame_base = {
if node.name == found_name_to_use then if node.name == found_name_to_use then
objs = minetest.get_objects_inside_radius(pos, 0.5) objs = minetest.get_objects_inside_radius(pos, 0.5)
else
return -- short circuit if it's somehow not the right thing.
end end
if objs then if objs then
if mode == screwdriver.ROTATE_FACE or mode == screwdriver.ROTATE_AXIS then
for _, obj in ipairs(objs) do for _, obj in ipairs(objs) do
if obj and obj:get_luaentity() then if obj and obj:get_luaentity() then
local obj_name = obj:get_luaentity().name local obj_name = obj:get_luaentity().name
if obj_name == "mcl_itemframes:item" or obj_name == "mcl_itemframes:glow_item" then if obj_name == "mcl_itemframes:item" or obj_name == "mcl_itemframes:glow_item" then
mcl_itemframes.update_item_entity(pos, node, (node.param2 + 1) % 4) if mode == screwdriver.ROTATE_AXIS then
update_roll(obj, pos)
end
break break
elseif obj_name == found_name_to_use .. "_item" then elseif obj_name == found_name_to_use .. "_item" then
mcl_itemframes.update_generic_item_entity(pos, node, (node.param2 + 1) % 4) if mode == screwdriver.ROTATE_AXIS then
update_roll(obj, pos)
end
break break
end end
end end
end end
end
return
elseif mode == screwdriver.ROTATE_AXIS then
return false return false
end end
end
end, end,
} }
local function update_map_texture (self, staticdata)
self.id = staticdata
local result = true
result = mcl_maps.load_map(self.id, function(texture)
-- will not crash even if self.object is invalid by now
-- update... quite possibly will screw up with each version of Minetest. >.<
if not texture then
minetest.log("error", "Failed to load the map texture using mcl_maps.")
end
self.object:set_properties({ textures = { texture } })
end)
if result ~= nil and result == false then
mintest.log("error", "[mcl_itemframes] Error setting up Map Item.")
end
end
--- reworked to set up the base item definitions, and to register them for item and glow_item. --- reworked to set up the base item definitions, and to register them for item and glow_item.
function mcl_itemframes.create_base_item_entity() function mcl_itemframes.create_base_item_entity()
if 1 == 1 then if 1 == 1 then
@ -615,7 +705,6 @@ function mcl_itemframes.create_base_item_entity()
on_activate = function(self, staticdata) on_activate = function(self, staticdata)
if 1 == 1 then if 1 == 1 then
minetest.log("action", "[mcl_itemframes] map_item:on_activate.") minetest.log("action", "[mcl_itemframes] map_item:on_activate.")
end end
update_map_texture(self, staticdata) update_map_texture(self, staticdata)
end, end,
@ -787,23 +876,6 @@ function mcl_itemframes.create_base_frames()
mcl_itemframes.glow_frame_base.wield_image = "mcl_itemframes_glow_item_frame.png" mcl_itemframes.glow_frame_base.wield_image = "mcl_itemframes_glow_item_frame.png"
mcl_itemframes.glow_frame_base.mesh = "mcl_itemframes_glow_item_frame.obj" mcl_itemframes.glow_frame_base.mesh = "mcl_itemframes_glow_item_frame.obj"
--mcl_itemframes.glow_frame_base.light_source = minetest.LIGHT_MAX -- add in glow (a hack at best, but it's a node) TODO: make actual glow.
mcl_itemframes.glow_frame_base.on_timer = function(pos)
local inv = minetest.get_meta(pos):get_inventory()
local stack = inv:get_stack("main", 1)
local itemname = stack:get_name()
if minetest.get_item_group(itemname, "clock") > 0 then
local new_name = "mcl_clock:clock_" .. (mcl_worlds.clock_works(pos) and mcl_clock.old_time or mcl_clock.random_frame)
if itemname ~= new_name then
stack:set_name(new_name)
inv:set_stack("main", 1, stack)
local node = minetest.get_node(pos)
mcl_itemframes.update_item_entity(pos, node, node.param2)
end
minetest.get_node_timer(pos):start(1.0)
end
end
minetest.register_node("mcl_itemframes:glow_item_frame", mcl_itemframes.glow_frame_base) minetest.register_node("mcl_itemframes:glow_item_frame", mcl_itemframes.glow_frame_base)
mcl_itemframes.update_frame_registry("false", "mcl_itemframes:item_frame", false) mcl_itemframes.update_frame_registry("false", "mcl_itemframes:item_frame", false)
@ -811,4 +883,3 @@ function mcl_itemframes.create_base_frames()
create_register_lbm("mcl_itemframes:item_frame") create_register_lbm("mcl_itemframes:item_frame")
create_register_lbm("mcl_itemframes:glow_item_frame") create_register_lbm("mcl_itemframes:glow_item_frame")
end end

View File

@ -1,3 +1,2 @@
name = mcl_itemframes name = mcl_itemframes
depends = mcl_core, mcl_sounds, mcl_compass, mcl_maps depends = mcl_core, mcl_sounds, mcl_compass, mcl_maps, screwdriver
optional_depends = screwdriver