mirror of
https://codeberg.org/tenplus1/mobs_redo.git
synced 2025-07-23 02:20:30 +02:00
Compare commits
30 Commits
26ec61ee29
...
83f0b901a4
Author | SHA1 | Date | |
---|---|---|---|
83f0b901a4 | |||
e4ac59609a | |||
7ac8506dda | |||
90df44aeaf | |||
25ab9591e4 | |||
8e6fa64f2d | |||
ce7c4c1449 | |||
08dcdf382a | |||
d2a4150dcb | |||
ca34cc2274 | |||
168014b86f | |||
6f8b6fe3f5 | |||
dd16d63e8e | |||
7bb5e2b382 | |||
7b429df9e9 | |||
0e72f0ca81 | |||
fb42be6b28 | |||
f54c3da9d7 | |||
65e369e5fc | |||
9f74408792 | |||
18c7f0a422 | |||
2fb7bf2c66 | |||
f01e8a61d0 | |||
b756aa50f5 | |||
e83620553d | |||
e5d1958e16 | |||
6a4a02f3fb | |||
5d88766b74 | |||
d31da2d069 | |||
00db86c924 |
228
api.lua
228
api.lua
@ -1,14 +1,34 @@
|
||||
-- Load support for intllib.
|
||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
||||
local S = minetest.get_translator and minetest.get_translator("mobs_redo") or
|
||||
dofile(MP .. "/intllib.lua")
|
||||
|
||||
-- Check for translation method
|
||||
local S
|
||||
if minetest.get_translator ~= nil then
|
||||
S = minetest.get_translator("mobs") -- 5.x translation function
|
||||
else
|
||||
if minetest.get_modpath("intllib") then
|
||||
dofile(minetest.get_modpath("intllib") .. "/init.lua")
|
||||
if intllib.make_gettext_pair then
|
||||
gettext, ngettext = intllib.make_gettext_pair() -- new gettext method
|
||||
else
|
||||
gettext = intllib.Getter() -- old text file method
|
||||
end
|
||||
S = gettext
|
||||
else -- boilerplate function
|
||||
S = function(str, ...)
|
||||
local args = {...}
|
||||
return str:gsub("@%d+", function(match)
|
||||
return args[tonumber(match:sub(2))]
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- CMI support check
|
||||
local use_cmi = minetest.global_exists("cmi")
|
||||
|
||||
mobs = {
|
||||
mod = "redo",
|
||||
version = "20210920",
|
||||
version = "20220804",
|
||||
intllib = S,
|
||||
invis = minetest.global_exists("invisibility") and invisibility or {}
|
||||
}
|
||||
@ -86,8 +106,8 @@ local stuck_timeout = 3 -- how long before stuck mod starts searching
|
||||
local stuck_path_timeout = 5 -- how long will mob follow path before giving up
|
||||
|
||||
-- default nodes
|
||||
local node_fire = "fire:basic_flame"
|
||||
local node_permanent_flame = "fire:permanent_flame"
|
||||
--local node_fire = "fire:basic_flame"
|
||||
--local node_permanent_flame = "fire:permanent_flame"
|
||||
local node_ice = "default:ice"
|
||||
local node_snowblock = "default:snowblock"
|
||||
local node_snow = "default:snow"
|
||||
@ -254,9 +274,9 @@ local check_for = function(look_for, look_inside)
|
||||
return true
|
||||
end
|
||||
|
||||
if str:find("group:") then
|
||||
if str and str:find("group:") then
|
||||
|
||||
local group = str:split(":")[2]
|
||||
local group = str:split(":")[2] or ""
|
||||
|
||||
if minetest.get_item_group(look_for, group) ~= 0 then
|
||||
return true
|
||||
@ -401,8 +421,7 @@ function mob_class:set_animation(anim, force)
|
||||
self.object:set_animation({
|
||||
x = self.animation[anim .. "_start"],
|
||||
y = self.animation[anim .. "_end"]},
|
||||
self.animation[anim .. "_speed"] or
|
||||
self.animation.speed_normal or 15,
|
||||
self.animation[anim .. "_speed"] or self.animation.speed_normal or 15,
|
||||
0, self.animation[anim .. "_loop"] ~= false)
|
||||
end
|
||||
|
||||
@ -526,6 +545,7 @@ local new_line_of_sight = function(self, pos1, pos2, stepsize)
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
-- check line of sight using raycasting (thanks Astrobe)
|
||||
local ray_line_of_sight = function(self, pos1, pos2)
|
||||
|
||||
@ -730,7 +750,7 @@ local HORNY_AGAIN_TIME = 60 * 5 -- 5 minutes
|
||||
local CHILD_GROW_TIME = 60 * 20 -- 20 minutes
|
||||
|
||||
|
||||
-- update nametag colour
|
||||
-- update nametag and infotext
|
||||
function mob_class:update_tag()
|
||||
|
||||
local col = "#00FF00"
|
||||
@ -764,8 +784,16 @@ function mob_class:update_tag()
|
||||
|
||||
end
|
||||
|
||||
if self.protected then
|
||||
if self.protected == 2 then
|
||||
text = text .. "\nProtection: Level 2"
|
||||
else
|
||||
text = text .. "\nProtection: Level 1"
|
||||
end
|
||||
end
|
||||
|
||||
self.infotext = "Health: " .. self.health .. " / " .. self.hp_max
|
||||
.. "\n" .. "Owner: " .. self.owner
|
||||
.. (self.owner == "" and "" or "\nOwner: " .. self.owner)
|
||||
.. text
|
||||
|
||||
-- set changes
|
||||
@ -894,18 +922,7 @@ function mob_class:check_for_death(cmi_cause)
|
||||
self.health = self.hp_max
|
||||
end
|
||||
|
||||
-- backup nametag so we can show health stats
|
||||
-- if not self.nametag2 then
|
||||
-- self.nametag2 = self.nametag or ""
|
||||
-- end
|
||||
|
||||
-- if show_health
|
||||
-- and (cmi_cause and cmi_cause.type == "punch") then
|
||||
|
||||
-- self.htimer = 2
|
||||
-- self.nametag = "♥ " .. self.health .. " / " .. self.hp_max
|
||||
self:update_tag()
|
||||
-- end
|
||||
self:update_tag()
|
||||
|
||||
return false
|
||||
end
|
||||
@ -989,32 +1006,30 @@ end
|
||||
-- get node but use fallback for nil or unknown
|
||||
local node_ok = function(pos, fallback)
|
||||
|
||||
fallback = fallback or mobs.fallback_node
|
||||
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
|
||||
if node and minetest.registered_nodes[node.name] then
|
||||
return node
|
||||
end
|
||||
|
||||
return minetest.registered_nodes[fallback]
|
||||
return minetest.registered_nodes[(fallback or mobs.fallback_node)]
|
||||
end
|
||||
|
||||
|
||||
-- Returns true is node can deal damage to self
|
||||
local is_node_dangerous = function(self, nodename)
|
||||
function mobs:is_node_dangerous(mob_object, nodename)
|
||||
|
||||
if self.water_damage > 0
|
||||
if mob_object.water_damage > 0
|
||||
and minetest.get_item_group(nodename, "water") ~= 0 then
|
||||
return true
|
||||
end
|
||||
|
||||
if self.lava_damage > 0
|
||||
if mob_object.lava_damage > 0
|
||||
and minetest.get_item_group(nodename, "lava") ~= 0 then
|
||||
return true
|
||||
end
|
||||
|
||||
if self.fire_damage > 0
|
||||
if mob_object.fire_damage > 0
|
||||
and minetest.get_item_group(nodename, "fire") ~= 0 then
|
||||
return true
|
||||
end
|
||||
@ -1026,11 +1041,15 @@ local is_node_dangerous = function(self, nodename)
|
||||
return false
|
||||
end
|
||||
|
||||
local function is_node_dangerous(mob_object, nodename)
|
||||
return mobs:is_node_dangerous(mob_object, nodename)
|
||||
end
|
||||
|
||||
|
||||
-- is mob facing a cliff
|
||||
function mob_class:is_at_cliff()
|
||||
|
||||
if self.fear_height == 0 then -- 0 for no falling protection!
|
||||
if self.driver or self.fear_height == 0 then -- 0 for no falling protection!
|
||||
return false
|
||||
end
|
||||
|
||||
@ -1053,7 +1072,7 @@ function mob_class:is_at_cliff()
|
||||
return true
|
||||
end
|
||||
|
||||
local bnode = node_ok(blocker)
|
||||
local bnode = node_ok(blocker, "air")
|
||||
|
||||
-- will we drop onto dangerous node?
|
||||
if is_node_dangerous(self, bnode.name) then
|
||||
@ -1074,14 +1093,7 @@ function mob_class:do_env_damage()
|
||||
self.htimer = self.htimer - 1
|
||||
end
|
||||
|
||||
-- reset nametag after showing health stats
|
||||
-- if self.htimer < 1 and self.nametag2 then
|
||||
|
||||
-- self.nametag = self.nametag2
|
||||
-- self.nametag2 = nil
|
||||
|
||||
self:update_tag()
|
||||
-- end
|
||||
self:update_tag()
|
||||
|
||||
local pos = self.object:get_pos() ; if not pos then return end
|
||||
|
||||
@ -1250,15 +1262,9 @@ function mob_class:do_jump()
|
||||
-- set y_pos to base of mob
|
||||
pos.y = pos.y + self.collisionbox[2]
|
||||
|
||||
-- what is in front of mob?
|
||||
local nod = node_ok({
|
||||
x = pos.x + dir_x, y = pos.y + 0.5, z = pos.z + dir_z
|
||||
})
|
||||
|
||||
-- what is above and in front?
|
||||
local nodt = node_ok({
|
||||
x = pos.x + dir_x, y = pos.y + 1.5, z = pos.z + dir_z
|
||||
})
|
||||
-- what is in front of mob and above?
|
||||
local nod = node_ok({x = pos.x + dir_x, y = pos.y + 0.5, z = pos.z + dir_z})
|
||||
local nodt = node_ok({x = pos.x + dir_x, y = pos.y + 1.5, z = pos.z + dir_z})
|
||||
|
||||
local blocked = minetest.registered_nodes[nodt.name].walkable
|
||||
|
||||
@ -1266,6 +1272,7 @@ function mob_class:do_jump()
|
||||
if nod.name:find("fence") or nod.name:find("gate") or nod.name:find("wall") then
|
||||
self.facing_fence = true
|
||||
end
|
||||
|
||||
--[[
|
||||
print("on: " .. self.standing_on
|
||||
.. ", front: " .. nod.name
|
||||
@ -1274,6 +1281,13 @@ print("on: " .. self.standing_on
|
||||
.. ", fence: " .. (self.facing_fence and "yes" or "no")
|
||||
)
|
||||
]]
|
||||
|
||||
-- if mob can leap then remove blockages and let them try
|
||||
if self.can_leap == true then
|
||||
blocked = false
|
||||
self.facing_fence = false
|
||||
end
|
||||
|
||||
-- jump if standing on solid node (not snow) and not blocked
|
||||
if (self.walk_chance == 0 or minetest.registered_items[nod.name].walkable)
|
||||
and not blocked and not self.facing_fence and nod.name ~= node_snow then
|
||||
@ -1444,8 +1458,7 @@ function mob_class:breed()
|
||||
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
effect({x = pos.x, y = pos.y + 1, z = pos.z}, 8,
|
||||
"heart.png", 3, 4, 1, 0.1)
|
||||
effect({x = pos.x, y = pos.y + 1, z = pos.z}, 8, "heart.png", 3, 4, 1, 0.1)
|
||||
|
||||
local objs = minetest.get_objects_inside_radius(pos, 3)
|
||||
local ent
|
||||
@ -1466,6 +1479,7 @@ function mob_class:breed()
|
||||
local selfname = self.name:split(":")
|
||||
|
||||
if entname[1] == selfname[1] then
|
||||
|
||||
entname = entname[2]:split("_")
|
||||
selfname = selfname[2]:split("_")
|
||||
|
||||
@ -1553,7 +1567,7 @@ function mob_class:breed()
|
||||
self.base_selbox[4] * .5,
|
||||
self.base_selbox[5] * .5,
|
||||
self.base_selbox[6] * .5
|
||||
},
|
||||
}
|
||||
})
|
||||
-- tamed and owned by parents' owner
|
||||
ent2.child = true
|
||||
@ -1629,13 +1643,10 @@ end
|
||||
function mob_class:day_docile()
|
||||
|
||||
if self.docile_by_day == false then
|
||||
|
||||
return false
|
||||
|
||||
elseif self.docile_by_day == true
|
||||
and self.time_of_day > 0.2
|
||||
and self.time_of_day < 0.8 then
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
@ -1680,6 +1691,7 @@ end
|
||||
|
||||
|
||||
local pathfinder_mod = minetest.get_modpath("pathfinder")
|
||||
|
||||
-- path finding and smart mob routine by rnd,
|
||||
-- line_of_sight and other edits by Elkien3
|
||||
function mob_class:smart_mobs(s, p, dist, dtime)
|
||||
@ -2108,7 +2120,7 @@ function mob_class:follow_flop()
|
||||
|
||||
for n = 1, #players do
|
||||
|
||||
if get_distance(players[n]:get_pos(), s) < self.view_range
|
||||
if players[n] and get_distance(players[n]:get_pos(), s) < self.view_range
|
||||
and not is_invisible(self, players[n]:get_player_name()) then
|
||||
|
||||
self.following = players[n]
|
||||
@ -2365,11 +2377,22 @@ function mob_class:do_states(dtime)
|
||||
else
|
||||
self:set_velocity(self.walk_velocity)
|
||||
|
||||
-- figure out which animation to use while in motion
|
||||
if self:flight_check()
|
||||
and self.animation
|
||||
and self.animation.fly_start
|
||||
and self.animation.fly_end then
|
||||
self:set_animation("fly")
|
||||
|
||||
local on_ground = minetest.registered_nodes[self.standing_on].walkable
|
||||
local in_water = minetest.registered_nodes[self.standing_in].groups.water
|
||||
|
||||
if on_ground and in_water then
|
||||
self:set_animation("fly")
|
||||
elseif on_ground then
|
||||
self:set_animation("walk")
|
||||
else
|
||||
self:set_animation("fly")
|
||||
end
|
||||
else
|
||||
self:set_animation("walk")
|
||||
end
|
||||
@ -2618,7 +2641,7 @@ function mob_class:do_states(dtime)
|
||||
yaw = yaw_to_pos(self, p)
|
||||
|
||||
-- move towards enemy if beyond mob reach
|
||||
if dist > self.reach then
|
||||
if dist > (self.reach + (self.reach_ext or 0)) then
|
||||
|
||||
-- path finding by rnd
|
||||
if self.pathfinding -- only if mob has pathfinding enabled
|
||||
@ -2630,8 +2653,13 @@ function mob_class:do_states(dtime)
|
||||
-- distance padding to stop spinning mob
|
||||
local pad = abs(p.x - s.x) + abs(p.z - s.z)
|
||||
|
||||
self.reach_ext = 0 -- extended ready off by default
|
||||
|
||||
if self.at_cliff or pad < 0.2 then
|
||||
|
||||
-- when on top of player extend reach slightly so player can
|
||||
-- still be attacked.
|
||||
self.reach_ext = 0.8
|
||||
self:set_velocity(0)
|
||||
self:set_animation("stand")
|
||||
else
|
||||
@ -2989,7 +3017,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
||||
if self:check_for_death({type = "punch", puncher = hitter, hot = hot}) then
|
||||
return true
|
||||
end
|
||||
end -- END if damage
|
||||
end
|
||||
|
||||
-- knock back effect (only on full punch)
|
||||
if self.knock_back and tflp >= punch_interval then
|
||||
@ -3132,8 +3160,6 @@ function mob_class:mob_staticdata()
|
||||
end
|
||||
end
|
||||
|
||||
--print('===== '..self.name..'\n'.. dump(tmp)..'\n=====\n')
|
||||
|
||||
return minetest.serialize(tmp)
|
||||
end
|
||||
|
||||
@ -3262,7 +3288,7 @@ function mob_class:mob_activate(staticdata, def, dtime)
|
||||
if type(self.armor) == "table" then
|
||||
armor = table_copy(self.armor)
|
||||
else
|
||||
armor = {fleshy = self.armor} -- immortal = 1
|
||||
armor = {fleshy = self.armor, immortal = 1}
|
||||
end
|
||||
self.object:set_armor_groups(armor)
|
||||
|
||||
@ -3344,8 +3370,7 @@ function mob_class:mob_expire(pos, dtime)
|
||||
end
|
||||
end
|
||||
|
||||
-- minetest.log("action",
|
||||
-- S("lifetimer expired, removed @1", self.name))
|
||||
-- minetest.log("action", S("lifetimer expired, removed @1", self.name))
|
||||
|
||||
effect(pos, 15, "tnt_smoke.png", 2, 4, 2, 0)
|
||||
|
||||
@ -3372,9 +3397,9 @@ function mob_class:on_step(dtime, moveresult)
|
||||
-- early warning check, if no yaw then no entity, skip rest of function
|
||||
if not yaw then return end
|
||||
|
||||
-- get node at foot level every quarter second
|
||||
self.node_timer = (self.node_timer or 0) + dtime
|
||||
|
||||
-- get nodes above and below foot level every 1/4 second
|
||||
if self.node_timer > 0.25 then
|
||||
|
||||
self.node_timer = 0
|
||||
@ -3396,8 +3421,7 @@ function mob_class:on_step(dtime, moveresult)
|
||||
|
||||
-- if standing inside solid block then jump to escape
|
||||
if minetest.registered_nodes[self.standing_in].walkable
|
||||
and minetest.registered_nodes[self.standing_in].drawtype
|
||||
== "normal" then
|
||||
and minetest.registered_nodes[self.standing_in].drawtype == "normal" then
|
||||
|
||||
self.object:set_velocity({
|
||||
x = 0,
|
||||
@ -3571,6 +3595,7 @@ minetest.register_entity(name, setmetatable({
|
||||
on_flop = def.on_flop,
|
||||
do_custom = def.do_custom,
|
||||
jump_height = def.jump_height,
|
||||
can_leap = def.can_leap,
|
||||
drawtype = def.drawtype, -- DEPRECATED, use rotate instead
|
||||
rotate = rad(def.rotate or 0), -- 0=front 90=side 180=back 270=side2
|
||||
glow = def.glow,
|
||||
@ -3655,6 +3680,7 @@ minetest.register_entity(name, setmetatable({
|
||||
stay_near = def.stay_near,
|
||||
randomly_turn = def.randomly_turn ~= false,
|
||||
ignore_invisibility = def.ignore_invisibility,
|
||||
messages = def.messages,
|
||||
|
||||
on_spawn = def.on_spawn,
|
||||
|
||||
@ -3672,7 +3698,7 @@ minetest.register_entity(name, setmetatable({
|
||||
|
||||
get_staticdata = function(self)
|
||||
return self:mob_staticdata(self)
|
||||
end,
|
||||
end
|
||||
|
||||
}, mob_class_meta))
|
||||
|
||||
@ -3841,7 +3867,7 @@ function mobs:add_mob(pos, def)
|
||||
ent.base_selbox[4] * .5,
|
||||
ent.base_selbox[5] * .5,
|
||||
ent.base_selbox[6] * .5
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
ent.child = true
|
||||
@ -4337,7 +4363,7 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative)
|
||||
if def and def.on_rightclick then
|
||||
|
||||
return def.on_rightclick(
|
||||
pointed_thing.under, under, placer, itemstack)
|
||||
pointed_thing.under, under, placer, itemstack, pointed_thing)
|
||||
end
|
||||
|
||||
if pos
|
||||
@ -4388,7 +4414,7 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative)
|
||||
if def and def.on_rightclick then
|
||||
|
||||
return def.on_rightclick(
|
||||
pointed_thing.under, under, placer, itemstack)
|
||||
pointed_thing.under, under, placer, itemstack, pointed_thing)
|
||||
end
|
||||
|
||||
if pos
|
||||
@ -4474,7 +4500,7 @@ end
|
||||
function mobs:capture_mob(self, clicker, chance_hand, chance_net,
|
||||
chance_lasso, force_take, replacewith)
|
||||
|
||||
if not self --self.child
|
||||
if not self
|
||||
or not clicker:is_player()
|
||||
or not clicker:get_inventory() then
|
||||
return false
|
||||
@ -4643,8 +4669,7 @@ function mobs:protect(self, clicker)
|
||||
|
||||
pos.y = pos.y + self.collisionbox[2] + 0.5
|
||||
|
||||
effect(self.object:get_pos(), 25, "mobs_protect_particle.png",
|
||||
0.5, 4, 2, 15)
|
||||
effect(self.object:get_pos(), 25, "mobs_protect_particle.png", 0.5, 4, 2, 15)
|
||||
|
||||
self:mob_sound("mobs_spell")
|
||||
|
||||
@ -4678,15 +4703,6 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
|
||||
if self.health >= self.hp_max then
|
||||
|
||||
self.health = self.hp_max
|
||||
|
||||
-- if self.htimer < 1 then
|
||||
|
||||
-- minetest.chat_send_player(clicker:get_player_name(),
|
||||
-- S("@1 at full health (@2)",
|
||||
-- self.name:split(":")[2], tostring(self.health)))
|
||||
|
||||
-- self.htimer = 5
|
||||
-- end
|
||||
end
|
||||
|
||||
self.object:set_hp(self.health)
|
||||
@ -4694,7 +4710,6 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
|
||||
-- make children grow quicker
|
||||
if self.child == true then
|
||||
|
||||
-- self.hornytimer = self.hornytimer + 20
|
||||
-- deduct 10% of the time to adulthood
|
||||
self.hornytimer = math.floor(self.hornytimer + (
|
||||
(CHILD_GROW_TIME - self.hornytimer) * 0.1))
|
||||
@ -4833,7 +4848,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
end)
|
||||
|
||||
|
||||
-- compatibility function for old entities to new modpack entities
|
||||
-- compatibility function for old mobs entities to new mobs_redo modpack
|
||||
function mobs:alias_mob(old_name, new_name)
|
||||
|
||||
-- check old_name entity doesnt already exist
|
||||
@ -4864,3 +4879,44 @@ function mobs:alias_mob(old_name, new_name)
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
-- admin command to remove untamed mobs around players
|
||||
minetest.register_chatcommand("clear_mobs", {
|
||||
params = "<text>",
|
||||
description = "Remove untamed mobs from around players.",
|
||||
privs = {server = true},
|
||||
|
||||
func = function (name, param)
|
||||
|
||||
local count = 0
|
||||
|
||||
for _, player in pairs(minetest.get_connected_players()) do
|
||||
|
||||
if player then
|
||||
|
||||
local pos = player:get_pos()
|
||||
|
||||
local objs = minetest.get_objects_inside_radius(pos, 28)
|
||||
|
||||
for _, obj in pairs(objs) do
|
||||
|
||||
if obj then
|
||||
|
||||
local ent = obj:get_luaentity()
|
||||
|
||||
-- only remove mobs redo mobs that are not tamed
|
||||
if ent and ent._cmi_is_mob and ent.tamed ~= true then
|
||||
|
||||
remove_mob(ent, true)
|
||||
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.chat_send_player(name, S("@1 mobs removed.", count))
|
||||
end
|
||||
})
|
||||
|
13
api.txt
13
api.txt
@ -42,6 +42,8 @@ functions needed for the mob to work properly which contains the following:
|
||||
randomly turn while walking or standing.
|
||||
'jump' when true allows your mob to jump updwards.
|
||||
'jump_height' holds the height your mob can jump, 0 to disable jumping.
|
||||
'can_leap' when true obstacles like fences or pits wont stop a mob
|
||||
from trying to jump out.
|
||||
'stepheight' height of a block that your mob can easily walk up onto,
|
||||
defaults to 1.1.
|
||||
'fly' when true allows your mob to fly around instead of walking.
|
||||
@ -223,6 +225,9 @@ functions needed for the mob to work properly which contains the following:
|
||||
'fly_start' when a mob is flying.
|
||||
'fly_end'
|
||||
'fly_speed'
|
||||
'jump_start' when a mob is jumping
|
||||
'jump_end'
|
||||
'jump_speed'
|
||||
'punch_start' when a mob melee attacks.
|
||||
'punch_end'
|
||||
'punch_speed'
|
||||
@ -415,7 +420,7 @@ the mobs:spawn, so it is recommended to use the above instead.
|
||||
mobs:register_spawn(name, nodes, max_light, min_light, chance,
|
||||
active_object_count, max_height, day_toggle)
|
||||
|
||||
mobs:spawn_specfic(name, nodes, neighbors, min_light, max_light, interval,
|
||||
mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval,
|
||||
chance, active_object_count, min_height, max_height, day_toggle, on_spawn)
|
||||
|
||||
A simpler way to handle mob spawns has been added with the mobs:spawn(def)
|
||||
@ -691,6 +696,12 @@ space to spawn mob [name], if so then a new position is returned for use,
|
||||
otherwise nil is returned.
|
||||
|
||||
|
||||
mobs:is_node_dangerous(mob_object, nodename)
|
||||
|
||||
This function returns true if the node name given is harmful to the mob (mob_object),
|
||||
it is mainly used when a mob is near a node it has to avoid.
|
||||
|
||||
|
||||
External Settings for "minetest.conf"
|
||||
------------------------------------
|
||||
|
||||
|
@ -8,3 +8,4 @@ lucky_block?
|
||||
cmi?
|
||||
toolranks?
|
||||
pathfinder?
|
||||
player_api?
|
||||
|
2
init.lua
2
init.lua
@ -22,4 +22,4 @@ dofile(path .. "/spawner.lua")
|
||||
-- Lucky Blocks
|
||||
dofile(path .. "/lucky_block.lua")
|
||||
|
||||
minetest.log("action", "[MOD] Mobs Redo loaded")
|
||||
print("[MOD] Mobs Redo loaded")
|
||||
|
@ -1,3 +0,0 @@
|
||||
-- Support for the old multi-load method
|
||||
dofile(minetest.get_modpath("intllib").."/init.lua")
|
||||
|
@ -11,7 +11,7 @@ msgstr ""
|
||||
"PO-Revision-Date: 2017-07-02 14:27+0200\n"
|
||||
"Last-Translator: Wuzzy <almikes@aol.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: de_DE\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
2
mod.conf
2
mod.conf
@ -1,4 +1,4 @@
|
||||
name = mobs
|
||||
depends =
|
||||
optional_depends = default, tnt, dye, farming, invisibility, intllib, lucky_block, cmi, toolranks, pathfinder
|
||||
optional_depends = default, tnt, dye, farming, invisibility, intllib, lucky_block, cmi, toolranks, pathfinder, player_api
|
||||
description = Adds a mob api for mods to add animals or monsters etc.
|
||||
|
76
mount.lua
76
mount.lua
@ -1,14 +1,16 @@
|
||||
-- lib_mount by Blert2112 (edited by TenPlus1)
|
||||
|
||||
local is_50 = minetest.get_modpath("player_api") -- 5.x compatibility
|
||||
|
||||
local abs, cos, floor, sin, sqrt, pi =
|
||||
math.abs, math.cos, math.floor, math.sin, math.sqrt, math.pi
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Helper functions
|
||||
--
|
||||
|
||||
local node_ok = function(pos, fallback)
|
||||
|
||||
fallback = fallback or mobs.fallback_node
|
||||
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
@ -46,6 +48,7 @@ end
|
||||
|
||||
|
||||
local function get_sign(i)
|
||||
|
||||
i = i or 0
|
||||
|
||||
if i == 0 then
|
||||
@ -57,6 +60,7 @@ end
|
||||
|
||||
|
||||
local function get_velocity(v, yaw, y)
|
||||
|
||||
local x = -sin(yaw) * v
|
||||
local z = cos(yaw) * v
|
||||
|
||||
@ -71,6 +75,8 @@ end
|
||||
|
||||
local function force_detach(player)
|
||||
|
||||
if not player then return end
|
||||
|
||||
local attached_to = player:get_attach()
|
||||
|
||||
if not attached_to then
|
||||
@ -85,19 +91,27 @@ local function force_detach(player)
|
||||
end
|
||||
|
||||
player:set_detach()
|
||||
player_api.player_attached[player:get_player_name()] = false
|
||||
player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
|
||||
player_api.set_animation(player, "stand", 30)
|
||||
player:set_properties({visual_size = {x = 1, y = 1}})
|
||||
|
||||
local name = player:get_player_name()
|
||||
|
||||
if is_50 then
|
||||
player_api.player_attached[name] = false
|
||||
player_api.set_animation(player, "stand", 30)
|
||||
else
|
||||
default.player_attached[name] = false
|
||||
default.player_set_animation(player, "stand", 30)
|
||||
end
|
||||
|
||||
player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
|
||||
player:set_properties({visual_size = {x = 1, y = 1}})
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
force_detach(player)
|
||||
end)
|
||||
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
|
||||
local players = minetest.get_connected_players()
|
||||
@ -107,12 +121,12 @@ minetest.register_on_shutdown(function()
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
minetest.register_on_dieplayer(function(player)
|
||||
force_detach(player)
|
||||
return true
|
||||
end)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
-- Just for correct detaching
|
||||
local function find_free_pos(pos)
|
||||
@ -147,7 +161,6 @@ local function find_free_pos(pos)
|
||||
return pos
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function mobs.attach(entity, player)
|
||||
|
||||
@ -169,8 +182,13 @@ function mobs.attach(entity, player)
|
||||
|
||||
force_detach(player)
|
||||
|
||||
if is_50 then
|
||||
player_api.player_attached[player:get_player_name()] = true
|
||||
else
|
||||
default.player_attached[player:get_player_name()] = true
|
||||
end
|
||||
|
||||
player:set_attach(entity.object, "", attach_at, entity.player_rotation)
|
||||
player_api.player_attached[player:get_player_name()] = true
|
||||
player:set_eye_offset(eye_offset, {x = 0, y = 0, z = 0})
|
||||
|
||||
player:set_properties({
|
||||
@ -183,7 +201,12 @@ function mobs.attach(entity, player)
|
||||
minetest.after(0.2, function()
|
||||
|
||||
if player and player:is_player() then
|
||||
player_api.set_animation(player, "sit", 30)
|
||||
|
||||
if is_50 then
|
||||
player_api.set_animation(player, "sit", 30)
|
||||
else
|
||||
default.player_set_animation(player, "sit", 30)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
@ -192,6 +215,7 @@ end
|
||||
|
||||
|
||||
function mobs.detach(player)
|
||||
|
||||
force_detach(player)
|
||||
|
||||
minetest.after(0.1, function()
|
||||
@ -218,7 +242,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
end
|
||||
|
||||
local acce_y = 0
|
||||
local velo = entity.object:get_velocity()
|
||||
local velo = entity.object:get_velocity() ; if not velo then return end
|
||||
|
||||
entity.v = get_v(velo) * get_sign(entity.v)
|
||||
|
||||
@ -230,7 +254,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
-- move forwards
|
||||
if ctrl.up then
|
||||
|
||||
entity.v = entity.v + entity.accel / 10
|
||||
entity.v = entity.v + entity.accel * dtime
|
||||
|
||||
-- move backwards
|
||||
elseif ctrl.down then
|
||||
@ -239,7 +263,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
return
|
||||
end
|
||||
|
||||
entity.v = entity.v - entity.accel / 10
|
||||
entity.v = entity.v - entity.accel * dtime
|
||||
end
|
||||
|
||||
-- mob rotation
|
||||
@ -262,6 +286,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
entity.object:set_yaw(horz - entity.rotate)
|
||||
|
||||
if can_fly then
|
||||
|
||||
-- fly up
|
||||
if ctrl.jump then
|
||||
|
||||
@ -271,7 +296,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
|
||||
elseif velo.y > 0 then
|
||||
|
||||
velo.y = velo.y - 0.1
|
||||
velo.y = velo.y - dtime
|
||||
|
||||
if velo.y < 0 then velo.y = 0 end
|
||||
end
|
||||
@ -285,7 +310,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
|
||||
elseif velo.y < 0 then
|
||||
|
||||
velo.y = velo.y + 0.1
|
||||
velo.y = velo.y + dtime
|
||||
|
||||
if velo.y > 0 then velo.y = 0 end
|
||||
end
|
||||
@ -330,14 +355,10 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
end
|
||||
|
||||
-- enforce speed limit forward and reverse
|
||||
local max_spd = entity.max_speed_reverse
|
||||
|
||||
if get_sign(entity.v) >= 0 then
|
||||
max_spd = entity.max_speed_forward
|
||||
end
|
||||
|
||||
if abs(entity.v) > max_spd then
|
||||
entity.v = entity.v - get_sign(entity.v)
|
||||
if entity.v > entity.max_speed_forward then
|
||||
entity.v = entity.max_speed_forward
|
||||
elseif entity.v < -entity.max_speed_reverse then
|
||||
entity.v = -entity.max_speed_reverse
|
||||
end
|
||||
|
||||
-- Set position, velocity and acceleration
|
||||
@ -345,7 +366,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
|
||||
if not p then return end
|
||||
|
||||
local new_acce = {x = 0, y = -9.81, z = 0}
|
||||
local new_acce = {x = 0, y = entity.fall_speed, z = 0}
|
||||
|
||||
p.y = p.y - 0.5
|
||||
|
||||
@ -427,14 +448,15 @@ end
|
||||
-- directional flying routine by D00Med (edited by TenPlus1)
|
||||
function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
|
||||
|
||||
local ctrl = entity.driver:get_player_control()
|
||||
local ctrl = entity.driver:get_player_control() ; if not ctrl then return end
|
||||
local velo = entity.object:get_velocity()
|
||||
local dir = entity.driver:get_look_dir()
|
||||
local yaw = entity.driver:get_look_horizontal() + 1.57 -- offset fix between old and new commands
|
||||
local yaw = entity.driver:get_look_horizontal() + 1.57
|
||||
|
||||
if not ctrl or not velo then return end
|
||||
if not ctrl or not velo then return end
|
||||
|
||||
if ctrl.up then
|
||||
|
||||
entity.object:set_velocity({
|
||||
x = dir.x * speed,
|
||||
y = dir.y * speed + 2,
|
||||
|
Reference in New Issue
Block a user