Mob motion improvements

* mods/ENTITIES/mcl_mobs/api.lua (on_step): Cease calling
slow_mob or testing always_clime, and call motion_step each
tick.

* mods/ENTITIES/mcl_mobs/effects.lua (set_animation_speed):
Don't integrate velocity.

* mods/ENTITIES/mcl_mobs/init.lua (mcl_mobs): Adjust default
jump height and fall speed to match Minecraft values.  Specify
default values of water_friction and water_velocity.
(on_activate): Clear acc_dir and acc_speed.

* mods/ENTITIES/mcl_mobs/movement.lua (do_jump): Set jumping
flag if mob should jump.
(follow_player): Reduce target distance to blocks.
(do_states_stand, do_states_fly, swim_or_jump, do_states_swim):
Remove calls to slow_mob.
(climb): Delete function.

* mods/ENTITIES/mcl_mobs/pathfinding.lua (check_gowp): Clear
acceleration when halting mob.

* mods/ENTITIES/mcl_mobs/physics.lua (collision): Optimize
slightly and don't set fire to objects.
(slow_mob): Delete function.
(set_velocity): Set directional acceleration.
(do_env_damage): Clear directional acceleration ignore when in
unloaded block.
(falling): Don't implement mob floating here.
(check_water_flow): Just return water flow vectors.
(check_dying): Clear directional acceleration.
(pow_by_step, scale_speed, accelerate_relative, jump_actual)
(jump_fluid, horiz_collision, clamp, check_collision)
(motion_step): New functions.

* mods/ENTITIES/mobs_mc/blaze.lua:

* mods/ENTITIES/mobs_mc/chicken.lua:

* mods/ENTITIES/mobs_mc/horse.lua:

* mods/ENTITIES/mobs_mc/parrot.lua:

* mods/ENTITIES/mobs_mc/zombie.lua: Adjust various constants to
match Minecraft.

* mods/ITEMS/mcl_enchanting/enchantments.lua
(depth_strider_level): New function.
This commit is contained in:
Po Lu 2024-09-14 13:48:13 +08:00 committed by cora
parent 44fc00b66b
commit c161afa948
No known key found for this signature in database
13 changed files with 266 additions and 169 deletions

View File

@ -393,10 +393,6 @@ function mob_class:on_step(dtime, moveresult)
self:update_tag()
if not should_drive or self.steer_class ~= "follow_item" then
self:slow_mob ()
end
if not (moveresult and moveresult.touching_ground) and self:falling(pos) then return end
-- Get nodes early for use in other functions
@ -415,6 +411,7 @@ function mob_class:on_step(dtime, moveresult)
local pos_head = vector.offset(p, 0, cbox[5] - 0.5, 0)
self.head_in = mcl_mobs.node_ok(pos_head, "air").name
self:motion_step (dtime, moveresult)
self:falling (pos)
if self.force_step then
@ -505,12 +502,6 @@ function mob_class:on_step(dtime, moveresult)
if self:env_damage (dtime, pos) then return end
if self:do_states(dtime) then return end
--mobs that can climb over stuff
if self.always_climb
and self:node_infront_ok(pos, 0).name ~= "air" then
self:climb()
end
if self.jump_sound_cooloff > 0 then
self.jump_sound_cooloff = self.jump_sound_cooloff - dtime
end

View File

@ -394,9 +394,6 @@ function mob_class:set_animation_speed(custom_speed)
self.object:set_animation_frame_speed(25)
end
end
if self.acc and mcl_mobs.check_vector(self.acc) then
self.object:add_velocity(self.acc)
end
end
end

View File

@ -39,7 +39,7 @@ mcl_mobs.mob_class = {
swims_in = { "mcl_core:water_source", "mclx_core:river_water_source", 'mcl_core:water_flowing', 'mclx_core:river_water_flowing' },
owner = "",
order = "",
jump_height = 4, -- was 6
jump_height = 8.4,
rotate = 0, -- 0=front, 90=side, 180=back, 270=side2
xp_min = 0,
xp_max = 0,
@ -58,7 +58,7 @@ mcl_mobs.mob_class = {
_mcl_freeze_damage = 2,
suffocation = true,
fall_damage = 1,
fall_speed = -9.81 * 1.5,
fall_speed = -1.6, -- Accelerate by 1.6 m/s per Minecraft tick.
drops = {},
armor = 100,
sounds = {},
@ -72,6 +72,8 @@ mcl_mobs.mob_class = {
shoot_offset = 0,
floats = 1,
floats_on_lava = 0,
water_friction = 0.8,
water_velocity = 0.4,
replace_offset = 0,
replace_delay = 0,
timer = 0,
@ -321,6 +323,8 @@ function mcl_mobs.register_mob(name, def)
collide_with_objects = false,
})
self._physics_factors = {}
self.acc_dir = vector.zero ()
self.acc_speed = 0
self._timers = {}
return self:mob_activate(staticdata, dtime)

View File

@ -356,7 +356,6 @@ function mob_class:drive_controls(moving_anim, stand_anim, can_fly, dtime)
local s = get_sign(self.v)
self.v = self.v - 0.02 * s
if s ~= get_sign(self.v) then
self.object:set_velocity({x = 0, y = 0, z = 0})
self.v = 0
return

View File

@ -419,43 +419,8 @@ function mob_class:do_jump()
and minetest.get_item_group(nod.name, "fence_gate") == 0
and minetest.get_item_group(nod.name, "wall") == 0
then
local dir_x, dir_z = self:forward_directions()
-- Extensive testing to get this to work ...
local v = vector.new(dir_x, self.jump_height + 0.5 * 10, dir_z)
if not in_water and self:can_jump_cliff() then
v = vector.multiply(v, vector.new(2.8, 1, 2.8))
end
-- ensure we don't turn if we are trying to jump up something
self.order = "jump"
self:set_animation("jump")
walk_log("jump at: " .. minetest.pos_to_string(self.object:get_pos()))
self.object:set_velocity(v)
self.object:set_acceleration(vector.new(v.x, 1, v.z))
-- when in air move forward
minetest.after(0.3, function(self, v)
if (not self.object) or (not self.object:get_luaentity()) or (self.state == "die") then
return
end
walk_log("move forward at: " .. minetest.pos_to_string(self.object:get_pos()))
self.object:set_acceleration(vector.new(v.x * 5, DEFAULT_FALL_SPEED, v.z * 5))
if self.order == "jump" then
self.order = ""
if self.state == "stand" then
self:set_velocity(self.walk_velocity)
self:set_state("walk")
self:set_animation("walk")
end
end
end, self, v)
if self:check_timer("jump_sound_cooloff", self.jump_sound_cooloff) then
self:mob_sound("jump")
end
else
self.facing_fence = true
end
@ -682,8 +647,7 @@ function mob_class:follow_player()
if p.x > s.x then yaw = yaw +math.pi end
self:set_yaw( yaw, 2.35)
-- anyone but standing npc's can move along
if dist > 3
and self.order ~= "stand" then
if dist > 2 and self.order ~= "stand" then
self:set_velocity(self.follow_velocity)
if self.walk_chance ~= 0 then
self:set_animation( "run")
@ -893,7 +857,6 @@ function mob_class:do_states_stand()
if self.order == "sleep" then
self:set_animation("stand")
self:set_velocity(0)
self:slow_mob()
return
end
@ -934,11 +897,9 @@ function mob_class:do_states_stand()
if self.order == "sit" then
self:set_animation("sit")
self:set_velocity(0)
self:slow_mob()
else
self:set_animation("stand")
self:set_velocity(0)
self:slow_mob()
end
--walk_log("stand in " .. self.standing_in .. ", on " .. self.standing_on)
@ -1020,13 +981,11 @@ function mob_class:do_states_fly()
if self:should_flap() then
fly_log("flapping?")
self:slow_mob()
self:set_animation("walk")
else
self:set_velocity(0)
self:set_state("stand")
self:set_animation("stand")
self:slow_mob()
fly_log("standing or floating?")
end
else
@ -1137,7 +1096,6 @@ function mob_class:swim_or_jump()
--self.object:set_acceleration({ x = 0, y = -1.5, z = 0 })
self.object:set_acceleration({ x = 0, y = DEFAULT_FALL_SPEED, z = 0 })
--local dir_x, dir_z = self:forward_directions()
self:slow_mob()
--self.object:set_velocity(vector.new(dir_x, -1, dir_z))
self:set_animation("walk")
self:set_state("swim")
@ -1222,7 +1180,6 @@ function mob_class:do_states_swim()
if self.facing_fence == true or facing_solid or math.random(1, 100) <= 30 then
self:set_state("stand")
self:turn_away(3)
self:slow_mob()
if self.object:get_velocity().y < 0.1 then
self:set_animation("stand")
else
@ -1286,17 +1243,3 @@ function mob_class:check_smooth_rotation(dtime)
end
-- end rotation
end
--this is a generic climb function
function mob_class:climb()
local current_velocity = self.object:get_velocity()
local goal_velocity = {x=0, y=3, z=0}
local new_velocity_addition = vector.subtract(goal_velocity,current_velocity)
new_velocity_addition.x = 0
new_velocity_addition.z = 0
--smooths out mobs a bit
if vector.length(new_velocity_addition) >= 0.0001 then
self.object:add_velocity(new_velocity_addition)
end
end

View File

@ -225,6 +225,7 @@ function mob_class:check_gowp()
self.order = "stand"
self.object:set_velocity({x = 0, y = 0, z = 0})
self.object:set_acceleration({x = 0, y = 0, z = 0})
self.acc_dir = vector.zero ()
if self.callback_arrived then return self.callback_arrived(self) end
return true
end
@ -257,6 +258,7 @@ function mob_class:check_gowp()
self._pf_last_failed = os.time()
self.object:set_velocity({x = 0, y = 0, z = 0})
self.object:set_acceleration({x = 0, y = 0, z = 0})
self.acc_dir = vector.zero ()
return
end
self:go_to_pos(self.current_target["pos"])

View File

@ -155,18 +155,12 @@ function mob_class:collision()
if not pos then return {0,0} end
local x = 0
local z = 0
local cbox = self.object:get_properties().collisionbox
local cbox = self.initial_properties.collisionbox
local width = -cbox[1] + cbox[4]
for object in minetest.objects_inside_radius(pos, width) do
for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do
local ent = object:get_luaentity()
if (self.pushable and object:is_player()) or
(self.mob_pushable and ent and ent.is_mob and object ~= self.object) then
if object:is_player() and mcl_burning.is_burning(self.object) then
mcl_burning.set_on_fire(object, 4)
end
if (self.pushable and object:is_player())
or (self.mob_pushable and ent and ent.is_mob and object ~= self.object) then
local pos2 = object:get_pos()
local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z}
local force = width - vector.distance(
@ -178,43 +172,22 @@ function mob_class:collision()
end
end
return({x,z})
end
function mob_class:slow_mob()
local d = 0.80
if self:check_dying() then d = 0.92 end
if self.object then
local v = self.object:get_velocity()
if v then
--diffuse object velocity
local y = v.y
if y > 0 then
y = y * d
end
self.object:set_velocity({ x = v.x * d, y = y, z = v.z * d })
end
end
return x, z
end
-- move mob in facing direction
function mob_class:set_velocity(v)
local c_x, c_y = 0, 0
-- can mob be pushed, if so calculate direction
if self.pushable or self.mob_pushable then
c_x, c_y = unpack(self:collision())
end
-- halt mob if it has been ordered to stay
if self.order == "stand" or self.order == "sit" then
self.acc=vector.new(0,0,0)
return
self.acc_speed = 0
self.acc_dir.z = 0
return
end
local yaw = (self.object:get_yaw() or 0) + self.rotate
local vv = self.object:get_velocity()
if vv and yaw then
self.acc = vector.new(((math.sin(yaw) * -v) + c_x) * .4, 0, ((math.cos(yaw) * v) + c_y) * .4)
self.acc_speed = v
self.acc_dir.z = v
end
end
@ -263,8 +236,6 @@ local function shortest_term_of_yaw_rotation(_, rot_origin, rot_target, nums)
return 1
end
-- set and return valid yaw
function mob_class:set_yaw(yaw, delay, dtime)
if self.noyaw then return end
@ -613,6 +584,7 @@ function mob_class:do_env_damage()
-- don't fall when on ignore, just stand still
if self.standing_in == "ignore" then
self.object:set_velocity({x = 0, y = 0, z = 0})
self.acc_dir = vector.zero ()
-- wither rose effect
elseif self.standing_in == "mcl_flowers:wither_rose" then
mcl_potions.give_effect_by_level("withering", self.object, 2, 2)
@ -871,38 +843,14 @@ function mob_class:falling(pos)
return
end
local v = self.object:get_velocity()
-- floating in water (or falling)
if v.y > 0 and v.y < -self.fall_speed then
-- when moving up, always use gravity
self.object:set_acceleration(vector.new(0, self.fall_speed, 0))
elseif v.y <= 0 and v.y > self.fall_speed then
-- fall downwards at set speed
self.object:set_acceleration(vector.new(0, self.fall_speed, 0))
else
-- stop accelerating once max fall speed hit
self.object:set_acceleration(vector.zero())
end
if self._just_portaled then
self.reset_fall_damage = 1
return false -- mob has teleported through portal - it's 99% not falling
end
if minetest.registered_nodes[mcl_mobs.node_ok(pos).name].groups.lava then
if self.floats_on_lava == 1 then
self.object:set_acceleration(vector.new(0, -self.fall_speed / (math.max(1, v.y) ^ 2), 0))
end
end
if minetest.registered_nodes[mcl_mobs.node_ok(pos).name].name == "mcl_powder_snow:powder_snow" then
self.reset_fall_damage = 1
end
-- in water then float up
if minetest.registered_nodes[mcl_mobs.node_ok(pos).name].groups.water then
local cbox = self.object:get_properties().collisionbox
if self.floats == 1 and minetest.registered_nodes[mcl_mobs.node_ok(vector.offset(pos,0,cbox[5] -0.25,0)).name].groups.water then
self.object:set_acceleration(vector.new(0, -self.fall_speed / (math.max(1, v.y) ^ 2), 0))
end
else if minetest.registered_nodes[mcl_mobs.node_ok(pos).name].groups.water then
-- Reset fall damage when falling into water first.
self.reset_fall_damage = 1
else
@ -928,41 +876,26 @@ function mob_class:falling(pos)
end
end
function mob_class:check_water_flow()
-- Add water flowing for mobs from mcl_item_entity
function mob_class:check_water_flow ()
local p, node, nn, def
p = self.object:get_pos()
node = minetest.get_node_or_nil(p)
p = self.object:get_pos ()
node = minetest.get_node_or_nil (p)
if node then
nn = node.name
def = minetest.registered_nodes[nn]
end
-- Move item around on flowing liquids
if def and def.liquidtype == "flowing" then
--[[ Get flowing direction (function call from flowlib), if there's a liquid.
NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7.
Luckily, this is exactly what we need if we only care about water, which has this flowing distance. ]]
-- Get flowing direction (function call from flowlib),
-- if there's a liquid. NOTE: According to
-- Qwertymine, flowlib.quickflow is only reliable for
-- liquids with a flowing distance of 7. Luckily,
-- this is exactly what we need if we only care about
-- water, which has this flowing distance.
local vec = flowlib.quick_flow(p, node)
-- Just to make sure we don't manipulate the speed for no reason
if vec.x ~= 0 or vec.y ~= 0 or vec.z ~= 0 then
-- Minecraft Wiki: Flowing speed is "about 1.39 meters per second"
local f = 1.39
-- Set new item moving speed into the direciton of the liquid
local newv = vector.multiply(vec, f)
self.object:set_acceleration({x = 0, y = 0, z = 0})
self.object:set_velocity({x = newv.x, y = -0.22, z = newv.z})
self.physical_state = true
self._flowing = true
self.object:set_properties({
physical = true
})
return
end
elseif self._flowing == true then
-- Disable flowing physics if not on/in flowing liquid
self._flowing = false
return
return vector.normalize (vec)
end
return nil
end
function mob_class:check_dying(reason, cmi_cause)
@ -987,6 +920,7 @@ function mob_class:check_suspend()
if acc.y > 0 or node_under ~= "air" then
self.object:set_acceleration(vector.new(0,0,0))
self.object:set_velocity(vector.new(0,0,0))
self.object:acc_dir = vector.zero ()
end
return true
end
@ -1017,3 +951,224 @@ function mob_class:remove_physics_factor (field, id)
self._physics_factors[field][id] = nil
apply_physics_factors (self, field, id)
end
-- Mob motion routines.
--- Constants. These remain constant for the duration of the game but
--- are adjusted so as to reflect the global step time.
-- TODO: read floating point settings.
-- local step_length = minetest.settings:get ("dedicated_server_step")
-- step_length = tonumber (step_length) or 0.09
-- local step_length = 0.05
local function pow_by_step (value, dtime)
return math.pow (value, dtime / 0.05)
end
local AIR_DRAG = 0.98
local AIR_FRICTION = 0.91
local WATER_DRAG = 0.8
local LAVA_FRICTION = 0.5
local LAVA_SPEED = 0.4
local BASE_SLIPPERY = 0.98
local BASE_FRICTION = 0.6
local LIQUID_FORCE = 0.28
local BASE_FRICTION3 = math.pow (0.6, 3)
local function scale_speed (speed, friction)
local f = BASE_FRICTION3 / (friction * friction * friction)
return speed * f
end
function mob_class:accelerate_relative (acc, speed)
local yaw = self.object:get_yaw ()
acc = vector.length (acc) == 1 and acc or vector.normalize (acc)
-- vector.rotate_around_axis is surprisingly inefficient.
-- local rv = vector.rotate_around_axis (acc, {x = 0, y = 1, z = 0,}, yaw)
local s = -math.sin (yaw)
local c = math.cos (yaw)
local rv = vector.new (acc.x * c + acc.z * s, 0, acc.z * c - acc.x * s)
return vector.multiply (rv, speed)
end
function mob_class:jump_actual (v)
self.order = ""
-- TODO: animation
v = {x = v.x, y = self.jump_height, z = v.z,}
if self:can_jump_cliff () then
v = vector.multiply (v, vector.new (2.8, 1, 2.8))
end
return v
end
function mob_class:jump_fluid (v)
self.order = ""
v = {x = v.x, y = 0.8, z = v.z,}
return v
end
local function horiz_collision (v, moveresult)
for _, item in ipairs (moveresult.collisions) do
if item.type == "node"
and (item.axis == "x" or item.axis == "z") then
return true
end
end
return moveresult.collides and not (moveresult.standing_on_object or moveresult.touching_ground)
end
--- TODO: correct direct invocations of set_acceleration and the like
--- TODO: flying and swimming mobs
--- TODO: correct uses of fall_speed and other modified fields
--- TODO: centralized motion control
local function clamp (num, min, max)
return math.min (max, math.max (num, min))
end
function mob_class:check_collision ()
-- can mob be pushed, if so calculate direction
if self.pushable or self.mob_pushable then
local c_x, c_y = self:collision ()
self.object:add_velocity ({x = c_x, y = 0, z = c_y})
end
end
function mob_class:motion_step (dtime, moveresult)
local standin = minetest.registered_nodes[self.standing_in]
local standon = minetest.registered_nodes[self.standing_on]
local acc_dir = self.acc_dir
local acc_speed = self.acc_speed
local fall_speed = self.fall_speed
local touching_ground = moveresult.touching_ground or moveresult.standing_on_object
local jumping = self.order == "jump"
local p
local h_scale
local climbing = false
self:check_dying ()
self:check_collision ()
p = pow_by_step (AIR_DRAG, dtime)
acc_dir.x = acc_dir.x * p
acc_dir.z = acc_dir.z * p
f = AIR_FRICTION
local v = self.object:get_velocity ()
-- If standing on a climable block and jumping or impeded
-- horizontally, begin climbing, and prevent fall speed from
-- exceeding 3.0 blocks/s.
if (self.always_climb and horiz_collision (v, moveresult))
or standin.climbable or standon.climbable then
if v.y < -3.0 then
v.y = -3.0
end
v.x = clamp (v.x, -3.0, 3.0)
v.z = clamp (v.z, -3.0, 3.0)
if jumping or horiz_collision (v, moveresult) then
v.y = 4.0
jumping = false
self.order = ""
end
climbing = true
self.reset_fall_damage = 1
end
local water_vec = self:check_water_flow ()
if standin.groups.water then
local friction = self.water_friction
local speed = self.water_velocity
-- Apply depth strider.
local level = math.min (3, mcl_enchanting.depth_strider_level (self))
level = touching_ground and level or level / 2
if level > 0 then
local delta = BASE_FRICTION * AIR_FRICTION - friction
friction = friction + delta * level / 3
delta = acc_speed - speed
speed = speed + delta * level / 3
end
-- TODO: apply Dolphin's Grace.
-- Adjust speed by friction.
local r, z = pow_by_step (friction, dtime), friction
h_scale = (1 - r) / (1 - z)
speed = speed * h_scale
local fv = self:accelerate_relative (acc_dir, speed)
p = pow_by_step (WATER_DRAG, dtime)
-- Apply friction.
v = vector.new (v.x * r, v.y * p, v.z * r)
-- Apply the new velocity in whole.
v.y = v.y + fall_speed * (1 - p) / (1 - WATER_DRAG)
v = vector.add (v, fv)
elseif standin.groups.lava then
local speed = LAVA_SPEED
local r, z = pow_by_step (LAVA_FRICTION, dtime), LAVA_FRICTION
h_scale = (1 - r) / (1 - z)
speed = speed * h_scale
local fv = self:accelerate_relative (acc_dir, speed)
v = vector.multiply (v, r)
v.y = v.y + fall_speed * h_scale
v = vector.add (v, fv)
else
-- If not standing on air, apply slippery to a base value of
-- 0.6.
local slippery = standon.groups.slippery
local friction
if slippery and slippery > 0 then
friction = BASE_SLIPPERY
else
friction = BASE_FRICTION
end
-- Apply friction, relative movement, and speed.
local speed
if touching_ground or climbing then
speed = scale_speed (acc_speed, friction)
else
speed = 0.04 -- 0.04 blocks/s
end
friction = friction * AIR_FRICTION
-- Adjust speed by friction.
local r, z = pow_by_step (friction, dtime), friction
h_scale = (1 - r) / (1 - z)
speed = speed * h_scale
local fv = self:accelerate_relative (acc_dir, speed)
local new_y = v.y + fall_speed * (1 - p) / (1 - AIR_DRAG)
v = vector.new (v.x * r, new_y * p, v.z * r)
-- Apply the new velocity in whole.
v = vector.add (v, fv)
end
if water_vec ~= nil and vector.length (water_vec) ~= 0 then
v.x = v.x + water_vec.x * LIQUID_FORCE * h_scale
v.z = v.z + water_vec.z * LIQUID_FORCE * h_scale
end
if self.gravity_drag and v.y < 0 and not touching_ground then
local f = pow_by_step (self.gravity_drag, dtime)
v.y = v.y * f
end
if touching_ground and jumping then
if standin.groups.water or standin.groups.lava then
v = self:jump_fluid (v)
else
v = self:jump_actual (v)
end
end
self.object:set_velocity (v)
end

View File

@ -79,6 +79,7 @@ mcl_mobs.register_mob("mobs_mc:blaze", {
fire_damage = 0,
fall_damage = 0,
fall_speed = -2.25,
gravity_drag = 0.6,
light_damage = 0,
view_range = 16,
attack_type = "dogshoot",

View File

@ -51,7 +51,7 @@ mcl_mobs.register_mob("mobs_mc:chicken", {
looting = "common",},
},
fall_damage = 0,
fall_speed = -2.25,
gravity_drag = 0.6,
sounds = {
random = "mobs_mc_chicken_buck",
damage = "mobs_mc_chicken_hurt",

View File

@ -149,7 +149,7 @@ local horse = {
floats = 1,
makes_footstep_sound = true,
jump = true,
jump_height = 5.75,
jump_height = 15,
drops = { base_drop },
should_drive = function (self)
return self._saddle and mob_class.should_drive (self)
@ -498,7 +498,7 @@ local donkey = table.merge(horse, {
horse.collisionbox[6] * d,
},
jump = true,
jump_height = 3.75,
jump_height = 15,
})
mcl_mobs.register_mob("mobs_mc:donkey", donkey)

View File

@ -166,8 +166,8 @@ mcl_mobs.register_mob("mobs_mc:parrot", {
-- TODO: more unused animations between 45 and 130
},
fall_damage = 0,
fall_speed = -2.25,
attack_type = "dogfight",
gravity_drag = 0.6,
floats = 1,
physical = true,
walk_velocity = 0.5,

View File

@ -89,7 +89,7 @@ local zombie = {
fear_height = 4,
pathfinding = 1,
jump = true,
jump_height = 4,
jump_height = 8.4,
group_attack = { "mobs_mc:zombie", "mobs_mc:baby_zombie", "mobs_mc:husk", "mobs_mc:baby_husk" },
drops = drops_zombie,
animation = {

View File

@ -107,6 +107,11 @@ mcl_player.register_globalstep_slow(function(player)
end
end)
function mcl_enchanting.depth_strider_level (mob)
-- TODO: depth strider for mobs.
return 0
end
-- implemented via on_enchant
mcl_enchanting.enchantments.efficiency = {
name = S("Efficiency"),