forked from MTSR/techage_modpack
320 lines
9.2 KiB
Lua
320 lines
9.2 KiB
Lua
--[[
|
|
|
|
TechAge
|
|
=======
|
|
|
|
Copyright (C) 2021 Joachim Stolberg
|
|
|
|
AGPL v3
|
|
See LICENSE.txt for more information
|
|
|
|
TA1 Watermill
|
|
|
|
]]--
|
|
|
|
local M = minetest.get_meta
|
|
local S = techage.S
|
|
|
|
local function calc_dir(dir, facedir)
|
|
if facedir == 1 then
|
|
return {x = dir.z, y = dir.y, z = -dir.x}
|
|
elseif facedir == 2 then
|
|
return {x = -dir.x, y = dir.y, z = -dir.z}
|
|
elseif facedir == 3 then
|
|
return {x = -dir.z, y = dir.y, z = dir.x}
|
|
end
|
|
return {x = dir.x, y = dir.y, z = dir.z}
|
|
end
|
|
|
|
local function add_node(pos, dir, facedir, node_name)
|
|
local pos2 = vector.add(pos, calc_dir(dir, facedir))
|
|
local node = minetest.get_node(pos2)
|
|
if techage.is_air_like(node.name) then
|
|
minetest.swap_node(pos2, {name = node_name})
|
|
end
|
|
end
|
|
|
|
local function remove_node(pos, dir, facedir, node_name)
|
|
local pos2 = vector.add(pos, calc_dir(dir, facedir))
|
|
local node = minetest.get_node(pos2)
|
|
if node.name == node_name then
|
|
minetest.swap_node(pos2, {name = "air"})
|
|
end
|
|
end
|
|
|
|
local function water_flowing(pos, facedir, tRes)
|
|
facedir = ((facedir or 0) + 1) % 4
|
|
local dir = minetest.facedir_to_dir(facedir)
|
|
|
|
local pos2 = vector.add(pos, dir)
|
|
pos2.y = pos2.y + 1
|
|
local node = minetest.get_node(pos2)
|
|
if node.name == "default:water_flowing" or node.name == "default:river_water_flowing" then
|
|
tRes.backward = false
|
|
return true
|
|
end
|
|
|
|
pos2 = vector.subtract(pos, dir)
|
|
pos2.y = pos2.y + 1
|
|
node = minetest.get_node(pos2)
|
|
if node.name == "default:water_flowing" or node.name == "default:river_water_flowing" then
|
|
tRes.backward = true
|
|
return true
|
|
end
|
|
end
|
|
|
|
local function enough_space(pos, facedir)
|
|
local pos1 = vector.add(pos, calc_dir({x =-1, y =-1, z = 0}, facedir))
|
|
local pos2 = vector.add(pos, calc_dir({x = 1, y = 1, z = 0}, facedir))
|
|
local _, nodes = minetest.find_nodes_in_area(pos1, pos2, {"air"})
|
|
return nodes["air"] and nodes["air"] == 8
|
|
end
|
|
|
|
local function remove_nodes(pos, facedir)
|
|
remove_node(pos, {x = 0, y = 1, z = 0}, facedir, "techage:water_stop")
|
|
remove_node(pos, {x =-1, y = 0, z = 0}, facedir, "techage:water_stop")
|
|
remove_node(pos, {x = 1, y = 0, z = 0}, facedir, "techage:water_stop")
|
|
remove_node(pos, {x =-1, y = 1, z =-1}, facedir, "techage:water_stop")
|
|
remove_node(pos, {x = 1, y = 1, z =-1}, facedir, "techage:water_stop")
|
|
remove_node(pos, {x =-1, y = 1, z = 1}, facedir, "techage:water_stop")
|
|
remove_node(pos, {x = 1, y = 1, z = 1}, facedir, "techage:water_stop")
|
|
end
|
|
|
|
local function start_wheel(pos, facedir, backward)
|
|
local obj = minetest.add_entity(pos, "techage:ta1_watermill_entity")
|
|
local dir = minetest.facedir_to_dir(facedir)
|
|
local yaw = minetest.dir_to_yaw(dir)
|
|
if backward then
|
|
obj:set_rotation({x=-math.pi/2, y=yaw, z=0})
|
|
else
|
|
obj:set_rotation({x=math.pi/2, y=yaw, z=0})
|
|
end
|
|
local self = obj:get_luaentity()
|
|
self.facedir = facedir
|
|
|
|
add_node(pos, {x = 0, y = 1, z = 0}, facedir, "techage:water_stop")
|
|
add_node(pos, {x =-1, y = 0, z = 0}, facedir, "techage:water_stop")
|
|
add_node(pos, {x = 1, y = 0, z = 0}, facedir, "techage:water_stop")
|
|
add_node(pos, {x =-1, y = 1, z =-1}, facedir, "techage:water_stop")
|
|
add_node(pos, {x = 1, y = 1, z =-1}, facedir, "techage:water_stop")
|
|
add_node(pos, {x =-1, y = 1, z = 1}, facedir, "techage:water_stop")
|
|
add_node(pos, {x = 1, y = 1, z = 1}, facedir, "techage:water_stop")
|
|
minetest.remove_node(pos)
|
|
end
|
|
|
|
local function stop_wheel(pos, self)
|
|
self.facedir = self.facedir or 0
|
|
if self.facedir == 0 or self.facedir == 2 then
|
|
minetest.swap_node(pos, {name = "techage:ta1_watermill", param2 = 4})
|
|
M(pos):set_int("facedir", self.facedir)
|
|
minetest.get_node_timer(pos):start(2)
|
|
elseif self.facedir == 1 or self.facedir == 3 then
|
|
minetest.swap_node(pos, {name = "techage:ta1_watermill", param2 = 13})
|
|
M(pos):set_int("facedir", self.facedir)
|
|
minetest.get_node_timer(pos):start(2)
|
|
end
|
|
|
|
remove_nodes(pos, self.facedir)
|
|
self.object:remove()
|
|
end
|
|
|
|
local function trigger_consumer(pos, facedir)
|
|
local outdir = facedir + 1
|
|
local resp = techage.transfer(
|
|
pos,
|
|
outdir, -- outdir
|
|
"trigger", -- topic
|
|
nil, -- payload
|
|
techage.TA1Axle, -- network
|
|
nil) -- valid nodes
|
|
if not resp then
|
|
outdir = tubelib2.Turn180Deg[outdir]
|
|
resp = techage.transfer(
|
|
pos,
|
|
outdir, -- outdir
|
|
"trigger", -- topic
|
|
nil, -- payload
|
|
techage.TA1Axle, -- network
|
|
nil) -- valid nodes
|
|
end
|
|
end
|
|
|
|
minetest.register_node("techage:ta1_watermill", {
|
|
description = S("TA1 Watermill"),
|
|
tiles = {
|
|
-- up, down, right, left, back, front
|
|
"default_wood.png",
|
|
"default_wood.png",
|
|
"default_wood.png",
|
|
"default_wood.png",
|
|
"default_wood.png",
|
|
"default_wood.png",
|
|
},
|
|
drawtype = "nodebox",
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-1/2, -1/2, -1/2, 1/2, 1/2, 1/2},
|
|
|
|
{-4.5/2, -1/2, 0.8/2, 4.5/2, 1/2, 1.0/2},
|
|
{-4.5/2, -1/2, -1.0/2, 4.5/2, 1/2, -0.8/2},
|
|
{-3.8/2, -1/2, 2.1/2, 3.8/2, 1/2, 2.3/2},
|
|
{-3.8/2, -1/2, -2.3/2, 3.8/2, 1/2, -2.1/2},
|
|
|
|
{ 0.8/2, -1/2, -4.5/2, 1.0/2, 1/2, 4.5/2},
|
|
{-1.0/2, -1/2, -4.5/2, -0.8/2, 1/2, 4.5/2},
|
|
{ 2.1/2, -1/2, -3.8/2, 2.3/2, 1/2, 3.8/2},
|
|
{-2.3/2, -1/2, -3.8/2, -2.1/2, 1/2, 3.8/2},
|
|
},
|
|
},
|
|
on_rightclick = function(pos, node, clicker)
|
|
start_wheel(pos, M(pos):get_int("facedir"))
|
|
end,
|
|
|
|
on_timer = function(pos, elapsed)
|
|
local tRes = {}
|
|
if water_flowing(pos, M(pos):get_int("facedir"), tRes) then
|
|
start_wheel(pos, M(pos):get_int("facedir"), tRes.backward)
|
|
end
|
|
return true
|
|
end,
|
|
|
|
paramtype2 = "facedir",
|
|
paramtype = "light",
|
|
use_texture_alpha = techage.CLIP,
|
|
sunlight_propagates = true,
|
|
is_ground_content = false,
|
|
groups = {cracky = 2, crumbly = 2, choppy = 2, not_in_creative_inventory = 1},
|
|
node_placement_prediction = "",
|
|
drop = "techage:ta1_watermill_inv",
|
|
})
|
|
|
|
-- A smaller one for the inventory
|
|
minetest.register_node("techage:ta1_watermill_inv", {
|
|
description = S("TA1 Watermill"),
|
|
--inventory_image = "techage_waterwheel_inv.png",
|
|
--wield_image = "techage_waterwheel_inv.png",
|
|
tiles = {
|
|
-- up, down, right, left, back, front
|
|
"default_wood.png",
|
|
"default_wood.png",
|
|
"default_wood.png",
|
|
"default_wood.png",
|
|
"default_wood.png",
|
|
"default_wood.png",
|
|
},
|
|
drawtype = "nodebox",
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-1/4, -1/4, -1/4, 1/4, 1/4, 1/4},
|
|
|
|
{-4.5/4, 0.8/4, -1/4, 4.5/4, 1.0/4, 1/4},
|
|
{-4.5/4, -1.0/4, -1/4, 4.5/4, -0.8/4, 1/4},
|
|
{-3.8/4, 2.1/4, -1/4, 3.8/4, 2.3/4, 1/4},
|
|
{-3.8/4, -2.3/4, -1/4, 3.8/4, -2.1/4, 1/4},
|
|
|
|
{ 0.8/4, -4.5/4, -1/4, 1.0/4, 4.5/4, 1/4},
|
|
{-1.0/4, -4.5/4, -1/4, -0.8/4, 4.5/4, 1/4},
|
|
{ 2.1/4, -3.8/4, -1/4, 2.3/4, 3.8/4, 1/4},
|
|
{-2.3/4, -3.8/4, -1/4, -2.1/4, 3.8/4, 1/4},
|
|
},
|
|
},
|
|
|
|
after_place_node = function(pos, placer)
|
|
local node = minetest.get_node(pos)
|
|
M(pos):set_int("facedir", node.param2)
|
|
remove_nodes(pos, node.param2)
|
|
if (node.param2 == 0 or node.param2 == 2) and enough_space(pos, node.param2) then
|
|
minetest.swap_node(pos, {name = "techage:ta1_watermill", param2 = 4})
|
|
minetest.get_node_timer(pos):start(2)
|
|
elseif (node.param2 == 1 or node.param2 == 3) and enough_space(pos, node.param2) then
|
|
minetest.swap_node(pos, {name = "techage:ta1_watermill", param2 = 13})
|
|
minetest.get_node_timer(pos):start(2)
|
|
else
|
|
minetest.remove_node(pos)
|
|
return true
|
|
end
|
|
end,
|
|
|
|
paramtype2 = "facedir",
|
|
node_placement_prediction = "",
|
|
diggable = false,
|
|
})
|
|
|
|
techage.register_node({"techage:ta1_watermill"}, {
|
|
on_node_load = function(pos, node)
|
|
minetest.get_node_timer(pos):start(2)
|
|
end,
|
|
})
|
|
|
|
|
|
minetest.register_entity("techage:ta1_watermill_entity", {
|
|
initial_properties = {
|
|
physical = true,
|
|
collisionbox = {-0.5, -1.5, -1.5, 0.5, 1.5, 1.5},
|
|
visual = "wielditem",
|
|
wield_item = "techage:ta1_watermill",
|
|
visual_size = {x=0.67, y=0.67, z=0.67},
|
|
static_save = true,
|
|
automatic_rotate = -math.pi * 0.2,
|
|
pointable = false,
|
|
},
|
|
|
|
on_step = function(self, dtime)
|
|
self.dtime = (self.dtime or 0) + dtime
|
|
|
|
if self.dtime > 2 then
|
|
self.dtime = 0
|
|
local pos = vector.round(self.object:get_pos())
|
|
if not water_flowing(pos, self.facedir, {}) then
|
|
stop_wheel(pos, self)
|
|
end
|
|
trigger_consumer(pos, self.facedir)
|
|
minetest.sound_play("techage_watermill", {gain = 0.5, pos = pos,
|
|
max_hear_distance = 10}, true)
|
|
end
|
|
end,
|
|
|
|
on_rightclick = function(self, clicker)
|
|
local pos = vector.round(self.object:get_pos())
|
|
stop_wheel(pos, self)
|
|
end,
|
|
|
|
on_activate = function(self, staticdata)
|
|
self.facedir = tonumber(staticdata) or 0
|
|
end,
|
|
|
|
get_staticdata = function(self)
|
|
return self.facedir
|
|
end,
|
|
})
|
|
|
|
minetest.register_node("techage:water_stop", {
|
|
description = "Water Stop",
|
|
drawtype = "glasslike_framed_optional",
|
|
tiles = {"techage_invisible.png"},
|
|
inventory_image = 'techage_invisible_inv.png',
|
|
|
|
use_texture_alpha = "blend",
|
|
paramtype = "light",
|
|
walkable = false,
|
|
pointable = false,
|
|
diggable = false,
|
|
buildable_to = true,
|
|
sunlight_propagates = true,
|
|
is_ground_content = false,
|
|
groups = {cracky = 3, oddly_breakable_by_hand = 3},
|
|
sounds = default.node_sound_glass_defaults(),
|
|
drop = "",
|
|
})
|
|
|
|
minetest.register_craft({
|
|
output = "techage:ta1_watermill_inv",
|
|
recipe = {
|
|
{"techage:ta1_board1_apple", "techage:ta1_board1_apple", "techage:ta1_board1_apple"},
|
|
{"techage:ta1_board1_apple", "default:wood", "techage:ta1_board1_apple"},
|
|
{"techage:ta1_board1_apple", "techage:ta1_board1_apple", "techage:ta1_board1_apple"},
|
|
},
|
|
})
|