Skip to content

Commit

Permalink
Improve the placement logic for slabs, etc (#160)
Browse files Browse the repository at this point in the history
Co-authored-by: Hugo Locurcio <[email protected]>
  • Loading branch information
Oblomov and Calinou authored Dec 14, 2020
1 parent 5aacb05 commit ab91ad9
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 11 deletions.
23 changes: 13 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,24 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Added

- Clean Glass versions of Trap and (Super) Glowing Glass

### Removed

- Legacy Stairs+ conversion code.
- It was only required to import worlds last edited before Q3 2013.
- Clean Glass versions of Trap and (Super) Glowing Glass.
- Compressed desert cobblestone.

### Changed

- Switch to GitHub Actions.
- Benefits include faster responses.
- Revised placing strategy that takes into account which side of the face
(top/bottom for horizontal, left/right for vertical placement) is being clicked.
Aux (sprint/special, default E) key can be used to place the node with the orientation
it would have if placed from the other side.
When placing nodes next to nodes of the same gategory (e.g.slab to slab) the other
node's orientation is copied, flipping it placing on top or below an upright or
upside-down node. In this case the aux key will disable the special processing of
same-category nodes.

### Added
### Removed

- Compressed desert cobblestone.
- Legacy Stairs+ conversion code.
- It was only required to import worlds last edited before Q3 2013.

## [2.0.0] - 2019-11-25

Expand Down
93 changes: 92 additions & 1 deletion stairsplus/common.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,97 @@ local descriptions = {
["stair"] = S("%s Stairs"),
}

-- Extends the standad rotate_node placement so that it takes into account
-- the side (top/bottom or left/right) of the face being pointed at.
-- As with the standard rotate_node, sneak can be used to force the perpendicular
-- placement (wall placement on floor/ceiling, floor/ceiling placement on walls).
-- Additionally, the aux / sprint / special key can be used to place the node
-- as if from the opposite side.
--
-- When placing a node next to one of the same category (e.g. slab to slab or
-- stair to stair), the default placement (regardless of sneak) is to copy the
-- under node's param2, flipping if placed above or below it. The aux key disable
-- this behavior.
local wall_right_dirmap = {9, 18, 7, 12}
local wall_left_dirmap = {11, 16, 5, 14}
local ceil_dirmap = {20, 23, 22, 21}

stairsplus.rotate_node_aux = function(itemstack, placer, pointed_thing)
local sneak = placer and placer:get_player_control().sneak
local aux = placer and placer:get_player_control().aux1

-- namestring for what we are placing, up to the first _ (exclusive)
local item_prefix = itemstack:get_name():gsub("_.*$", "")
-- namestring for what we are placing against
local under = pointed_thing.under
local under_node = minetest.get_node(under)
local under_prefix = under_node and under_node.name:gsub("_.*$", "")

local same_cat = item_prefix == under_prefix

-- standard (floor) facedir, also used for sneak placement against the lower half of the wall
local p2 = placer and minetest.dir_to_facedir(placer:get_look_dir()) or 0

-- check which face and which quadrant we are interested in
-- this is used both to check if we're handling parallel placement in the same-category case,
-- and in general for sneak placement
local face_pos = minetest.pointed_thing_to_face_pos(placer, pointed_thing)
local face_off = vector.subtract(face_pos, under)
local wallmounted = minetest.dir_to_wallmounted(face_off)

if same_cat and not aux then
p2 = under_node.param2
-- flip if placing above or below an upright or upside-down node
-- TODO should we also flip when placing next to a side-mounted node?
if wallmounted < 2 then
if p2 < 4 then
p2 = (p2 + 2) % 4
p2 = ceil_dirmap[p2 + 1]
elseif p2 > 19 then
p2 = ceil_dirmap[p2 - 19] - 20
p2 = (p2 + 2) % 4
end
end
else
-- for same-cat placement, aux is used to disable param2 copying
if same_cat then
aux = not aux
end

local remap = nil

-- standard placement against the wall
local use_wallmap = (wallmounted > 1 and not sneak) or (wallmounted < 2 and sneak)

-- standard placement against the ceiling, or sneak placement against the upper half of the wall
local use_ceilmap = wallmounted == 1 and not sneak
use_ceilmap = use_ceilmap or (wallmounted > 1 and sneak and face_off.y > 0)

if use_wallmap then
local left = (p2 == 0 and face_off.x < 0) or
(p2 == 1 and face_off.z > 0) or
(p2 == 2 and face_off.x > 0) or
(p2 == 3 and face_off.z < 0)
if aux then
left = not left
end
remap = left and wall_left_dirmap or wall_right_dirmap
elseif use_ceilmap then
remap = ceil_dirmap
end

if aux then
p2 = (p2 + 2) % 4
end

if remap then
p2 = remap[p2 + 1]
end
end

return minetest.item_place(itemstack, placer, pointed_thing, p2)
end

stairsplus.register_single = function(category, alternate, info, modname, subname, recipeitem, fields)
local src_def = minetest.registered_nodes[recipeitem] or {}
local desc_base = descriptions[category]:format(fields.description)
Expand Down Expand Up @@ -42,7 +133,7 @@ stairsplus.register_single = function(category, alternate, info, modname, subnam
-- Darken light sources slightly to make up for their smaller visual size
def.light_source = math.max(0, (def.light_source or 0) - 1)

def.on_place = minetest.rotate_node
def.on_place = stairsplus.rotate_node_aux
def.groups = stairsplus:prepare_groups(fields.groups)

if category == "slab" then
Expand Down

0 comments on commit ab91ad9

Please sign in to comment.