1
0
mirror of https://codeberg.org/tenplus1/mobs_redo.git synced 2025-07-24 19:10:22 +02:00

Compare commits

...

11 Commits

7 changed files with 98 additions and 29 deletions

100
api.lua
View File

@ -8,7 +8,7 @@ local use_cmi = minetest.global_exists("cmi")
mobs = { mobs = {
mod = "redo", mod = "redo",
version = "20210614", version = "20210920",
intllib = S, intllib = S,
invis = minetest.global_exists("invisibility") and invisibility or {} invis = minetest.global_exists("invisibility") and invisibility or {}
} }
@ -56,6 +56,7 @@ local disable_blood = settings:get_bool("mobs_disable_blood")
local mobs_drop_items = settings:get_bool("mobs_drop_items") ~= false local mobs_drop_items = settings:get_bool("mobs_drop_items") ~= false
local mobs_griefing = settings:get_bool("mobs_griefing") ~= false local mobs_griefing = settings:get_bool("mobs_griefing") ~= false
local spawn_protected = settings:get_bool("mobs_spawn_protected") ~= false local spawn_protected = settings:get_bool("mobs_spawn_protected") ~= false
local spawn_monster_protected = settings:get_bool("mobs_spawn_monster_protected") ~= false
local remove_far = settings:get_bool("remove_far_mobs") ~= false local remove_far = settings:get_bool("remove_far_mobs") ~= false
local mob_area_spawn = settings:get_bool("mob_area_spawn") local mob_area_spawn = settings:get_bool("mob_area_spawn")
local difficulty = tonumber(settings:get("mob_difficulty")) or 1.0 local difficulty = tonumber(settings:get("mob_difficulty")) or 1.0
@ -82,7 +83,7 @@ local aoc_range = tonumber(settings:get("active_block_range")) * 16
-- pathfinding settings -- pathfinding settings
local enable_pathfinding = true local enable_pathfinding = true
local stuck_timeout = 3 -- how long before stuck mod starts searching local stuck_timeout = 3 -- how long before stuck mod starts searching
local stuck_path_timeout = 10 -- how long will mob follow path before giving up local stuck_path_timeout = 5 -- how long will mob follow path before giving up
-- default nodes -- default nodes
local node_fire = "fire:basic_flame" local node_fire = "fire:basic_flame"
@ -159,6 +160,7 @@ local mob_class = {
attack_players = true, attack_players = true,
attack_npcs = true, attack_npcs = true,
facing_fence = false, facing_fence = false,
_breed_countdown = nil,
_cmi_is_mob = true _cmi_is_mob = true
} }
@ -273,7 +275,9 @@ function mob_class:set_velocity(v)
-- halt mob if it has been ordered to stay -- halt mob if it has been ordered to stay
if self.order == "stand" then if self.order == "stand" then
self.object:set_velocity({x = 0, y = 0, z = 0}) local vel = self.object:get_velocity() or {y = 0}
self.object:set_velocity({x = 0, y = vel.y, z = 0})
return return
end end
@ -719,6 +723,13 @@ function mobs:effect(pos, amount, texture, min_size, max_size,
end end
-- Thanks Wuzzy for the following editable settings
local HORNY_TIME = 30
local HORNY_AGAIN_TIME = 60 * 5 -- 5 minutes
local CHILD_GROW_TIME = 60 * 20 -- 20 minutes
-- update nametag colour -- update nametag colour
function mob_class:update_tag() function mob_class:update_tag()
@ -737,9 +748,25 @@ function mob_class:update_tag()
col = "#FF0000" col = "#FF0000"
end end
-- build infotext local text = ""
if self.horny == true then
text = "\nLoving: " .. (self.hornytimer - (HORNY_TIME + HORNY_AGAIN_TIME))
elseif self.child == true then
text = "\nGrowing: " .. (self.hornytimer - CHILD_GROW_TIME)
elseif self._breed_countdown then
text = "\nBreeding: " .. self._breed_countdown
end
self.infotext = "Health: " .. self.health .. " / " .. self.hp_max self.infotext = "Health: " .. self.health .. " / " .. self.hp_max
.. "\n" .. "Owner: " .. self.owner .. "\n" .. "Owner: " .. self.owner
.. text
-- set changes -- set changes
self.object:set_properties({ self.object:set_properties({
@ -1355,10 +1382,6 @@ function mob_class:follow_holding(clicker)
return false return false
end end
-- Thanks Wuzzy for the following editable settings
local HORNY_TIME = 30
local HORNY_AGAIN_TIME = 60 * 5 -- 5 minutes
local CHILD_GROW_TIME = 60 * 20 -- 20 minutes
-- find two animals of same type and breed if nearby and horny -- find two animals of same type and breed if nearby and horny
function mob_class:breed() function mob_class:breed()
@ -1411,6 +1434,8 @@ function mob_class:breed()
self.hornytimer = 0 self.hornytimer = 0
self.horny = false self.horny = false
end end
self:update_tag()
end end
-- find another same animal who is also horny and mate if nearby -- find another same animal who is also horny and mate if nearby
@ -1466,6 +1491,8 @@ function mob_class:breed()
self.hornytimer = HORNY_TIME + 1 self.hornytimer = HORNY_TIME + 1
ent.hornytimer = HORNY_TIME + 1 ent.hornytimer = HORNY_TIME + 1
self:update_tag()
-- have we reached active mob limit -- have we reached active mob limit
if active_limit > 0 and active_mobs >= active_limit then if active_limit > 0 and active_mobs >= active_limit then
minetest.chat_send_player(self.owner, minetest.chat_send_player(self.owner,
@ -1651,6 +1678,8 @@ local can_dig_drop = function(pos)
return false return false
end end
local pathfinder_mod = minetest.get_modpath("pathfinder")
-- path finding and smart mob routine by rnd, -- path finding and smart mob routine by rnd,
-- line_of_sight and other edits by Elkien3 -- line_of_sight and other edits by Elkien3
function mob_class:smart_mobs(s, p, dist, dtime) function mob_class:smart_mobs(s, p, dist, dtime)
@ -1779,13 +1808,18 @@ function mob_class:smart_mobs(s, p, dist, dtime)
jumpheight = 1 jumpheight = 1
end end
self.path.way = minetest.find_path(s, p1, 16, jumpheight, if pathfinder_mod then
dropheight, "Dijkstra") self.path.way = pathfinder.find_path(s, p1, self, dtime)
else
self.path.way = minetest.find_path(s, p1, 16, jumpheight,
dropheight, "Dijkstra")
end
--[[ --[[
-- show path using particles -- show path using particles
if self.path.way and #self.path.way > 0 then if self.path.way and #self.path.way > 0 then
print("-- path length:" .. tonumber(#self.path.way)) print("-- path length:" .. tonumber(#self.path.way))
for _,pos in pairs(self.path.way) do for _,pos in pairs(self.path.way) do
minetest.add_particle({ minetest.add_particle({
pos = pos, pos = pos,
@ -2693,6 +2727,12 @@ function mob_class:do_states(dtime)
local obj = minetest.add_entity(p, self.arrow) local obj = minetest.add_entity(p, self.arrow)
local ent = obj:get_luaentity() local ent = obj:get_luaentity()
local amount = (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) ^ 0.5 local amount = (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) ^ 0.5
-- check for custom override for arrow
if self.arrow_override then
self.arrow_override(ent)
end
local v = ent.velocity or 1 -- or set to default local v = ent.velocity or 1 -- or set to default
ent.switch = 1 ent.switch = 1
@ -3253,7 +3293,7 @@ function mob_class:mob_activate(staticdata, def, dtime)
self.object:set_texture_mod(self.texture_mods) self.object:set_texture_mod(self.texture_mods)
-- set 5.x flag to remove monsters when map area unloaded -- set 5.x flag to remove monsters when map area unloaded
if remove_far and self.type == "monster" then if remove_far and self.type == "monster" and not self.tamed then
self.static_save = false self.static_save = false
end end
@ -3563,6 +3603,7 @@ minetest.register_entity(name, setmetatable({
armor = def.armor, armor = def.armor,
on_rightclick = def.on_rightclick, on_rightclick = def.on_rightclick,
arrow = def.arrow, arrow = def.arrow,
arrow_override = def.arrow_override,
shoot_interval = def.shoot_interval, shoot_interval = def.shoot_interval,
sounds = def.sounds, sounds = def.sounds,
animation = def.animation, animation = def.animation,
@ -3956,8 +3997,10 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter
return return
end end
-- mobs cannot spawn in protected areas when enabled -- check if mob can spawn inside protected areas
if not spawn_protected if (spawn_protected == false
or (spawn_monster_protected == false
and minetest.registered_entities[name].type == "monster"))
and minetest.is_protected(pos, "") then and minetest.is_protected(pos, "") then
--print("--- inside protected area", name) --print("--- inside protected area", name)
return return
@ -4431,7 +4474,7 @@ end
function mobs:capture_mob(self, clicker, chance_hand, chance_net, function mobs:capture_mob(self, clicker, chance_hand, chance_net,
chance_lasso, force_take, replacewith) chance_lasso, force_take, replacewith)
if self.child if not self --self.child
or not clicker:is_player() or not clicker:is_player()
or not clicker:get_inventory() then or not clicker:get_inventory() then
return false return false
@ -4648,25 +4691,25 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
self.object:set_hp(self.health) self.object:set_hp(self.health)
self:update_tag()
-- make children grow quicker -- make children grow quicker
if self.child == true then if self.child == true then
-- self.hornytimer = self.hornytimer + 20 -- self.hornytimer = self.hornytimer + 20
-- deduct 10% of the time to adulthood -- deduct 10% of the time to adulthood
self.hornytimer = self.hornytimer + ( self.hornytimer = math.floor(self.hornytimer + (
(CHILD_GROW_TIME - self.hornytimer) * 0.1) (CHILD_GROW_TIME - self.hornytimer) * 0.1))
--print ("====", self.hornytimer) --print ("====", self.hornytimer)
return true return true
end end
-- feed and tame -- feed and tame
self.food = (self.food or 0) + 1 self.food = (self.food or 0) + 1
self._breed_countdown = feed_count - self.food
if self.food >= feed_count then if self.food >= feed_count then
self.food = 0 self.food = 0
self._breed_countdown = nil
if breed and self.hornytimer == 0 then if breed and self.hornytimer == 0 then
self.horny = true self.horny = true
@ -4681,6 +4724,7 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
end end
self.tamed = true self.tamed = true
self.static_save = true
if not self.owner or self.owner == "" then if not self.owner or self.owner == "" then
self.owner = clicker:get_player_name() self.owner = clicker:get_player_name()
@ -4691,6 +4735,8 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
self:mob_sound(self.sounds.random) self:mob_sound(self.sounds.random)
end end
self:update_tag()
return true return true
end end
@ -4720,6 +4766,22 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
return true return true
end end
-- if mob follows items and user right clicks while holding sneak it shows info
if self.follow then
if clicker:get_player_control().sneak then
if type(self.follow) == "string" then
self.follow = {self.follow}
end
minetest.chat_send_player(clicker:get_player_name(),
S("@1 follows:\n- @2",
self.name:split(":")[2],
table.concat(self.follow, "\n- ")))
end
end
return false return false
end end

View File

@ -123,6 +123,8 @@ functions needed for the mob to work properly which contains the following:
continue chasing. continue chasing.
'arrow' holds the pre-defined arrow object to shoot when 'arrow' holds the pre-defined arrow object to shoot when
attacking. attacking.
'arrow_override' function that allows tweaking of arrow entity from
inside mob definition (self) passed to function.
'dogshoot_switch' allows switching between attack types by using timers 'dogshoot_switch' allows switching between attack types by using timers
(1 for shoot, 2 for dogfight) (1 for shoot, 2 for dogfight)
'dogshoot_count_max' contains how many seconds before switching from 'dogshoot_count_max' contains how many seconds before switching from
@ -699,6 +701,8 @@ External Settings for "minetest.conf"
is false) is false)
'mobs_spawn_protected' if set to false then mobs will not spawn in protected 'mobs_spawn_protected' if set to false then mobs will not spawn in protected
areas (default is true) areas (default is true)
'mobs_spawn_monster_protected' if set to false then monsters will not spawn in
protected areas (default is true)
'remove_far_mobs' if true then untamed mobs that are outside players 'remove_far_mobs' if true then untamed mobs that are outside players
visual range will be removed (default is true) visual range will be removed (default is true)
'mobname' can change specific mob chance rate (0 to disable) and 'mobname' can change specific mob chance rate (0 to disable) and

View File

@ -10,7 +10,6 @@ minetest.register_craftitem("mobs:nametag", {
if minetest.get_modpath("dye") and minetest.get_modpath("farming") then if minetest.get_modpath("dye") and minetest.get_modpath("farming") then
minetest.register_craft({ minetest.register_craft({
-- type = "shapeless",
output = "mobs:nametag", output = "mobs:nametag",
recipe = {{"default:paper", "dye:black", "farming:string"}} recipe = {{"default:paper", "dye:black", "farming:string"}}
}) })
@ -149,7 +148,7 @@ minetest.register_craft({
-- make sure we can register fences -- make sure we can register fences
if default.register_fence then if minetest.get_modpath("default") and default.register_fence then
-- mob fence (looks like normal fence but collision is 2 high) -- mob fence (looks like normal fence but collision is 2 high)
default.register_fence("mobs:fence_wood", { default.register_fence("mobs:fence_wood", {
@ -165,6 +164,7 @@ default.register_fence("mobs:fence_wood", {
} }
} }
}) })
end
-- mob fence top (has enlarged collisionbox to stop mobs getting over) -- mob fence top (has enlarged collisionbox to stop mobs getting over)
minetest.register_node("mobs:fence_top", { minetest.register_node("mobs:fence_top", {
@ -197,8 +197,6 @@ minetest.register_craft({
} }
}) })
end
-- items that can be used as fuel -- items that can be used as fuel
minetest.register_craft({ minetest.register_craft({
@ -361,9 +359,9 @@ minetest.register_node("mobs:meatblock", {
tiles = {"mobs_meat_top.png", "mobs_meat_bottom.png", "mobs_meat_side.png"}, tiles = {"mobs_meat_top.png", "mobs_meat_bottom.png", "mobs_meat_side.png"},
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {choppy = 1, oddly_breakable_by_hand = 1, flammable = 2}, groups = {choppy = 1, oddly_breakable_by_hand = 1, flammable = 2},
sounds = default.node_sound_leaves_defaults(), sounds = default and default.node_sound_leaves_defaults(),
on_place = minetest.rotate_node, on_place = minetest.rotate_node,
on_use = minetest.item_eat(20), on_use = minetest.item_eat(20)
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -1,4 +1,4 @@
default default?
tnt? tnt?
dye? dye?
farming? farming?
@ -7,3 +7,4 @@ intllib?
lucky_block? lucky_block?
cmi? cmi?
toolranks? toolranks?
pathfinder?

View File

@ -1,4 +1,4 @@
name = mobs name = mobs
depends = default depends =
optional_depends = tnt, dye, farming, invisibility, intllib, lucky_block, cmi, toolranks optional_depends = default, tnt, dye, farming, invisibility, intllib, lucky_block, cmi, toolranks, pathfinder
description = Adds a mob api for mods to add animals or monsters etc. description = Adds a mob api for mods to add animals or monsters etc.

View File

@ -23,7 +23,8 @@ Lucky Blocks: 9
Changelog: Changelog:
- 1.55 - Add 'peaceful_player' privelage and setting so mobs don't attack specific players (thanks sfence) - 1.56 - Added arrow_override function to mob definition to tweak arrow entity settings, tamed monsters no longer despawn when outside loaded map area.
- 1.55 - Add 'peaceful_player' privelage and setting so mobs don't attack specific players (thanks sfence), add support for MarkBu's pathfinder mod, remove need for default mod
- 1.54 - Simplified animal breeding function, added editable settings (thanks Wuzzy), Child mobs now take 20 mins to grow up, reverted to simple mob spawning with setting to use area checks, on_flop added, air_damage added. - 1.54 - Simplified animal breeding function, added editable settings (thanks Wuzzy), Child mobs now take 20 mins to grow up, reverted to simple mob spawning with setting to use area checks, on_flop added, air_damage added.
- 1.53 - Added 'on_map_load' settings to mobs:spawn so that mobs will only spawn when new areas of map are loaded. - 1.53 - Added 'on_map_load' settings to mobs:spawn so that mobs will only spawn when new areas of map are loaded.
- 1.52 - Added 'mob_active_limit' in settings to set number of mobs in game, - 1.52 - Added 'mob_active_limit' in settings to set number of mobs in game,

View File

@ -13,6 +13,9 @@ mobs_griefing (Griefing Mobs) bool true
# If false then Mobs no longer spawn inside player protected areas # If false then Mobs no longer spawn inside player protected areas
mobs_spawn_protected (Spawn Mobs in protected areas) bool true mobs_spawn_protected (Spawn Mobs in protected areas) bool true
# If false then Monsters no longer spawn inside player protected areas
mobs_spawn_monster_protected (Spawn Monsters in protected areas) bool true
# If true Mobs will be removed once a map chunk is out of view # If true Mobs will be removed once a map chunk is out of view
remove_far_mobs (Remove far Mobs) bool true remove_far_mobs (Remove far Mobs) bool true