1
0
mirror of https://codeberg.org/tenplus1/mobs_redo.git synced 2025-01-08 08:50:20 +01:00

tweak & tidy code, exploding mobs brighten and glow

This commit is contained in:
tenplus1 2024-12-28 11:19:44 +00:00
parent b170b51f2d
commit 57fe6cf2e3

141
api.lua
View File

@ -12,16 +12,14 @@ local use_invisibility = minetest.get_modpath("invisibility")
-- Node check helper -- Node check helper
local function has(nodename) local function has(nodename)
if nodename and minetest.registered_nodes[nodename] then return nodename end return minetest.registered_nodes[nodename] and nodename
end end
-- Global table -- Global table
mobs = { mobs = {
mod = "redo", mod = "redo", version = "20241228",
version = "20241226", spawning_mobs = {}, translate = S,
spawning_mobs = {},
translate = S,
node_snow = has(minetest.registered_aliases["mapgen_snow"]) node_snow = has(minetest.registered_aliases["mapgen_snow"])
or has("mcl_core:snow") or has("default:snow") or "air", or has("mcl_core:snow") or has("default:snow") or "air",
node_dirt = has(minetest.registered_aliases["mapgen_dirt"]) node_dirt = has(minetest.registered_aliases["mapgen_dirt"])
@ -31,21 +29,16 @@ mobs.fallback_node = mobs.node_dirt
-- localize common functions -- localize common functions
local pi, abs = math.pi, math.abs local pi, abs, min, max = math.pi, math.abs, math.min, math.max
local square, random = math.sqrt, math.random local square, random = math.sqrt, math.random
local sin, cos = math.sin, math.cos local sin, cos, rad, deg = math.sin, math.cos, math.rad, math.deg
local min, max = math.min, math.max local floor, ceil, vdirection = math.floor, math.ceil, vector.direction
local floor, ceil = math.floor, math.ceil local vmultiply, vsubtract = vector.multiply, vector.subtract
local rad, deg = math.rad, math.deg local settings, atann = minetest.settings, math.atan
local atann = math.atan
local function atan(x) local function atan(x)
if not x or x ~= x then return 0 else return atann(x) end if not x or x ~= x then return 0 else return atann(x) end
end end
local table_copy, table_remove = table.copy, table.remove local table_copy, table_remove = table.copy, table.remove
local vdirection = vector.direction
local vmultiply = vector.multiply
local vsubtract = vector.subtract
local settings = minetest.settings
-- creative check -- creative check
@ -79,19 +72,17 @@ local mob_log_spawn = settings:get_bool("mob_log_spawn") == true
local active_mobs = 0 local active_mobs = 0
-- loop interval for node and main functions timers -- loop interval for node and main functions timers
local node_timer_interval = tonumber(settings:get("mob_node_timer_interval") or 0.25) local node_timer_interval = tonumber(settings:get("mob_node_timer_interval") or 0.25)
local main_timer_interval = tonumber(settings:get("mob_main_timer_interval") or 1.0) local main_timer_interval = tonumber(settings:get("mob_main_timer_interval") or 1.0)
-- pathfinding settings -- pathfinding settings
local pathfinding_enable = settings:get_bool("mob_pathfinding_enable") or true local pathfinding_enable = settings:get_bool("mob_pathfinding_enable") or true
-- how long before stuck mobs start searching
local pathfinding_stuck_timeout = tonumber( local pathfinding_stuck_timeout = tonumber(
settings:get("mob_pathfinding_stuck_timeout")) or 3.0 settings:get("mob_pathfinding_stuck_timeout")) or 3.0
-- how long will mob follow path before giving up
local pathfinding_stuck_path_timeout = tonumber( local pathfinding_stuck_path_timeout = tonumber(
settings:get("mob_pathfinding_stuck_path_timeout")) or 5.0 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" local pathfinding_algorithm = settings:get("mob_pathfinding_algorithm") or "Dijkstra"
if pathfinding_algorithm == "AStar_noprefetch" then if pathfinding_algorithm == "AStar_noprefetch" then
@ -100,15 +91,13 @@ elseif pathfinding_algorithm == "AStar" then
pathfinding_algorithm = "A*" pathfinding_algorithm = "A*"
end end
-- max search distance from search positions (default 16) local pathfinding_max_jump = tonumber(settings:get("mob_pathfinding_max_jump") or 4)
local pathfinding_max_drop = tonumber(settings:get("mob_pathfinding_max_drop") or 6)
local pathfinding_searchdistance = tonumber( local pathfinding_searchdistance = tonumber(
settings:get("mob_pathfinding_searchdistance") or 16) settings:get("mob_pathfinding_searchdistance") or 16)
-- max jump height (default 4)
local pathfinding_max_jump = tonumber(settings:get("mob_pathfinding_max_jump") or 4)
-- max drop height (default 6)
local pathfinding_max_drop = tonumber(settings:get("mob_pathfinding_max_drop") or 6)
-- Peaceful mode message so players will know there are no monsters -- Peaceful mode message so players will know there are no monsters
if peaceful_only then if peaceful_only then
minetest.register_on_joinplayer(function(player) minetest.register_on_joinplayer(function(player)
minetest.chat_send_player(player:get_player_name(), minetest.chat_send_player(player:get_player_name(),
@ -117,9 +106,11 @@ if peaceful_only then
end end
-- calculate aoc range for mob count -- calculate aoc range for mob count
local aoc_range = tonumber(settings:get("active_block_range")) * 16 local aoc_range = tonumber(settings:get("active_block_range")) * 16
-- can we attack Creatura mobs ? -- can we attack Creatura mobs ?
local creatura = minetest.get_modpath("creatura") and local creatura = minetest.get_modpath("creatura") and
settings:get_bool("mobs_attack_creatura") == true settings:get_bool("mobs_attack_creatura") == true
@ -281,7 +272,7 @@ end
local function check_for(look_for, look_inside) local function check_for(look_for, look_inside)
if type(look_inside) == "string" and look_inside == look_for then return true if look_inside == look_for then return true
elseif type(look_inside) == "table" then elseif type(look_inside) == "table" then
@ -383,9 +374,7 @@ function mob_class:set_animation(anim, force)
-- only use different animation for attacks when using same set -- only use different animation for attacks when using same set
if force ~= true and anim ~= "punch" and anim ~= "shoot" if force ~= true and anim ~= "punch" and anim ~= "shoot"
and string.find(self.animation.current, anim) then and string.find(self.animation.current, anim) then return end
return
end
local num = 0 local num = 0
@ -393,9 +382,7 @@ function mob_class:set_animation(anim, force)
for n = 1, 4 do for n = 1, 4 do
if self.animation[anim .. n .. "_start"] if self.animation[anim .. n .. "_start"]
and self.animation[anim .. n .. "_end"] then and self.animation[anim .. n .. "_end"] then num = n end
num = n
end
end end
-- choose random animation from set -- choose random animation from set
@ -406,9 +393,7 @@ function mob_class:set_animation(anim, force)
if (anim == self.animation.current and force ~= true) if (anim == self.animation.current and force ~= true)
or not self.animation[anim .. "_start"] or not self.animation[anim .. "_start"]
or not self.animation[anim .. "_end"] then or not self.animation[anim .. "_end"] then return end
return
end
self.animation.current = anim self.animation.current = anim
@ -755,9 +740,7 @@ function mob_class:check_for_death(cmi_cause)
-- make sure health isn't higher than max -- make sure health isn't higher than max
if self.health > prop.hp_max then self.health = prop.hp_max end if self.health > prop.hp_max then self.health = prop.hp_max end
self:update_tag() self:update_tag() ; return false
return false
end end
self.cause_of_death = cmi_cause self.cause_of_death = cmi_cause
@ -780,9 +763,7 @@ function mob_class:check_for_death(cmi_cause)
self:on_death(cmi_cause) self:on_death(cmi_cause)
remove_mob(self, true) remove_mob(self, true) ; return true
return true
end end
-- execute custom death function -- execute custom death function
@ -792,9 +773,7 @@ function mob_class:check_for_death(cmi_cause)
if use_cmi then cmi.notify_die(self.object, cmi_cause) end if use_cmi then cmi.notify_die(self.object, cmi_cause) end
remove_mob(self, true) remove_mob(self, true) ; return true
return true
end end
-- reset vars and set state -- reset vars and set state
@ -948,10 +927,7 @@ function mob_class:do_env_damage()
-- halt mob if standing inside ignore node -- halt mob if standing inside ignore node
if self.standing_in == "ignore" then if self.standing_in == "ignore" then
self.object:set_velocity({x = 0, y = 0, z = 0}) ; return true
self.object:set_velocity({x = 0, y = 0, z = 0})
return true
end end
local prop = self.object:get_properties() local prop = self.object:get_properties()
@ -1121,9 +1097,7 @@ function mob_class:do_jump()
self:mob_sound(self.sounds.jump) self:mob_sound(self.sounds.jump)
end end
self.jump_count = 0 self.jump_count = 0 ; return true
return true
end end
-- if blocked for 3 counts then turn -- if blocked for 3 counts then turn
@ -1203,21 +1177,17 @@ function mob_class:breed()
if self.hornytimer > CHILD_GROW_TIME then if self.hornytimer > CHILD_GROW_TIME then
self.child = false self.child = false ; self.hornytimer = 0
self.hornytimer = 0
-- replace child texture with adult one -- replace child texture with adult one
if self.mommy_tex then if self.mommy_tex then
self.base_texture = self.mommy_tex self.base_texture = self.mommy_tex ; self.mommy_tex = nil
self.mommy_tex = nil
end end
self.object:set_properties({ self.object:set_properties({
textures = self.base_texture, textures = self.base_texture,
mesh = self.base_mesh, mesh = self.base_mesh, visual_size = self.base_size,
visual_size = self.base_size, collisionbox = self.base_colbox, selectionbox = self.base_selbox
collisionbox = self.base_colbox,
selectionbox = self.base_selbox
}) })
-- custom function when child grows up -- custom function when child grows up
@ -1785,8 +1755,7 @@ function mob_class:general_attack()
-- go through remaining entities and select closest -- go through remaining entities and select closest
for _,player in pairs(objs) do for _,player in pairs(objs) do
p = player:get_pos() p = player:get_pos() ; sp = s
sp = s
dist = get_distance(p, s) dist = get_distance(p, s)
@ -2211,6 +2180,7 @@ function mob_class:do_states(dtime)
self.blinktimer = 0 self.blinktimer = 0
self.blinkstatus = false self.blinkstatus = false
self.object:set_texture_mod("") self.object:set_texture_mod("")
self.object:set_properties({glow = self.glow})
end end
-- walk right up to player unless the timer is active -- walk right up to player unless the timer is active
@ -2237,8 +2207,10 @@ function mob_class:do_states(dtime)
if self.blinkstatus then if self.blinkstatus then
self.object:set_texture_mod(self.texture_mods) self.object:set_texture_mod(self.texture_mods)
self.object:set_properties({glow = (self.glow or 0)})
else else
self.object:set_texture_mod(self.texture_mods .. "^[brighten") self.object:set_texture_mod(self.texture_mods .. "^[brighten")
self.object:set_properties({glow = (self.glow or 0) + 3})
end end
self.blinkstatus = not self.blinkstatus self.blinkstatus = not self.blinkstatus
@ -2250,7 +2222,7 @@ function mob_class:do_states(dtime)
local pos = self.object:get_pos() local pos = self.object:get_pos()
-- dont damage anything if area protected or next to water -- dont damage anything if area protected or near water
if minetest.find_node_near(pos, 1, {"group:water"}) if minetest.find_node_near(pos, 1, {"group:water"})
or minetest.is_protected(pos, "") then or minetest.is_protected(pos, "") then
node_break_radius = 1 node_break_radius = 1
@ -2312,24 +2284,20 @@ function mob_class:do_states(dtime)
-- no paths longer than 50 -- no paths longer than 50
if #self.path.way > 50 or dist < self.reach then if #self.path.way > 50 or dist < self.reach then
self.path.following = false self.path.following = false ; return
return
end end
local p1 = self.path.way[1] local p1 = self.path.way[1]
if not p1 then if not p1 then
self.path.following = false self.path.following = false ; return
return
end end
if abs(p1.x - s.x) + abs(p1.z - s.z) < 0.6 then if abs(p1.x - s.x) + abs(p1.z - s.z) < 0.6 then
-- reached waypoint, remove it from queue table_remove(self.path.way, 1) -- remove waypoint once reached
table_remove(self.path.way, 1)
end end
-- set new temporary target p = {x = p1.x, y = p1.y, z = p1.z} -- set new temporary target
p = {x = p1.x, y = p1.y, z = p1.z}
end end
self:yaw_to_pos(p) self:yaw_to_pos(p)
@ -2349,8 +2317,7 @@ function mob_class:do_states(dtime)
if self.at_cliff or pad < 0.2 then if self.at_cliff or pad < 0.2 then
-- when on top of player extend reach slightly so player can -- extend reach slightly when on top of player
-- still be attacked.
self.reach_ext = 0.8 self.reach_ext = 0.8
self:set_velocity(0) self:set_velocity(0)
self:set_animation("stand") self:set_animation("stand")
@ -2421,8 +2388,7 @@ function mob_class:do_states(dtime)
local vec = {x = p.x - s.x, y = p.y - s.y, z = p.z - s.z} local vec = {x = p.x - s.x, y = p.y - s.y, z = p.z - s.z}
self:yaw_to_pos(p) self:yaw_to_pos(p) ; self:set_velocity(0)
self:set_velocity(0)
if self.shoot_interval and self.timer > self.shoot_interval if self.shoot_interval and self.timer > self.shoot_interval
and random(100) <= 60 then and random(100) <= 60 then
@ -3945,11 +3911,9 @@ function mobs:register_arrow(name, def)
self:hit_player(thing.ref) self:hit_player(thing.ref)
self.object:remove()
--print("hit player", thing.ref:get_player_name()) --print("hit player", thing.ref:get_player_name())
return self.object:remove() ; return
end end
@ -3959,22 +3923,18 @@ function mobs:register_arrow(name, def)
self:hit_mob(thing.ref) self:hit_mob(thing.ref)
self.object:remove()
--print("hit mob", entity.name) --print("hit mob", entity.name)
return self.object:remove() ; return
end end
if entity and self.hit_object and (not entity._cmi_is_mob) then if entity and self.hit_object and (not entity._cmi_is_mob) then
self:hit_object(thing.ref) self:hit_object(thing.ref)
self.object:remove()
--print("hit object", entity.name) --print("hit object", entity.name)
return self.object:remove() ; return
end end
end end
@ -3998,11 +3958,9 @@ function mobs:register_arrow(name, def)
self.object:get_luaentity().name) self.object:get_luaentity().name)
end end
self.object:remove()
--print("hit node", node.name) --print("hit node", node.name)
return self.object:remove() ; return
end end
end end
@ -4076,8 +4034,7 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative)
local is_mob = minetest.registered_entities[mob] local is_mob = minetest.registered_entities[mob]
if not is_mob then if not is_mob then
print("[Mobs Redo] Spawn Egg cannot be created for " .. mob) print("[Mobs Redo] Spawn Egg cannot be created for " .. mob) ; return
return
end end
-- get mob collisionbox and determine y_offset when spawning -- get mob collisionbox and determine y_offset when spawning
@ -4250,19 +4207,13 @@ function mobs:capture_mob(
-- is mob tamed? -- is mob tamed?
if self.tamed == false and force_take == false then if self.tamed == false and force_take == false then
minetest.chat_send_player(name, S("Not tamed!")) ; return false
minetest.chat_send_player(name, S("Not tamed!"))
return false
end end
-- cannot pick up if not owner (unless player has protection_bypass priv) -- cannot pick up if not owner (unless player has protection_bypass priv)
if not minetest.check_player_privs(name, "protection_bypass") if not minetest.check_player_privs(name, "protection_bypass")
and self.owner ~= name and force_take == false then and self.owner ~= name and force_take == false then
minetest.chat_send_player(name, S("@1 is owner!", self.owner)) ; return false
minetest.chat_send_player(name, S("@1 is owner!", self.owner))
return false
end end
if clicker:get_inventory():room_for_item("main", mobname) then if clicker:get_inventory():room_for_item("main", mobname) then