Browse Source

Item meta pointing range (#14347)

cx384 1 month ago
parent
commit
234b01a8c2

+ 1 - 0
builtin/game/features.lua

@@ -38,6 +38,7 @@ core.features = {
 	dynamic_add_media_startup = true,
 	dynamic_add_media_filepath = true,
 	lsystem_decoration_type = true,
+	item_meta_range = true,
 }
 
 function core.has_feature(arg)

+ 5 - 0
doc/lua_api.md

@@ -2560,6 +2560,8 @@ Some of the values in the key-value store are handled specially:
   0 = default, 1 = left / up, 2 = middle, 3 = right / down
   The default currently is the same as right/down.
   Example: 6 = 2 + 1*4 = middle,up
+* `range`: Overrides the pointing range
+  Example: `meta:set_float("range", 4.2)`
 
 Example:
 
@@ -5397,6 +5399,8 @@ Utilities
       dynamic_add_media_filepath = true,
        -- L-system decoration type (5.9.0)
       lsystem_decoration_type = true,
+      -- Overrideable pointing range using the itemstack meta key `"range"` (5.9.0)
+      item_meta_range = true,
   }
   ```
 
@@ -8980,6 +8984,7 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
 
     range = 4.0,
     -- Range of node and object pointing that is possible with this item held
+    -- Can be overridden with itemstack meta.
 
     liquids_pointable = false,
     -- If true, item can point to all liquid nodes (`liquidtype ~= "none"`),

+ 15 - 0
games/devtest/mods/testitems/init.lua

@@ -90,3 +90,18 @@ minetest.register_craftitem("testitems:image_meta", {
 		return itemstack
 	end,
 })
+
+minetest.register_craftitem("testitems:telescope_stick", {
+	description = S("Telescope Stick (Increases range on use.)"),
+	inventory_image = "testitems_telescope_stick.png",
+	on_use = function(itemstack, player)
+		local meta = itemstack:get_meta()
+		local range = meta:get_float("range") + 1.2
+		if range > 10 then
+			range = 0
+		end
+		meta:set_float("range", range)
+		minetest.chat_send_player(player:get_player_name(), "Telescope Stick range set to "..range)
+		return itemstack
+	end,
+})

BIN
games/devtest/mods/testitems/textures/testitems_telescope_stick.png


+ 2 - 2
src/client/game.cpp

@@ -1384,7 +1384,7 @@ void Game::copyServerClientCache()
 {
 	// It would be possible to let the client directly read the media files
 	// from where the server knows they are. But aside from being more complicated
-	// it would also *not* fill the media cache and cause slower joining of
+	// it would also *not* fill the media cache and cause slower joining of 
 	// remote servers.
 	// (Imagine that you launch a game once locally and then connect to a server.)
 
@@ -3233,7 +3233,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
 	const ItemStack &tool_item = player->getWieldedItem(&selected_item, &hand_item);
 
 	const ItemDefinition &selected_def = selected_item.getDefinition(itemdef_manager);
-	f32 d = getToolRange(selected_def, hand_item.getDefinition(itemdef_manager));
+	f32 d = getToolRange(selected_item, hand_item, itemdef_manager);
 
 	core::line3d<f32> shootline;
 

+ 1 - 2
src/network/serverpackethandler.cpp

@@ -895,8 +895,7 @@ bool Server::checkInteractDistance(RemotePlayer *player, const f32 d, const std:
 {
 	ItemStack selected_item, hand_item;
 	player->getWieldedItem(&selected_item, &hand_item);
-	f32 max_d = BS * getToolRange(selected_item.getDefinition(m_itemdef),
-			hand_item.getDefinition(m_itemdef));
+	f32 max_d = BS * getToolRange(selected_item, hand_item, m_itemdef);
 
 	// Cube diagonal * 1.5 for maximal supported node extents:
 	// sqrt(3) * 1.5 ≅ 2.6

+ 11 - 5
src/tool.cpp

@@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/hex.h"
 #include "common/c_content.h"
 #include <json/json.h>
-	
+
 
 void ToolGroupCap::toJson(Json::Value &object) const
 {
@@ -246,7 +246,7 @@ std::optional<WearBarParams> WearBarParams::deserializeJson(std::istream &is)
 		blend = static_cast<WearBarParams::BlendMode>(blendInt);
 	else
 		return std::nullopt;
-	
+
 	const Json::Value &color_stops_object = root["color_stops"];
 	std::map<f32, video::SColor> colorStops;
 	for (const std::string &key : color_stops_object.getMemberNames()) {
@@ -491,10 +491,16 @@ PunchDamageResult getPunchDamage(
 	return result;
 }
 
-f32 getToolRange(const ItemDefinition &def_selected, const ItemDefinition &def_hand)
+f32 getToolRange(const ItemStack &wielded_item, const ItemStack &hand_item,
+		const IItemDefManager *itemdef_manager)
 {
-	float max_d = def_selected.range;
-	float max_d_hand = def_hand.range;
+	const std::string &wielded_meta_range = wielded_item.metadata.getString("range");
+	const std::string &hand_meta_range = hand_item.metadata.getString("range");
+
+	f32 max_d = wielded_meta_range.empty() ? wielded_item.getDefinition(itemdef_manager).range :
+			stof(wielded_meta_range);
+	f32 max_d_hand = hand_meta_range.empty() ? hand_item.getDefinition(itemdef_manager).range :
+			stof(hand_meta_range);
 
 	if (max_d < 0 && max_d_hand >= 0)
 		max_d = max_d_hand;

+ 3 - 1
src/tool.h

@@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <optional>
 
 struct ItemDefinition;
+class IItemDefManager;
 
 struct ToolGroupCap
 {
@@ -179,4 +180,5 @@ PunchDamageResult getPunchDamage(
 );
 
 u32 calculateResultWear(const u32 uses, const u16 initial_wear);
-f32 getToolRange(const ItemDefinition &def_selected, const ItemDefinition &def_hand);
+f32 getToolRange(const ItemStack &wielded_item, const ItemStack &hand_item,
+		const IItemDefManager *itemdef_manager);