Add mob tags

This commit is contained in:
Wuzzy 2024-03-18 15:04:47 +01:00
parent 4b0d537925
commit a4006464a1
12 changed files with 51 additions and 29 deletions

View File

@ -310,6 +310,18 @@ The field `_cmi_is_mob=true` will be set automatically for all mobs and can be u
* Built-in animations are:
* `"idle"`: Played when mob has nothing to do (empty task queue)
* `"dead_static"`: Played when mob is dead (no animation, just a static frame)
* `tags`: Table of tags.
* Tags are arbitrary strings used to logically categorize the mob.
* The table keys are tag names and value for each key must always be 1.
* You can check if a mob has a tag with `rp_mobs.has_tag` or `rp_mobs.mobdef_has_tag`.
* Built-in tag names:
* `"animal"`: This mob is an animal. Some items and achievements check for this tag
* `"peaceful"`: Mob is considered 'peaceful' towards players if unprovoked. It normally leaves
the player alone. Peaceful mobs may still turn hostile when provoked.
Mobs that start hostile towards the player do not count as peaceful.
If the setting `spawn_peaceful_only` is enabled, only mobs with this tag can spawn.
* Example: `tags = { animal = 1, peaceful = 1, exploder = 1 }`
* A peaceful animal, plus a custom `"exploder"` tag.
##### Drop table
@ -826,7 +838,18 @@ by a mob, usually on death, but it may also be used on other events.
The difference from `minetest.add_item` is that it adds some random velocity
so this is the recommended function to make a mob drop something.
#### `rp_mobs.has_tag(mob, tag_name)`
Returns true if mob has the given `tag_name` or false if not.
See `rp_mobs.register_mob` for for info about tags.
#### `rp_mobs.mobdef_has_tag(mob_name, tag_name)
Return true if the mob definition for the mob with the given `mob_name` exists
and has a tag with the given `tag_name`. Returns false otherwise.
See `rp_mobs.register_mob` for for info about tags.
## Appendix

View File

@ -78,7 +78,7 @@ rp_mobs.register_on_die(function(mob, killer)
end
end
end
if drops_food and killer ~= nil and killer:is_player() and mobdef.entity_definition._is_animal then
if drops_food and killer ~= nil and killer:is_player() and rp_mobs.has_tag(mob, "animal") then
achievements.trigger_achievement(killer, "hunter")
end
end)

View File

@ -4,13 +4,13 @@ local animals = {}
local animal_names = {}
minetest.register_on_mods_loaded(function()
for k,v in pairs(minetest.registered_entities) do
if v._cmi_is_mob and v._is_animal then
table.insert(animals, k)
if v._description then
table.insert(animal_names, v._description)
for mobname, mobdef in pairs(rp_mobs.registered_mobs) do
if mobdef._cmi_is_mob and rp_mobs.mobdef_has_tag(mobname, "animal") then
table.insert(animals, mobname)
if mobdef._description then
table.insert(animal_names, mobdef._description)
else
table.insert(animal_names, k)
table.insert(animal_names, mobname)
end
end
end

View File

@ -166,10 +166,7 @@ rp_mobs.register_mob = function(mobname, def)
mdef.entity_definition.initial_properties = initprop
mdef.entity_definition._cmi_is_mob = true
mdef.entity_definition._description = def.description
-- TODO: Put in a group-like system
mdef.entity_definition._is_animal = def.is_animal
-- TODO: Put in a group-like system
mdef.entity_definition._is_peaceful = def.is_peaceful
mdef.entity_definition._tags = table.copy(def.tags or {})
mdef.entity_definition._base_size = table.copy(initprop.visual_size or { x=1, y=1, z=1 })
mdef.entity_definition._base_selbox = table.copy(initprop.selectionbox or { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, rotate = false })
mdef.entity_definition._base_colbox = table.copy(initprop.collisionbox or { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5})
@ -203,6 +200,18 @@ rp_mobs.get_staticdata_default = function(self)
return staticdata
end
rp_mobs.has_tag = function(mob, tag_name)
return mob._tags[tag_name] == 1
end
rp_mobs.mobdef_has_tag = function(mobname, tag_name)
local mobdef = rp_mobs.registered_mobs[mobname]
if not mobdef then
return false
end
return mobdef._tags[tag_name] == 1
end
local flip_over_collisionbox = function(box, is_child, y_offset)
local off
if is_child then
@ -438,8 +447,7 @@ rp_mobs.init_tasks = function(self)
end
rp_mobs.init_mob = function(self)
local entdef = minetest.registered_entities[self.name]
if setting_peaceful_only and not entdef._is_peaceful then
if setting_peaceful_only and not rp_mobs.has_tag(self, "peaceful") then
self.object:remove()
minetest.log("action", "[mobs] Hostile mob '"..self.name.."' removed at "..minetest.pos_to_string(self.object:get_pos(), 1).." (only peaceful mobs allowed)")
return
@ -703,7 +711,7 @@ rp_mobs.register_mob_item = function(mobname, invimg, desc, on_create_capture_it
groups = { spawn_egg = 1 },
stack_max = 1,
on_place = function(itemstack, placer, pointed_thing)
if setting_peaceful_only and not entdef._is_peaceful then
if setting_peaceful_only and not rp_mobs.mobdef_has_tag(mobname, "peaceful") then
if placer and placer:is_player() then
local pname = placer:get_player_name()
minetest.chat_send_player(pname, minetest.colorize("#FFFF00", S("Hostile mobs are disabled!")))

View File

@ -109,8 +109,7 @@ rp_mobs.feed_tame_breed = function(mob, feeder, allowed_foods, food_till_tamed,
end
-- Update achievement
local entdef = minetest.registered_entities[mob.name]
if entdef and entdef._is_animal == true then
if rp_mobs.has_tag(mob, "animal") then
achievements.trigger_subcondition(feeder, "gonna_feed_em_all", mob.name)
end

View File

@ -36,8 +36,7 @@ local task_queue_roam_settings = {
--
rp_mobs.register_mob("rp_mobs_mobs:boar", {
description = S("Boar"),
is_animal = true,
is_peaceful = true,
tags = { animal = 1, peaceful = 1 },
drops = {
{name="rp_mobs_mobs:pork_raw", chance=1, min=1, max=4},
},

View File

@ -150,8 +150,6 @@ end
rp_mobs.register_mob("rp_mobs_mobs:mineturtle", {
description = S("Mine Turtle"),
is_animal = false,
is_peaceful = false,
drops = {
{name = "rp_tnt:tnt", chance = 1, min = 1, max = 3},
},

View File

@ -151,8 +151,7 @@ end
rp_mobs.register_mob("rp_mobs_mobs:sheep", {
description = S("Sheep"),
is_animal = true,
is_peaceful = true,
tags = { animal = 1, peaceful = 1 },
drops = {
{name="rp_mobs_mobs:meat_raw", chance=1, min=2, max=4},
},

View File

@ -32,8 +32,7 @@ local task_queue_roam_settings = {
rp_mobs.register_mob("rp_mobs_mobs:skunk", {
description = S("Skunk"),
is_animal = true,
is_peaceful = true,
tags = { animal = 1, peaceful = 1 },
drops = {
{name="rp_mobs_mobs:meat_raw", chance=1, min=1, max=2},
},

View File

@ -401,8 +401,7 @@ for _, villager_type_table in pairs(villager_types) do
rp_mobs.register_mob("rp_mobs_mobs:villager_"..villager_type, {
description = villager_name,
is_animal = false,
is_peaceful = true,
tags = { peaceful = 1 },
drops = {
{ name = "rp_default:planks_oak", chance = 1, min = 1, max = 3 },
{ name = "rp_default:apple", chance = 2, min = 1, max = 2 },

View File

@ -35,8 +35,6 @@ local task_queue_roam_settings = {
rp_mobs.register_mob("rp_mobs_mobs:walker", {
description = S("Walker"),
is_animal = false,
is_peaceful = false,
drops = {
{
name = "rp_default:stick",

View File

@ -65,7 +65,7 @@ function rp_mobs_spawn.register_spawn(name, params)
end
-- Non-peaceful mobs cannot spawn if setting restricts it
if setting_peaceful_only and minetest.registered_entities[name]._is_peaceful then
if setting_peaceful_only and rp_mobs.mobdef_has_tag(name, "peaceful") then
return
end