Compare commits

..

No commits in common. "8ddc9217895072f94f635a54576e355319d65e15" and "c02fdfe5f0214d3a0b324cf8b4a201f0bbf29f1c" have entirely different histories.

4 changed files with 48 additions and 115 deletions

145
api.lua
View File

@ -33,7 +33,7 @@ local use_mc2 = minetest.get_modpath("mcl_core")
-- Global
mobs = {
mod = "redo",
version = "20231106",
version = "20230927",
translate = S, intllib = S,
invis = minetest.global_exists("invisibility") and invisibility or {},
node_ice = "default:ice",
@ -114,8 +114,7 @@ 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"
@ -183,7 +182,6 @@ 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",
@ -219,7 +217,6 @@ mobs.mob_class = {
friendly_fire = true,
facing_fence = false,
_breed_countdown = nil,
_tame_countdown = nil,
_cmi_is_mob = true
}
@ -230,20 +227,21 @@ local mob_class_meta = {__index = mob_class}
-- play sound
function mob_class:mob_sound(sound)
if not sound then return end
if sound then
-- 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 and self.sounds.distance) or 10,
pitch = pitch
}, true)
minetest.sound_play(sound, {
object = self.object,
gain = 1.0,
max_hear_distance = self.sounds.distance,
pitch = pitch
}, true)
end
end
@ -834,8 +832,6 @@ 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
@ -1860,9 +1856,7 @@ function mob_class:smart_mobs(s, p, dist, dtime)
s.y = sground.y + 1
end
local p1 = self.attack and self.attack:get_pos()
if not p1 then return end
local p1 = self.attack:get_pos()
p1.x = floor(p1.x + 0.5)
p1.y = floor(p1.y + 0.5)
@ -2006,7 +2000,8 @@ 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
@ -2342,21 +2337,6 @@ 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)
@ -2535,28 +2515,19 @@ function mob_class:do_states(dtime)
--print(" ** stop attacking **", self.name, self.health, dist, self.view_range)
self: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)
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)
@ -2571,7 +2542,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 in_sight then
and self:line_of_sight(s, p, 2) then
self.v_start = true
self.timer = 0
@ -2583,7 +2554,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 in_sight) then
and (dist > self.reach or not self:line_of_sight(s, p, 2)) then
--print("=== explosion timer stopped")
@ -2617,8 +2588,10 @@ 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
@ -2631,9 +2604,10 @@ function mob_class:do_states(dtime)
local pos = self.object:get_pos()
-- dont damage anything if area protected or next to water
-- dont damage anything if area protected or next to waterpathfinding_max_jump
if minetest.find_node_near(pos, 1, {"group:water"})
or minetest.is_protected(pos, "") then
node_break_radius = 1
end
@ -3264,28 +3238,6 @@ 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
@ -3573,7 +3525,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
@ -3730,7 +3682,7 @@ function mobs:register_mob(name, def)
minetest.register_entity(name, setmetatable({
stepheight = def.stepheight or 1.1,
stepheight = def.stepheight,
name = (name:find(":") and name or ":"..name),
type = def.type,
attack_type = def.attack_type,
@ -3785,7 +3737,6 @@ 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,
@ -4089,7 +4040,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/10))) > 1 then
if map_load and random(max(1, (chance * mob_chance_multiplier))) > 1 then
return
end
@ -4221,16 +4172,14 @@ 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
local pos_string = pos and minetest.pos_to_string(pos) or ""
minetest.log(
"[MOBS] Spawned "
.. (name or "")
.. " at "
.. pos_string
)
minetest.log("[MOBS] Spawned " .. name .. " at "
.. minetest.pos_to_string(pos))
end
if on_spawn and mob then
@ -4261,7 +4210,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/10))),
chance = max(1, (chance * mob_chance_multiplier)),
catch_up = false,
action = function(pos, node, active_object_count, active_object_count_wider)
@ -4477,6 +4426,7 @@ 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)
@ -4827,7 +4777,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 = floor(self.hornytimer + (
self.hornytimer = math.floor(self.hornytimer + (
(CHILD_GROW_TIME - self.hornytimer) * 0.1))
--print ("====", self.hornytimer)
return true
@ -4835,8 +4785,7 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
-- feed and tame
self.food = (self.food or 0) + 1
self._breed_countdown = breed and (feed_count - self.food)
self._tame_countdown = not self.tamed and tame and (feed_count - self.food)
self._breed_countdown = feed_count - self.food
if self.food >= feed_count then
@ -4966,10 +4915,10 @@ function mobs:alias_mob(old_name, new_name)
end
-- spawn egg
minetest.register_alias( (old_name:find(":") and old_name or ":"..old_name), new_name)
minetest.register_alias(old_name, new_name)
-- entity
minetest.register_entity( ":"..old_name , {
minetest.register_entity( (old_name:find(":") and old_name or ":"..old_name) , {
physical = false, static_save = false,

11
api.txt
View File

@ -104,8 +104,6 @@ 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.
@ -389,15 +387,6 @@ 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,7 +241,6 @@ 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://codeberg.org/minenux/minetest-mod-mobs_redo
https://forum.minetest.net/viewtopic.php?f=11&t=9917
Information
-----------
@ -12,10 +12,6 @@ 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