mirror of
https://codeberg.org/tenplus1/mobs_redo.git
synced 2025-07-15 23:00:30 +02:00
Compare commits
7 Commits
39002cf4e7
...
b6fb1948e8
Author | SHA1 | Date | |
---|---|---|---|
b6fb1948e8 | |||
67e4ede31b | |||
3009da0efe | |||
bd8be0905a | |||
89523195d5 | |||
c6dffd1390 | |||
499d43a9aa |
363
api.lua
363
api.lua
@ -9,7 +9,7 @@ local use_cmi = minetest.global_exists("cmi")
|
||||
|
||||
mobs = {
|
||||
mod = "redo",
|
||||
version = "20200825",
|
||||
version = "20200916",
|
||||
intllib = S,
|
||||
invis = minetest.global_exists("invisibility") and invisibility or {}
|
||||
}
|
||||
@ -2685,20 +2685,20 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
||||
|
||||
-- mob health check
|
||||
if self.health <= 0 then
|
||||
return
|
||||
return true
|
||||
end
|
||||
|
||||
-- custom punch function
|
||||
if self.do_punch
|
||||
and self:do_punch(hitter, tflp, tool_capabilities, dir) == false then
|
||||
return
|
||||
return true
|
||||
end
|
||||
|
||||
-- error checking when mod profiling is enabled
|
||||
if not tool_capabilities then
|
||||
minetest.log("warning",
|
||||
"[mobs] Mod profiling enabled, damage not enabled")
|
||||
return
|
||||
return true
|
||||
end
|
||||
|
||||
-- is mob protected?
|
||||
@ -2709,7 +2709,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
||||
minetest.chat_send_player(hitter:get_player_name(),
|
||||
S("Mob has been protected!"))
|
||||
|
||||
return
|
||||
return true
|
||||
end
|
||||
|
||||
local weapon = hitter:get_wielded_item()
|
||||
@ -2770,7 +2770,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
||||
if use_cmi
|
||||
and cmi.notify_punch(
|
||||
self.object, hitter, tflp, tool_capabilities, dir, damage) then
|
||||
return
|
||||
return true
|
||||
end
|
||||
|
||||
-- add weapon wear
|
||||
@ -2875,7 +2875,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
||||
local v = self.object:get_velocity()
|
||||
|
||||
-- sanity check
|
||||
if not v then return end
|
||||
if not v then return true end
|
||||
|
||||
local kb = damage or 1
|
||||
local up = 2
|
||||
@ -3699,8 +3699,8 @@ function mobs:spawn_abm_check(pos, node, name)
|
||||
end
|
||||
|
||||
|
||||
function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
|
||||
interval, chance, aoc, min_height, max_height, day_toggle, on_spawn)
|
||||
function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval,
|
||||
chance, aoc, min_height, max_height, day_toggle, on_spawn, map_load)
|
||||
|
||||
-- Do mobs spawn at all?
|
||||
if not mobs_spawn or not mobs.spawning_mobs[name] then
|
||||
@ -3725,191 +3725,215 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
|
||||
minetest.log("action", string.format(
|
||||
"[mobs] Chance setting for %s changed to %s (total: %s)",
|
||||
name, chance, aoc))
|
||||
|
||||
end
|
||||
|
||||
mobs.spawning_mobs[name].aoc = aoc
|
||||
|
||||
minetest.register_abm({
|
||||
local spawn_action = function(pos, node, active_object_count,
|
||||
active_object_count_wider)
|
||||
|
||||
label = name .. " spawning",
|
||||
nodenames = nodes,
|
||||
neighbors = neighbors,
|
||||
interval = interval,
|
||||
chance = max(1, (chance * mob_chance_multiplier)),
|
||||
catch_up = false,
|
||||
-- use instead of abm's chance setting when using lbm
|
||||
if map_load and random(max(1, (chance * mob_chance_multiplier))) > 1 then
|
||||
return
|
||||
end
|
||||
|
||||
action = function(pos, node, active_object_count,
|
||||
active_object_count_wider)
|
||||
-- use instead of abm's neighbor setting when using lbm
|
||||
if map_load and not minetest.find_node_near(pos, 1, neighbors) then
|
||||
--print("--- lbm neighbors not found")
|
||||
return
|
||||
end
|
||||
|
||||
-- is mob actually registered?
|
||||
if not mobs.spawning_mobs[name]
|
||||
or not minetest.registered_entities[name] then
|
||||
-- is mob actually registered?
|
||||
if not mobs.spawning_mobs[name]
|
||||
or not minetest.registered_entities[name] then
|
||||
--print("--- mob doesn't exist", name)
|
||||
return
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- are we over active mob limit
|
||||
if active_limit > 0 and active_mobs >= active_limit then
|
||||
-- are we over active mob limit
|
||||
if active_limit > 0 and active_mobs >= active_limit then
|
||||
--print("--- active mob limit reached", active_mobs, active_limit)
|
||||
return
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- additional custom checks for spawning mob
|
||||
if mobs:spawn_abm_check(pos, node, name) == true then
|
||||
return
|
||||
end
|
||||
-- additional custom checks for spawning mob
|
||||
if mobs:spawn_abm_check(pos, node, name) == true then
|
||||
return
|
||||
end
|
||||
|
||||
-- do not spawn if too many entities in area
|
||||
if active_object_count_wider >= max_per_block then
|
||||
-- do not spawn if too many entities in area
|
||||
if active_object_count_wider
|
||||
and active_object_count_wider >= max_per_block then
|
||||
--print("--- too many entities in area", active_object_count_wider)
|
||||
return
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- get total number of this mob in area
|
||||
local num_mob, is_pla = count_mobs(pos, name)
|
||||
-- get total number of this mob in area
|
||||
local num_mob, is_pla = count_mobs(pos, name)
|
||||
|
||||
if not is_pla then
|
||||
if not is_pla then
|
||||
--print("--- no players within active area, will not spawn " .. name)
|
||||
return
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if num_mob >= aoc then
|
||||
if num_mob >= aoc then
|
||||
--print("--- too many " .. name .. " in area", num_mob .. "/" .. aoc)
|
||||
return
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- if toggle set to nil then ignore day/night check
|
||||
if day_toggle ~= nil then
|
||||
if day_toggle ~= nil then
|
||||
|
||||
local tod = (minetest.get_timeofday() or 0) * 24000
|
||||
local tod = (minetest.get_timeofday() or 0) * 24000
|
||||
|
||||
if tod > 4500 and tod < 19500 then
|
||||
-- daylight, but mob wants night
|
||||
if day_toggle == false then
|
||||
if tod > 4500 and tod < 19500 then
|
||||
-- daylight, but mob wants night
|
||||
if day_toggle == false then
|
||||
--print("--- mob needs night", name)
|
||||
return
|
||||
end
|
||||
else
|
||||
-- night time but mob wants day
|
||||
if day_toggle == true then
|
||||
return
|
||||
end
|
||||
else
|
||||
-- night time but mob wants day
|
||||
if day_toggle == true then
|
||||
--print("--- mob needs day", name)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- spawn above node
|
||||
pos.y = pos.y + 1
|
||||
|
||||
-- are we spawning within height limits?
|
||||
if pos.y > max_height
|
||||
or pos.y < min_height then
|
||||
--print("--- height limits not met", name, pos.y)
|
||||
return
|
||||
end
|
||||
|
||||
-- are light levels ok?
|
||||
local light = minetest.get_node_light(pos)
|
||||
if not light
|
||||
or light > max_light
|
||||
or light < min_light then
|
||||
--print("--- light limits not met", name, light)
|
||||
return
|
||||
end
|
||||
|
||||
-- mobs cannot spawn in protected areas when enabled
|
||||
if not spawn_protected
|
||||
and minetest.is_protected(pos, "") then
|
||||
--print("--- inside protected area", name)
|
||||
return
|
||||
end
|
||||
|
||||
-- only spawn a set distance away from player
|
||||
local objs = minetest.get_objects_inside_radius(
|
||||
pos, mob_nospawn_range)
|
||||
|
||||
for n = 1, #objs do
|
||||
|
||||
if objs[n]:is_player() then
|
||||
--print("--- player too close", name)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- do we have enough space to spawn mob? (thanks wuzzy)
|
||||
local ent = minetest.registered_entities[name]
|
||||
local width_x = max(1,
|
||||
ceil(ent.collisionbox[4] - ent.collisionbox[1]))
|
||||
local min_x, max_x
|
||||
|
||||
if width_x % 2 == 0 then
|
||||
max_x = floor(width_x / 2)
|
||||
min_x = -(max_x - 1)
|
||||
else
|
||||
max_x = floor(width_x / 2)
|
||||
min_x = -max_x
|
||||
end
|
||||
|
||||
local width_z = max(1,
|
||||
ceil(ent.collisionbox[6] - ent.collisionbox[3]))
|
||||
local min_z, max_z
|
||||
|
||||
if width_z % 2 == 0 then
|
||||
max_z = floor(width_z / 2)
|
||||
min_z = -(max_z - 1)
|
||||
else
|
||||
max_z = floor(width_z / 2)
|
||||
min_z = -max_z
|
||||
end
|
||||
|
||||
local max_y = max(0,
|
||||
ceil(ent.collisionbox[5] - ent.collisionbox[2]) - 1)
|
||||
|
||||
for y = 0, max_y do
|
||||
for x = min_x, max_x do
|
||||
for z = min_z, max_z do
|
||||
|
||||
local pos2 = {
|
||||
x = pos.x + x,
|
||||
y = pos.y + y,
|
||||
z = pos.z + z}
|
||||
|
||||
if minetest.registered_nodes[
|
||||
node_ok(pos2).name].walkable == true then
|
||||
--print("--- not enough space to spawn", name)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- spawn mob 1/2 node above ground
|
||||
pos.y = pos.y + 0.5
|
||||
|
||||
-- tweak X/Z spawn pos
|
||||
if width_x % 2 == 0 then
|
||||
pos.x = pos.x + 0.5
|
||||
end
|
||||
|
||||
if width_z % 2 == 0 then
|
||||
pos.z = pos.z + 0.5
|
||||
end
|
||||
|
||||
local mob = minetest.add_entity(pos, name)
|
||||
|
||||
-- print("[mobs] Spawned " .. name .. " at "
|
||||
-- .. minetest.pos_to_string(pos) .. " on "
|
||||
-- .. node.name .. " near " .. neighbors[1])
|
||||
|
||||
if on_spawn then
|
||||
|
||||
local ent = mob:get_luaentity()
|
||||
|
||||
on_spawn(ent, pos)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
-- spawn above node
|
||||
pos.y = pos.y + 1
|
||||
|
||||
-- are we spawning within height limits?
|
||||
if pos.y > max_height
|
||||
or pos.y < min_height then
|
||||
--print("--- height limits not met", name, pos.y)
|
||||
return
|
||||
end
|
||||
|
||||
-- are light levels ok?
|
||||
local light = minetest.get_node_light(pos)
|
||||
if not light
|
||||
or light > max_light
|
||||
or light < min_light then
|
||||
--print("--- light limits not met", name, light)
|
||||
return
|
||||
end
|
||||
|
||||
-- mobs cannot spawn in protected areas when enabled
|
||||
if not spawn_protected
|
||||
and minetest.is_protected(pos, "") then
|
||||
--print("--- inside protected area", name)
|
||||
return
|
||||
end
|
||||
|
||||
-- only spawn a set distance away from player
|
||||
local objs = minetest.get_objects_inside_radius(pos, mob_nospawn_range)
|
||||
|
||||
for n = 1, #objs do
|
||||
|
||||
if objs[n]:is_player() then
|
||||
--print("--- player too close", name)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- do we have enough space to spawn mob? (thanks wuzzy)
|
||||
local ent = minetest.registered_entities[name]
|
||||
local width_x = max(1, ceil(ent.collisionbox[4] - ent.collisionbox[1]))
|
||||
local min_x, max_x
|
||||
|
||||
if width_x % 2 == 0 then
|
||||
max_x = floor(width_x / 2)
|
||||
min_x = -(max_x - 1)
|
||||
else
|
||||
max_x = floor(width_x / 2)
|
||||
min_x = -max_x
|
||||
end
|
||||
|
||||
local width_z = max(1, ceil(ent.collisionbox[6] - ent.collisionbox[3]))
|
||||
local min_z, max_z
|
||||
|
||||
if width_z % 2 == 0 then
|
||||
max_z = floor(width_z / 2)
|
||||
min_z = -(max_z - 1)
|
||||
else
|
||||
max_z = floor(width_z / 2)
|
||||
min_z = -max_z
|
||||
end
|
||||
|
||||
local max_y = max(0, ceil(ent.collisionbox[5] - ent.collisionbox[2]) - 1)
|
||||
|
||||
for y = 0, max_y do
|
||||
for x = min_x, max_x do
|
||||
for z = min_z, max_z do
|
||||
|
||||
local pos2 = {
|
||||
x = pos.x + x,
|
||||
y = pos.y + y,
|
||||
z = pos.z + z}
|
||||
|
||||
if minetest.registered_nodes[node_ok(pos2).name].walkable == true then
|
||||
--print("--- not enough space to spawn", name)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- spawn mob 1/2 node above ground
|
||||
pos.y = pos.y + 0.5
|
||||
|
||||
-- tweak X/Z spawn pos
|
||||
if width_x % 2 == 0 then
|
||||
pos.x = pos.x + 0.5
|
||||
end
|
||||
|
||||
if width_z % 2 == 0 then
|
||||
pos.z = pos.z + 0.5
|
||||
end
|
||||
|
||||
local mob = minetest.add_entity(pos, name)
|
||||
|
||||
-- print("[mobs] Spawned " .. name .. " at "
|
||||
-- .. minetest.pos_to_string(pos) .. " on "
|
||||
-- .. node.name .. " near " .. neighbors[1])
|
||||
|
||||
if on_spawn then
|
||||
on_spawn(mob:get_luaentity(), pos)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- are we registering an abm or lbm?
|
||||
if map_load == true then
|
||||
|
||||
minetest.register_lbm({
|
||||
name = name .. "_spawning",
|
||||
label = name .. " spawning",
|
||||
nodenames = nodes,
|
||||
run_at_every_load = false,
|
||||
|
||||
action = function(pos, node)
|
||||
spawn_action(pos, node)
|
||||
end
|
||||
})
|
||||
|
||||
else
|
||||
|
||||
minetest.register_abm({
|
||||
label = name .. " spawning",
|
||||
nodenames = nodes,
|
||||
neighbors = neighbors,
|
||||
interval = interval,
|
||||
chance = max(1, (chance * mob_chance_multiplier)),
|
||||
catch_up = false,
|
||||
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
spawn_action(pos, node, active_object_count, active_object_count_wider)
|
||||
end
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -3922,7 +3946,7 @@ function mobs:register_spawn(name, nodes, max_light, min_light, chance,
|
||||
end
|
||||
|
||||
|
||||
-- MarkBu's spawn function
|
||||
-- MarkBu's spawn function (USE this one please)
|
||||
function mobs:spawn(def)
|
||||
|
||||
mobs:spawn_specific(
|
||||
@ -3937,7 +3961,8 @@ function mobs:spawn(def)
|
||||
def.min_height or -31000,
|
||||
def.max_height or 31000,
|
||||
def.day_toggle,
|
||||
def.on_spawn)
|
||||
def.on_spawn,
|
||||
def.on_map_load)
|
||||
end
|
||||
|
||||
|
||||
@ -4563,6 +4588,8 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
|
||||
.. ";" .. tag .. "]"
|
||||
.. "button_exit[2.5,3.5;3,1;mob_rename;"
|
||||
.. minetest.formspec_escape(S("Rename")) .. "]")
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
|
7
api.txt
7
api.txt
@ -383,6 +383,9 @@ default setting and can be omitted:
|
||||
anytime
|
||||
'on_spawn' is a custom function which runs after mob has spawned
|
||||
and gives self and pos values.
|
||||
'on_map_load' when true mobs will have a chance of spawning only
|
||||
when new areas of map are loaded, interval will not be
|
||||
used.
|
||||
|
||||
The older spawn functions are still active and working but have no defaults like
|
||||
the mobs:spawn, so it is recommended to use the above instead.
|
||||
@ -698,8 +701,8 @@ mobs_monster:sand_monster 100
|
||||
...you can also change how many of a certain mob appear in an active mapblock by
|
||||
adding a comma and then a new value e.g.
|
||||
|
||||
mobs_animal:cow 8000,4 <-- 4 cows per mapblock at 8000 spawn chance
|
||||
mobs_monster:dirt_monster ,20 <-- 20 dirt monsters per mapblock
|
||||
mobs_animal:cow = 8000,4 <-- 4 cows per mapblock at 8000 spawn chance
|
||||
mobs_monster:dirt_monster = ,20 <-- 20 dirt monsters per mapblock
|
||||
|
||||
|
||||
Rideable Horse Example Mob
|
||||
|
22
crafts.lua
22
crafts.lua
@ -331,3 +331,25 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
tex_obj = nil
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
-- Meat Block (thanks to painterlypack.net for allowing me to use these textures)
|
||||
minetest.register_node("mobs:meatblock", {
|
||||
description = S("Meat Block"),
|
||||
tiles = {"mobs_meat_top.png", "mobs_meat_bottom.png", "mobs_meat_side.png"},
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy = 1, oddly_breakable_by_hand = 1, flammable = 2},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
on_place = minetest.rotate_node,
|
||||
on_use = minetest.item_eat(20),
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "mobs:meatblock",
|
||||
type = "shapeless",
|
||||
recipe = {
|
||||
"group:food_meat", "group:food_meat", "group:food_meat",
|
||||
"group:food_meat", "group:food_meat", "group:food_meat",
|
||||
"group:food_meat", "group:food_meat", "group:food_meat"
|
||||
}
|
||||
})
|
||||
|
@ -23,7 +23,8 @@ Lucky Blocks: 9
|
||||
|
||||
|
||||
Changelog:
|
||||
- 1.52 - Added 'mob_active_limit' in settings to set number of mobs in game
|
||||
- 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,
|
||||
(default is 0 for unlimited), removed {immortal} from mob armor, fluid viscocity slows mobs
|
||||
- 1.51 - Added some node checks for dangerous nodes, jumping and falling tweaks, spawn area check (thx for idea wuzzy), re-enabled mob suffocation, add 'mob_nospawn_range' setting
|
||||
- 1.50 - Added new line_of_sight function that uses raycasting if mt5.0 is found, (thanks Astrobe), dont spawn mobs if world anchor nearby (technic or simple_anchor mods), chinese local added
|
||||
|
BIN
textures/mobs_meat_bottom.png
Normal file
BIN
textures/mobs_meat_bottom.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 253 B |
BIN
textures/mobs_meat_side.png
Normal file
BIN
textures/mobs_meat_side.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 271 B |
BIN
textures/mobs_meat_top.png
Normal file
BIN
textures/mobs_meat_top.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 287 B |
Reference in New Issue
Block a user