Added transforms, tweaked ifc

master
Aftermoth 2016-07-01 19:50:09 +12:00 committed by GitHub
parent 0918474a3a
commit c2dab77fd3
1 changed files with 227 additions and 163 deletions

390
init.lua
View File

@ -1,21 +1,5 @@
--[[
Copyright (C) 2016 Aftermoth, Zolan Davis
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License,
or (at your option) version 3 of the License.
http://www.gnu.org/licenses/lgpl-2.1.html
--]]
-- ======== FYI ========
minetest.register_alias("nudger", "nudger:nudger")
minetest.register_craft({
output = "nudger:nudger",
recipe = {
@ -24,6 +8,24 @@ minetest.register_craft({
}
})
nudger = {}
local transforms = {}
nudger.register_transforms = function(prefix, suffixes, cost, callback)
--[[
prefix = string. First common part of node names. Longer is better. Can be ''.
suffixes = table of strings. Remainders of node names with prefix removed. Can include ''.
cost = integer. How many rotations worth of tool wear should one transform cost for this group.
callback = function, called with (pos). In case other adjustments are needed after transforming. Can be nil.
--]]
local l, n = string.len(prefix), 0
for i,j in ipairs(transforms) do
if string.len(j[1]) <= l then break end
n=i
end
table.insert(transforms,n+1,{prefix, suffixes, cost, callback})
end
-- ======== Chat ========
local menu0 = {
@ -36,23 +38,23 @@ local menu0 = {
}
local menu1 = {
"Reverse rotations.",
"Store a node's rotation.",
"Equip stored rotation.",
"Reverse directions.",
"Store orientation.",
"Equip orientation.",
"Transform.",
"Toggle chat level.",
"Buy nudgiquin for 20% tool wear.",
"Get sixel node for 20% tool wear.",
"",
"",
"Nudge to stored rotation.",
-- submenu
"Nudge to orientation.",
"Store ...",
}
-- ======== Helpers ========
local function say(msg, plr)
minetest.chat_send_player(plr:get_player_name(), msg)
local function say(msg, plr, sh)
if sh ~= 1 then minetest.chat_send_player(plr and plr:get_player_name() or "singleplayer", msg) end
end
local function edit_ok(pos, plr)
@ -64,30 +66,32 @@ local function edit_ok(pos, plr)
end
local function node_ok(pos, plr)
local node = minetest.get_node_or_nil(pos)
local node = minetest.get_node(pos)
local ndef = minetest.registered_nodes[node.name]
if not ndef or not (ndef.paramtype2 == "facedir") or node.param2 == nil
or (ndef.drawtype == "nodebox" and not (ndef.node_box.type == "fixed")) then
say("Target can't be nudged.", plr)
if plr then say("Target can't be nudged.", plr) end
return
end
return node
end
local function is_sixel(pos)
return minetest.get_node(pos).name:sub(1,12) == "nudger:sixel"
end
local function tool_use(istk, cost, pos)
if not pos or minetest.get_node_or_nil(pos).name ~= "nudger:nudgiquin" then
local wear = tonumber(istk:get_wear()) + 327*cost
if wear > 65535 then istk:clear()
if not pos or not is_sixel(pos) then
local wear = tonumber(istk:get_wear()) + 257*cost
if wear > 65534 then istk:clear()
else istk:set_wear(wear)
end
end
return istk
end
-- ======== Rotation ========
-- ======== Actions ========
-- == Choose axis of rotation ==
-- Choose axis of rotation
local function face(ptd)
local a, u = ptd.above.x, ptd.under.x
@ -128,7 +132,7 @@ local function choose_axis(plr, ptd, mode)
end
-- == Do rotation ==
-- == Rotate ==
local map = {
{ -- x
@ -151,7 +155,7 @@ local map = {
local function rotate(istk, plr, ptd, mode, sgn)
local pos = ptd.under
local node = node_ok(pos, plr)
if not node then return istk end
if not node then return end
local p = (node.param2)%24
local q, r = math.floor(p/4), p%4
local a, s = choose_axis(plr,ptd,mode)
@ -166,143 +170,160 @@ local function rotate(istk, plr, ptd, mode, sgn)
end
node.param2 = p
minetest.swap_node(pos, node)
return tool_use(istk, 1, pos), p
tool_use(istk, 1, pos)
return p
end
-- == Store / Apply ==
-- == Store / Apply Orientation ==
local function store(istk, pos, plr)
local node = node_ok(pos, plr)
if not node then return istk end
return tool_use(istk, 4, pos), node.param2
local function store(istk, pos)
local node = node_ok(pos)
if not node then return 0 end
tool_use(istk, 8, pos)
return node.param2
end
local function apply(istk, pos, plr, p2)
local node = node_ok(pos, plr)
if not node then return istk end
if not node then return end
node.param2 = p2
minetest.swap_node(pos, node)
return tool_use(istk, 1, pos), p2
tool_use(istk, 1, pos)
return p2
end
-- == Transform ==
local function transform(istk,pos,plr)
local node = minetest.get_node(pos)
local name = node.name
for i,j in ipairs(transforms) do
if string.match(name,'^'..j[1]) then
s = string.sub(name, string.len(j[1])+1)
jj = j[2]
for k,t in ipairs(jj) do
if t == s then
node.name=j[1]..jj[k%#jj+1]
minetest.swap_node(pos,node)
if j[4] then j[4](pos) end
tool_use(istk,j[3])
return
end
end
end
end
say("Target can't transform.",plr)
end
-- ======== Sixel ========
local function sixel(istk,plr)
if tonumber(istk:get_wear()) > 52428 then
say("Sorry, this nudger is too damaged.",plr)
else
tool_use(istk,51,nil)
local inv = plr:get_inventory()
local stk = inv:add_item("main",ItemStack("nudger:sixel"))
if not stk:is_empty() then
minetest.item_drop(stk,plr,plr:get_pos())
end
say("Sixel can be nudged without tool damage,",plr)
say(" and reports its param2 with 'More chat.'",plr)
end
end
-- ======== Interface ========
local function shop(istk,plr)
if tonumber(istk:get_wear()) > 52428 then
say("Sorry, this nudger is too damaged.",plr)
else
tool_use(istk,40,nil)
local inv = plr:get_inventory()
local stk = inv:add_item("main",ItemStack("nudger:nudgiquin"))
if not stk:is_empty() then
minetest.item_drop(stk,plr,plr:get_pos())
end
say("Nudgiquin can be nudged without tool damage.",plr)
say("It will also report its param2 with 'More chat.'",plr)
end
end
local function reset(istk, plr)
say("Shift+click to cycle options.", plr)
say("Right click to switch menus.", plr)
istk:set_name("nudger:nudger0")
return 0
end
local function do_on_use(istk, plr, ptd)
local function do_on_use(istk, plr, ptd, rt)
local m = tonumber(istk:get_metadata())
if not m then m = reset(istk, plr) end
-- unpack metadata
local p2 = math.floor(m/120)
local sh = math.floor((m%120)/60)
local mm = math.floor((m%60)/6)
local rm = m%6
local sr, dr = math.floor(rm/3), rm%3
-- menu options
if plr:get_player_control().sneak then
if mm == 0 then
rm = 3*sr + (dr + 1)%3
elseif mm < 6 then
mm = mm%5 + 1
elseif mm < 10 then
mm = 17 - mm
end
if mm == 0 then
if sh==0 then say(menu0[rm + 1], plr) end
istk:set_name("nudger:nudger"..rm)
else
say(menu1[mm], plr)
if mm == 2 or mm == 9 then istk:set_name("nudger:nudger6")
elseif mm == 3 then istk:set_name("nudger:nudger")
elseif mm == 8 then istk:set_name("nudger:nudger7")
end
end
-- menu actions
else
local once = true
if mm == 1 then
rm = 3*(1 - sr) + dr
if sh==0 then say("Reversed.", plr) end
elseif mm == 4 then
sh = 1 - sh
say(((sh==0 and "More") or "Less").." chat.", plr)
elseif mm == 5 then
shop(istk,plr)
else
once = false
end
local pos = (ptd.type == "node" and ptd.under) or false
local qp2
if pos and not once then
if mm == 0 then
if edit_ok(pos, plr) then
istk, qp2 = rotate(istk, plr, ptd, dr, 1-2*sr)
end
elseif mm == 2 or mm == 3 or mm == 9 then
if mm == 2 or mm == 9 then
istk, qp2 = store(istk, pos, plr)
if qp2 then p2 = qp2 end
if sh==0 then say("Stored.", plr) end
end
mm = 8
istk:set_name("nudger:nudger7")
say(menu1[8], plr)
elseif mm == 8 then
if edit_ok(pos, plr) then
istk, qp2 = apply(istk, pos, plr, p2)
end
end
end
if qp2 and sh==0 and minetest.get_node_or_nil(pos).name == "nudger:nudgiquin" then say("nq: "..qp2, plr) end
if once then
mm = 0
istk:set_name("nudger:nudger"..rm)
end
end
istk:set_metadata(120*p2 + 60*sh + 6*mm + rm)
return istk
end
local function do_on_place(istk, plr)
local m = tonumber(istk:get_metadata())
if not m then m = reset(istk, plr)
else
local mh = math.floor(m/60)
local sh = mh%2
if m then
-- unpack metadata
local p2 = math.floor(m/120)
local sh = math.floor((m%120)/60)
local mm = math.floor((m%60)/6)
local rm = m%6
mm = (mm == 0 and 1) or 0
if mm == 1 then
if sh==0 then say(menu1[1], plr) end
istk:set_name("nudger:nudger")
local sr, dr = math.floor(rm/3), rm%3
-- Switch menus
if rt then
mm = (mm == 0 and 1) or 0
if mm == 1 then
say(menu1[1], plr, sh)
istk:set_name("nudger:nudger")
else
istk:set_name("nudger:nudger"..rm)
end
-- Cycle menu options
elseif plr:get_player_control().sneak then
if mm == 0 then
rm = 3*sr + (dr + 1)%3
elseif mm < 7 then
mm = mm%6 + 1
elseif mm < 10 then
mm = 17 - mm
end
-- show correct tool
if mm == 0 then
say(menu0[rm + 1], plr, sh)
istk:set_name("nudger:nudger"..rm)
else
say(menu1[mm], plr)
if mm == 3 or mm == 5 then istk:set_name("nudger:nudger")
elseif mm == 2 or mm == 9 then istk:set_name("nudger:nudger6")
elseif mm == 4 then istk:set_name("nudger:nudger8")
elseif mm == 8 then istk:set_name("nudger:nudger7")
end
end
-- Apply menu actions
else
istk:set_name("nudger:nudger"..rm)
local once = true
if mm == 1 then
rm = 3*(1 - sr) + dr
say("Reversed.", plr, sh)
elseif mm == 5 then
sh = 1 - sh
say(((sh==0 and "More") or "Less").." chat.", plr)
elseif mm == 6 then
sixel(istk,plr)
else
local pos = ptd.type == "node" and ptd.under
if pos then
if mm == 2 or mm == 3 or mm == 9 then
if mm ~= 3 then
p2 = store(istk, pos)
say(p2.." Stored.", plr, sh)
end
if mm ~= 9 then say(" * storage submenu *", plr, sh) end
mm = 8
istk:set_name("nudger:nudger7")
say(menu1[8], plr)
elseif edit_ok(pos, plr) then
local qp2
if mm == 0 then
qp2 = rotate(istk, plr, ptd, dr, 1-2*sr)
elseif mm == 4 then
transform(istk,pos,plr)
elseif mm == 8 then
qp2 = apply(istk, pos, plr, p2)
end
if qp2 and is_sixel(pos) then
say("sixel: "..qp2, plr, sh)
end
end
end
once = false
end
if once then
mm = 0
istk:set_name("nudger:nudger"..rm)
end
end
m = 60*mh + 6*mm + rm
m = 120*p2 + 60*sh + 6*mm + rm
else m = 0
say("Shift click to cycle menu options.", plr)
say("Right click to switch menus.", plr)
istk:set_name("nudger:nudger0")
end
istk:set_metadata(m)
return istk
@ -311,6 +332,8 @@ end
-- ======== Registration ========
-- * Tools *
minetest.register_tool("nudger:nudger", {
description = "Nudger",
inventory_image = "nudger.png",
@ -318,11 +341,11 @@ minetest.register_tool("nudger:nudger", {
return do_on_use(istk, plr, ptd)
end,
on_place = function(istk, plr, ptd)
return do_on_place(istk, plr)
return do_on_use(istk, plr, ptd, 1)
end,
})
local adj={"+cw","lf","dn","-cw","rt","up","copy","paste"}
local adj={"+cw","lf","dn","-cw","rt","up","store","apply"}
for i = 0, 7 do
minetest.register_tool("nudger:nudger"..i, {
@ -333,19 +356,60 @@ for i = 0, 7 do
on_use = function(istk, plr, ptd)
return do_on_use(istk, plr, ptd)
end,
on_place = function(istk, plr, ptd)
return do_on_place(istk, plr)
end,
on_place = function(istk, plr, ptd)
return do_on_use(istk, plr, ptd, 1)
end,
})
end
minetest.register_node("nudger:nudgiquin", {
description = "Nudgiquin",
drop = "nudger:nudgiquin",
tiles = {"nq_up.png","nq_dn.png","nq_rt.png","nq_lf.png","nq_fc.png","nq_bk.png"},
minetest.register_tool("nudger:nudger8", {
description = "Gerund",
inventory_image = "nudger.png^[transform1",
on_use = function(istk, plr, ptd)
return do_on_use(istk, plr, ptd)
end,
on_place = function(istk, plr, ptd)
return do_on_use(istk, plr, ptd, 1)
end,
})
-- * Nodes *
minetest.register_node("nudger:sixel", {
description = "Sixel",
drop = "nudger:sixel",
tiles = {"sixel_tp.png","sixel_bt.png","sixel_rt.png","sixel_lf.png","sixel_ft.png","sixel_bk.png"},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = true,
groups = {dig_immediate=3},
})
minetest.register_node("nudger:sixel_t", {
description = "Sixel t",
drop = "nudger:sixel",
tiles = {"sixel_t2.png","sixel_t2.png","sixel_t1.png","sixel_t3.png","sixel_t1.png","sixel_t3.png",},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = true,
groups = {dig_immediate=3,not_in_creative_inventory=1},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, -0.3, -0.3},
{-0.3, -0.3, -0.5, -0.1, 0.5, -0.3},
{-0.5, -0.3, -0.5, -0.3, -0.1, 0.5},
},
},
})
-- * Transforms *
local function example(pos)
say('Sixel transformed at '..pos.x..','..pos.y..','..pos.z)
end
nudger.register_transforms('nudger:sixel', {'','_t'}, 0, example)