Initial commit

Wohooo!
master
AspireMint 2020-12-22 18:36:40 +01:00 committed by GitHub
parent b73d8ec80f
commit 76a9ccfc85
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 374 additions and 0 deletions

17
README.md Normal file
View File

@ -0,0 +1,17 @@
# slap_rotate
Easiest way to rotate nodes? :-)
Slap node with glove!
Glove recipe (like screwdriver, but uses wool instead of steel ingot):
{ group:wool }
{ group:stick }
Usage:
- left-click (dig) rotates node horizontally
- right-click (place) rotates node vertically
License:
code - GNU General Public License v3.0
media - CC by SA 3.0, for more details: http://creativecommons.org/licenses/by-sa/3.0/

15
data/axis.lua Normal file
View File

@ -0,0 +1,15 @@
local AXIS = {
x = 0,
y = 1,
z = 2
}
local LOOK_DIR = {
[0] = {axis_index=AXIS.z, polarity=1, perpendicular_axis_index=AXIS.x},
[1] = {axis_index=AXIS.x, polarity=-1, perpendicular_axis_index=AXIS.z},
[2] = {axis_index=AXIS.z, polarity=-1, perpendicular_axis_index=AXIS.x},
[3] = {axis_index=AXIS.x, polarity=1, perpendicular_axis_index=AXIS.z},
y = {axis_index=AXIS.y, polarity=-1, perpendicular_axis_index=AXIS.y}, --[[special case]]--
}
return AXIS, LOOK_DIR

15
data/paramtype.lua Normal file
View File

@ -0,0 +1,15 @@
local PARAMTYPE_GROUP = {
facedir = 0,
wallmounted = 1,
special = 42
}
local PARAMTYPE = {
facedir = {index=PARAMTYPE_GROUP.facedir, mask=32},
colorfacedir = {index=PARAMTYPE_GROUP.facedir, mask=32},
wallmounted = {index=PARAMTYPE_GROUP.wallmounted, mask=8},
colorwallmounted = {index=PARAMTYPE_GROUP.wallmounted, mask=8},
special_slab = {index=PARAMTYPE_GROUP.special, mask=32}
}
return PARAMTYPE, PARAMTYPE_GROUP

20
data/rotate.lua Normal file
View File

@ -0,0 +1,20 @@
local current_modname = minetest.get_current_modname()
local path = minetest.get_modpath(current_modname)
local _, PARAMTYPE_GROUP = dofile(path.."/data/paramtype.lua")
local AXIS = dofile(path.."/data/axis.lua")
local ROTATE = {
[PARAMTYPE_GROUP.facedir] = {
[AXIS.x] = {[0]=4, 5, 6, 7, 22, 23, 20, 21, 0, 1, 2, 3, 13, 14, 15, 12, 19, 16, 17, 18, 10, 11, 8, 9},
[AXIS.y] = {[0]=1, 2, 3, 0, 13, 14, 15, 12, 17, 18, 19, 16, 9, 10, 11, 8, 5, 6, 7, 4, 23, 20, 21, 22},
[AXIS.z] = {[0]=16, 17, 18, 19, 5, 6, 7, 4, 11, 8, 9, 10, 0, 1, 2, 3, 20, 21, 22, 23, 12, 13, 14, 15}
},
[PARAMTYPE_GROUP.wallmounted] = {
[AXIS.x] = {[0]=4, 5, 2, 3, 1, 0},
[AXIS.y] = {[0]=0, 1, 5, 4, 2, 3},
[AXIS.z] = {[0]=3, 2, 0, 1, 4, 5}
}
}
return ROTATE

2
depends.txt Normal file
View File

@ -0,0 +1,2 @@
default
wool

4
init.lua Normal file
View File

@ -0,0 +1,4 @@
local current_modname = minetest.get_current_modname()
local path = minetest.get_modpath(current_modname)
dofile(path.."/tools/glove.lua")

12
test.lua Normal file
View File

@ -0,0 +1,12 @@
local current_modname = minetest.get_current_modname()
local path = minetest.get_modpath(current_modname)
do
local test = dofile(path.."/tests/rotate.lua")
test()
end
do
local test = dofile(path.."/tests/flip.lua")
test()
end

50
tests/flip.lua Normal file
View File

@ -0,0 +1,50 @@
local current_modname = minetest.get_current_modname()
local path = minetest.get_modpath(current_modname)
local FLIP = dofile(path.."/data/flip.lua")
local test_flip = function()
local errors = 0
for pti,at in pairs(FLIP) do
for ai,rt in pairs(at) do
local found_rot = {}
for ri=0,#rt do
local o = rt[ri]
function rot(p, c)
if c < 1 then
return p
end
c = c-1
return rot(rt[p], c)
end
local p2 = rot(o, 2)
if o ~= p2 then
errors = errors + 1
--[[
print("WARNING: corrupted flip table:",
"paramtype_index:"..pti,
"axis_index: "..ai,
"origin: "..o,
"param2:"..p2)
]]
else
found_rot[p2] = true
end
end
for fri=0,#rt do
if not found_rot[fri] then
error("FATAL ERROR: corrupted flip table, fix it ASAP")
end
end
end
end
if errors == 0 then
print("flip table looks ok to me")
else
print("DO NOT TOUCH ROTATION TABLE!!! Errors: "..errors)
end
end
return test_flip

52
tests/rotate.lua Normal file
View File

@ -0,0 +1,52 @@
local current_modname = minetest.get_current_modname()
local path = minetest.get_modpath(current_modname)
local ROTATE = dofile(path.."/data/rotate.lua")
local test_rotate = function()
local errors = 0
for pti,at in pairs(ROTATE) do
for ai,rt in pairs(at) do
for c=4,1,-1 do
local found_rot = {}
for ri=0,#rt do
local o = rt[ri]
function rot(p, c)
if c < 1 then
return p
end
c = c-1
return rot(rt[p], c)
end
local p2 = rot(o, c)
if found_rot[p2] or c==4 and o ~= p2 then
errors = errors + 1
--[[
print("WARNING: corrupted rotation table:",
"paramtype_index:"..pti,
"axis_index: "..ai,
"origin: "..o,
"param2:"..p2)
]]
else
found_rot[p2] = true
end
end
for fri=0,#rt do
if not found_rot[fri] then
error("FATAL ERROR: corrupted rotation table, fix it ASAP")
end
end
end
end
end
if errors == 0 then
print("rotation table looks ok to me")
else
print("DO NOT TOUCH ROTATION TABLE!!! Errors: "..errors)
end
end
return test_rotate

BIN
textures/leather_glove.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

74
tools/glove.lua Normal file
View File

@ -0,0 +1,74 @@
local current_modname = minetest.get_current_modname()
local path = minetest.get_modpath(current_modname)
local AXIS, LOOK_DIR = dofile(path.."/data/axis.lua")
local axis_util = dofile(path.."/utils/axis.lua")
local node_util = dofile(path.."/utils/node.lua")
local paramtype_util = dofile(path.."/utils/paramtype.lua")
local rotate_util = dofile(path.."/utils/rotate.lua")
local TOOL_NAME = "glove"
local get_new_rotation = function(paramtype, axis, origin, angle)
local count = rotate_util.get_repetition(angle)
local rotation = origin
for i=1,count do
rotation = rotate_util.rotate(paramtype, axis, rotation)
end
return rotation
end
local handler = function(itemstack, user, pointed_thing, look_dir)
if pointed_thing.type ~= "node" then
return
end
local pos = pointed_thing.under
if not node_util.can_interact(user, pos) then
return itemstack
end
local node = minetest.get_node(pos)
if not rotate_util.can_rotate(node) then
return itemstack
end
local ndef = minetest.registered_nodes[node.name]
local rotation = node.param2 % paramtype_util.get_mask(ndef.paramtype2)
local angle = -90*look_dir.polarity
local axis_index = look_dir.perpendicular_axis_index
local new_rotation = get_new_rotation(ndef.paramtype2, axis_index, rotation, angle)
local param2_supplement = node.param2 - rotation
node.param2 = new_rotation + param2_supplement
minetest.swap_node(pos, node)
return itemstack
end
minetest.register_tool(current_modname..":"..TOOL_NAME, {
description = "Leather glove\n"
.."left-click rotates node horizontally\n"
.."right-click rotates node vertically",
inventory_image = "leather_glove.png^[transformFXR90",
groups = {tool = 1},
on_use = function(itemstack, user, pointed_thing)
return handler(itemstack, user, pointed_thing, LOOK_DIR.y)
end,
on_place = function(itemstack, user, pointed_thing)
local look_dir = axis_util.get_look_dir(user)
return handler(itemstack, user, pointed_thing, look_dir)
end,
})
minetest.register_craft({
output = current_modname..":"..TOOL_NAME,
recipe = {
{"group:wool"},
{"group:stick"},
}
})
return

24
utils/axis.lua Normal file
View File

@ -0,0 +1,24 @@
local current_modname = minetest.get_current_modname()
local path = minetest.get_modpath(current_modname)
local AXIS, LOOK_DIR = dofile(path.."/data/axis.lua")
local util = {}
util.axis_exists = function(axis)
return not not AXIS[axis]
end
util.get_axis_index = function(axis)
if not util.axis_exists(axis) then
error("Are you trying to open new dimension? Not in this universe!")
end
return AXIS[axis]
end
util.get_look_dir = function(user)
local facedir = minetest.dir_to_facedir(user:get_look_dir(), false)
return LOOK_DIR[facedir]
end
return util

18
utils/node.lua Normal file
View File

@ -0,0 +1,18 @@
local util = {}
util.can_interact = function(user, pos)
local node = minetest.get_node(pos)
local ndef = minetest.registered_nodes[node.name]
if not ndef then
return false
end
local player_name = user and user:get_player_name() or ""
if minetest.is_protected(pos, player_name) then
minetest.record_protection_violation(pos, player_name)
return false
end
return true
end
return util

36
utils/paramtype.lua Normal file
View File

@ -0,0 +1,36 @@
local current_modname = minetest.get_current_modname()
local path = minetest.get_modpath(current_modname)
local PARAMTYPE, PARAMTYPE_GROUP = dofile(path.."/data/paramtype.lua")
local util = {}
util.get_index = function(paramtype)
return PARAMTYPE[paramtype].index
end
util.get_mask = function(paramtype)
return PARAMTYPE[paramtype].mask
end
util.paramtype_or_special_case = function(node)
if string.match(node.name, 'stairs:slab') then
return 'special_slab'
end
local ndef = minetest.registered_nodes[node.name]
return ndef.paramtype2
end
util.is_facedir_group = function(node)
local ndef = minetest.registered_nodes[node.name]
local param_index = util.get_index(ndef.paramtype2)
return param_index == PARAMTYPE_GROUP.facedir
end
util.is_wallmounted_group = function(node)
local ndef = minetest.registered_nodes[node.name]
local param_index = util.get_index(ndef.paramtype2)
return param_index == PARAMTYPE_GROUP.wallmounted
end
return util

35
utils/rotate.lua Normal file
View File

@ -0,0 +1,35 @@
local current_modname = minetest.get_current_modname()
local path = minetest.get_modpath(current_modname)
local ROTATE = dofile(path.."/data/rotate.lua")
local axis_util = dofile(path.."/utils/axis.lua")
local paramtype_util = dofile(path.."/utils/paramtype.lua")
local util = {}
util.rotate = function(paramtype, axis, rotation)
local paramtype_index = paramtype_util.get_index(paramtype)
local axis_index = type(axis)=='number' and axis or axis_util.get_axis_index(axis)
return ROTATE[paramtype_index][axis_index][rotation]
end
util.rotation_exist = function(paramtype)
return pcall(util.rotate, paramtype, 0, 0)
end
util.can_rotate = function(node)
local ndef = minetest.registered_nodes[node.name]
return util.rotation_exist(ndef.paramtype2)
and (paramtype_util.is_wallmounted_group(node) or paramtype_util.is_facedir_group(node))
end
util.get_repetition = function(angle)
local get_positive_angle = function(angle)
angle = angle % 360
return angle % 90 == 0 and angle or 0--=do not rotate
end
return get_positive_angle(angle) / 90
end
return util