From b84c06b9c2143281ac6782dfe4737c54530a4e8d Mon Sep 17 00:00:00 2001 From: kno10 Date: Mon, 11 Nov 2024 17:29:07 +0100 Subject: [PATCH] Rewrite the head swivel code math --- mods/ENTITIES/mcl_mobs/effects.lua | 96 +++---- mods/ENTITIES/mcl_mobs/init.lua | 7 +- mods/ENTITIES/mcl_mobs/movement.lua | 2 + mods/ENTITIES/mobs_mc/axolotl.lua | 5 +- mods/ENTITIES/mobs_mc/blaze.lua | 8 +- mods/ENTITIES/mobs_mc/chicken.lua | 5 +- mods/ENTITIES/mobs_mc/cow+mooshroom.lua | 3 +- mods/ENTITIES/mobs_mc/iron_golem.lua | 3 +- mods/ENTITIES/mobs_mc/llama.lua | 7 +- mods/ENTITIES/mobs_mc/ocelot.lua | 3 +- mods/ENTITIES/mobs_mc/parrot.lua | 3 +- mods/ENTITIES/mobs_mc/pig.lua | 5 +- mods/ENTITIES/mobs_mc/piglin.lua | 3 +- mods/ENTITIES/mobs_mc/pillager.lua | 248 +++++++++--------- mods/ENTITIES/mobs_mc/polar_bear.lua | 3 +- mods/ENTITIES/mobs_mc/rabbit.lua | 17 +- mods/ENTITIES/mobs_mc/sheep.lua | 5 +- mods/ENTITIES/mobs_mc/skeleton+stray.lua | 3 +- mods/ENTITIES/mobs_mc/skeleton_wither.lua | 3 +- mods/ENTITIES/mobs_mc/spider.lua | 3 +- mods/ENTITIES/mobs_mc/stalker.lua | 4 +- mods/ENTITIES/mobs_mc/villager.lua | 4 +- mods/ENTITIES/mobs_mc/villager_evoker.lua | 4 +- mods/ENTITIES/mobs_mc/villager_illusioner.lua | 4 +- mods/ENTITIES/mobs_mc/villager_vindicator.lua | 20 +- mods/ENTITIES/mobs_mc/villager_zombie.lua | 2 +- mods/ENTITIES/mobs_mc/wolf.lua | 4 +- mods/ENTITIES/mobs_mc/zombie.lua | 5 +- 28 files changed, 243 insertions(+), 236 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/effects.lua b/mods/ENTITIES/mcl_mobs/effects.lua index 27811e5c2..37d63e48c 100644 --- a/mods/ENTITIES/mcl_mobs/effects.lua +++ b/mods/ENTITIES/mcl_mobs/effects.lua @@ -5,7 +5,11 @@ local validate_vector = mcl_util.validate_vector local active_particlespawners = {} local disable_blood = minetest.settings:get_bool("mobs_disable_blood") local DEFAULT_FALL_SPEED = -9.81*1.5 -local PI_THIRD = math.pi / 3 -- 60 degrees +local PI = math.pi +local TWOPI = math.pi * 2 +local PI_HALF = math.pi * 0.5 -- 90 degrees +local MAX_PITCH = math.pi * 0.45 -- about 80 degrees +local MAX_YAW = math.pi * 0.66 -- about 120 degrees local PATHFINDING = "gowp" @@ -348,58 +352,62 @@ function mob_class:check_head_swivel(dtime) local locked_object = self._locked_object if locked_object and (locked_object:is_player() or locked_object:get_luaentity()) and locked_object:get_hp() > 0 then - local _locked_object_eye_height = 1.5 - if locked_object:is_player() then - _locked_object_eye_height = locked_object:get_properties().eye_height - elseif locked_object:get_luaentity() then - _locked_object_eye_height = locked_object:get_luaentity().head_eye_height + local _locked_object_eye_height = (locked_object:is_player() and locked_object:get_properties().eye_height * 0.8) -- food in hands of player + or (locked_object:get_luaentity() and locked_object:get_luaentity().head_eye_height) or 1.5 + local self_rot = self.object:get_rotation() + -- If a mob is attached, should we really be messing with what they are looking at? + -- Should this be excluded? + if self.object:get_attach() and self.object:get_attach():get_rotation() then + self_rot = self.object:get_attach():get_rotation() end - if _locked_object_eye_height then - local self_rot = self.object:get_rotation() - -- If a mob is attached, should we really be messing with what they are looking at? - -- Should this be excluded? - if self.object:get_attach() and self.object:get_attach():get_rotation() then - self_rot = self.object:get_attach():get_rotation() - end - local ps = self.object:get_pos() - ps.y = ps.y + self.head_eye_height * .7 - local pt = locked_object:get_pos() - pt.y = pt.y + _locked_object_eye_height - local dir = vector.direction(ps, pt) - local mob_yaw = self_rot.y + math.atan2(dir.x, dir.z) + self.head_yaw_offset - local mob_pitch = math.asin(-dir.y) * self.head_pitch_multiplier + local ps = self.object:get_pos() + ps.y = ps.y + self.head_eye_height -- why here, instead of below? * .7 + local pt = locked_object:get_pos() + pt.y = pt.y + _locked_object_eye_height + local dir = vector.direction(ps, pt) -- is (pt-ps):normalize() + local mob_yaw = math.atan2(dir.x, dir.z) + local mob_pitch = -math.asin(dir.y) * (self.head_pitch_multiplier or 1) -- allow axis inversion - if (mob_yaw < -PI_THIRD or mob_yaw > PI_THIRD) and not (self.attack and self.state == "attack" and not self.runaway) then - newr = vector.multiply(oldr, 0.9) - elseif self.attack and self.state == "attack" and not self.runaway then - if self.head_yaw == "y" then - newr = vector.new(mob_pitch, mob_yaw, 0) - elseif self.head_yaw == "z" then - newr = vector.new(mob_pitch, 0, -mob_yaw) - end - else - if self.head_yaw == "y" then - newr = vector.new((mob_pitch-oldr.x)*.3+oldr.x, (mob_yaw-oldr.y)*.3+oldr.y, 0) - elseif self.head_yaw == "z" then - newr = vector.new((mob_pitch-oldr.x)*.3+oldr.x, 0, ((mob_yaw-oldr.y)*.3+oldr.y)*-3) - end - end + mob_yaw = mob_yaw + self_rot.y -- to relative orientation + while mob_yaw > PI do mob_yaw = mob_yaw - TWOPI end + while mob_yaw < -PI do mob_yaw = mob_yaw + TWOPI end + mob_yaw = mob_yaw * 0.8 -- lessen the effect so it become less staring + local max_yaw = self.head_max_yaw or MAX_YAW + mob_yaw = (mob_yaw < -max_yaw and -max_yaw) or (mob_yaw < max_yaw and mob_yaw) or max_yaw -- avoid twisting the neck + + mob_pitch = mob_pitch * 0.8 -- make it less obvious that this is computed + local max_pitch = self.head_max_pitch or MAX_PITCH + mob_pitch = (mob_pitch < -max_pitch and -max_pitch) or (mob_pitch < max_pitch and mob_pitch) or max_pitch + + local smoothing = (self.state == "attack" and self.attack and 0.25) or 0.05 + local old_pitch = oldr.x + local old_yaw = (self.head_yaw == "y" and oldr.y or -oldr.z) - self.head_yaw_offset + -- to -pi:+pi range, so we rotate over 0 when interpolating: + while old_yaw > PI do old_yaw = old_yaw - TWOPI end + while old_yaw < -PI do old_yaw = old_yaw + TWOPI end + mob_pitch, mob_yaw = (mob_pitch-old_pitch)*smoothing+old_pitch, (mob_yaw-old_yaw)*smoothing+old_yaw + -- apply the yaw to the mob + mob_yaw = mob_yaw + self.head_yaw_offset + if self.head_yaw == "y" then + newr = vector.new(mob_pitch, mob_yaw, 0) + elseif self.head_yaw == "z" then + newr = vector.new(mob_pitch, 0, -mob_yaw) -- z yaw is opposite direction end - elseif not locked_object and math.abs(oldr.y) > 0.05 and math.abs(oldr.x) < 0.05 then - newr = vector.multiply(oldr, 0.9) + elseif math.abs(oldr.x) + math.abs(oldr.y) + math.abs(oldr.z) > 0.05 then + newr = vector.multiply(oldr, 0.9) -- smooth stop looking end - + -- 0.02 is about 1.14 degrees tolerance, to update less often - local newp = vector.new(0, self.bone_eye_height, self.horizontal_head_height) - if math.abs(oldr.x-newr.x) + math.abs(oldr.y-newr.y) + math.abs(oldr.z-newr.z) < 0.02 and vector.equals(oldp, newp) then return end + if math.abs(oldr.x-newr.x) + math.abs(oldr.y-newr.y) + math.abs(oldr.z-newr.z) < 0.02 and vector.equals(oldp, vector.zero()) then return end + if self.object.get_bone_override then -- minetest >= 5.9 self.object:set_bone_override(self.head_swivel, { - position = { vec = newp, absolute = true }, - rotation = { vec = newr, absolute = true } }) + position = { vec = self.head_bone_position, absolute = true }, + rotation = { vec = newr, absolute = true, interpolation = 0.1 } }) else -- minetest < 5.9 - -- old API uses degrees not radians - self.object:set_bone_position(self.head_swivel, newp, vector.apply(newr, math.deg)) + -- old API uses degrees not radians and absolute positions + self.object:set_bone_position(self.head_swivel, self.head_bone_position, vector.apply(newr, math.deg)) end end diff --git a/mods/ENTITIES/mcl_mobs/init.lua b/mods/ENTITIES/mcl_mobs/init.lua index b0a7ed9d4..1fcbb944a 100644 --- a/mods/ENTITIES/mcl_mobs/init.lua +++ b/mods/ENTITIES/mcl_mobs/init.lua @@ -143,11 +143,12 @@ function mcl_mobs.register_mob(name, def) head_swivel = def.head_swivel or nil, -- bool to activate this function head_yaw_offset = math.rad(def.head_yaw_offset or 0), -- for wonkey model bones head_pitch_multiplier = def.head_pitch_multiplier or 1, --for inverted pitch - bone_eye_height = def.bone_eye_height or 1.4, -- head bone offset - head_eye_height = def.head_eye_height or def.bone_eye_height or 0, -- how hight aproximatly the mobs head is fromm the ground to tell the mob how high to look up at the player + head_eye_height = def.head_eye_height or 1, -- how high approximately the mobs eyes are from the ground to tell the mob how high to look up at the player + head_max_yaw = def.head_max_yaw, -- how far the mob may turn the head + head_max_pitch = def.head_max_pitch, -- how far up and down the mob may pitch the head + head_bone_position = def.head_bone_position or { 0, def.bone_eye_height or 1.4, def.horizontal_head_height or 0}, curiosity = def.curiosity or 1, -- how often mob will look at player on idle head_yaw = def.head_yaw or "y", -- axis to rotate head on - horizontal_head_height = def.horizontal_head_height or 0, wears_armor = def.wears_armor, -- a number value used to index texture slot for armor stepheight = def.stepheight or 0.6, name = name, diff --git a/mods/ENTITIES/mcl_mobs/movement.lua b/mods/ENTITIES/mcl_mobs/movement.lua index dc4dcd272..de002b8df 100644 --- a/mods/ENTITIES/mcl_mobs/movement.lua +++ b/mods/ENTITIES/mcl_mobs/movement.lua @@ -761,6 +761,8 @@ function mob_class:check_follow() self:set_velocity(self.follow_velocity) if self.walk_chance ~= 0 then self:set_animation( "run") + else + self:set_animation( "stand") end else self:set_velocity(0) diff --git a/mods/ENTITIES/mobs_mc/axolotl.lua b/mods/ENTITIES/mobs_mc/axolotl.lua index 5f5a90764..171dacc39 100644 --- a/mods/ENTITIES/mobs_mc/axolotl.lua +++ b/mods/ENTITIES/mobs_mc/axolotl.lua @@ -12,9 +12,8 @@ local axolotl = { xp_max = 7, head_swivel = "head.control", - bone_eye_height = -1, - head_eye_height = -0.5, - horizontal_head_height = 0, + head_eye_height = 0.5, + head_bone_position = vector.new( 0, -1, 0 ), -- for minetest <= 5.8 curiosity = 10, head_yaw="z", diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index f5dd40470..676a22a2f 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -26,14 +26,14 @@ mcl_mobs.register_mob("mobs_mc:blaze", { xp_min = 10, xp_max = 10, collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.79, 0.3}, - rotate = -180, + rotate = 180, + head_yaw_offset = 180, visual = "mesh", mesh = "mobs_mc_blaze.b3d", head_swivel = "head.control", - bone_eye_height = 4, - head_eye_height = 3.5, + head_eye_height = 1.4, + head_bone_position = vector.new( 0, 4, 0 ), -- for minetest <= 5.8 curiosity = 10, - head_yaw_offset = 180, head_pitch_multiplier=-1, textures = { {"mobs_mc_blaze.png"}, diff --git a/mods/ENTITIES/mobs_mc/chicken.lua b/mods/ENTITIES/mobs_mc/chicken.lua index 1adf47569..32dfff789 100644 --- a/mods/ENTITIES/mobs_mc/chicken.lua +++ b/mods/ENTITIES/mobs_mc/chicken.lua @@ -21,9 +21,8 @@ mcl_mobs.register_mob("mobs_mc:chicken", { collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.69, 0.2}, floats = 1, head_swivel = "head.control", - bone_eye_height = 4, - head_eye_height = 1.5, - horizontal_head_height = -.3, + head_eye_height = 0.5, + head_bone_position = vector.new(0, 4, -.3), -- for minetest <= 5.8 curiosity = 10, head_yaw="z", visual_size = {x=1,y=1}, diff --git a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua index 4722c157c..8d960d9cb 100644 --- a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua +++ b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua @@ -22,9 +22,8 @@ local cow_def = { "blank.png", }, }, head_swivel = "head.control", - bone_eye_height = 10, head_eye_height = 1.1, - horizontal_head_height=-1.8, + head_bone_position = vector.new( 0, 10, 0 ), -- for minetest <= 5.8 curiosity = 2, head_yaw="z", makes_footstep_sound = true, diff --git a/mods/ENTITIES/mobs_mc/iron_golem.lua b/mods/ENTITIES/mobs_mc/iron_golem.lua index 774a599a6..77967db7f 100644 --- a/mods/ENTITIES/mobs_mc/iron_golem.lua +++ b/mods/ENTITIES/mobs_mc/iron_golem.lua @@ -25,7 +25,8 @@ mcl_mobs.register_mob("mobs_mc:iron_golem", { visual = "mesh", mesh = "mobs_mc_iron_golem.b3d", head_swivel = "head.control", - bone_eye_height = 3.38, + head_eye_height = 2.5, + head_bone_position = vector.new( 0, 3.38, 0 ), -- for minetest <= 5.8 curiosity = 10, textures = { {"mobs_mc_iron_golem.png"}, diff --git a/mods/ENTITIES/mobs_mc/llama.lua b/mods/ENTITIES/mobs_mc/llama.lua index 78d190121..d8bc74f02 100644 --- a/mods/ENTITIES/mobs_mc/llama.lua +++ b/mods/ENTITIES/mobs_mc/llama.lua @@ -60,11 +60,10 @@ mcl_mobs.register_mob("mobs_mc:llama", { spawn_in_group = 4, -- was 6 nerfed until we can cap them properly locally. this is a group size, not a per spawn attempt head_swivel = "head.control", - bone_eye_height = 11, - head_eye_height = 3, - horizontal_head_height=0, - curiosity = 60, + head_eye_height = 1.5, head_yaw = "z", + head_bone_position = vector.new( 0, 11, 0 ), -- for minetest <= 5.8 + curiosity = 60, hp_min = 15, hp_max = 30, diff --git a/mods/ENTITIES/mobs_mc/ocelot.lua b/mods/ENTITIES/mobs_mc/ocelot.lua index 8f79a589d..a8d75ea0f 100644 --- a/mods/ENTITIES/mobs_mc/ocelot.lua +++ b/mods/ENTITIES/mobs_mc/ocelot.lua @@ -37,9 +37,8 @@ local ocelot = { xp_min = 1, xp_max = 3, head_swivel = "head.control", - bone_eye_height = 6.2, head_eye_height = 0.4, - horizontal_head_height=-0, + head_bone_position = vector.new( 0, 6.2, 0 ), -- for minetest <= 5.8 head_yaw="z", curiosity = 4, collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.69, 0.3}, diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index 834ad22ae..185fcdd41 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -136,8 +136,7 @@ mcl_mobs.register_mob("mobs_mc:parrot", { xp_min = 1, xp_max = 3, head_swivel = "head.control", - bone_eye_height = 1.1, - horizontal_head_height=0, + head_bone_position = vector.new( 0, 1.1, 0 ), -- for minetest <= 5.8 curiosity = 10, collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.89, 0.25}, visual = "mesh", diff --git a/mods/ENTITIES/mobs_mc/pig.lua b/mods/ENTITIES/mobs_mc/pig.lua index 304c4c800..02668ba8e 100644 --- a/mods/ENTITIES/mobs_mc/pig.lua +++ b/mods/ENTITIES/mobs_mc/pig.lua @@ -20,9 +20,8 @@ mcl_mobs.register_mob("mobs_mc:pig", { "blank.png", -- saddle }}, head_swivel = "head.control", - bone_eye_height = 7.5, - head_eye_height = 0.8, - horizontal_head_height=-1, + head_eye_height = 0.7, + head_bone_position = vector.new( 0, 7.5, -1 ), -- for minetest <= 5.8 curiosity = 3, head_yaw="z", makes_footstep_sound = true, diff --git a/mods/ENTITIES/mobs_mc/piglin.lua b/mods/ENTITIES/mobs_mc/piglin.lua index 8062e2da6..c3831c7b0 100644 --- a/mods/ENTITIES/mobs_mc/piglin.lua +++ b/mods/ENTITIES/mobs_mc/piglin.lua @@ -252,7 +252,7 @@ local zombified_piglin = { damage = 9, reach = 2, head_swivel = "head.control", - bone_eye_height = 2.4, + head_bone_position = vector.new( 0, 2.4, 0 ), -- for minetest <= 5.8 head_eye_height = 1.4, curiosity = 15, collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3}, -- same @@ -325,6 +325,7 @@ mcl_mobs.register_mob("mobs_mc:zombified_piglin", zombified_piglin) local baby_zombified_piglin = table.copy(zombified_piglin) baby_zombified_piglin.description = S("Baby Zombie Piglin") baby_zombified_piglin.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25} +baby_zombified_piglin.head_eye_height = 0.8 baby_zombified_piglin.xp_min = 13 baby_zombified_piglin.xp_max = 13 baby_zombified_piglin.textures = { diff --git a/mods/ENTITIES/mobs_mc/pillager.lua b/mods/ENTITIES/mobs_mc/pillager.lua index 5e07d8dc5..b73577323 100644 --- a/mods/ENTITIES/mobs_mc/pillager.lua +++ b/mods/ENTITIES/mobs_mc/pillager.lua @@ -1,125 +1,125 @@ -local S = minetest.get_translator("mobs_mc") - -local function reload(self) - if not self.object:get_pos() then return end - minetest.sound_play("mcl_bows_crossbow_drawback_1", {object = self.object, max_hear_distance=16}, true) - local props = self.object:get_properties() - if not props then return end - props.textures[2] = "mcl_bows_crossbow_3.png^[resize:16x16" - self.object:set_properties(props) -end - -local function reset_animation(self, animation) - if not self.object:get_pos() or self._current_animation ~= animation then return end - self._current_animation = "stand_reload" -- Mobs Redo won't set the animation unless we do this - self:set_animation(animation) -end - -pillager = { - description = S("Pillager"), - type = "monster", - spawn_class = "hostile", - hp_min = 24, - hp_max = 24, - xp_min = 6, - xp_max = 6, - breath_max = -1, - eye_height = 1.5, - shoot_interval = 3, - shoot_offset = 1.5, - armor = {fleshy = 100}, - can_despawn = false, - collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.98, 0.3}, - pathfinding = 1, - group_attack = true, - visual = "mesh", - mesh = "mobs_mc_pillager.b3d", - visual_size = {x=2.75, y=2.75}, - makes_footstep_sound = true, - walk_velocity = 1.2, - run_velocity = 4, - view_range = 16, - fear_height = 4, - arrow = "mcl_bows:arrow_entity", - attack_type = "dogshoot", -- Alternate punching/shooting - attack_npcs = true, - reach = 0, -- Punching max distance - damage = 0, -- Punching damage - dogshoot_switch = 1, -- Start of shooting - dogshoot_count_max = 5, -- Max time spent shooting (standing) - dogshoot_count2_max = 1, -- Max time spent punching (running) - sounds = { - random = "mobs_mc_pillager_grunt2", - war_cry = "mobs_mc_pillager_grunt1", - death = "mobs_mc_pillager_ow2", - damage = "mobs_mc_pillager_ow1", - distance = 16, - }, - textures = { - { - "mobs_mc_pillager.png", -- Skin - "mcl_bows_crossbow_3.png^[resize:16x16", -- Wielded item - } - }, - drops = { - { - name = "mcl_bows:arrow", - chance = 1, - min = 0, - max = 2, - looting = "common", - }, - { - name = "mcl_bows:crossbow", - chance = 100 / 8.5, - min = 1, - max = 1, - looting = "rare", - }, - }, - animation = { - unloaded_walk_start = 1, unloaded_walk_end = 40, - unloaded_stand_start = 41, unloaded_stand_end = 60, - reload_stand_start = 61, reload_stand_end = 100, reload_stand_speed = 20, - stand_start = 101, stand_end = 109, stand_speed = 6, - walk_start = 111, walk_end = 150, walk_speed = 30, - run_start = 111, run_end = 150, run_speed = 50, - reload_run_start = 151, reload_run_end = 190, reload_run_speed = 20, - die_start = 191, die_end = 192, die_speed = 15, - stand_unloaded_start = 40, stand_unloaded_end = 59, - die_loop = false, - }, - shoot_arrow = function(self, pos, dir) - minetest.sound_play("mcl_bows_crossbow_shoot", {object = self.object, max_hear_distance=16}, true) - local props = self.object:get_properties() - props.textures[2] = "mcl_bows_crossbow_0.png^[resize:16x16" - self.object:set_properties(props) - local old_anim = self._current_animation - if old_anim == "run" or old_anim == "walk" then - self:set_animation("reload_run") - end - if old_anim == "stand" then - self:set_animation("reload_stand") - end - self._current_animation = old_anim -- Mobs Redo will imediately reset the animation otherwise - minetest.after(1, reload, self) - minetest.after(2, reset_animation, self, old_anim) - - -- 2-4 damage per arrow - local dmg = math.max(4, math.random(2, 8)) - mcl_bows_s.shoot_arrow_crossbow("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg) - - -- While we are at it, change the sounds since there is no way to do this in Mobs Redo - if self.sounds and self.sounds.random then - self.sounds = table.copy(self.sounds) - self.sounds.random = "mobs_mc_pillager_grunt" .. math.random(2) - end - - -- Randomize reload time - self.shoot_interval = math.random(3, 4) - end, -} - -mcl_mobs.register_mob("mobs_mc:pillager", pillager) -mcl_mobs.register_egg("mobs_mc:pillager", S("Pillager"), "#532f36", "#959b9b", 0) +local S = minetest.get_translator("mobs_mc") + +local function reload(self) + if not self.object:get_pos() then return end + minetest.sound_play("mcl_bows_crossbow_drawback_1", {object = self.object, max_hear_distance=16}, true) + local props = self.object:get_properties() + if not props then return end + props.textures[2] = "mcl_bows_crossbow_3.png^[resize:16x16" + self.object:set_properties(props) +end + +local function reset_animation(self, animation) + if not self.object:get_pos() or self._current_animation ~= animation then return end + self._current_animation = "stand_reload" -- Mobs Redo won't set the animation unless we do this + self:set_animation(animation) +end + +pillager = { + description = S("Pillager"), + type = "monster", + spawn_class = "hostile", + hp_min = 24, + hp_max = 24, + xp_min = 6, + xp_max = 6, + breath_max = -1, + eye_height = 1.5, + shoot_interval = 3, + shoot_offset = 1.5, + armor = {fleshy = 100}, + can_despawn = false, + collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.98, 0.3}, + pathfinding = 1, + group_attack = true, + visual = "mesh", + mesh = "mobs_mc_pillager.b3d", + visual_size = {x=2.75, y=2.75}, + makes_footstep_sound = true, + walk_velocity = 1.2, + run_velocity = 4, + view_range = 16, + fear_height = 4, + arrow = "mcl_bows:arrow_entity", + attack_type = "dogshoot", -- Alternate punching/shooting + attack_npcs = true, + reach = 0, -- Punching max distance + damage = 0, -- Punching damage + dogshoot_switch = 1, -- Start of shooting + dogshoot_count_max = 5, -- Max time spent shooting (standing) + dogshoot_count2_max = 1, -- Max time spent punching (running) + sounds = { + random = "mobs_mc_pillager_grunt2", + war_cry = "mobs_mc_pillager_grunt1", + death = "mobs_mc_pillager_ow2", + damage = "mobs_mc_pillager_ow1", + distance = 16, + }, + textures = { + { + "mobs_mc_pillager.png", -- Skin + "mcl_bows_crossbow_3.png^[resize:16x16", -- Wielded item + } + }, + drops = { + { + name = "mcl_bows:arrow", + chance = 1, + min = 0, + max = 2, + looting = "common", + }, + { + name = "mcl_bows:crossbow", + chance = 100 / 8.5, + min = 1, + max = 1, + looting = "rare", + }, + }, + animation = { + unloaded_walk_start = 1, unloaded_walk_end = 40, + unloaded_stand_start = 41, unloaded_stand_end = 60, + reload_stand_start = 61, reload_stand_end = 100, reload_stand_speed = 20, + stand_start = 101, stand_end = 109, stand_speed = 6, + walk_start = 111, walk_end = 150, walk_speed = 30, + run_start = 111, run_end = 150, run_speed = 50, + reload_run_start = 151, reload_run_end = 190, reload_run_speed = 20, + die_start = 191, die_end = 192, die_speed = 15, + stand_unloaded_start = 40, stand_unloaded_end = 59, + die_loop = false, + }, + shoot_arrow = function(self, pos, dir) + minetest.sound_play("mcl_bows_crossbow_shoot", {object = self.object, max_hear_distance=16}, true) + local props = self.object:get_properties() + props.textures[2] = "mcl_bows_crossbow_0.png^[resize:16x16" + self.object:set_properties(props) + local old_anim = self._current_animation + if old_anim == "run" or old_anim == "walk" then + self:set_animation("reload_run") + end + if old_anim == "stand" then + self:set_animation("reload_stand") + end + self._current_animation = old_anim -- Mobs Redo will imediately reset the animation otherwise + minetest.after(1, reload, self) + minetest.after(2, reset_animation, self, old_anim) + + -- 2-4 damage per arrow + local dmg = math.max(4, math.random(2, 8)) + mcl_bows_s.shoot_arrow_crossbow("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg) + + -- While we are at it, change the sounds since there is no way to do this in Mobs Redo + if self.sounds and self.sounds.random then + self.sounds = table.copy(self.sounds) + self.sounds.random = "mobs_mc_pillager_grunt" .. math.random(2) + end + + -- Randomize reload time + self.shoot_interval = math.random(3, 4) + end, +} + +mcl_mobs.register_mob("mobs_mc:pillager", pillager) +mcl_mobs.register_egg("mobs_mc:pillager", S("Pillager"), "#532f36", "#959b9b", 0) mcl_mobs:non_spawn_specific("mobs_mc:pillager","overworld",0,7) diff --git a/mods/ENTITIES/mobs_mc/polar_bear.lua b/mods/ENTITIES/mobs_mc/polar_bear.lua index aa690bc20..82f54a868 100644 --- a/mods/ENTITIES/mobs_mc/polar_bear.lua +++ b/mods/ENTITIES/mobs_mc/polar_bear.lua @@ -25,9 +25,8 @@ mcl_mobs.register_mob("mobs_mc:polar_bear", { {"mobs_mc_polarbear.png"}, }, head_swivel = "head.control", - bone_eye_height = 2.6, head_eye_height = 1, - horizontal_head_height = 0, + head_bone_position = vector.new( 0, 2.6, 0 ), -- for minetest <= 5.8 curiosity = 20, head_yaw="z", visual_size = {x=3.0, y=3.0}, diff --git a/mods/ENTITIES/mobs_mc/rabbit.lua b/mods/ENTITIES/mobs_mc/rabbit.lua index c519e5e7f..7408d4c02 100644 --- a/mods/ENTITIES/mobs_mc/rabbit.lua +++ b/mods/ENTITIES/mobs_mc/rabbit.lua @@ -16,20 +16,19 @@ local rabbit = { xp_max = 3, collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.49, 0.2}, head_swivel = "head.control", - bone_eye_height = 2, - head_eye_height = 0.5, - horizontal_head_height = -.3, + head_eye_height = 0.35, + head_bone_position = vector.new( 0, 2, -.3 ), -- for minetest <= 5.8 curiosity = 20, head_yaw="z", visual = "mesh", mesh = "mobs_mc_rabbit.b3d", textures = { - {"mobs_mc_rabbit_brown.png"}, - {"mobs_mc_rabbit_gold.png"}, - {"mobs_mc_rabbit_white.png"}, - {"mobs_mc_rabbit_white_splotched.png"}, - {"mobs_mc_rabbit_salt.png"}, - {"mobs_mc_rabbit_black.png"}, + {"mobs_mc_rabbit_brown.png"}, + {"mobs_mc_rabbit_gold.png"}, + {"mobs_mc_rabbit_white.png"}, + {"mobs_mc_rabbit_white_splotched.png"}, + {"mobs_mc_rabbit_salt.png"}, + {"mobs_mc_rabbit_black.png"}, }, sounds = { random = "mobs_mc_rabbit_random", diff --git a/mods/ENTITIES/mobs_mc/sheep.lua b/mods/ENTITIES/mobs_mc/sheep.lua index e0df5323c..67da51691 100644 --- a/mods/ENTITIES/mobs_mc/sheep.lua +++ b/mods/ENTITIES/mobs_mc/sheep.lua @@ -65,9 +65,8 @@ mcl_mobs.register_mob("mobs_mc:sheep", { xp_max = 3, collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.29, 0.45}, head_swivel = "head.control", - bone_eye_height = 3.3, - head_eye_height = 1.1, - horizontal_head_height=-.7, + head_eye_height = 1.0, + head_bone_position = vector.new( 0, 3.3, -.7 ), -- for minetest <= 5.8 curiosity = 6, head_yaw="z", visual = "mesh", diff --git a/mods/ENTITIES/mobs_mc/skeleton+stray.lua b/mods/ENTITIES/mobs_mc/skeleton+stray.lua index 711c11091..11fb30f88 100644 --- a/mods/ENTITIES/mobs_mc/skeleton+stray.lua +++ b/mods/ENTITIES/mobs_mc/skeleton+stray.lua @@ -26,7 +26,8 @@ local skeleton = { pathfinding = 1, group_attack = true, head_swivel = "Head_Control", - bone_eye_height = 2.38, + head_eye_height = 1.5, + head_bone_position = vector.new( 0, 2.38, 0 ), -- for minetest <= 5.8 curiosity = 6, visual = "mesh", mesh = "mobs_mc_skeleton.b3d", diff --git a/mods/ENTITIES/mobs_mc/skeleton_wither.lua b/mods/ENTITIES/mobs_mc/skeleton_wither.lua index 331b4fd06..5e14a8aaa 100644 --- a/mods/ENTITIES/mobs_mc/skeleton_wither.lua +++ b/mods/ENTITIES/mobs_mc/skeleton_wither.lua @@ -25,7 +25,8 @@ mcl_mobs.register_mob("mobs_mc:witherskeleton", { visual = "mesh", mesh = "mobs_mc_witherskeleton.b3d", head_swivel = "head.control", - bone_eye_height = 2.38, + head_eye_height = 1.5, + head_bone_position = vector.new( 0, 2.38, 0 ), -- for minetest <= 5.8 curiosity = 60, textures = { { diff --git a/mods/ENTITIES/mobs_mc/spider.lua b/mods/ENTITIES/mobs_mc/spider.lua index 7fd8909ba..0e5dd256c 100644 --- a/mods/ENTITIES/mobs_mc/spider.lua +++ b/mods/ENTITIES/mobs_mc/spider.lua @@ -63,7 +63,8 @@ local spider = { end end, head_swivel = "Head_Control", - bone_eye_height = 1, + head_eye_height = 0.6, + head_bone_position = vector.new( 0, 1, 0 ), -- for minetest <= 5.8 curiosity = 10, head_yaw="z", collisionbox = {-0.7, -0.01, -0.7, 0.7, 0.89, 0.7}, diff --git a/mods/ENTITIES/mobs_mc/stalker.lua b/mods/ENTITIES/mobs_mc/stalker.lua index bcb5a5d7e..9ce966065 100644 --- a/mods/ENTITIES/mobs_mc/stalker.lua +++ b/mods/ENTITIES/mobs_mc/stalker.lua @@ -75,8 +75,8 @@ mcl_mobs.register_mob("mobs_mc:stalker", { visual = "mesh", mesh = "vl_stalker.b3d", -- head_swivel = "Head_Control", - bone_eye_height = 2.35, - head_eye_height = 1.8; + head_eye_height = 1.2; + head_bone_position = vector.new( 0, 2.35, 0 ), -- for minetest <= 5.8 curiosity = 2, textures = { {get_texture({}), diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 5ea20c707..96bd8f971 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -2110,8 +2110,8 @@ mcl_mobs.register_mob("mobs_mc:villager", { hp_min = 20, hp_max = 20, head_swivel = "head.control", - bone_eye_height = 6.3, - head_eye_height = 2.2, + head_eye_height = 1.5, + head_bone_position = vector.new( 0, 6.3, 0 ), -- for minetest <= 5.8 curiosity = 10, runaway = true, collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3}, diff --git a/mods/ENTITIES/mobs_mc/villager_evoker.lua b/mods/ENTITIES/mobs_mc/villager_evoker.lua index 2dc175341..5cbe7f012 100644 --- a/mods/ENTITIES/mobs_mc/villager_evoker.lua +++ b/mods/ENTITIES/mobs_mc/villager_evoker.lua @@ -25,8 +25,8 @@ mcl_mobs.register_mob("mobs_mc:evoker", { xp_min = 10, xp_max = 10, head_swivel = "head.control", - bone_eye_height = 6.3, - head_eye_height = 2.2, + head_eye_height = 1.5, + head_bone_position = vector.new( 0, 6.3, 0 ), -- for minetest <= 5.8 curiosity = 10, collisionbox = {-0.4, -0.01, -0.4, 0.4, 1.95, 0.4}, visual = "mesh", diff --git a/mods/ENTITIES/mobs_mc/villager_illusioner.lua b/mods/ENTITIES/mobs_mc/villager_illusioner.lua index 930a1edfe..ce4401008 100644 --- a/mods/ENTITIES/mobs_mc/villager_illusioner.lua +++ b/mods/ENTITIES/mobs_mc/villager_illusioner.lua @@ -34,8 +34,8 @@ mcl_mobs.register_mob("mobs_mc:illusioner", { "mcl_bows_bow.png", }, }, head_swivel = "head.control", - bone_eye_height = 2.2, - head_eye_height = 2.2, + head_eye_height = 1.5, + head_bone_position = vector.new( 0, 2.2, 0 ), -- for minetest <= 5.8 curiosity = 10, sounds = { -- TODO: more sounds diff --git a/mods/ENTITIES/mobs_mc/villager_vindicator.lua b/mods/ENTITIES/mobs_mc/villager_vindicator.lua index 9ccb8509c..8c371753b 100644 --- a/mods/ENTITIES/mobs_mc/villager_vindicator.lua +++ b/mods/ENTITIES/mobs_mc/villager_vindicator.lua @@ -24,17 +24,17 @@ mcl_mobs.register_mob("mobs_mc:vindicator", { visual = "mesh", mesh = "mobs_mc_vindicator.b3d", head_swivel = "head.control", - bone_eye_height = 2.2, - head_eye_height = 2.2, + head_eye_height = 1.5, + head_bone_position = vector.new( 0, 2.2, 0 ), -- for minetest <= 5.8 curiosity = 10, - textures = { - { - "mobs_mc_vindicator.png", - "blank.png", --no hat - "default_tool_steelaxe.png", - -- TODO: Glow when attacking (mobs_mc_vindicator.png) - }, - }, + textures = { + { + "mobs_mc_vindicator.png", + "blank.png", --no hat + "default_tool_steelaxe.png", + -- TODO: Glow when attacking (mobs_mc_vindicator.png) + }, + }, visual_size = {x=2.75, y=2.75}, makes_footstep_sound = true, damage = 13, diff --git a/mods/ENTITIES/mobs_mc/villager_zombie.lua b/mods/ENTITIES/mobs_mc/villager_zombie.lua index 6e343c327..4de3d6e1a 100644 --- a/mods/ENTITIES/mobs_mc/villager_zombie.lua +++ b/mods/ENTITIES/mobs_mc/villager_zombie.lua @@ -40,7 +40,7 @@ mcl_mobs.register_mob("mobs_mc:villager_zombie", { visual = "mesh", mesh = "mobs_mc_villager_zombie.b3d", head_swivel = "Head_Control", - bone_eye_height = 2.35, + head_bone_position = vector.new( 0, 2.35, 0 ), -- for minetest <= 5.8 curiosity = 2, textures = { {"mobs_mc_zombie_butcher.png"}, diff --git a/mods/ENTITIES/mobs_mc/wolf.lua b/mods/ENTITIES/mobs_mc/wolf.lua index 13e76a602..944aabe37 100644 --- a/mods/ENTITIES/mobs_mc/wolf.lua +++ b/mods/ENTITIES/mobs_mc/wolf.lua @@ -27,8 +27,8 @@ local wolf = { }, makes_footstep_sound = true, head_swivel = "head.control", - bone_eye_height = 3.5, - head_eye_height = 1.1, + head_eye_height = 0.5, + head_bone_position = vector.new( 0, 3.5, 0 ), -- for minetest <= 5.8 horizontal_head_height=0, curiosity = 3, head_yaw="z", diff --git a/mods/ENTITIES/mobs_mc/zombie.lua b/mods/ENTITIES/mobs_mc/zombie.lua index 83eae82ad..b145b0550 100644 --- a/mods/ENTITIES/mobs_mc/zombie.lua +++ b/mods/ENTITIES/mobs_mc/zombie.lua @@ -54,8 +54,8 @@ local zombie = { xp_min = 5, xp_max = 5, head_swivel = "head.control", - bone_eye_height = 6.3, - head_eye_height = 2.2, + head_eye_height = 1.4, + head_bone_position = vector.new( 0, 6.3, 0 ), -- for minetest <= 5.8 curiosity = 7, head_pitch_multiplier=-1, breath_max = -1, @@ -110,6 +110,7 @@ mcl_mobs.register_mob("mobs_mc:zombie", zombie) local baby_zombie = table.copy(zombie) baby_zombie.description = S("Baby Zombie") +baby_zombie.head_eye_height = 0.8 baby_zombie.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.98, 0.25} baby_zombie.xp_min = 12 baby_zombie.xp_max = 12