forked from mtcontrib/mobs_redo
Fix staticdata, tidy code
This commit is contained in:
parent
80a86b658c
commit
c2ecb8321e
280
api.lua
280
api.lua
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
-- Mobs Api (17th March 2017)
|
-- Mobs Api (18th March 2017)
|
||||||
|
|
||||||
mobs = {}
|
mobs = {}
|
||||||
mobs.mod = "redo"
|
mobs.mod = "redo"
|
||||||
|
@ -29,6 +29,27 @@ if rawget(_G, "invisibility") then
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- localize math functions
|
||||||
|
local pi = math.pi
|
||||||
|
local square = math.sqrt
|
||||||
|
local sin = math.sin
|
||||||
|
local cos = math.cos
|
||||||
|
local abs = math.abs
|
||||||
|
local min = math.min
|
||||||
|
local max = math.max
|
||||||
|
local atann = math.atan
|
||||||
|
local random = math.random
|
||||||
|
local floor = math.floor
|
||||||
|
local atan = function(x)
|
||||||
|
if x ~= x then
|
||||||
|
--error("atan bassed NaN")
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return atann(x)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Load settings
|
-- Load settings
|
||||||
local damage_enabled = minetest.setting_getbool("enable_damage")
|
local damage_enabled = minetest.setting_getbool("enable_damage")
|
||||||
local peaceful_only = minetest.setting_getbool("only_peaceful_mobs")
|
local peaceful_only = minetest.setting_getbool("only_peaceful_mobs")
|
||||||
|
@ -43,35 +64,15 @@ local max_per_block = tonumber(minetest.setting_get("max_objects_per_block") or
|
||||||
-- calculate aoc range for mob count
|
-- calculate aoc range for mob count
|
||||||
local aosrb = tonumber(minetest.setting_get("active_object_send_range_blocks"))
|
local aosrb = tonumber(minetest.setting_get("active_object_send_range_blocks"))
|
||||||
local abr = tonumber(minetest.setting_get("active_block_range"))
|
local abr = tonumber(minetest.setting_get("active_block_range"))
|
||||||
local aoc_range = math.max(aosrb, abr) * 16
|
local aoc_range = max(aosrb, abr) * 16
|
||||||
|
|
||||||
-- pathfinding settings
|
-- pathfinding settings
|
||||||
local enable_pathfinding = true
|
local enable_pathfinding = true
|
||||||
local stuck_timeout = 3 -- how long before mob gets stuck in place and starts searching
|
local stuck_timeout = 3 -- how long before mob gets stuck in place and starts searching
|
||||||
local stuck_path_timeout = 10 -- how long will mob follow path before giving up
|
local stuck_path_timeout = 10 -- how long will mob follow path before giving up
|
||||||
|
|
||||||
-- localize functions
|
|
||||||
local pi = math.pi
|
|
||||||
local square = math.sqrt
|
|
||||||
local sin = math.sin
|
|
||||||
local cos = math.cos
|
|
||||||
local abs = math.abs
|
|
||||||
local min = math.min
|
|
||||||
local max = math.max
|
|
||||||
local atann = math.atan
|
|
||||||
local random = math.random
|
|
||||||
local floor = math.floor
|
|
||||||
local atan = function(x)
|
|
||||||
|
|
||||||
if x ~= x then
|
|
||||||
--error("atan bassed NaN")
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return atann(x)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
-- play sound
|
||||||
mob_sound = function(self, sound)
|
mob_sound = function(self, sound)
|
||||||
|
|
||||||
if sound then
|
if sound then
|
||||||
|
@ -84,6 +85,7 @@ mob_sound = function(self, sound)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- attack player/mob
|
||||||
do_attack = function(self, player)
|
do_attack = function(self, player)
|
||||||
|
|
||||||
if self.state == "attack" then
|
if self.state == "attack" then
|
||||||
|
@ -99,6 +101,7 @@ do_attack = function(self, player)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- move mob in facing direction
|
||||||
set_velocity = function(self, v)
|
set_velocity = function(self, v)
|
||||||
|
|
||||||
local yaw = self.object:getyaw() + self.rotate
|
local yaw = self.object:getyaw() + self.rotate
|
||||||
|
@ -111,6 +114,7 @@ set_velocity = function(self, v)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- get overall speed of mob
|
||||||
get_velocity = function(self)
|
get_velocity = function(self)
|
||||||
|
|
||||||
local v = self.object:getvelocity()
|
local v = self.object:getvelocity()
|
||||||
|
@ -1338,15 +1342,14 @@ local do_states = function(self, dtime)
|
||||||
self.state = "walk"
|
self.state = "walk"
|
||||||
set_animation(self, "walk")
|
set_animation(self, "walk")
|
||||||
|
|
||||||
-- fly up/down randombly for flying mobs
|
-- fly up/down randombly for flying mobs
|
||||||
if self.fly and random(1, 100) <= self.walk_chance then
|
if self.fly and random(1, 100) <= self.walk_chance then
|
||||||
|
|
||||||
local v = self.object:getvelocity()
|
local v = self.object:getvelocity()
|
||||||
local ud = random(-1, 2) / 9
|
local ud = random(-1, 2) / 9
|
||||||
|
|
||||||
self.object:setvelocity({x = v.x, y = ud, z = v.z})
|
|
||||||
end
|
|
||||||
|
|
||||||
|
self.object:setvelocity({x = v.x, y = ud, z = v.z})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1393,10 +1396,10 @@ end
|
||||||
|
|
||||||
if lp.x > s.x then yaw = yaw + pi end
|
if lp.x > s.x then yaw = yaw + pi end
|
||||||
|
|
||||||
-- look towards land and jump/move in that direction
|
-- look towards land and jump/move in that direction
|
||||||
self.object:setyaw(yaw)
|
self.object:setyaw(yaw)
|
||||||
do_jump(self)
|
do_jump(self)
|
||||||
set_velocity(self, self.walk_velocity)
|
set_velocity(self, self.walk_velocity)
|
||||||
else
|
else
|
||||||
yaw = (random(0, 360) - 180) / 180 * pi
|
yaw = (random(0, 360) - 180) / 180 * pi
|
||||||
end
|
end
|
||||||
|
@ -1576,7 +1579,6 @@ set_velocity(self, self.walk_velocity)
|
||||||
if self.fly
|
if self.fly
|
||||||
and dist > self.reach then
|
and dist > self.reach then
|
||||||
|
|
||||||
-- local nod = node_ok(s)
|
|
||||||
local p1 = s
|
local p1 = s
|
||||||
local me_y = floor(p1.y)
|
local me_y = floor(p1.y)
|
||||||
local p2 = p
|
local p2 = p
|
||||||
|
@ -1861,6 +1863,7 @@ local falling = function(self, pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- deal damage and effects when mob punched
|
||||||
local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
||||||
|
|
||||||
-- mob health check
|
-- mob health check
|
||||||
|
@ -2070,11 +2073,56 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local mob_activate = function(self, staticdata, dtime_s, def)
|
-- get entity staticdata
|
||||||
|
local mob_staticdata = function(self)
|
||||||
|
|
||||||
|
-- remove mob when out of range unless tamed
|
||||||
|
if remove_far
|
||||||
|
and self.remove_ok
|
||||||
|
and not self.tamed
|
||||||
|
and self.lifetimer < 20000 then
|
||||||
|
|
||||||
|
--print ("REMOVED " .. self.name)
|
||||||
|
|
||||||
|
self.object:remove()
|
||||||
|
|
||||||
|
return ""-- nil
|
||||||
|
end
|
||||||
|
|
||||||
|
self.remove_ok = true
|
||||||
|
self.attack = nil
|
||||||
|
self.following = nil
|
||||||
|
self.state = "stand"
|
||||||
|
|
||||||
|
-- used to rotate older mobs
|
||||||
|
if self.drawtype
|
||||||
|
and self.drawtype == "side" then
|
||||||
|
self.rotate = math.rad(90)
|
||||||
|
end
|
||||||
|
|
||||||
|
local tmp = {}
|
||||||
|
|
||||||
|
for _,stat in pairs(self) do
|
||||||
|
|
||||||
|
local t = type(stat)
|
||||||
|
|
||||||
|
if t ~= "function"
|
||||||
|
and t ~= "nil"
|
||||||
|
and t ~= "userdata" then
|
||||||
|
tmp[_] = self[_]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--print('===== '..self.name..'\n'.. dump(tmp)..'\n=====\n')
|
||||||
|
return minetest.serialize(tmp)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- activate mob and reload settings
|
||||||
|
local mob_activate = function(self, staticdata, def)
|
||||||
|
|
||||||
-- remove monsters in peaceful mode, or when no data
|
-- remove monsters in peaceful mode, or when no data
|
||||||
if (self.type == "monster" and peaceful_only)
|
if (self.type == "monster" and peaceful_only) then
|
||||||
or not staticdata then
|
|
||||||
|
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
|
|
||||||
|
@ -2085,7 +2133,6 @@ local mob_activate = function(self, staticdata, dtime_s, def)
|
||||||
local tmp = minetest.deserialize(staticdata)
|
local tmp = minetest.deserialize(staticdata)
|
||||||
|
|
||||||
if tmp then
|
if tmp then
|
||||||
|
|
||||||
for _,stat in pairs(tmp) do
|
for _,stat in pairs(tmp) do
|
||||||
self[_] = stat
|
self[_] = stat
|
||||||
end
|
end
|
||||||
|
@ -2175,6 +2222,7 @@ local mob_activate = function(self, staticdata, dtime_s, def)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- main mob function
|
||||||
local mob_step = function(self, dtime)
|
local mob_step = function(self, dtime)
|
||||||
|
|
||||||
local pos = self.object:getpos()
|
local pos = self.object:getpos()
|
||||||
|
@ -2305,7 +2353,7 @@ end
|
||||||
|
|
||||||
mobs.spawning_mobs = {}
|
mobs.spawning_mobs = {}
|
||||||
|
|
||||||
-- register mob function
|
-- register mob entity
|
||||||
function mobs:register_mob(name, def)
|
function mobs:register_mob(name, def)
|
||||||
|
|
||||||
mobs.spawning_mobs[name] = true
|
mobs.spawning_mobs[name] = true
|
||||||
|
@ -2402,51 +2450,12 @@ minetest.register_entity(name, {
|
||||||
|
|
||||||
on_punch = mob_punch,
|
on_punch = mob_punch,
|
||||||
|
|
||||||
on_activate = function(self, staticdata, dtime_s)
|
on_activate = function(self, staticdata)
|
||||||
mob_activate(self, staticdata, dtime_s, def)
|
return mob_activate(self, staticdata, def)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
get_staticdata = function(self)
|
get_staticdata = function(self)
|
||||||
|
return mob_staticdata(self)
|
||||||
-- remove mob when out of range unless tamed
|
|
||||||
if remove_far
|
|
||||||
and self.remove_ok
|
|
||||||
and not self.tamed
|
|
||||||
and self.lifetimer < 20000 then
|
|
||||||
|
|
||||||
--print ("REMOVED " .. self.name)
|
|
||||||
|
|
||||||
self.object:remove()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
self.remove_ok = true
|
|
||||||
self.attack = nil
|
|
||||||
self.following = nil
|
|
||||||
self.state = "stand"
|
|
||||||
|
|
||||||
-- used to rotate older mobs
|
|
||||||
if self.drawtype
|
|
||||||
and self.drawtype == "side" then
|
|
||||||
self.rotate = math.rad(90)
|
|
||||||
end
|
|
||||||
|
|
||||||
local tmp = {}
|
|
||||||
|
|
||||||
for _,stat in ipairs(self) do
|
|
||||||
|
|
||||||
local t = type(stat)
|
|
||||||
|
|
||||||
if t ~= 'function'
|
|
||||||
and t ~= 'nil'
|
|
||||||
and t ~= 'userdata' then
|
|
||||||
tmp[_] = self[_]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- print('===== '..self.name..'\n'.. dump(tmp)..'\n=====\n')
|
|
||||||
return minetest.serialize(tmp)
|
|
||||||
end,
|
end,
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -2865,7 +2874,7 @@ function mobs:register_arrow(name, def)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Spawn Egg
|
-- register spawn eggs
|
||||||
function mobs:register_egg(mob, desc, background, addegg, no_creative)
|
function mobs:register_egg(mob, desc, background, addegg, no_creative)
|
||||||
|
|
||||||
local grp = {}
|
local grp = {}
|
||||||
|
@ -2882,6 +2891,56 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative)
|
||||||
"^[mask:mobs_chicken_egg_overlay.png)"
|
"^[mask:mobs_chicken_egg_overlay.png)"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- register new spawn egg containing mob information
|
||||||
|
minetest.register_craftitem(mob .. "_set", {
|
||||||
|
|
||||||
|
description = desc .. " (Tamed)",
|
||||||
|
inventory_image = invimg,
|
||||||
|
groups = {not_in_creative_inventory = 1},
|
||||||
|
stack_max = 1,
|
||||||
|
|
||||||
|
on_place = function(itemstack, placer, pointed_thing)
|
||||||
|
|
||||||
|
local pos = pointed_thing.above
|
||||||
|
|
||||||
|
-- am I clicking on something with existing on_rightclick function?
|
||||||
|
local under = minetest.get_node(pointed_thing.under)
|
||||||
|
local def = minetest.registered_nodes[under.name]
|
||||||
|
if def and def.on_rightclick then
|
||||||
|
return def.on_rightclick(pointed_thing.under, under, placer, itemstack)
|
||||||
|
end
|
||||||
|
|
||||||
|
if pos
|
||||||
|
and within_limits(pos, 0)
|
||||||
|
and not minetest.is_protected(pos, placer:get_player_name()) then
|
||||||
|
|
||||||
|
pos.y = pos.y + 1
|
||||||
|
|
||||||
|
local data = itemstack:get_metadata()
|
||||||
|
local mob = minetest.add_entity(pos, mob, data)
|
||||||
|
local ent = mob:get_luaentity()
|
||||||
|
|
||||||
|
if not ent then
|
||||||
|
mob:remove()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if ent.type ~= "monster" then
|
||||||
|
-- set owner and tame if not monster
|
||||||
|
ent.owner = placer:get_player_name()
|
||||||
|
ent.tamed = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- since mob is unique we remove egg once spawned
|
||||||
|
itemstack:take_item()
|
||||||
|
end
|
||||||
|
|
||||||
|
return itemstack
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
-- register old stackable mob egg
|
||||||
minetest.register_craftitem(mob, {
|
minetest.register_craftitem(mob, {
|
||||||
|
|
||||||
description = desc,
|
description = desc,
|
||||||
|
@ -2929,53 +2988,6 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- spawn egg containing mob information
|
|
||||||
minetest.register_craftitem(mob .. "_set", {
|
|
||||||
|
|
||||||
description = desc .. " (Tamed)",
|
|
||||||
inventory_image = invimg,
|
|
||||||
groups = {not_in_creative_inventory = 1},
|
|
||||||
stack_max = 1,
|
|
||||||
|
|
||||||
on_place = function(itemstack, placer, pointed_thing)
|
|
||||||
|
|
||||||
local pos = pointed_thing.above
|
|
||||||
|
|
||||||
-- am I clicking on something with existing on_rightclick function?
|
|
||||||
local under = minetest.get_node(pointed_thing.under)
|
|
||||||
local def = minetest.registered_nodes[under.name]
|
|
||||||
if def and def.on_rightclick then
|
|
||||||
return def.on_rightclick(pointed_thing.under, under, placer, itemstack)
|
|
||||||
end
|
|
||||||
|
|
||||||
if pos
|
|
||||||
and within_limits(pos, 0)
|
|
||||||
and not minetest.is_protected(pos, placer:get_player_name()) then
|
|
||||||
|
|
||||||
pos.y = pos.y + 1
|
|
||||||
|
|
||||||
local data = itemstack:get_metadata()
|
|
||||||
local mob = minetest.add_entity(pos, mob, data)
|
|
||||||
local ent = mob:get_luaentity()
|
|
||||||
|
|
||||||
if not ent then
|
|
||||||
mob:remove()
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if ent.type ~= "monster" then
|
|
||||||
-- set owner and tame if not monster
|
|
||||||
ent.owner = placer:get_player_name()
|
|
||||||
ent.tamed = true
|
|
||||||
end
|
|
||||||
|
|
||||||
-- since mob is unique we remove egg once spawned
|
|
||||||
itemstack:take_item()
|
|
||||||
end
|
|
||||||
|
|
||||||
return itemstack
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -3058,9 +3070,9 @@ function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso,
|
||||||
|
|
||||||
for _,stat in pairs(self) do
|
for _,stat in pairs(self) do
|
||||||
local t = type(stat)
|
local t = type(stat)
|
||||||
if t ~= 'function'
|
if t ~= "function"
|
||||||
and t ~= 'nil'
|
and t ~= "nil"
|
||||||
and t ~= 'userdata' then
|
and t ~= "userdata" then
|
||||||
tmp[_] = self[_]
|
tmp[_] = self[_]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -3090,7 +3102,7 @@ function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso,
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- protect tamed mob with rune iten
|
-- protect tamed mob with rune item
|
||||||
function mobs:protect(self, clicker)
|
function mobs:protect(self, clicker)
|
||||||
|
|
||||||
local name = clicker:get_player_name()
|
local name = clicker:get_player_name()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user