mirror of
https://git.minetest.land/MineClone2/MineClone2.git
synced 2024-12-05 01:03:44 +01:00
Mob pushing improvements
This commit is contained in:
parent
b91f48b419
commit
77c6c34d0e
@ -361,7 +361,7 @@ function mob_class:env_danger_movement_checks(player_in_active_range)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if self:is_at_cliff_or_danger() and not self._can_jump_cliff then
|
if not self._can_jump_cliff and self:is_at_cliff_or_danger() then
|
||||||
if logging then
|
if logging then
|
||||||
minetest.log("action", "[mcl_mobs] "..self.name.." at cliff danger, rotate")
|
minetest.log("action", "[mcl_mobs] "..self.name.." at cliff danger, rotate")
|
||||||
end
|
end
|
||||||
@ -858,7 +858,7 @@ function mob_class:do_states_walk()
|
|||||||
self:set_yaw(yaw, 8)
|
self:set_yaw(yaw, 8)
|
||||||
end
|
end
|
||||||
self:stand()
|
self:stand()
|
||||||
self:turn_by(PIHALF * (random() - 0.5), 6)
|
self:turn_by(PI * (random() - 0.5), 6)
|
||||||
return
|
return
|
||||||
elseif logging then
|
elseif logging then
|
||||||
minetest.log("action", "[mcl_mobs] "..self.name.." ignores the danger "..tostring(danger))
|
minetest.log("action", "[mcl_mobs] "..self.name.." ignores the danger "..tostring(danger))
|
||||||
@ -910,7 +910,7 @@ function mob_class:do_states_walk()
|
|||||||
if logging then
|
if logging then
|
||||||
minetest.log("action", "[mcl_mobs] "..self.name.." facing a wall, turning.")
|
minetest.log("action", "[mcl_mobs] "..self.name.." facing a wall, turning.")
|
||||||
end
|
end
|
||||||
self:turn_by(PI * (random() - 0.5), 6)
|
self:turn_by(TWOPI * (random() - 0.5), 6)
|
||||||
-- otherwise randomly turn
|
-- otherwise randomly turn
|
||||||
elseif random() <= 0.3 then
|
elseif random() <= 0.3 then
|
||||||
self:turn_by(PIHALF * (random() - 0.5), 10)
|
self:turn_by(PIHALF * (random() - 0.5), 10)
|
||||||
@ -920,8 +920,6 @@ function mob_class:do_states_walk()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function mob_class:do_states_stand(player_in_active_range)
|
function mob_class:do_states_stand(player_in_active_range)
|
||||||
local yaw = self.object:get_yaw() or 0
|
|
||||||
|
|
||||||
if random() < 0.25 then
|
if random() < 0.25 then
|
||||||
local lp
|
local lp
|
||||||
if player_in_active_range and self.look_at_players then
|
if player_in_active_range and self.look_at_players then
|
||||||
@ -942,10 +940,10 @@ function mob_class:do_states_stand(player_in_active_range)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if self.order == "sit" then
|
if self.order == "sit" then
|
||||||
self:set_animation( "sit")
|
self:set_animation("sit")
|
||||||
self:set_velocity(0)
|
self:set_velocity(0)
|
||||||
else
|
else
|
||||||
self:set_animation( "stand")
|
self:set_animation("stand")
|
||||||
self:set_velocity(0)
|
self:set_velocity(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -970,10 +968,7 @@ function mob_class:do_states_stand(player_in_active_range)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function mob_class:do_states_runaway()
|
function mob_class:do_states_runaway()
|
||||||
local yaw = self.object:get_yaw() or 0
|
|
||||||
|
|
||||||
self.runaway_timer = self.runaway_timer + 1
|
self.runaway_timer = self.runaway_timer + 1
|
||||||
|
|
||||||
-- stop after 5 seconds or when at cliff
|
-- stop after 5 seconds or when at cliff
|
||||||
if self.runaway_timer > 5
|
if self.runaway_timer > 5
|
||||||
or self:is_at_cliff_or_danger() then
|
or self:is_at_cliff_or_danger() then
|
||||||
|
@ -159,32 +159,29 @@ end
|
|||||||
-- collision function borrowed amended from jordan4ibanez open_ai mod
|
-- collision function borrowed amended from jordan4ibanez open_ai mod
|
||||||
function mob_class:collision()
|
function mob_class:collision()
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
if not pos then return {0,0} end
|
if not pos then return 0,0 end
|
||||||
local vel = self.object:get_velocity()
|
local vel = self.object:get_velocity()
|
||||||
local x = 0
|
local x, z = 0, 0
|
||||||
local z = 0
|
|
||||||
local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5
|
local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5
|
||||||
for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do
|
for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do
|
||||||
|
|
||||||
local ent = object:get_luaentity()
|
local ent = object:get_luaentity()
|
||||||
if object:is_player() or (ent and ent.is_mob and object ~= self.object) then
|
if object:is_player() or (ent and ent.is_mob and object ~= self.object) then
|
||||||
|
|
||||||
if object:is_player() and mcl_burning.is_burning(self.object) then
|
if object:is_player() and mcl_burning.is_burning(self.object) then
|
||||||
mcl_burning.set_on_fire(object, 4)
|
mcl_burning.set_on_fire(object, 4)
|
||||||
end
|
end
|
||||||
|
|
||||||
local pos2 = object:get_pos()
|
local pos2 = object:get_pos()
|
||||||
local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z}
|
local vx, vz = pos.x - pos2.x, pos.z - pos2.z
|
||||||
local force = (width + 0.5) - vector.distance(
|
local force = width - (vx*vx+vz*vz)^0.5
|
||||||
{x = pos.x, y = 0, z = pos.z},
|
if force > 0 then
|
||||||
{x = pos2.x, y = 0, z = pos2.z})
|
force = force * force * (object:is_player() and 2 or 1) -- players push more
|
||||||
|
-- minetest.log("mob push force "..force.." "..tostring(self.name).." by "..tostring(ent and ent.name or "player"))
|
||||||
x = x + (vec.x * force)
|
x = x + vx * force
|
||||||
z = z + (vec.z * force)
|
z = z + vz * force
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
return({x,z})
|
return x, z
|
||||||
end
|
end
|
||||||
|
|
||||||
function mob_class:check_death_and_slow_mob()
|
function mob_class:check_death_and_slow_mob()
|
||||||
@ -195,44 +192,45 @@ function mob_class:check_death_and_slow_mob()
|
|||||||
local v = self.object:get_velocity()
|
local v = self.object:get_velocity()
|
||||||
if v then
|
if v then
|
||||||
--diffuse object velocity
|
--diffuse object velocity
|
||||||
self.object:set_velocity({x = v.x*d, y = v.y, z = v.z*d})
|
self.object:set_velocity(vector.new(v.x*d, v.y, v.z*d))
|
||||||
end
|
end
|
||||||
return dying
|
return dying
|
||||||
end
|
end
|
||||||
|
|
||||||
-- move mob in facing direction
|
-- move mob in facing direction
|
||||||
function mob_class:set_velocity(v)
|
function mob_class:set_velocity(v)
|
||||||
if not v then return end
|
local c_x, c_z = 0, 0
|
||||||
|
|
||||||
local c_x, c_y = 0, 0
|
|
||||||
|
|
||||||
-- can mob be pushed, if so calculate direction
|
-- can mob be pushed, if so calculate direction
|
||||||
if self.pushable then
|
if self.pushable then
|
||||||
c_x, c_y = unpack(self:collision())
|
c_x, c_z = self:collision()
|
||||||
end
|
end
|
||||||
|
if v > 0 then
|
||||||
-- halt mob if it has been ordered to stay
|
|
||||||
if self.order == "stand" or self.order == "sit" then
|
|
||||||
self.acc = vector.zero()
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local yaw = (self.object:get_yaw() or 0) + self.rotate
|
local yaw = (self.object:get_yaw() or 0) + self.rotate
|
||||||
local vv = self.object:get_velocity()
|
local x = ((-math.sin(yaw) * v) + c_x) * .4
|
||||||
|
local z = (( math.cos(yaw) * v) + c_z) * .4
|
||||||
if vv and yaw then
|
if not self.acc then
|
||||||
self.acc = vector.new(((math.sin(yaw) * -v) + c_x) * .4, 0, ((math.cos(yaw) * v) + c_y) * .4)
|
self.acc = vector.new(x, 0, z)
|
||||||
|
else
|
||||||
|
self.acc.x = x
|
||||||
|
self.acc.y = 0
|
||||||
|
self.acc.z = z
|
||||||
|
end
|
||||||
|
else -- allow standing mobs to be pushed
|
||||||
|
if not self.acc then
|
||||||
|
self.acc = vector.new(c_x * .2, 0, c_z * .2)
|
||||||
|
else
|
||||||
|
self.acc.x = c_x * .2
|
||||||
|
self.acc.y = 0
|
||||||
|
self.acc.z = c_z * .2
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- calculate mob velocity
|
-- calculate mob velocity (2d)
|
||||||
function mob_class:get_velocity()
|
function mob_class:get_velocity()
|
||||||
local v = self.object:get_velocity()
|
local v = self.object:get_velocity()
|
||||||
if v then
|
if not v then return 0 end
|
||||||
return (v.x * v.x + v.z * v.z) ^ 0.5
|
return (v.x*v.x + v.z*v.z)^0.5
|
||||||
end
|
|
||||||
|
|
||||||
return 0
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function mob_class:update_roll()
|
function mob_class:update_roll()
|
||||||
@ -292,25 +290,26 @@ function mob_class:check_smooth_rotation(dtime)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local delay = self.delay
|
local delay = self.delay
|
||||||
local yaw = self.object:get_yaw() or 0
|
local initial_yaw = self.object:get_yaw() or 0
|
||||||
local target_yaw = self.target_yaw
|
local yaw -- resulting yaw for this tick
|
||||||
if delay and delay > 1 then
|
if delay and delay > 1 then
|
||||||
local dif = (target_yaw - yaw + PI) % TWOPI - PI
|
local dif = (self.target_yaw - initial_yaw + PI) % TWOPI - PI
|
||||||
yaw = (yaw + dif / delay) % TWOPI
|
yaw = (initial_yaw + dif / delay) % TWOPI
|
||||||
self.delay = delay - 1
|
self.delay = delay - 1
|
||||||
else
|
else
|
||||||
yaw = target_yaw
|
yaw = self.target_yaw
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.shaking then
|
if self.shaking then
|
||||||
yaw = yaw + (random() * 2 - 1) / 72 * dtime
|
yaw = yaw + (random() * 2 - 1) / 72 * dtime
|
||||||
end
|
end
|
||||||
|
if self.acc then
|
||||||
|
local change = yaw - initial_yaw
|
||||||
|
local si, co = math.sin(change), math.cos(change)
|
||||||
|
self.acc.x, self.acc.y = co * self.acc.x - si * self.acc.y, si * self.acc.x + co * self.acc.y
|
||||||
|
end
|
||||||
self.object:set_yaw(yaw)
|
self.object:set_yaw(yaw)
|
||||||
-- TODO: needed?
|
self:update_roll()
|
||||||
--if validate_vector(self.acc) then
|
|
||||||
-- self.acc=vector.rotate_around_axis(self.acc,vector.new(0,1,0), target_shortest_path*(3.6*ddtime))
|
|
||||||
--end
|
|
||||||
--self:update_roll()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- global function to set mob yaw
|
-- global function to set mob yaw
|
||||||
@ -596,7 +595,7 @@ function mob_class:do_env_damage()
|
|||||||
|
|
||||||
-- what is mob standing in?
|
-- what is mob standing in?
|
||||||
pos.y = pos.y + y_level + 0.25 -- foot level
|
pos.y = pos.y + y_level + 0.25 -- foot level
|
||||||
local pos2 = {x=pos.x, y=pos.y-1, z=pos.z}
|
local pos2 = vector.new(pos.x, pos.y-1, pos.z)
|
||||||
self.standing_in = node_ok(pos, "air").name
|
self.standing_in = node_ok(pos, "air").name
|
||||||
self.standing_on = node_ok(pos2, "air").name
|
self.standing_on = node_ok(pos2, "air").name
|
||||||
|
|
||||||
@ -605,7 +604,7 @@ function mob_class:do_env_damage()
|
|||||||
|
|
||||||
-- don't fall when on ignore, just stand still
|
-- don't fall when on ignore, just stand still
|
||||||
if self.standing_in == "ignore" then
|
if self.standing_in == "ignore" then
|
||||||
self.object:set_velocity({x = 0, y = 0, z = 0})
|
self.object:set_velocity(vector.zero())
|
||||||
-- wither rose effect
|
-- wither rose effect
|
||||||
elseif self.standing_in == "mcl_flowers:wither_rose" then
|
elseif self.standing_in == "mcl_flowers:wither_rose" then
|
||||||
mcl_potions.give_effect_by_level("withering", self.object, 2, 2)
|
mcl_potions.give_effect_by_level("withering", self.object, 2, 2)
|
||||||
@ -885,7 +884,7 @@ function mob_class:falling(pos, moveresult)
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- stop accelerating once max fall speed hit
|
-- stop accelerating once max fall speed hit
|
||||||
new_acceleration =vector.zero()
|
new_acceleration = vector.zero()
|
||||||
end
|
end
|
||||||
|
|
||||||
self.object:set_acceleration(new_acceleration)
|
self.object:set_acceleration(new_acceleration)
|
||||||
@ -949,8 +948,8 @@ function mob_class:check_water_flow()
|
|||||||
local f = 1.39
|
local f = 1.39
|
||||||
-- Set new item moving speed into the direciton of the liquid
|
-- Set new item moving speed into the direciton of the liquid
|
||||||
local newv = vector.multiply(vec, f)
|
local newv = vector.multiply(vec, f)
|
||||||
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
self.object:set_acceleration(vector.zero())
|
||||||
self.object:set_velocity({x = newv.x, y = -0.22, z = newv.z})
|
self.object:set_velocity(vector.new(newv.x, -0.22, newv.z))
|
||||||
|
|
||||||
self.physical_state = true
|
self.physical_state = true
|
||||||
self._flowing = true
|
self._flowing = true
|
||||||
|
Loading…
Reference in New Issue
Block a user