Compare commits

...

11 Commits

Author SHA1 Message Date
general 8ddc921789 add self.attack_patience to add custom times, add self.attack nil check to pathfinding
* backport commit 9e27f45663cc0c0df0e329bfbcf92466cca2ce3c from upstream
  and fix previous commit of this version that for rare reason mixed only one line
2024-04-07 17:10:38 -04:00
mckaygerhard 7771da2e0a fix autodetect ":" to beginning of entity registration for alias_mob
* commit a4cf246fce has an error, alias
  must be registered with `:MODNAME:obejectname` so if you dont
  add the prefix of `:` the default is the mod class parent, so
  swaping here the sustitution detection, for now..
  this addressed older https://notabug.org/TenPlus1/mobs_redo/issues/154
  fixed in good way, also commit b1ad4451a7
2024-03-30 22:05:02 -04:00
mckaygerhard 910a46b16d fix missing end on the backguar compatibility
* related to the commit c41176b807
  backguard compat 0.4, intlib only for older of tweak for mineclone
  and 5.x, backguard compat 0.4, intlib only for older
2024-03-30 22:00:04 -04:00
general e4623dec52 update information readme 2024-03-30 04:39:17 -04:00
general d76d2d307a harden spawn log message, better fix for nil checks
* reported, closes https://codeberg.org/tenplus1/mobs_redo/issues/1
  referece at https://github.com/Archtec-io/bugtracker/issues/130
  this are not so good so implement in better way.
* related to commit bf79985730cee684a1e11e4b4df0ac140d7e8980
  and commit a62bfe3828bf2d6889a71ab7d906c31641593663
  at bf79985730
  and a62bfe3828
2024-03-30 04:06:07 -04:00
general 4bf2555144 small fix sync with lost commit, cos upstream never document
* backported from "use api functions for riding mob"
  commit 768ef84bd88736d965c659b8b33620e4f90e350e
  as 768ef84bd8
2024-03-30 03:57:49 -04:00
general c876bb63c7 add taming countdown infotext
* do not need to fix knockback cos i do not change
  things constantly, code was already working
2024-03-30 03:53:40 -04:00
general 0a86398377 only show breed infotext if mob can breed
* backported commit e8adf9b244770854f06efc3182f4b804d14d3947
  from e8adf9b244
2024-03-30 03:37:53 -04:00
general 320ca97164 fix nil var stepheight
* backported commit 7f1ad098704f757d873a01568267c94f587cd814
  from 7f1ad09870
2024-03-30 03:34:51 -04:00
general cbfe800342 use self.backup_properties instead of self.initial_properties
* fix math.floor non local use with floor local function
2024-03-30 03:24:56 -04:00
general f0fe65ec50 backport initial properties future use 2024-03-30 03:21:07 -04:00
4 changed files with 115 additions and 48 deletions

145
api.lua
View File

@ -33,7 +33,7 @@ local use_mc2 = minetest.get_modpath("mcl_core")
-- Global
mobs = {
mod = "redo",
version = "20230927",
version = "20231106",
translate = S, intllib = S,
invis = minetest.global_exists("invisibility") and invisibility or {},
node_ice = "default:ice",
@ -114,7 +114,8 @@ local pathfinder_enable = settings:get_bool("mob_pathfinder_enable") or true
local pathfinding_stuck_timeout = tonumber(
settings:get("mob_pathfinding_stuck_timeout")) or 3.0
-- how long will mob follow path before giving up
local pathfinding_stuck_path_timeout = tonumber(settings:get("mob_pathfinding_stuck_path_timeout")) or 5.0
local pathfinding_stuck_path_timeout = tonumber(
settings:get("mob_pathfinding_stuck_path_timeout")) or 5.0
-- which algorithm to use, Dijkstra(default) or A*_noprefetch or A*
-- fix settings not allowing "*"
local pathfinding_algorithm = settings:get("mob_pathfinding_algorithm") or "Dijkstra"
@ -182,6 +183,7 @@ mobs.mob_class = {
walk_chance = 50,
stand_chance = 30,
attack_chance = 5,
attack_patience = 11
passive = false,
blood_amount = 5,
blood_texture = "mobs_blood.png",
@ -217,6 +219,7 @@ mobs.mob_class = {
friendly_fire = true,
facing_fence = false,
_breed_countdown = nil,
_tame_countdown = nil,
_cmi_is_mob = true
}
@ -227,21 +230,20 @@ local mob_class_meta = {__index = mob_class}
-- play sound
function mob_class:mob_sound(sound)
if sound then
if not sound then return end
-- higher pitch for a child
local pitch = self.child and 1.5 or 1.0
-- higher pitch for a child
local pitch = self.child and 1.5 or 1.0
-- a little random pitch to be different
pitch = pitch + random(-10, 10) * 0.005
-- a little random pitch to be different
pitch = pitch + random(-10, 10) * 0.005
minetest.sound_play(sound, {
object = self.object,
gain = 1.0,
max_hear_distance = self.sounds.distance,
pitch = pitch
}, true)
end
minetest.sound_play(sound, {
object = self.object,
gain = 1.0,
max_hear_distance = (self.sounds and self.sounds.distance) or 10,
pitch = pitch
}, true)
end
@ -832,6 +834,8 @@ function mob_class:update_tag()
text = "\nLoving: " .. (self.hornytimer - (HORNY_TIME + HORNY_AGAIN_TIME))
elseif self.child == true then
text = "\nGrowing: " .. (self.hornytimer - CHILD_GROW_TIME)
elseif self._tame_countdown then
text = "\nTaming: " .. self._tame_countdown
elseif self._breed_countdown then
text = "\nBreeding: " .. self._breed_countdown
end
@ -1856,7 +1860,9 @@ function mob_class:smart_mobs(s, p, dist, dtime)
s.y = sground.y + 1
end
local p1 = self.attack:get_pos()
local p1 = self.attack and self.attack:get_pos()
if not p1 then return end
p1.x = floor(p1.x + 0.5)
p1.y = floor(p1.y + 0.5)
@ -2000,8 +2006,7 @@ local function is_peaceful_player(player)
local player_name = player:get_player_name()
-- player priv enabled
if player_name
and minetest.check_player_privs(player_name, "peaceful_player") then
if player_name and minetest.check_player_privs(player_name, "peaceful_player") then
return true
end
end
@ -2337,6 +2342,21 @@ function mob_class:dogswitch(dtime)
end
-- stop attack
function mob_class:stop_attack()
self.attack = nil
self.following = nil
self.v_start = false
self.timer = 0
self.blinktimer = 0
self.path.way = nil
self:set_velocity(0)
self.state = "stand"
self:set_animation("stand", true)
end
-- execute current state (stand, walk, run, attacks)
function mob_class:do_states(dtime)
@ -2515,19 +2535,28 @@ function mob_class:do_states(dtime)
--print(" ** stop attacking **", self.name, self.health, dist, self.view_range)
self.attack = nil
self.following = nil
self.v_start = false
self.timer = 0
self.blinktimer = 0
self.path.way = nil
self:set_velocity(0)
self.state = "stand"
self:set_animation("stand", true)
self:stop_attack()
return
end
-- check enemy is in sight
local in_sight = self:line_of_sight(
{x = s.x, y = s.y + 0.5, z = s.z},
{x = p.x, y = p.y + 0.5, z = p.z})
-- stop attacking when enemy not seen for 11 seconds
if not in_sight then
self.target_time_lost = (self.target_time_lost or 0) + dtime
if self.target_time_lost > self.attack_patience then
self:stop_attack()
end
else
self.target_time_lost = 0
end
if self.attack_type == "explode" then
yaw_to_pos(self, p)
@ -2542,7 +2571,7 @@ function mob_class:do_states(dtime)
-- start timer when in reach and line of sight
if not self.v_start
and dist <= self.reach
and self:line_of_sight(s, p, 2) then
and in_sight then
self.v_start = true
self.timer = 0
@ -2554,7 +2583,7 @@ function mob_class:do_states(dtime)
-- stop timer if out of reach or direct line of sight
elseif self.allow_fuse_reset
and self.v_start
and (dist > self.reach or not self:line_of_sight(s, p, 2)) then
and (dist > self.reach or not in_sight) then
--print("=== explosion timer stopped")
@ -2588,10 +2617,8 @@ function mob_class:do_states(dtime)
self.blinktimer = 0
if self.blinkstatus then
self.object:set_texture_mod(self.texture_mods)
else
self.object:set_texture_mod(self.texture_mods .. "^[brighten")
end
@ -2604,10 +2631,9 @@ function mob_class:do_states(dtime)
local pos = self.object:get_pos()
-- dont damage anything if area protected or next to waterpathfinding_max_jump
-- dont damage anything if area protected or next to water
if minetest.find_node_near(pos, 1, {"group:water"})
or minetest.is_protected(pos, "") then
node_break_radius = 1
end
@ -3238,6 +3264,28 @@ function mob_class:mob_staticdata()
self.serialized_cmi_components = cmi.serialize_components(self._cmi_components)
end
-- move existing variables to new table for future compatibility
-- using self.initial_properties lost some variables when backing up?!?
if not self.backup_properties then
self.backup_properties = {
hp_max = self.hp_max,
physical = self.physical,
collisionbox = self.collisionbox,
selectionbox = self.selectionbox,
visual = self.visual,
visual_size = self.visual_size,
mesh = self.mesh,
textures = self.textures,
make_footstep_sound = self.make_footstep_sound,
stepheight = self.stepheight,
glow = self.glow,
nametag = self.nametag,
damage_texture_modifier = self.damage_texture_modifier,
infotext = self.infotext
}
end
return minetest.serialize(clean_staticdata(self))
end
@ -3525,7 +3573,7 @@ function mob_class:on_step(dtime, moveresult)
-- check and stop if standing at cliff and fear of heights
self.at_cliff = self:is_at_cliff()
if self.pause_timer <= 0 and self.at_cliff then
if self.pause_timer < 0 and self.at_cliff then
self:set_velocity(0)
end
@ -3682,7 +3730,7 @@ function mobs:register_mob(name, def)
minetest.register_entity(name, setmetatable({
stepheight = def.stepheight,
stepheight = def.stepheight or 1.1,
name = (name:find(":") and name or ":"..name),
type = def.type,
attack_type = def.attack_type,
@ -3737,6 +3785,7 @@ minetest.register_entity(name, setmetatable({
walk_chance = def.walk_chance,
stand_chance = def.stand_chance,
attack_chance = def.attack_chance,
attack_patience = def.attack_patience,
passive = def.passive,
knock_back = def.knock_back,
blood_amount = def.blood_amount,
@ -4040,7 +4089,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter
pos, node, active_object_count, active_object_count_wider)
-- use instead of abm's chance setting when using lbm
if map_load and random(max(1, (chance * mob_chance_multiplier))) > 1 then
if map_load and random(max(1, (chance * mob_chance_multiplier/10))) > 1 then
return
end
@ -4172,14 +4221,16 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter
local mob = minetest.add_entity(pos, name)
-- print("[mobs] Spawned " .. name .. " at "
-- .. minetest.pos_to_string(pos) .. " on "
-- .. node.name .. " near " .. neighbors[1])
if mob_log_spawn then
minetest.log("[MOBS] Spawned " .. name .. " at "
.. minetest.pos_to_string(pos))
local pos_string = pos and minetest.pos_to_string(pos) or ""
minetest.log(
"[MOBS] Spawned "
.. (name or "")
.. " at "
.. pos_string
)
end
if on_spawn and mob then
@ -4210,7 +4261,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter
nodenames = nodes,
neighbors = neighbors,
interval = interval,
chance = max(1, (chance * mob_chance_multiplier)),
chance = max(1, (chance * (mob_chance_multiplier/10))),
catch_up = false,
action = function(pos, node, active_object_count, active_object_count_wider)
@ -4426,7 +4477,6 @@ end
-- Register spawn eggs
-- Note: This also introduces the “spawn_egg” group:
-- * spawn_egg=1: Spawn egg (generic mob, no metadata)
-- * spawn_egg=2: Spawn egg (captured/tamed mob, metadata)
@ -4777,7 +4827,7 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
if self.child == true then
-- deduct 10% of the time to adulthood
self.hornytimer = math.floor(self.hornytimer + (
self.hornytimer = floor(self.hornytimer + (
(CHILD_GROW_TIME - self.hornytimer) * 0.1))
--print ("====", self.hornytimer)
return true
@ -4785,7 +4835,8 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
-- feed and tame
self.food = (self.food or 0) + 1
self._breed_countdown = feed_count - self.food
self._breed_countdown = breed and (feed_count - self.food)
self._tame_countdown = not self.tamed and tame and (feed_count - self.food)
if self.food >= feed_count then
@ -4915,10 +4966,10 @@ function mobs:alias_mob(old_name, new_name)
end
-- spawn egg
minetest.register_alias(old_name, new_name)
minetest.register_alias( (old_name:find(":") and old_name or ":"..old_name), new_name)
-- entity
minetest.register_entity( (old_name:find(":") and old_name or ":"..old_name) , {
minetest.register_entity( ":"..old_name , {
physical = false, static_save = false,

11
api.txt
View File

@ -104,6 +104,8 @@ functions needed for the mob to work properly which contains the following:
hours and only attacking player at night or when
provoked.
'attack_chance' 0 to 100 chance the mob will attack (default is 5).
'attack_patience' Time in seconds before mob gives up attacking if
player isn't seen (Defaults to 11).
'attack_monsters' when true mob will attack monsters.
'attack_animals' when true mob will attack animals.
'attack_npcs' when true mob will attack npcs within range.
@ -387,6 +389,15 @@ for each mob.
in it's name.
Internal Functions
------------------
Each mob contains a set of functions that can be called for use internally or from
another mod entirely, replace mob_class with the mob entity variable:
mob_class:stop_attack() -- stops mob attacking
Adding Mobs in World
--------------------

View File

@ -241,6 +241,7 @@ function mobs.attach(entity, player)
else
default.player_set_animation(player, "sit", 30)
end
end
end
end)

View File

@ -4,7 +4,7 @@ MOBS REDO for MINETEST
This mod contains the API only for adding your own mobs into the world, so
please use the additional modpacks to add animals, monsters, and npcs.
https://forum.minetest.net/viewtopic.php?f=11&t=9917
https://codeberg.org/minenux/minetest-mod-mobs_redo
Information
-----------
@ -12,6 +12,10 @@ Information
Built from PilzAdam's original Simple Mobs with additional mobs by KrupnoPavel,
Zeg9, ExeterDad and AspireMint.
This mod is special one already compatible with older engines.. with backported
patches to work both in multicraft, minetest, mineclone and finetest, becouse
the tenplus1 only works in last minetest, admins will not wants to constant upgrades!
## Crafts
- **Nametag**. Can be crafted by paper, black dye, and string. Can be used