Skip to content

Commit

Permalink
Tool specific pointing and blocking pointable type (#13992)
Browse files Browse the repository at this point in the history
  • Loading branch information
cx384 committed Jan 22, 2024
1 parent fb461d2 commit 5958714
Show file tree
Hide file tree
Showing 39 changed files with 676 additions and 67 deletions.
2 changes: 2 additions & 0 deletions builtin/game/features.lua
Expand Up @@ -33,6 +33,8 @@ core.features = {
random_state_restore = true,
after_order_expiry_registration = true,
wallmounted_rotate = true,
item_specific_pointabilities = true,
blocking_pointability_type = true,
}

function core.has_feature(arg)
Expand Down
35 changes: 33 additions & 2 deletions doc/lua_api.md
Expand Up @@ -5298,6 +5298,10 @@ Utilities
-- wallmounted nodes mounted at floor or ceiling may additionally
-- be rotated by 90° with special param2 values (5.9.0)
wallmounted_rotate = true,
-- Availability of the `pointabilities` property in the item definition (5.9.0)
item_specific_pointabilities = true,
-- Nodes `pointable` property can be `"blocking"` (5.9.0)
blocking_pointability_type = true,
}
```

Expand Down Expand Up @@ -8382,7 +8386,9 @@ Player properties need to be saved manually.


pointable = true,
-- Whether the object can be pointed at
-- Can be `true` if it is pointable, `false` if it can be pointed through,
-- or `"blocking"` if it is pointable but not selectable.
-- Can be overridden by the `pointabilities` of the held item.

visual = "cube" / "sprite" / "upright_sprite" / "mesh" / "wielditem" / "item",
-- "cube" is a node-sized cube.
Expand Down Expand Up @@ -8746,6 +8752,27 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
-- If true, item can point to all liquid nodes (`liquidtype ~= "none"`),
-- even those for which `pointable = false`

pointabilities = {
nodes = {
["default:stone"] = "blocking",
["group:leaves"] = false,
},
objects = {
["modname:entityname"] = true,
["group:ghosty"] = true, -- (an armor group)
}
},
-- Contains lists to override the `pointable` property of pointed nodes and objects.
-- The index can be a node/entity name or a group with the prefix `"group:"`.
-- (For objects `armor_groups` are used and for players the entity name is irrelevant.)
-- If multiple fields fit, the following priority order is applied:
-- value of matching node/entity name
-- `true` for any group
-- `false` for any group
-- `"blocking"` for any group
-- `liquids_pointable` if it is a liquid node
-- `pointable` property of the node or object

light_source = 0,
-- When used for nodes: Defines amount of light emitted by node.
-- Otherwise: Defines texture glow when viewed as a dropped item
Expand Down Expand Up @@ -8971,7 +8998,11 @@ Used by `minetest.register_node`.

walkable = true, -- If true, objects collide with node

pointable = true, -- If true, can be pointed at
pointable = true,
-- Can be `true` if it is pointable, `false` if it can be pointed through,
-- or `"blocking"` if it is pointable but not selectable.
-- Can be overridden by the `pointabilities` of the held item.
-- A client may be able to point non-pointable nodes, since it isn't checked server-side.

diggable = true, -- If false, can never be dug

Expand Down
1 change: 1 addition & 0 deletions games/devtest/mods/testentities/init.lua
@@ -1,3 +1,4 @@
dofile(minetest.get_modpath("testentities").."/visuals.lua")
dofile(minetest.get_modpath("testentities").."/selectionbox.lua")
dofile(minetest.get_modpath("testentities").."/armor.lua")
dofile(minetest.get_modpath("testentities").."/pointable.lua")
23 changes: 23 additions & 0 deletions games/devtest/mods/testentities/pointable.lua
@@ -0,0 +1,23 @@
-- Pointability test Entities

-- Register wrapper for compactness
local function register_pointable_testentity(name, pointable)
local texture = "testnodes_"..name..".png"
minetest.register_entity("testentities:"..name, {
initial_properties = {
visual = "cube",
visual_size = {x = 0.6, y = 0.6, z = 0.6},
textures = {
texture, texture, texture, texture, texture, texture
},
pointable = pointable,
},
on_activate = function(self)
self.object:set_armor_groups({[name.."_test"] = 1})
end
})
end

register_pointable_testentity("pointable", true)
register_pointable_testentity("not_pointable", false)
register_pointable_testentity("blocking_pointable", "blocking")
20 changes: 20 additions & 0 deletions games/devtest/mods/testnodes/properties.lua
Expand Up @@ -663,3 +663,23 @@ minetest.register_node("testnodes:post_effect_color_shaded_true", {
is_ground_content = false,
groups = {dig_immediate=3},
})

-- Pointability

-- Register wrapper for compactness
local function register_pointable_test_node(name, description, pointable)
local texture = "testnodes_"..name..".png"
minetest.register_node("testnodes:"..name, {
description = S(description),
tiles = {texture},
drawtype = "glasslike_framed",
paramtype = "light",
walkable = false,
pointable = pointable,
groups = {dig_immediate=3, [name.."_test"]=1},
})
end

register_pointable_test_node("pointable", "Pointable Node", true)
register_pointable_test_node("not_pointable", "Not Pointable Node", false)
register_pointable_test_node("blocking_pointable", "Blocking Pointable Node", "blocking")
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 66 additions & 0 deletions games/devtest/mods/testtools/init.lua
Expand Up @@ -7,6 +7,20 @@ dofile(minetest.get_modpath("testtools") .. "/light.lua")
dofile(minetest.get_modpath("testtools") .. "/privatizer.lua")
dofile(minetest.get_modpath("testtools") .. "/particles.lua")

local pointabilities_nodes = {
nodes = {
["group:blocking_pointable_test"] = true,
["group:not_pointable_test"] = true,
},
}

local pointabilities_objects = {
objects = {
["group:blocking_pointable_test"] = true,
["group:not_pointable_test"] = true,
},
}

minetest.register_tool("testtools:param2tool", {
description = S("Param2 Tool") .."\n"..
S("Modify param2 value of nodes") .."\n"..
Expand All @@ -16,6 +30,7 @@ minetest.register_tool("testtools:param2tool", {
S("Sneak+Place: -8"),
inventory_image = "testtools_param2tool.png",
groups = { testtool = 1, disable_repair = 1 },
pointabilities = pointabilities_nodes,
on_use = function(itemstack, user, pointed_thing)
local pos = minetest.get_pointed_thing_position(pointed_thing)
if pointed_thing.type ~= "node" or (not pos) then
Expand Down Expand Up @@ -58,6 +73,7 @@ minetest.register_tool("testtools:node_setter", {
S("Place in air: Manually select a node"),
inventory_image = "testtools_node_setter.png",
groups = { testtool = 1, disable_repair = 1 },
pointabilities = pointabilities_nodes,
on_use = function(itemstack, user, pointed_thing)
local pos = minetest.get_pointed_thing_position(pointed_thing)
if pointed_thing.type == "nothing" then
Expand Down Expand Up @@ -118,6 +134,10 @@ minetest.register_tool("testtools:remover", {
S("Punch: Remove pointed node or object"),
inventory_image = "testtools_remover.png",
groups = { testtool = 1, disable_repair = 1 },
pointabilities = {
nodes = pointabilities_nodes.nodes,
objects = pointabilities_objects.objects,
},
on_use = function(itemstack, user, pointed_thing)
local pos = minetest.get_pointed_thing_position(pointed_thing)
if pointed_thing.type == "node" and pos ~= nil then
Expand All @@ -139,6 +159,7 @@ minetest.register_tool("testtools:falling_node_tool", {
S("Place: Move pointed node 2 units upwards, then make it fall"),
inventory_image = "testtools_falling_node_tool.png",
groups = { testtool = 1, disable_repair = 1 },
pointabilities = pointabilities_nodes,
on_place = function(itemstack, user, pointed_thing)
-- Teleport node 1-2 units upwards (if possible) and make it fall
local pos = minetest.get_pointed_thing_position(pointed_thing)
Expand Down Expand Up @@ -192,6 +213,7 @@ minetest.register_tool("testtools:rotator", {
S("Aux1+Punch: Roll"),
inventory_image = "testtools_entity_rotator.png",
groups = { testtool = 1, disable_repair = 1 },
pointabilities = pointabilities_objects,
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "object" then
return
Expand Down Expand Up @@ -250,6 +272,7 @@ minetest.register_tool("testtools:object_mover", {
S("Sneak+Place: Decrease distance"),
inventory_image = "testtools_object_mover.png",
groups = { testtool = 1, disable_repair = 1 },
pointabilities = pointabilities_objects,
on_place = mover_config,
on_secondary_use = mover_config,
on_use = function(itemstack, user, pointed_thing)
Expand Down Expand Up @@ -296,6 +319,7 @@ minetest.register_tool("testtools:entity_scaler", {
S("Sneak+Punch: Decrease scale"),
inventory_image = "testtools_entity_scaler.png",
groups = { testtool = 1, disable_repair = 1 },
pointabilities = pointabilities_objects,
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "object" then
return
Expand Down Expand Up @@ -355,6 +379,7 @@ minetest.register_tool("testtools:branding_iron", {
S("Devices that accept the returned name also accept \"player:<playername>\" for players."),
inventory_image = "testtools_branding_iron.png",
groups = { testtool = 1, disable_repair = 1 },
pointabilities = pointabilities_objects,
on_use = function(_itemstack, user, pointed_thing)
local obj
local msg
Expand Down Expand Up @@ -499,6 +524,7 @@ minetest.register_tool("testtools:object_editor", {
S("Punch air: Edit yourself"),
inventory_image = "testtools_object_editor.png",
groups = { testtool = 1, disable_repair = 1 },
pointabilities = pointabilities_objects,
on_use = function(itemstack, user, pointed_thing)
if user and user:is_player() then
local name = user:get_player_name()
Expand Down Expand Up @@ -586,6 +612,7 @@ minetest.register_tool("testtools:object_attacher", {
S("Aux1+Sneak+Place: Decrease attachment rotation"),
inventory_image = "testtools_object_attacher.png",
groups = { testtool = 1, disable_repair = 1 },
pointabilities = pointabilities_objects,
on_place = attacher_config,
on_secondary_use = attacher_config,
on_use = function(itemstack, user, pointed_thing)
Expand Down Expand Up @@ -679,6 +706,7 @@ minetest.register_tool("testtools:children_getter", {
S("Punch air to show your own 'children'"),
inventory_image = "testtools_children_getter.png",
groups = { testtool = 1, disable_repair = 1 },
pointabilities = pointabilities_objects,
on_use = function(itemstack, user, pointed_thing)
if user and user:is_player() then
local name = user:get_player_name()
Expand Down Expand Up @@ -998,3 +1026,41 @@ minetest.register_on_leaveplayer(function(player)
meta_latest_keylist[name] = nil
node_meta_posses[name] = nil
end)

-- Pointing Staffs

minetest.register_tool("testtools:blocked_pointing_staff", {
description = S("Blocked Pointing Staff").."\n"..
S("Can point the Blocking Pointable Node/Object and "..
"the Pointable Node/Object is point blocking."),
inventory_image = "testtools_blocked_pointing_staff.png",
pointabilities = {
nodes = {
["testnodes:blocking_pointable"] = true,
["group:pointable_test"] = "blocking"
},
objects = {
["testentities:blocking_pointable"] = true,
["group:pointable_test"] = "blocking"
}
}
})

minetest.register_tool("testtools:ultimate_pointing_staff", {
description = S("Ultimate Pointing Staff").."\n"..
S("Can point all pointable test nodes, objects and liquids."),
inventory_image = "testtools_ultimate_pointing_staff.png",
liquids_pointable = true,
pointabilities = {
nodes = {
["group:blocking_pointable_test"] = true,
["group:pointable_test"] = true,
["testnodes:not_pointable"] = true
},
objects = {
["group:blocking_pointable_test"] = true,
["group:pointable_test"] = true,
["testentities:not_pointable"] = true
}
}
})
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 19 additions & 4 deletions src/client/clientenvironment.cpp
Expand Up @@ -489,7 +489,8 @@ ClientEnvEvent ClientEnvironment::getClientEnvEvent()

void ClientEnvironment::getSelectedActiveObjects(
const core::line3d<f32> &shootline_on_map,
std::vector<PointedThing> &objects)
std::vector<PointedThing> &objects,
const std::optional<Pointabilities> &pointabilities)
{
auto allObjects = m_ao_manager.getActiveSelectableObjects(shootline_on_map);
const v3f line_vector = shootline_on_map.getVector();
Expand All @@ -516,9 +517,23 @@ void ClientEnvironment::getSelectedActiveObjects(
current_raw_normal = current_normal;
}
if (collision) {
current_intersection += obj->getPosition();
objects.emplace_back(obj->getId(), current_intersection, current_normal, current_raw_normal,
(current_intersection - shootline_on_map.start).getLengthSQ());
PointabilityType pointable;
if (pointabilities) {
if (gcao->isPlayer()) {
pointable = pointabilities->matchPlayer(gcao->getGroups()).value_or(
gcao->getProperties().pointable);
} else {
pointable = pointabilities->matchObject(gcao->getName(),
gcao->getGroups()).value_or(gcao->getProperties().pointable);
}
} else {
pointable = gcao->getProperties().pointable;
}
if (pointable != PointabilityType::POINTABLE_NOT) {
current_intersection += obj->getPosition();
objects.emplace_back(obj->getId(), current_intersection, current_normal, current_raw_normal,
(current_intersection - shootline_on_map.start).getLengthSQ(), pointable);
}
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/client/clientenvironment.h
Expand Up @@ -131,7 +131,8 @@ class ClientEnvironment : public Environment

virtual void getSelectedActiveObjects(
const core::line3d<f32> &shootline_on_map,
std::vector<PointedThing> &objects
std::vector<PointedThing> &objects,
const std::optional<Pointabilities> &pointabilities
);

const std::set<std::string> &getPlayerNames() { return m_player_names; }
Expand Down
3 changes: 1 addition & 2 deletions src/client/content_cao.cpp
Expand Up @@ -411,8 +411,7 @@ GenericCAO::~GenericCAO()

bool GenericCAO::getSelectionBox(aabb3f *toset) const
{
if (!m_prop.is_visible || !m_is_visible || m_is_local_player
|| !m_prop.pointable) {
if (!m_prop.is_visible || !m_is_visible || m_is_local_player) {
return false;
}
*toset = m_selection_box;
Expand Down
7 changes: 7 additions & 0 deletions src/client/content_cao.h
Expand Up @@ -174,6 +174,8 @@ class GenericCAO : public ClientActiveObject

inline const ObjectProperties &getProperties() const { return m_prop; }

inline const std::string &getName() const { return m_name; }

scene::ISceneNode *getSceneNode() const override;

scene::IAnimatedMeshSceneNode *getAnimatedMeshSceneNode() const override;
Expand Down Expand Up @@ -208,6 +210,11 @@ class GenericCAO : public ClientActiveObject
return m_is_local_player;
}

inline bool isPlayer() const
{
return m_is_player;
}

inline bool isVisible() const
{
return m_is_visible;
Expand Down
6 changes: 5 additions & 1 deletion src/client/game.cpp
Expand Up @@ -841,13 +841,15 @@ class Game {
* the camera position. This also gives the maximal distance
* of the search.
* @param[in] liquids_pointable if false, liquids are ignored
* @param[in] pointabilities item specific pointable overriding
* @param[in] look_for_object if false, objects are ignored
* @param[in] camera_offset offset of the camera
* @param[out] selected_object the selected object or
* NULL if not found
*/
PointedThing updatePointedThing(
const core::line3d<f32> &shootline, bool liquids_pointable,
const std::optional<Pointabilities> &pointabilities,
bool look_for_object, const v3s16 &camera_offset);
void handlePointingAtNothing(const ItemStack &playerItem);
void handlePointingAtNode(const PointedThing &pointed,
Expand Down Expand Up @@ -3343,6 +3345,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)

PointedThing pointed = updatePointedThing(shootline,
selected_def.liquids_pointable,
selected_def.pointabilities,
!runData.btn_down_for_dig,
camera_offset);

Expand Down Expand Up @@ -3454,6 +3457,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
PointedThing Game::updatePointedThing(
const core::line3d<f32> &shootline,
bool liquids_pointable,
const std::optional<Pointabilities> &pointabilities,
bool look_for_object,
const v3s16 &camera_offset)
{
Expand All @@ -3470,7 +3474,7 @@ PointedThing Game::updatePointedThing(
runData.selected_object = NULL;
hud->pointing_at_object = false;

RaycastState s(shootline, look_for_object, liquids_pointable);
RaycastState s(shootline, look_for_object, liquids_pointable, pointabilities);
PointedThing result;
env.continueRaycast(&s, &result);
if (result.type == POINTEDTHING_OBJECT) {
Expand Down

0 comments on commit 5958714

Please sign in to comment.