Fix creatures (zombies)
This commit is contained in:
parent
abc4a45152
commit
e58fbf9c82
@ -1,5 +1,8 @@
|
||||
creatures = {}
|
||||
|
||||
-- Max number of mobs per mapblock
|
||||
creatures.zombie_max = 3
|
||||
|
||||
creatures.ANIM_STAND = 1
|
||||
creatures.ANIM_SIT = 2
|
||||
creatures.ANIM_LAY = 3
|
||||
@ -7,26 +10,58 @@ creatures.ANIM_WALK = 4
|
||||
creatures.ANIM_EAT = 5
|
||||
creatures.ANIM_RUN = 6
|
||||
|
||||
-- Drop items (when not killed by player) only if items get removed
|
||||
creatures.drop_on_death = false
|
||||
local remove_items = minetest.setting_get("remove_items")
|
||||
local remove_items_2 = minetest.setting_get("item_entity_ttl")
|
||||
if minetest.get_modpath("builtin_item") ~= nil and ((remove_items ~= nil and tonumber(remove_items) > 0) or
|
||||
(remove_items_2 ~= nil and tonumber(remove_items_2) > 0)) then
|
||||
creatures.drop_on_death = true
|
||||
end
|
||||
|
||||
-- spawning controls (experimental)
|
||||
creatures.spawned = {}
|
||||
local spawn_day = 600
|
||||
local tod = 0
|
||||
local absolute_mob_max = 50
|
||||
|
||||
local function timer(tick)
|
||||
tod = tod + 1
|
||||
if tod > spawn_day then
|
||||
tod = 0
|
||||
creatures.spawned = nil
|
||||
creatures.spawned = {}
|
||||
end
|
||||
minetest.after(tick, timer, tick)
|
||||
end
|
||||
|
||||
timer(1)
|
||||
|
||||
|
||||
local tool_uses = {0, 30, 110, 150, 280, 300, 500, 1000}
|
||||
|
||||
-- helping functions
|
||||
|
||||
function creatures.spawn(pos, number, mob, limit, range)
|
||||
function creatures.spawn(pos, number, mob, limit, range, abs_max)
|
||||
if not pos or not number or not mob then return end
|
||||
if number < 1 then return end
|
||||
if limit == nil then limit = 1 end
|
||||
if range == nil then range = 10 end
|
||||
if abs_max == nil then abs_max = absolute_mob_max end
|
||||
local m_name = string.sub(mob,11)
|
||||
local spawned = creatures.spawned[m_name]
|
||||
if not spawned then spawned = 0 end
|
||||
local res,mobs,player_near = creatures.find_mates(pos, m_name, range)
|
||||
for i=1,number do
|
||||
local x = 1/math.random(1,3)
|
||||
local z = 1/math.random(1,3)
|
||||
local p = {x=pos.x+x,y=pos.y,z=pos.z+z}
|
||||
if mobs+i <= limit then
|
||||
minetest.after(i/5,function()
|
||||
minetest.env:add_entity(p, mob)
|
||||
if mobs+i <= limit and spawned+i < abs_max then
|
||||
local obj = minetest.add_entity(p, mob)
|
||||
if obj then
|
||||
creatures.spawned[m_name] = spawned + 1
|
||||
minetest.log("action", "Spawned "..mob.." at ("..pos.x..","..pos.y..","..pos.z..")")
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -58,7 +93,7 @@ function creatures.drop(pos, items, dir)
|
||||
if node == nil or not node.name or node.name ~= "air" then
|
||||
p = pos
|
||||
end
|
||||
local obj = minetest.env:add_item(p, {name=item.name})
|
||||
local obj = minetest.add_item(p, {name=item.name})
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -66,20 +101,20 @@ end
|
||||
function creatures.find_mates(pos, name, radius)
|
||||
local player_near = false
|
||||
local mobs = 0
|
||||
for _,obj in ipairs(minetest.env:get_objects_inside_radius(pos, radius)) do
|
||||
local res = false
|
||||
for _,obj in ipairs(minetest.get_objects_inside_radius(pos, radius)) do
|
||||
if obj:is_player() then
|
||||
player_near = true
|
||||
else
|
||||
local entity = obj:get_luaentity()
|
||||
if entity and entity.mob_name and entity.mob_name == name then
|
||||
mobs = mobs + 1
|
||||
mobs = mobs + 1
|
||||
res = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if mobs > 1 then
|
||||
return true,mobs,player_near
|
||||
end
|
||||
return false,mobs,player_near
|
||||
|
||||
return res,mobs,player_near
|
||||
end
|
||||
|
||||
function creatures.compare_pos(pos1,pos2)
|
||||
@ -122,7 +157,37 @@ function creatures.jump(self, pos, jump_y, timer)
|
||||
def2 = minetest.registered_items[n2.name]
|
||||
end
|
||||
if def and def.walkable and def2 and not def2.walkable and not def.groups.fences and n.name ~= "default:fence_wood" then--
|
||||
self.object:setvelocity({x=self.object:getvelocity().x,y=jump_y,z=self.object:getvelocity().z})
|
||||
self.object:setvelocity({x=self.object:getvelocity().x*2.2,y=jump_y,z=self.object:getvelocity().z*2.2})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function creatures.follow(self, items, radius)
|
||||
local current_pos = self.object:getpos()
|
||||
-- seach for players
|
||||
for _,object in ipairs(minetest.env:get_objects_inside_radius(current_pos, radius)) do
|
||||
if object:is_player() then
|
||||
local item = object:get_wielded_item()
|
||||
local item_name = item:get_name()
|
||||
if item and item_name and item_name ~= "" then
|
||||
local quit = true
|
||||
for _,food in ipairs(items) do
|
||||
if food.name == item_name then
|
||||
quit = false
|
||||
end
|
||||
end
|
||||
if quit then return end
|
||||
NPC = current_pos
|
||||
PLAYER = object:getpos()
|
||||
self.vec = {x=PLAYER.x-NPC.x, y=PLAYER.y-NPC.y, z=PLAYER.z-NPC.z}
|
||||
self.yaw = math.atan(self.vec.z/self.vec.x)+math.pi^2
|
||||
if PLAYER.x > NPC.x then
|
||||
self.yaw = self.yaw + math.pi
|
||||
end
|
||||
self.yaw = self.yaw - 2
|
||||
self.object:setyaw(self.yaw)
|
||||
self.feeder = object
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,16 +1,21 @@
|
||||
local max_mobs_sum = creatures.zombie_max
|
||||
-- hostile mobs
|
||||
if not minetest.setting_getbool("only_peaceful_mobs") then
|
||||
-- zombie
|
||||
minetest.register_abm({
|
||||
nodenames = creatures.z_spawn_nodes,
|
||||
neighbors = {"air"},
|
||||
interval = 40.0,
|
||||
chance = 7600,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
-- check per mapblock max (max per creature is done by .spawn())
|
||||
if active_object_count_wider > max_mobs_sum then
|
||||
return
|
||||
end
|
||||
local n = minetest.get_node_or_nil(pos)
|
||||
--if n and n.name and n.name ~= "default:stone" and math.random(1,4)>3 then return end
|
||||
pos.y = pos.y+1
|
||||
local ll = minetest.env:get_node_light(pos)
|
||||
local wtime = minetest.env:get_timeofday()
|
||||
local ll = minetest.get_node_light(pos) or nil
|
||||
if not ll then
|
||||
return
|
||||
end
|
||||
@ -20,13 +25,13 @@ if not minetest.setting_getbool("only_peaceful_mobs") then
|
||||
if ll < -1 then
|
||||
return
|
||||
end
|
||||
if minetest.env:get_node(pos).name ~= "air" then
|
||||
if minetest.get_node(pos).name ~= "air" then
|
||||
return
|
||||
end
|
||||
pos.y = pos.y+1
|
||||
if minetest.env:get_node(pos).name ~= "air" then
|
||||
if minetest.get_node(pos).name ~= "air" then
|
||||
return
|
||||
end
|
||||
creatures.spawn(pos, 1, "creatures:zombie", 2, 20)
|
||||
end})
|
||||
end
|
||||
end
|
||||
|
@ -7,7 +7,7 @@ local z_drop = "creatures:rotten_flesh"
|
||||
local z_life_max = 80 --~5min
|
||||
|
||||
local z_player_radius = 14
|
||||
z_hit_radius = 1.4
|
||||
local z_hit_radius = 1.4
|
||||
creatures.z_ll = 7
|
||||
|
||||
local z_sound_normal = "creatures_zombie"
|
||||
@ -170,7 +170,7 @@ ZOMBIE_DEF.on_step = function(self, dtime)
|
||||
self.object:set_animation({x=self.anim.lay_START,y=self.anim.lay_END}, z_animation_speed, 0)
|
||||
minetest.after(1, function()
|
||||
self.object:remove()
|
||||
if self.object:get_hp() < 1 then
|
||||
if self.object:get_hp() < 1 and creatures.drop_on_death then
|
||||
creatures.drop(current_pos, {{name=z_drop, count=math.random(0,2)}})
|
||||
end
|
||||
end)
|
||||
|
Loading…
x
Reference in New Issue
Block a user