mirror of
https://git.minetest.land/MineClone2/MineClone2.git
synced 2024-12-04 08:43:45 +01:00
Rewrite the head swivel code math
This commit is contained in:
parent
4e8c8f1cde
commit
c6c77766e3
@ -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
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
|
||||
|
@ -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"},
|
||||
|
@ -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},
|
||||
|
@ -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,
|
||||
|
@ -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"},
|
||||
|
@ -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,
|
||||
|
@ -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},
|
||||
|
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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 = {
|
||||
|
@ -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)
|
||||
|
@ -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},
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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 = {
|
||||
{
|
||||
|
@ -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},
|
||||
|
@ -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({}),
|
||||
|
@ -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},
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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"},
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user