Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions mods/drawers/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,26 @@ function drawers.register_drawer(name, def)
def.on_metadata_inventory_put = drawers.add_drawer_upgrade
def.on_metadata_inventory_take = drawers.remove_drawer_upgrade

if minetest.get_modpath 'screwdriver' and screwdriver then def.on_rotate = def.on_rotate or screwdriver.disallow end
if minetest.get_modpath 'screwdriver' and screwdriver then
def.on_rotate = function(pos, node, user, mode, new_param2)
if mode ~= screwdriver.ROTATE_FACE then
return false
end

local rotation = node.param2 % 32
local color_bits = node.param2 - rotation
local new_rotation = (rotation + 1) % 4

node.param2 = color_bits + new_rotation
minetest.swap_node(pos, node)

-- Respawn visuals with new rotation
drawers.remove_visuals(pos)
drawers.spawn_visuals(pos)

return true
end
end

if minetest.get_modpath 'pipeworks' and pipeworks then
def.groups.tubedevice = 1
Expand Down Expand Up @@ -411,4 +430,4 @@ function drawers.register_drawer_upgrade(name, def)
}
template = name
end
end
end
81 changes: 77 additions & 4 deletions mods/sbz_pipeworks/autoplace_tubes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,58 @@ local function nodeside(node, tubedir)
local right = vector.dot(rightdir, tubedir)
if right == 1 then
return "right"
else
elseif right == -1 then
return "left"
end

-- Fallback with a warning for inapplicable values
-- (e.g. one that produces a direction not aligned to any axis).
core.log("warning", "[pipeworks] nodeside: unexpected tubedir, defaulting to left. " ..
"node.param2=" .. tostring(node.param2) ..
" tubedir=" .. minetest.pos_to_string(tubedir))
return "left"
end

-- Convert camera yaw and pitch to the nearest facedir param2 value.

-- Degrees start at 0 facing North, increasing while turning counter-clockwise (if looking down from above):
-- 0 = looking toward +Z (North)
-- π/2 = looking toward -X (West)
-- π = looking toward -Z (South)
-- 3π/2 = looking toward +X (East)
--
local function look_to_facedir(yaw, pitch)
-- Vertical placement threshold (directionality favors yaw, but allows pitch)
local limit = math.pi * 0.40 -- ≈ 72°

-- Looking up means node faces down
if pitch > limit then
return 0
elseif pitch < -limit then
return 20
end

-- Round yaw to nearest 90° sector.
-- Normalise to [0, 2π) first so the modulo is well-defined.
yaw = yaw % (2 * math.pi)
local sector = math.floor(yaw / (math.pi / 2) + 0.5) % 4

-- Map sector index to facedir param2.
-- Sector 0 (yaw ≈ 0): looking toward +Z (North) | param2 as 2 would make node face North
-- Sector 1 (yaw ≈ π/2): looking toward -X (West) | param2 as 1 would make node face West
-- Sector 2 (yaw ≈ π): looking toward -Z (South) | param2 as 0 would make node face South
-- Sector 3 (yaw ≈ 3π/2):looking toward +X (East) | param2 as 3 would make node face East

-- Use opposite angles instead so that it faces camera
return ({ [0] = 0, 3, 2, 1 })[sector] -- node mirrors (not matches) camera angle when placed
end

local function yaw_to_4dir(yaw)
yaw = yaw % (2 * math.pi)
local sector = math.floor(yaw / (math.pi / 2) + 0.5) % 4

-- Map yaw sectors to 4dir param2
return ({ [0] = 0, 3, 2, 1 })[sector]
end

local vts = { 0, 3, 1, 4, 2, 5 }
Expand Down Expand Up @@ -100,13 +149,37 @@ local function tube_autoroute(pos)
end

function pipeworks.scan_for_tube_objects(pos)
for side = 0, 6 do
for side = 1, 6 do
tube_autoroute(vector.add(pos, pipeworks.directions.side_to_dir(side)))
end
end

function pipeworks.after_place(pos)
pipeworks.scan_for_tube_objects(pos)
-- FIX: after_place previously saved original_param2, called scan_for_tube_objects
-- (which skipped autorouting pos itself), then restored original_param2 — but that
-- restoration was misguided because:
-- 1. The placed node IS a tube and SHOULD be autorouted like any other tube.
-- 2. Neighbours were updated while seeing whatever param2 the node happened to
-- have at placement time, which may not match the final autorouted state.

function pipeworks.after_place(pos, placer)
if placer and placer.get_look_horizontal then
local node = minetest.get_node(pos)
local def = minetest.registered_nodes[node.name]

local yaw = placer:get_look_horizontal()
local pitch = placer.get_look_vertical and placer:get_look_vertical() or 0

if def.paramtype2 == "4dir" then
node.param2 = yaw_to_4dir(yaw)
elseif def.paramtype2 == "facedir" then
node.param2 = look_to_facedir(yaw, pitch)
end

minetest.swap_node(pos, node)
end

tube_autoroute(pos)
pipeworks.scan_for_tube_objects(pos)
end

function pipeworks.after_dig(pos)
Expand Down
4 changes: 3 additions & 1 deletion mods/sbz_pipeworks/basic_tubes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,9 @@ minetest.register_node('pipeworks:one_way_tube', {
end,
priority = 75, -- Higher than normal tubes, but lower than receivers
},
after_place_node = pipeworks.after_place,
after_place_node = function(pos)
pipeworks.scan_for_tube_objects(pos)
end,
after_dig_node = pipeworks.after_dig,
on_rotate = pipeworks.on_rotate,
})
Expand Down
14 changes: 13 additions & 1 deletion mods/sbz_pipeworks/wielder.lua
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ function pipeworks.register_wielder(def)

-- Rotate to face the clicked block
local dir = vector.subtract(pointed_thing.above, pointed_thing.under)

-- Flip direction if this wielder should face away
if def.place_facing == "away" then
dir = vector.multiply(dir, -1)
end

local param2 = minetest.dir_to_facedir(dir, true)

local node = minetest.get_node(pos)
Expand Down Expand Up @@ -229,6 +235,7 @@ function pipeworks.register_wielder(def)
})
end

-- Nodebreaker faces away from clicked block side when placed.
pipeworks.register_wielder {
name = 'pipeworks:nodebreaker',
description = S 'Node Breaker',
Expand All @@ -241,6 +248,7 @@ pipeworks.register_wielder {
'nodebreaker_front.png',
},
connect_sides = { top = 1, bottom = 1, left = 1, right = 1, back = 1 },
place_facing = "away",
wield_inv = { name = 'pick', width = 1, height = 1 },
wield_hand = true,
eject_drops = true,
Expand Down Expand Up @@ -291,6 +299,7 @@ pipeworks.register_wielder {
cost = 20,
}

-- Deployer faces away from clicked block side when placed.
pipeworks.register_wielder {
name = 'pipeworks:deployer',
description = S 'Deployer',
Expand All @@ -302,6 +311,7 @@ pipeworks.register_wielder {
'deployer_back.png',
'deployer_front.png',
},
place_facing = "away",
wield_inv = { name = 'main', width = 3, height = 3 },
connect_sides = { back = 1 },
action = function(fakeplayer, pointed)
Expand All @@ -321,6 +331,7 @@ pipeworks.register_wielder {
cost = 20,
}

-- Puncher faces toward clicked block side when placed.
pipeworks.register_wielder {
name = 'pipeworks:puncher',
description = S 'Puncher',
Expand All @@ -332,6 +343,7 @@ pipeworks.register_wielder {
'interactor_bottom.png', -- back
'interactor_top.png', -- front
},
place_facing = "toward",
wield_inv = { name = 'pick', width = 1, height = 1 },
connect_sides = { top = 1, bottom = 1, left = 1, right = 1, back = 1 },
wield_hand = true,
Expand Down Expand Up @@ -403,4 +415,4 @@ do
{ I, I, I },
},
})
end
end
23 changes: 22 additions & 1 deletion mods/sbz_resources/storinators.lua
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,27 @@ local function register_storinator(added_name, def)
def_copy.on_metadata_inventory_move = update_node_texture
def_copy.info_extra = def_copy.slots .. " Slots"

def_copy.on_rotate = function(pos, node, user, mode, new_param2)
-- Only handle the 'Face' rotation (Left Click)
if mode ~= screwdriver.ROTATE_FACE then
return false
end

-- 1. Isolate the rotation (first 5 bits) and the color (everything else)
local rotation = node.param2 % 32
local color_bits = node.param2 - rotation

-- 2. Manually cycle through the 4 horizontal directions (0, 1, 2, 3)
-- This makes it behave exactly like the Crystal Grower
local new_rotation = (rotation + 1) % 4

-- 3. Re-combine and apply
node.param2 = color_bits + new_rotation
minetest.swap_node(pos, node)

return true -- Tells the screwdriver we handled it!
end

local dropname = "sbz_resources:storinator"
if #added_name ~= 0 then
dropname = dropname .. "_" .. added_name
Expand Down Expand Up @@ -303,4 +324,4 @@ minetest.register_craft({
{ "sbz_resources:matter_plate", "sbz_resources:simple_circuit", "sbz_resources:matter_plate" },
{ "sbz_resources:retaining_circuit", "sbz_resources:matter_plate", "sbz_resources:retaining_circuit" }
}
})
})