Add nametag support to mobs

This commit is contained in:
Wuzzy 2024-05-22 17:56:25 +02:00
parent 31662dc440
commit a8f44c7bb6
4 changed files with 81 additions and 10 deletions

View File

@ -7,6 +7,8 @@ rp_label = {}
-- Maximum length of the name of a named node (e.g. with label)
local NAMED_NODE_MAX_TEXT_LENGTH = 40
local mod_mobs = minetest.get_modpath("rp_mobs") ~= nil
local form_label = ""
form_label = form_label .. rp_formspec.default.version
form_label = form_label .. "size[8.5,4.5]"
@ -16,6 +18,7 @@ form_label = form_label .. rp_formspec.button_exit(2.75, 3, 3, 1, "", minetest.f
rp_formspec.register_page("rp_label:label", form_label)
local active_posses = {}
local active_objects = {}
rp_label.container_label_formspec_element = function(meta)
local name = meta:get_string("name")
@ -28,8 +31,7 @@ rp_label.container_label_formspec_element = function(meta)
return form
end
-- Assign a name to a node
rp_label.write_name = function(pos, text)
local restrict_text = function(text)
-- Discard everything after the first newline or carriage return
local tsplit = string.split(text, "\n", nil, 1)
if #tsplit >= 1 then
@ -40,9 +42,16 @@ rp_label.write_name = function(pos, text)
text = tsplit[1]
end
-- Limit name length
-- Limit text length
text = string.sub(text, 1, NAMED_NODE_MAX_TEXT_LENGTH)
return text
end
-- Assign a name to a node
rp_label.write_name = function(pos, text)
text = restrict_text(text)
local node = minetest.get_node(pos)
local def
if minetest.registered_nodes[node.name] then
@ -61,6 +70,29 @@ local write = function(itemstack, player, pointed_thing)
if util.handle_node_protection(player, pointed_thing) then
return itemstack
end
if pointed_thing.type == "object" then
if not mod_mobs then
return itemstack
end
local obj = pointed_thing.ref
local lua = obj:get_luaentity()
if lua and lua._cmi_is_mob then
local text = rp_mobs.get_nametag(lua)
local form = rp_formspec.get_page("rp_label:label")
form = form .. "field[1,1.5;6.5,0.5;text;;"..minetest.formspec_escape(text).."]"
form = form .. "set_focus[text;true]"
minetest.show_formspec(player:get_player_name(), "rp_label:label", form)
active_objects[player:get_player_name()] = obj
if not minetest.is_creative_enabled(player:get_player_name()) then
itemstack:take_item()
end
end
return itemstack
end
if pointed_thing.type ~= "node" then
return itemstack
end
@ -90,7 +122,7 @@ minetest.register_craftitem(
"rp_label:label",
{
description = S("Label and Graphite"),
_tt_help = S("Give a name to containers"),
_tt_help = S("Give a name to a container or creature"),
inventory_image = "rp_label_label.png",
wield_image = "rp_label_label.png",
on_use = write,
@ -100,18 +132,30 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "rp_label:label" then
return
end
local pname = player:get_player_name()
if fields.text then
local pos = active_posses[player:get_player_name()]
local pos = active_posses[pname]
if pos then
rp_label.write_name(pos, fields.text)
elseif mod_mobs then
local obj = active_objects[pname]
if obj then
local lua = obj:get_luaentity()
if lua and lua._cmi_is_mob then
local text = restrict_text(fields.text)
rp_mobs.set_nametag(lua, text)
end
end
end
elseif fields.quit then
active_posses[player:get_player_name()] = nil
active_posses[pname] = nil
active_objects[pname] = nil
end
end)
minetest.register_on_leaveplayer(function(player)
active_posses[player:get_player_name()] = nil
active_objects[player:get_player_name()] = nil
end)

View File

@ -1,3 +1,3 @@
name = rp_label
description = Labels to give names to containers like chests
description = Labels to give names to containers and mobs
depends = rp_util, rp_formspec, rp_crafting

View File

@ -875,6 +875,20 @@ Make a mob play its “hurt” sound. The pitch will be slightly randomized. Chi
### Nametag functions
The nametag is a HUD text above the head of the mob.
#### `rp_mobs.set_nametag(mob, nametag)`
Set nametag text of mob to `nametag`.
#### `rp_mobs.get_nametag(mob)`
Get nametag text of `mob`.
### Event functions
#### `rp_mobs.register_on_die(callback)`

View File

@ -18,6 +18,9 @@ local DYING_TIME = 2
-- Default texture modifier when mob takes damage
local DAMAGE_TEXTURE_MODIFIER = "^[colorize:#df2222:180"
-- Text color for mob nametags
local NAMETAG_COLOR = { r = 0, g = 255, b = 0, a = 255 }
rp_mobs.GRAVITY_VECTOR = vector.new(0, -GRAVITY, 0)
rp_mobs.internal.add_persisted_entity_vars({
@ -27,6 +30,7 @@ rp_mobs.internal.add_persisted_entity_vars({
"_killer_player_name", -- if mob was killed by a player, this contains their name. Otherwise nil
"_textures_adult", -- persisted textures of mob in adult state
"_textures_child", -- persisted textures of mob in child state
"_name", -- persisted mob name (for nametag)
})
local microtask_to_string = function(microtask)
@ -241,6 +245,12 @@ rp_mobs.restore_state = function(self, staticdata)
makes_footstep_sound = false,
})
end
if self._name and type(self._name) == "string" then
self.object:set_nametag_attributes({
text = self._name,
color = NAMETAG_COLOR,
})
end
-- Make sure the custom state vars are always tables
if not self._custom_state then
@ -824,12 +834,15 @@ rp_mobs.drag = function(self, dtime, drag, drag_axes)
end
rp_mobs.set_nametag = function(self, nametag)
self.object:set_properties({nametag=nametag})
self._name = nametag
self.object:set_nametag_attributes({
text = self._name,
color = NAMETAG_COLOR,
})
end
rp_mobs.get_nametag = function(self)
local props = self.object:get_properties()
return props.nametag
return self._name or ""
end
minetest.register_on_chatcommand(function(name, command, params)