mirror of
https://git.minetest.land/MineClone2/MineClone2.git
synced 2024-12-27 11:47:32 +01:00
Merge pull request 'Mob Fixes' (#3242) from mob_fixes into master
Reviewed-on: https://git.minetest.land/MineClone2/MineClone2/pulls/3242 Reviewed-by: Michieal <michieal@noreply.git.minetest.land>
This commit is contained in:
commit
2ed3c1c480
@ -306,7 +306,7 @@ function mob_class:do_states(dtime)
|
||||
end
|
||||
|
||||
local function update_timers (self, dtime)
|
||||
-- knockback timer
|
||||
-- knockback timer. set in on_punch
|
||||
if self.pause_timer > 0 then
|
||||
self.pause_timer = self.pause_timer - dtime
|
||||
return true
|
||||
@ -330,17 +330,15 @@ end
|
||||
|
||||
-- main mob function
|
||||
function mob_class:on_step(dtime)
|
||||
self.lifetimer = self.lifetimer - dtime
|
||||
|
||||
local pos = self.object:get_pos()
|
||||
if not pos then return end
|
||||
|
||||
if self:check_despawn(pos) then return true end
|
||||
if self:check_despawn(pos, dtime) then return true end
|
||||
|
||||
self:slow_mob()
|
||||
if self:falling(pos) then return end
|
||||
|
||||
self:check_suspend()
|
||||
|
||||
self:check_water_flow()
|
||||
|
||||
self:env_danger_movement_checks (dtime)
|
||||
@ -355,21 +353,17 @@ function mob_class:on_step(dtime)
|
||||
|
||||
if self.state == "die" then return end
|
||||
|
||||
if self.jump_sound_cooloff > 0 then
|
||||
self.jump_sound_cooloff = self.jump_sound_cooloff - dtime
|
||||
end
|
||||
if self.opinion_sound_cooloff > 0 then
|
||||
self.opinion_sound_cooloff = self.opinion_sound_cooloff - dtime
|
||||
end
|
||||
self:follow_flop() -- Mob following code.
|
||||
|
||||
--Mob following code.
|
||||
self:follow_flop()
|
||||
--set animation speed relitive to velocity
|
||||
self:set_animation_speed()
|
||||
self:set_animation_speed() -- set animation speed relitive to velocity
|
||||
self:check_smooth_rotation(dtime)
|
||||
self:check_head_swivel(dtime)
|
||||
|
||||
if self.jump_sound_cooloff > 0 then
|
||||
self.jump_sound_cooloff = self.jump_sound_cooloff - dtime
|
||||
end
|
||||
self:do_jump()
|
||||
|
||||
self:set_armor_texture()
|
||||
self:check_runaway_from()
|
||||
|
||||
@ -390,6 +384,9 @@ function mob_class:on_step(dtime)
|
||||
self:check_particlespawners(dtime)
|
||||
self:check_item_pickup()
|
||||
|
||||
if self.opinion_sound_cooloff > 0 then
|
||||
self.opinion_sound_cooloff = self.opinion_sound_cooloff - dtime
|
||||
end
|
||||
-- mob plays random sound at times. Should be 120. Zombie and mob farms are ridiculous
|
||||
if math.random(1, 70) == 1 then
|
||||
self:mob_sound("random", true)
|
||||
|
@ -280,30 +280,55 @@ local function dir_to_pitch(dir)
|
||||
return -math.atan2(-dir.y, xz)
|
||||
end
|
||||
|
||||
function mob_class:check_head_swivel(dtime)
|
||||
if not self.head_swivel or type(self.head_swivel) ~= "string" then return end
|
||||
local final_rotation = vector.new(0,0,0)
|
||||
local oldp,oldr = self.object:get_bone_position(self.head_swivel)
|
||||
|
||||
local function who_are_you_looking_at (self)
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
for _, obj in pairs(minetest.get_objects_inside_radius(pos, 10)) do
|
||||
if obj:is_player() and not self.attack or obj:get_luaentity() and obj:get_luaentity().name == self.name and self ~= obj:get_luaentity() then
|
||||
if not self._locked_object then
|
||||
if math.random(5000/self.curiosity) == 1 or vector.distance(pos,obj:get_pos())<4 and obj:is_player() then
|
||||
self._locked_object = obj
|
||||
end
|
||||
else
|
||||
if math.random(10000/self.curiosity) == 1 then
|
||||
self._locked_object = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local stop_look_at_player_chance = math.random(833/self.curiosity)
|
||||
-- was 10000 - div by 12 for avg entities as outside loop
|
||||
|
||||
local stop_look_at_player = stop_look_at_player_chance == 1
|
||||
|
||||
if self.attack or self.following then
|
||||
self._locked_object = self.attack or self.following
|
||||
elseif self._locked_object then
|
||||
if stop_look_at_player then
|
||||
--minetest.log("Stop look: ".. self.name)
|
||||
self._locked_object = nil
|
||||
end
|
||||
elseif not self._locked_object then
|
||||
if math.random(1, 30) then
|
||||
--minetest.log("Change look check: ".. self.name)
|
||||
local look_at_player_chance = math.random(20/self.curiosity)
|
||||
-- was 5000 but called in loop based on entities. so div by 12 as estimate avg of entities found,
|
||||
-- then div by 20 as less freq lookup
|
||||
|
||||
local look_at_player = look_at_player_chance == 1
|
||||
|
||||
for _, obj in pairs(minetest.get_objects_inside_radius(pos, 8)) do
|
||||
if obj:is_player() and vector.distance(pos,obj:get_pos()) < 4 then
|
||||
--minetest.log("Change look to player: ".. self.name)
|
||||
self._locked_object = obj
|
||||
break
|
||||
elseif obj:is_player() or (obj:get_luaentity() and obj:get_luaentity().name == self.name and self ~= obj:get_luaentity()) then
|
||||
if look_at_player then
|
||||
--minetest.log("Change look to mob: ".. self.name)
|
||||
self._locked_object = obj
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
function mob_class:check_head_swivel(dtime)
|
||||
if not self.head_swivel or type(self.head_swivel) ~= "string" then return end
|
||||
|
||||
who_are_you_looking_at (self)
|
||||
|
||||
local final_rotation = vector.new(0,0,0)
|
||||
local oldp,oldr = self.object:get_bone_position(self.head_swivel)
|
||||
|
||||
if self._locked_object and (self._locked_object:is_player() or self._locked_object:get_luaentity()) and self._locked_object:get_hp() > 0 then
|
||||
local _locked_object_eye_height = 1.5
|
||||
@ -318,6 +343,7 @@ function mob_class:check_head_swivel(dtime)
|
||||
if self.object:get_attach() then
|
||||
self_rot = self.object:get_attach():get_rotation()
|
||||
end
|
||||
|
||||
if self.rot then
|
||||
local player_pos = self._locked_object:get_pos()
|
||||
local direction_player = vector.direction(vector.add(self.object:get_pos(), vector.new(0, self.head_eye_height*.7, 0)), vector.add(player_pos, vector.new(0, _locked_object_eye_height, 0)))
|
||||
@ -346,7 +372,7 @@ function mob_class:check_head_swivel(dtime)
|
||||
elseif not self._locked_object and math.abs(oldr.y) > 3 and math.abs(oldr.x) < 3 then
|
||||
final_rotation = vector.multiply(oldr, 0.9)
|
||||
else
|
||||
final_rotation = vector.new(0,0,0)
|
||||
--final_rotation = vector.new(0,0,0)
|
||||
end
|
||||
|
||||
mcl_util.set_bone_position(self.object,self.head_swivel, vector.new(0,self.bone_eye_height,self.horrizonatal_head_height), final_rotation)
|
||||
|
@ -244,6 +244,24 @@ local function count_mobs_total(mob_type)
|
||||
return num
|
||||
end
|
||||
|
||||
local function count_mobs_all()
|
||||
local mobs_found = {}
|
||||
local num = 0
|
||||
for _,entity in pairs(minetest.luaentities) do
|
||||
if entity.is_mob then
|
||||
local mob_type = entity.type -- animal / monster / npc
|
||||
local mob_name = entity.name
|
||||
if mobs_found[mob_name] then
|
||||
mobs_found[mob_name] = mobs_found[mob_name] + 1
|
||||
else
|
||||
mobs_found[mob_name] = 1
|
||||
end
|
||||
num = num + 1
|
||||
end
|
||||
end
|
||||
return mobs_found, num
|
||||
end
|
||||
|
||||
local function count_mobs_total_cap(mob_type)
|
||||
local num = 0
|
||||
for _,l in pairs(minetest.luaentities) do
|
||||
@ -628,6 +646,9 @@ if mobs_spawn then
|
||||
|
||||
local perlin_noise
|
||||
|
||||
-- Get pos to spawn, x and z are randomised, y is range
|
||||
|
||||
|
||||
local function spawn_a_mob(pos, dimension, y_min, y_max)
|
||||
--create a disconnected clone of the spawn dictionary
|
||||
--prevents memory leak
|
||||
@ -722,7 +743,9 @@ if mobs_spawn then
|
||||
end)
|
||||
end
|
||||
|
||||
function mob_class:check_despawn(pos)
|
||||
function mob_class:check_despawn(pos, dtime)
|
||||
self.lifetimer = self.lifetimer - dtime
|
||||
|
||||
-- Despawning: when lifetimer expires, remove mob
|
||||
if remove_far
|
||||
and self.can_despawn == true
|
||||
@ -755,5 +778,18 @@ minetest.register_chatcommand("mobstats",{
|
||||
minetest.chat_send_player(n,"total mobs:"..count_mobs_total())
|
||||
minetest.chat_send_player(n,"spawning attempts since server start:"..dbg_spawn_attempts)
|
||||
minetest.chat_send_player(n,"successful spawns since server start:"..dbg_spawn_succ)
|
||||
|
||||
|
||||
local mob_counts, total_mobs = count_mobs_all()
|
||||
if (total_mobs) then
|
||||
minetest.log("action", "Total mobs found: " .. total_mobs)
|
||||
end
|
||||
if mob_counts then
|
||||
for k, v1 in pairs(mob_counts) do
|
||||
minetest.log("action", "k: " .. tostring(k))
|
||||
minetest.log("action", "v1: " .. tostring(v1))
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
})
|
||||
|
@ -12,13 +12,13 @@ mcl_mobs.register_mob("mobs_mc:chicken", {
|
||||
description = S("Chicken"),
|
||||
type = "animal",
|
||||
spawn_class = "passive",
|
||||
|
||||
passive = true,
|
||||
runaway = true,
|
||||
hp_min = 4,
|
||||
hp_max = 4,
|
||||
xp_min = 1,
|
||||
xp_max = 3,
|
||||
collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.69, 0.2},
|
||||
runaway = true,
|
||||
floats = 1,
|
||||
head_swivel = "head.control",
|
||||
bone_eye_height = 4,
|
||||
|
@ -7,6 +7,7 @@ local cow_def = {
|
||||
type = "animal",
|
||||
spawn_class = "passive",
|
||||
passive = true,
|
||||
runaway = true,
|
||||
hp_min = 10,
|
||||
hp_max = 10,
|
||||
xp_min = 1,
|
||||
@ -40,7 +41,6 @@ local cow_def = {
|
||||
max = 2,
|
||||
looting = "common",},
|
||||
},
|
||||
runaway = true,
|
||||
sounds = {
|
||||
random = "mobs_mc_cow",
|
||||
damage = "mobs_mc_cow_hurt",
|
||||
|
@ -259,6 +259,7 @@ mcl_mobs.register_mob("mobs_mc:enderman", {
|
||||
description = S("Enderman"),
|
||||
type = "monster",
|
||||
spawn_class = "passive",
|
||||
can_despawn = true,
|
||||
passive = true,
|
||||
pathfinding = 1,
|
||||
hp_min = 40,
|
||||
@ -442,6 +443,7 @@ mcl_mobs.register_mob("mobs_mc:enderman", {
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- TAKE AND PLACE STUFF BEHAVIOUR BELOW.
|
||||
if not mobs_griefing then
|
||||
return
|
||||
@ -469,6 +471,7 @@ mcl_mobs.register_mob("mobs_mc:enderman", {
|
||||
local dug = minetest.get_node_or_nil(take_pos)
|
||||
if dug and dug.name == "air" then
|
||||
self._taken_node = node.name
|
||||
self.can_despawn = false
|
||||
local def = minetest.registered_nodes[self._taken_node]
|
||||
-- Update animation and texture accordingly (adds visibly carried block)
|
||||
local block_type
|
||||
@ -519,6 +522,7 @@ mcl_mobs.register_mob("mobs_mc:enderman", {
|
||||
if success then
|
||||
local def = minetest.registered_nodes[self._taken_node]
|
||||
-- Update animation accordingly (removes visible block)
|
||||
self.can_despawn = true
|
||||
self.animation = select_enderman_animation("normal")
|
||||
self:set_animation(self.animation.current)
|
||||
if def.sounds and def.sounds.place then
|
||||
|
@ -6,6 +6,7 @@ mcl_mobs.register_mob("mobs_mc:pig", {
|
||||
description = S("Pig"),
|
||||
type = "animal",
|
||||
spawn_class = "passive",
|
||||
passive = true,
|
||||
runaway = true,
|
||||
hp_min = 10,
|
||||
hp_max = 10,
|
||||
|
@ -56,6 +56,7 @@ mcl_mobs.register_mob("mobs_mc:sheep", {
|
||||
description = S("Sheep"),
|
||||
type = "animal",
|
||||
spawn_class = "passive",
|
||||
passive = true,
|
||||
hp_min = 8,
|
||||
hp_max = 8,
|
||||
xp_min = 1,
|
||||
|
@ -1930,8 +1930,6 @@ end)
|
||||
|
||||
--[=======[ MOB REGISTRATION AND SPAWNING ]=======]
|
||||
|
||||
local pick_up = { "mcl_farming:bread", "mcl_farming:carrot_item", "mcl_farming:beetroot_item" , "mcl_farming:potato_item" }
|
||||
|
||||
mcl_mobs.register_mob("mobs_mc:villager", {
|
||||
description = S("Villager"),
|
||||
type = "npc",
|
||||
@ -1976,7 +1974,7 @@ mcl_mobs.register_mob("mobs_mc:villager", {
|
||||
head_shake_start = 131, head_shake_end = 141, head_shake_loop = false,
|
||||
head_nod_start = 121, head_nod_end = 131, head_nod_loop = false,
|
||||
},
|
||||
follow = pick_up,
|
||||
follow = { "mcl_farming:bread", "mcl_farming:carrot_item", "mcl_farming:beetroot_item" , "mcl_farming:potato_item" },
|
||||
nofollow = true,
|
||||
view_range = 16,
|
||||
fear_height = 4,
|
||||
@ -1986,7 +1984,7 @@ mcl_mobs.register_mob("mobs_mc:villager", {
|
||||
_id = nil,
|
||||
_profession = "unemployed",
|
||||
look_at_player = true,
|
||||
pick_up = pick_up,
|
||||
pick_up = { "mcl_farming:bread", "mcl_farming:carrot_item", "mcl_farming:beetroot_item" , "mcl_farming:potato_item" },
|
||||
can_open_doors = true,
|
||||
on_pick_up = function(self,itementity)
|
||||
local clicker
|
||||
@ -2003,6 +2001,7 @@ mcl_mobs.register_mob("mobs_mc:villager", {
|
||||
return it
|
||||
end,
|
||||
on_rightclick = function(self, clicker)
|
||||
--minetest.log("In villager right click")
|
||||
if self.child or self._profession == "unemployed" or self._profession == "nitwit" then
|
||||
self.order = nil
|
||||
return
|
||||
|
@ -109,6 +109,7 @@ mcl_mobs.register_mob("mobs_mc:villager_zombie", {
|
||||
clicker:set_wielded_item(wielditem)
|
||||
self._curing = math.random(3 * 60, 5 * 60)
|
||||
self.shaking = true
|
||||
self.can_despawn = false
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
@ -22,6 +22,8 @@ local DEBUG = false
|
||||
local enable_burger = minetest.settings:get_bool("mcl_enable_hamburger",true)
|
||||
local use_alt = minetest.settings:get_bool("mcl_hamburger_alt_texture",false)
|
||||
|
||||
local HAMBURGER_NAME = "mcl_hamburger:hamburger"
|
||||
|
||||
mcl_hamburger = {}
|
||||
|
||||
if DEBUG then
|
||||
@ -32,12 +34,12 @@ end
|
||||
function mcl_hamburger.register_burger_craft(cooked_meat)
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "mcl_hamburger:hamburger",
|
||||
recipe = HAMBURGER_NAME,
|
||||
burntime = 2,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "mcl_hamburger:hamburger",
|
||||
output = HAMBURGER_NAME,
|
||||
recipe = {
|
||||
{ "mcl_farming:bread"},
|
||||
{ cooked_meat }, -- "mcl_mobitems:cooked_beef" for a reg hamburger. Grind up clowns for a Big Mac.
|
||||
@ -45,7 +47,7 @@ function mcl_hamburger.register_burger_craft(cooked_meat)
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "mcl_hamburger:hamburger",
|
||||
output = HAMBURGER_NAME,
|
||||
recipe = {
|
||||
-- "mcl_mobitems:cooked_beef" for a reg hamburger. Grind up clowns for a Big Mac.
|
||||
{ "mcl_farming:bread", cooked_meat, "mcl_farming:bread"},
|
||||
@ -72,23 +74,23 @@ if not enable_burger then
|
||||
end
|
||||
|
||||
if use_alt == false then
|
||||
minetest.register_craftitem("mcl_hamburger:hamburger", hamburger_def)
|
||||
minetest.register_craftitem(HAMBURGER_NAME, hamburger_def)
|
||||
else
|
||||
local hamburger_alt = table.copy(hamburger_def)
|
||||
hamburger_alt.inventory_image = "mcl_hamburger_alt.png"
|
||||
hamburger_alt.wield_image = "mcl_hamburger_alt.png"
|
||||
minetest.register_craftitem("mcl_hamburger:hamburger", hamburger_alt)
|
||||
minetest.register_craftitem(HAMBURGER_NAME, hamburger_alt)
|
||||
end
|
||||
|
||||
local function register_achievements()
|
||||
|
||||
awards.register_achievement("mcl_hamburger:hamburger", {
|
||||
awards.register_achievement(HAMBURGER_NAME, {
|
||||
title = S("Burger Time!"),
|
||||
description = S("Craft a Hamburger."),
|
||||
icon = "mcl_hamburger_alt.png",
|
||||
trigger = {
|
||||
type = "craft",
|
||||
item = "mcl_hamburger:hamburger",
|
||||
item = HAMBURGER_NAME,
|
||||
target = 1
|
||||
},
|
||||
type = "Advancement",
|
||||
@ -101,19 +103,47 @@ local function register_doc_entry()
|
||||
|
||||
-- register Doc entry
|
||||
if minetest.get_modpath("doc") then
|
||||
doc.add_entry_alias("craftitems", "mcl_hamburger:hamburger", "craftitems", "mcl_hamburger:hamburger")
|
||||
doc.add_entry_alias("craftitems", HAMBURGER_NAME, "craftitems", HAMBURGER_NAME)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if enable_burger then
|
||||
-- make the villagers follow the item
|
||||
minetest.registered_entities["mobs_mc:villager"].nofollow = false
|
||||
-- add it to the follow items.
|
||||
table.insert(minetest.registered_entities["mobs_mc:villager"].follow,"mcl_hamburger:hamburger")
|
||||
-- register the item and crafting recipe.
|
||||
local villager = minetest.registered_entities["mobs_mc:villager"]
|
||||
|
||||
table.insert(villager.follow, HAMBURGER_NAME)
|
||||
|
||||
local original_rightclick = villager.on_rightclick
|
||||
|
||||
local new_on_rightclick = function(self, clicker)
|
||||
--minetest.log("In wrapper function")
|
||||
|
||||
local item = clicker:get_wielded_item()
|
||||
if item:get_name() == HAMBURGER_NAME then
|
||||
if self.nofollow == true then
|
||||
--minetest.log("Turn off nofollow")
|
||||
self.nofollow = false
|
||||
elseif self.nofollow == false then
|
||||
--minetest.log("Turn on nofollow")
|
||||
self.nofollow = true
|
||||
end
|
||||
else
|
||||
--minetest.log("Not holding burger")
|
||||
if self.nofollow == false then
|
||||
--minetest.log("Turn on nofollow")
|
||||
self.nofollow = true
|
||||
end
|
||||
original_rightclick(self, clicker)
|
||||
end
|
||||
--minetest.log("Finishing wrapper")
|
||||
end
|
||||
|
||||
villager.on_rightclick = new_on_rightclick
|
||||
|
||||
mcl_hamburger.register_burger_craft("mcl_mobitems:cooked_beef")
|
||||
-- add in the super cool achievement(s)!
|
||||
minetest.register_alias("hamburger", HAMBURGER_NAME)
|
||||
|
||||
register_achievements()
|
||||
register_doc_entry()
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user