Merge master of upstream https://notabug.org/TenPlus1/mobs_redo into main
* can now ride mobs redo mobs in mineclone2 (must be fine tuned) better MineClone2 compatibility for api, items and crafts * harder player checks (must be in better way) add check to see what hit mob, player or entity for immune_to * monsters will always attack creatura mobs, anything else will defend it's owner if attacked * change mobs_swing.ogg to mono * can now add nodes to 'runaway_from' table * add damage_per_second nil check * on_breed spawns child a little higher * remove htimer, tweak update_tag() * add mtobjid mod to optional dependencies, stop mob count going * added check to be sure creatura mod enabled * if max_light_damage is 16 then use natural light value to damage mob * min/max light set to 15, only kill mob with natural light * better way to reset pause_timer with "stand" order * pause timer reset, mobs ordered to "stand", fix knockback * fix group attack anim reset, tidy code * simplify yaw clamping
This commit is contained in:
commit
90292f9af2
100
api.lua
100
api.lua
@ -27,10 +27,14 @@ local use_cmi = minetest.global_exists("cmi")
|
||||
|
||||
mobs = {
|
||||
mod = "redo",
|
||||
version = "20230613",
|
||||
version = "20230726",
|
||||
intllib = S,
|
||||
invis = minetest.global_exists("invisibility") and invisibility or {}
|
||||
invis = minetest.global_exists("invisibility") and invisibility or {},
|
||||
node_snow = minetest.registered_aliases["mapgen_snow"] or "mcl_core:snow",
|
||||
node_dirt = minetest.registered_aliases["mapgen_dirt"] or "mcl_core:dirt"
|
||||
}
|
||||
mobs.fallback_node = mobs.node_dirt
|
||||
|
||||
|
||||
-- localize common functions
|
||||
local pi = math.pi
|
||||
@ -135,12 +139,6 @@ local aoc_range = tonumber(settings:get("active_block_range")) * 16
|
||||
local creatura = minetest.get_modpath("creatura") and
|
||||
settings:get_bool("mobs_attack_creatura") == true
|
||||
|
||||
-- default nodes
|
||||
local node_ice = "default:ice"
|
||||
local node_snowblock = "default:snowblock"
|
||||
local node_snow = "default:snow"
|
||||
|
||||
mobs.fallback_node = minetest.registered_aliases["mapgen_dirt"] or "default:dirt"
|
||||
|
||||
mobs.mob_class = {
|
||||
stepheight = 1.1,
|
||||
@ -265,6 +263,15 @@ local get_distance = function(a, b)
|
||||
end
|
||||
|
||||
|
||||
-- are we a real player ?
|
||||
local function is_player(player)
|
||||
|
||||
if player and type(player) == "userdata" and minetest.is_player(player) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- collision function based on jordan4ibanez' open_ai mod
|
||||
function mob_class:collision()
|
||||
|
||||
@ -275,7 +282,7 @@ function mob_class:collision()
|
||||
|
||||
for _,object in ipairs(minetest.get_objects_inside_radius(pos, width)) do
|
||||
|
||||
if object:is_player() then
|
||||
if is_player(object) then
|
||||
|
||||
local pos2 = object:get_pos()
|
||||
local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z}
|
||||
@ -858,7 +865,7 @@ function mob_class:item_drop()
|
||||
-- was mob killed by player?
|
||||
local death_by_player = self.cause_of_death
|
||||
and self.cause_of_death.puncher
|
||||
and self.cause_of_death.puncher:is_player()
|
||||
and is_player(self.cause_of_death.puncher)
|
||||
|
||||
-- check for tool 'looting_level' under tool_capabilities as default, or use
|
||||
-- meta string 'looting_level' if found (max looting level is 3).
|
||||
@ -1312,7 +1319,7 @@ function mob_class:do_jump()
|
||||
and (self.walk_chance == 0 or minetest.registered_items[self.looking_at].walkable)
|
||||
and not blocked
|
||||
and not self.facing_fence
|
||||
and self.looking_at ~= node_snow then
|
||||
and self.looking_at ~= mobs.node_snow then
|
||||
|
||||
local v = self.object:get_velocity()
|
||||
|
||||
@ -2015,7 +2022,7 @@ function mob_class:general_attack()
|
||||
local ent = objs[n]:get_luaentity()
|
||||
|
||||
-- are we a player?
|
||||
if objs[n]:is_player() then
|
||||
if is_player(objs[n]) then
|
||||
|
||||
-- if player invisible or mob cannot attack then remove from list
|
||||
if not damage_enabled
|
||||
@ -2110,9 +2117,10 @@ function mob_class:do_runaway_from()
|
||||
local min_dist = self.view_range + 1
|
||||
local objs = minetest.get_objects_inside_radius(s, self.view_range)
|
||||
|
||||
-- loop through entities surrounding mob
|
||||
for n = 1, #objs do
|
||||
|
||||
if objs[n]:is_player() then
|
||||
if is_player(objs[n]) then
|
||||
|
||||
pname = objs[n]:get_player_name()
|
||||
|
||||
@ -2161,6 +2169,20 @@ function mob_class:do_runaway_from()
|
||||
self.state = "runaway"
|
||||
self.runaway_timer = 3
|
||||
self.following = nil
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
-- check for nodes to runaway from
|
||||
objs = minetest.find_node_near(s, self.view_range, self.runaway_from, true)
|
||||
|
||||
if objs then
|
||||
|
||||
yaw_to_pos(self, objs, 3)
|
||||
|
||||
self.state = "runaway"
|
||||
self.runaway_timer = 3
|
||||
self.following = nil
|
||||
end
|
||||
end
|
||||
|
||||
@ -2203,7 +2225,7 @@ function mob_class:follow_flop()
|
||||
end
|
||||
else
|
||||
-- stop following player if not holding specific item or mob is horny
|
||||
if self.following and self.following:is_player()
|
||||
if self.following and is_player(self.following)
|
||||
and (self:follow_holding(self.following) == false or self.horny) then
|
||||
self.following = nil
|
||||
end
|
||||
@ -2216,7 +2238,7 @@ function mob_class:follow_flop()
|
||||
local s = self.object:get_pos()
|
||||
local p
|
||||
|
||||
if self.following:is_player() then
|
||||
if is_player(self.following) then
|
||||
p = self.following:get_pos()
|
||||
elseif self.following.object then
|
||||
p = self.following.object:get_pos()
|
||||
@ -2316,22 +2338,13 @@ function mob_class:do_states(dtime)
|
||||
if is_node_dangerous(self, self.standing_in) then
|
||||
|
||||
local s = self.object:get_pos()
|
||||
local lp
|
||||
local grps = {}
|
||||
|
||||
-- is there something I need to avoid?
|
||||
if self.water_damage > 0
|
||||
and self.lava_damage > 0 then
|
||||
if self.water_damage > 0 then table.insert(grps, "group:water") end
|
||||
if self.fire_damage > 0 then table.insert(grps, "group:fire") end
|
||||
if self.lava_damage > 0 then table.insert(grps, "group:lava") end
|
||||
|
||||
lp = minetest.find_node_near(s, 1, {"group:water", "group:igniter"})
|
||||
|
||||
elseif self.water_damage > 0 then
|
||||
|
||||
lp = minetest.find_node_near(s, 1, {"group:water"})
|
||||
|
||||
elseif self.lava_damage > 0 then
|
||||
|
||||
lp = minetest.find_node_near(s, 1, {"group:igniter"})
|
||||
end
|
||||
local lp = minetest.find_node_near(s, 1, grps)
|
||||
|
||||
if lp then
|
||||
|
||||
@ -2340,7 +2353,7 @@ function mob_class:do_states(dtime)
|
||||
lp = minetest.find_nodes_in_area_under_air(
|
||||
{x = s.x - 5, y = s.y , z = s.z - 5},
|
||||
{x = s.x + 5, y = s.y + 2, z = s.z + 5},
|
||||
{"group:soil", "group:stone", "group:sand", node_ice, node_snowblock})
|
||||
{"group:cracky", "group:crumbly", "group:choppy", "group:solid"})
|
||||
|
||||
-- did we find land?
|
||||
if lp and #lp > 0 then
|
||||
@ -2372,7 +2385,7 @@ function mob_class:do_states(dtime)
|
||||
|
||||
for n = 1, #objs do
|
||||
|
||||
if objs[n]:is_player() then
|
||||
if is_player(objs[n]) then
|
||||
lp = objs[n]:get_pos()
|
||||
break
|
||||
end
|
||||
@ -2484,7 +2497,7 @@ function mob_class:do_states(dtime)
|
||||
or not self.attack
|
||||
or not self.attack:get_pos()
|
||||
or self.attack:get_hp() <= 0
|
||||
or (self.attack:is_player()
|
||||
or (is_player(self.attack)
|
||||
and is_invisible(self, self.attack:get_player_name())) then
|
||||
|
||||
--print(" ** stop attacking **", self.name, self.health, dist, self.view_range)
|
||||
@ -2875,7 +2888,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
||||
if self.protected then
|
||||
|
||||
-- did player hit mob and if so is it in protected area
|
||||
if hitter:is_player() then
|
||||
if is_player(hitter) then
|
||||
|
||||
local player_name = hitter:get_player_name()
|
||||
|
||||
@ -2933,10 +2946,17 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
||||
end
|
||||
end
|
||||
|
||||
-- check if hit by player item or entity
|
||||
local hit_item = weapon_def.name
|
||||
|
||||
if not is_player(hitter) then
|
||||
hit_item = hitter:get_luaentity().name
|
||||
end
|
||||
|
||||
-- check for tool immunity or special damage
|
||||
for n = 1, #self.immune_to do
|
||||
|
||||
if self.immune_to[n][1] == weapon_def.name then
|
||||
if self.immune_to[n][1] == hit_item then
|
||||
|
||||
damage = self.immune_to[n][2] or 0
|
||||
|
||||
@ -3036,7 +3056,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir, damage)
|
||||
local entity = hitter and hitter:get_luaentity()
|
||||
|
||||
-- check if arrow from same mob, if so then do no damage
|
||||
if (entity and entity.name ~= self.arrow) or hitter:is_player() then
|
||||
if (entity and entity.name ~= self.arrow) or is_player(hitter) then
|
||||
self.health = self.health - floor(damage)
|
||||
end
|
||||
end
|
||||
@ -3399,7 +3419,7 @@ function mob_class:mob_expire(pos, dtime)
|
||||
|
||||
for n = 1, #objs do
|
||||
|
||||
if objs[n]:is_player() then
|
||||
if is_player(objs[n]) then
|
||||
|
||||
self.lifetimer = 20
|
||||
|
||||
@ -3779,7 +3799,7 @@ local function count_mobs(pos, type)
|
||||
|
||||
for n = 1, #objs do
|
||||
|
||||
if not objs[n]:is_player() then
|
||||
if not is_player(objs[n]) then
|
||||
|
||||
ent = objs[n]:get_luaentity()
|
||||
|
||||
@ -4101,7 +4121,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter
|
||||
|
||||
for n = 1, #objs do
|
||||
|
||||
if objs[n]:is_player() then
|
||||
if is_player(objs[n]) then
|
||||
--print("--- player too close", name)
|
||||
return
|
||||
end
|
||||
@ -4297,7 +4317,7 @@ function mobs:register_arrow(name, def)
|
||||
|
||||
for _,player in pairs(minetest.get_objects_inside_radius(pos, 1.0)) do
|
||||
|
||||
if self.hit_player and player:is_player() then
|
||||
if self.hit_player and is_player(player) then
|
||||
|
||||
self:hit_player(player)
|
||||
|
||||
@ -4545,7 +4565,7 @@ end
|
||||
function mobs:capture_mob(
|
||||
self, clicker, chance_hand, chance_net, chance_lasso, force_take, replacewith)
|
||||
|
||||
if not self or not clicker:is_player() or not clicker:get_inventory() then
|
||||
if not self or not is_player(clicker) or not clicker:get_inventory() then
|
||||
return false
|
||||
end
|
||||
|
||||
|
4
api.txt
4
api.txt
@ -154,8 +154,8 @@ functions needed for the mob to work properly which contains the following:
|
||||
'friendly_fire` when set to false, mobs will not be able to harm other
|
||||
mobs of the same type with friendly fire arrows.
|
||||
Defaults to true.
|
||||
'runaway_from' contains a table with mob names to run away from, add
|
||||
"player" to list to runaway from player also.
|
||||
'runaway_from' contains a table with mob names or nodesto run away
|
||||
from, add "player" to list to runaway from player also.
|
||||
'ignore_invisibility' When true mob will still be able to see and attack
|
||||
player even if invisible (invisibility mod only).
|
||||
'blood_amount' contains the number of blood droplets to appear when
|
||||
|
77
crafts.lua
77
crafts.lua
@ -1,5 +1,24 @@
|
||||
|
||||
local S = mobs.intllib
|
||||
local mc2 = minetest.get_modpath("mcl_core")
|
||||
|
||||
-- recipe items
|
||||
local items = {
|
||||
paper = mc2 and "mcl_core:paper" or "default:paper",
|
||||
dye_black = mc2 and "mcl_dye:black" or "dye:black",
|
||||
string = mc2 and "mcl_mobitems:string" or "farming:string",
|
||||
stick = mc2 and "mcl_core:stick" or "default:stick",
|
||||
diamond = mc2 and "mcl_core:diamond" or "default:diamond",
|
||||
steel_ingot = mc2 and "mcl_core:iron_ingot" or "default:steel_ingot",
|
||||
gold_block = mc2 and "mcl_core:goldblock" or "default:goldblock",
|
||||
diamond_block = mc2 and "mcl_core:diamondblock" or "default:diamondblock",
|
||||
stone = mc2 and "mcl_core:stone" or "default:stone",
|
||||
mese_crystal = mc2 and "mcl_core:gold_ingot" or "default:mese_crystal",
|
||||
wood = mc2 and "mcl_core:wood" or "default:wood",
|
||||
fence_wood = mc2 and "group:fence_wood" or "default:fence_wood",
|
||||
meat_raw = mc2 and "mcl_mobitems:beef" or "group:food_meat_raw",
|
||||
meat_cooked = mc2 and "mcl_mobitems:cooked_beef" or "group:food_meat",
|
||||
}
|
||||
|
||||
-- name tag
|
||||
minetest.register_craftitem("mobs:nametag", {
|
||||
@ -8,12 +27,12 @@ minetest.register_craftitem("mobs:nametag", {
|
||||
groups = {flammable = 2, nametag = 1}
|
||||
})
|
||||
|
||||
if minetest.get_modpath("dye") and minetest.get_modpath("farming") then
|
||||
minetest.register_craft({
|
||||
output = "mobs:nametag",
|
||||
recipe = {{"default:paper", "dye:black", "farming:string"}}
|
||||
recipe = {
|
||||
{ items.paper, items.dye_black, items.string }
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
-- leather
|
||||
minetest.register_craftitem("mobs:leather", {
|
||||
@ -52,17 +71,14 @@ minetest.register_tool("mobs:lasso", {
|
||||
groups = {flammable = 2}
|
||||
})
|
||||
|
||||
if minetest.get_modpath("farming") then
|
||||
|
||||
minetest.register_craft({
|
||||
output = "mobs:lasso",
|
||||
recipe = {
|
||||
{"farming:string", "", "farming:string"},
|
||||
{"", "default:diamond", ""},
|
||||
{"farming:string", "", "farming:string"}
|
||||
{ items.string, "", items.string},
|
||||
{ "", items.diamond, "" },
|
||||
{ items.string, "", items.string }
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_alias("mobs:magic_lasso", "mobs:lasso")
|
||||
|
||||
@ -73,17 +89,14 @@ minetest.register_tool("mobs:net", {
|
||||
groups = {flammable = 2}
|
||||
})
|
||||
|
||||
if minetest.get_modpath("farming") then
|
||||
|
||||
minetest.register_craft({
|
||||
output = "mobs:net",
|
||||
recipe = {
|
||||
{"group:stick", "", "group:stick"},
|
||||
{"group:stick", "", "group:stick"},
|
||||
{"farming:string", "group:stick", "farming:string"}
|
||||
{ items.stick, "", items.stick },
|
||||
{ items.stick, "", items.stick },
|
||||
{ items.string, items.stick, items.string }
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
-- shears (right click to shear animal)
|
||||
minetest.register_tool("mobs:shears", {
|
||||
@ -95,8 +108,8 @@ minetest.register_tool("mobs:shears", {
|
||||
minetest.register_craft({
|
||||
output = "mobs:shears",
|
||||
recipe = {
|
||||
{"", "default:steel_ingot", ""},
|
||||
{"", "group:stick", "default:steel_ingot"}
|
||||
{ "", items.steel_ingot, "" },
|
||||
{ "", items.stick, items.steel_ingot }
|
||||
}
|
||||
})
|
||||
|
||||
@ -110,9 +123,9 @@ minetest.register_craftitem("mobs:protector", {
|
||||
minetest.register_craft({
|
||||
output = "mobs:protector",
|
||||
recipe = {
|
||||
{"default:stone", "default:stone", "default:stone"},
|
||||
{"default:stone", "default:goldblock", "default:stone"},
|
||||
{"default:stone", "default:stone", "default:stone"}
|
||||
{ items.stone, items.stone, items.stone },
|
||||
{ items.stone, items.gold_block, items.stone },
|
||||
{ items.stone, items.stone, items.stone }
|
||||
}
|
||||
})
|
||||
|
||||
@ -126,9 +139,9 @@ minetest.register_craftitem("mobs:protector2", {
|
||||
minetest.register_craft({
|
||||
output = "mobs:protector2",
|
||||
recipe = {
|
||||
{"mobs:protector", "default:mese_crystal", "mobs:protector"},
|
||||
{"default:mese_crystal", "default:diamondblock", "default:mese_crystal"},
|
||||
{"mobs:protector", "default:mese_crystal", "mobs:protector"}
|
||||
{ "mobs:protector", items.mese_crystal, "mobs:protector" },
|
||||
{ items.mese_crystal, items.diamond_block, items.mese_crystal },
|
||||
{ "mobs:protector", items.mese_crystal, "mobs:protector" }
|
||||
}
|
||||
})
|
||||
|
||||
@ -143,8 +156,8 @@ minetest.register_craft({
|
||||
output = "mobs:saddle",
|
||||
recipe = {
|
||||
{"mobs:leather", "mobs:leather", "mobs:leather"},
|
||||
{"mobs:leather", "default:steel_ingot", "mobs:leather"},
|
||||
{"mobs:leather", "default:steel_ingot", "mobs:leather"}
|
||||
{"mobs:leather", items.steel_ingot, "mobs:leather"},
|
||||
{"mobs:leather", items.steel_ingot, "mobs:leather"}
|
||||
}
|
||||
})
|
||||
|
||||
@ -197,7 +210,7 @@ minetest.register_craft({
|
||||
output = "mobs:fence_top 12",
|
||||
recipe = {
|
||||
{"group:wood", "group:wood", "group:wood"},
|
||||
{"", "default:fence_wood", ""}
|
||||
{"", items.fence_wood, ""}
|
||||
}
|
||||
})
|
||||
|
||||
@ -372,9 +385,9 @@ minetest.register_node("mobs:meatblock", {
|
||||
minetest.register_craft({
|
||||
output = "mobs:meatblock",
|
||||
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"}
|
||||
{ items.meat_cooked, items.meat_cooked, items.meat_cooked },
|
||||
{ items.meat_cooked, items.meat_cooked, items.meat_cooked },
|
||||
{ items.meat_cooked, items.meat_cooked, items.meat_cooked }
|
||||
}
|
||||
})
|
||||
|
||||
@ -392,9 +405,9 @@ minetest.register_node("mobs:meatblock_raw", {
|
||||
minetest.register_craft({
|
||||
output = "mobs:meatblock_raw",
|
||||
recipe = {
|
||||
{"group:food_meat_raw", "group:food_meat_raw", "group:food_meat_raw"},
|
||||
{"group:food_meat_raw", "group:food_meat_raw", "group:food_meat_raw"},
|
||||
{"group:food_meat_raw", "group:food_meat_raw", "group:food_meat_raw"}
|
||||
{ items.meat_raw, items.meat_raw, items.meat_raw },
|
||||
{ items.meat_raw, items.meat_raw, items.meat_raw },
|
||||
{ items.meat_raw, items.meat_raw, items.meat_raw }
|
||||
}
|
||||
})
|
||||
|
||||
|
1
init.lua
1
init.lua
@ -7,6 +7,7 @@ minetest.register_privilege("peaceful_player", {
|
||||
give_to_singleplayer = false
|
||||
})
|
||||
|
||||
|
||||
-- Mob API
|
||||
dofile(path .. "/api.lua")
|
||||
|
||||
|
61
mount.lua
61
mount.lua
@ -1,6 +1,20 @@
|
||||
-- lib_mount by Blert2112 (edited by TenPlus1)
|
||||
|
||||
--[[ one of these is needed (for now) to ride mobs, otherwise no riding for you
|
||||
if not minetest.get_modpath("default")
|
||||
or not minetest.get_modpath("player_api") then
|
||||
|
||||
function mobs.attach() end
|
||||
function mobs.detach() end
|
||||
function mobs.fly() end
|
||||
function mobs.drive() end
|
||||
|
||||
return
|
||||
end
|
||||
]]
|
||||
|
||||
local is_50 = minetest.get_modpath("player_api") -- 5.x compatibility
|
||||
local is_mc2 = minetest.get_modpath("mcl_mobs") -- MineClone2 compatibility
|
||||
|
||||
local abs, cos, floor, sin, sqrt, pi =
|
||||
math.abs, math.cos, math.floor, math.sin, math.sqrt, math.pi
|
||||
@ -75,9 +89,7 @@ end
|
||||
|
||||
local function force_detach(player)
|
||||
|
||||
if not player then return end
|
||||
|
||||
local attached_to = player:get_attach()
|
||||
local attached_to = player and player:get_attach()
|
||||
|
||||
if not attached_to then
|
||||
return
|
||||
@ -85,8 +97,7 @@ local function force_detach(player)
|
||||
|
||||
local entity = attached_to:get_luaentity()
|
||||
|
||||
if entity and entity.driver
|
||||
and entity.driver == player then
|
||||
if entity and entity.driver and entity.driver == player then
|
||||
entity.driver = nil
|
||||
end
|
||||
|
||||
@ -97,6 +108,9 @@ local function force_detach(player)
|
||||
if is_50 then
|
||||
player_api.player_attached[name] = false
|
||||
player_api.set_animation(player, "stand", 30)
|
||||
elseif is_mc2 then
|
||||
mcl_player.player_attached[player:get_player_name()] = false
|
||||
mcl_player.player_set_animation(player, "stand", 30)
|
||||
else
|
||||
default.player_attached[name] = false
|
||||
default.player_set_animation(player, "stand", 30)
|
||||
@ -151,8 +165,7 @@ local function find_free_pos(pos)
|
||||
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
|
||||
if def and not def.walkable and
|
||||
def.liquidtype == "none" then
|
||||
if def and not def.walkable and def.liquidtype == "none" then
|
||||
return npos
|
||||
end
|
||||
end
|
||||
@ -162,6 +175,15 @@ local function find_free_pos(pos)
|
||||
end
|
||||
|
||||
|
||||
-- are we a real player ?
|
||||
local function is_player(player)
|
||||
|
||||
if player and type(player) == "userdata" and minetest.is_player(player) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function mobs.attach(entity, player)
|
||||
|
||||
entity.player_rotation = entity.player_rotation or {x = 0, y = 0, z = 0}
|
||||
@ -184,6 +206,8 @@ function mobs.attach(entity, player)
|
||||
|
||||
if is_50 then
|
||||
player_api.player_attached[player:get_player_name()] = true
|
||||
elseif is_mc2 then
|
||||
mcl_player.player_attached[player:get_player_name()] = true
|
||||
else
|
||||
default.player_attached[player:get_player_name()] = true
|
||||
end
|
||||
@ -200,10 +224,12 @@ function mobs.attach(entity, player)
|
||||
|
||||
minetest.after(0.2, function()
|
||||
|
||||
if player and player:is_player() then
|
||||
if is_player(player) then
|
||||
|
||||
if is_50 then
|
||||
player_api.set_animation(player, "sit", 30)
|
||||
elseif is_mc2 then
|
||||
mcl_player.player_set_animation(player, "sit_mount" , 30)
|
||||
else
|
||||
default.player_set_animation(player, "sit", 30)
|
||||
end
|
||||
@ -251,13 +277,11 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
|
||||
local ctrl = entity.driver:get_player_control()
|
||||
|
||||
-- move forwards
|
||||
if ctrl.up then
|
||||
if ctrl.up then -- move forwards
|
||||
|
||||
entity.v = entity.v + entity.accel * dtime
|
||||
|
||||
-- move backwards
|
||||
elseif ctrl.down then
|
||||
elseif ctrl.down then -- move backwards
|
||||
|
||||
if entity.max_speed_reverse == 0 and entity.v == 0 then
|
||||
return
|
||||
@ -287,8 +311,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
|
||||
if can_fly then
|
||||
|
||||
-- fly up
|
||||
if ctrl.jump then
|
||||
if ctrl.jump then -- fly up
|
||||
|
||||
velo.y = velo.y + 1
|
||||
|
||||
@ -301,8 +324,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
if velo.y < 0 then velo.y = 0 end
|
||||
end
|
||||
|
||||
-- fly down
|
||||
if ctrl.sneak then
|
||||
if ctrl.sneak then -- fly down
|
||||
|
||||
velo.y = velo.y - 1
|
||||
|
||||
@ -315,8 +337,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
||||
if velo.y > 0 then velo.y = 0 end
|
||||
end
|
||||
else
|
||||
-- jump
|
||||
if ctrl.jump then
|
||||
if ctrl.jump then -- jump
|
||||
|
||||
if velo.y == 0 then
|
||||
velo.y = velo.y + entity.jump_height
|
||||
@ -449,12 +470,10 @@ end
|
||||
function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
|
||||
|
||||
local ctrl = entity.driver:get_player_control() ; if not ctrl then return end
|
||||
local velo = entity.object:get_velocity()
|
||||
local velo = entity.object:get_velocity() ; if not velo then return end
|
||||
local dir = entity.driver:get_look_dir()
|
||||
local yaw = entity.driver:get_look_horizontal() + 1.57
|
||||
|
||||
if not ctrl or not velo then return end
|
||||
|
||||
if ctrl.up then
|
||||
|
||||
entity.object:set_velocity({
|
||||
|
@ -37,6 +37,8 @@ Zeg9, ExeterDad and AspireMint.
|
||||
* Refactored do_jump and added get_nodes function
|
||||
* Many bug fixes and tweaks to improve performance
|
||||
* Added 'mobs_attack_creatura' setting so that monsters can attack Creatura mobs
|
||||
* Nodes can be added to 'runaway_from' table
|
||||
* Better Mineclone2 compatibility with api, items and recipes
|
||||
|
||||
### Version 1.56
|
||||
|
||||
|
Binary file not shown.
13
spawner.lua
13
spawner.lua
@ -1,8 +1,17 @@
|
||||
|
||||
local S = mobs.intllib
|
||||
|
||||
-- mob spawner
|
||||
|
||||
-- are we a real player ?
|
||||
local function is_player(player)
|
||||
|
||||
if player and type(player) == "userdata" and minetest.is_player(player) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- mob spawner
|
||||
local spawner_default = "mobs_animal:pumba 10 15 0 0 0"
|
||||
|
||||
minetest.register_node("mobs:spawner", {
|
||||
@ -148,7 +157,7 @@ minetest.register_abm({
|
||||
|
||||
for _, oir in pairs(objsp) do
|
||||
|
||||
if oir:is_player() then
|
||||
if is_player(oir) then
|
||||
|
||||
in_range = 1
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user