diff --git a/mods/ENTITIES/mcl_mobs/movement.lua b/mods/ENTITIES/mcl_mobs/movement.lua index 9fa30bb6c..a9e681f97 100644 --- a/mods/ENTITIES/mcl_mobs/movement.lua +++ b/mods/ENTITIES/mcl_mobs/movement.lua @@ -361,7 +361,7 @@ function mob_class:env_danger_movement_checks(player_in_active_range) return 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 minetest.log("action", "[mcl_mobs] "..self.name.." at cliff danger, rotate") end @@ -858,7 +858,7 @@ function mob_class:do_states_walk() self:set_yaw(yaw, 8) end self:stand() - self:turn_by(PIHALF * (random() - 0.5), 6) + self:turn_by(PI * (random() - 0.5), 6) return elseif logging then 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 minetest.log("action", "[mcl_mobs] "..self.name.." facing a wall, turning.") end - self:turn_by(PI * (random() - 0.5), 6) + self:turn_by(TWOPI * (random() - 0.5), 6) -- otherwise randomly turn elseif random() <= 0.3 then self:turn_by(PIHALF * (random() - 0.5), 10) @@ -920,8 +920,6 @@ function mob_class:do_states_walk() end function mob_class:do_states_stand(player_in_active_range) - local yaw = self.object:get_yaw() or 0 - if random() < 0.25 then local lp 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 if self.order == "sit" then - self:set_animation( "sit") + self:set_animation("sit") self:set_velocity(0) else - self:set_animation( "stand") + self:set_animation("stand") self:set_velocity(0) end @@ -970,10 +968,7 @@ function mob_class:do_states_stand(player_in_active_range) end function mob_class:do_states_runaway() - local yaw = self.object:get_yaw() or 0 - self.runaway_timer = self.runaway_timer + 1 - -- stop after 5 seconds or when at cliff if self.runaway_timer > 5 or self:is_at_cliff_or_danger() then diff --git a/mods/ENTITIES/mcl_mobs/physics.lua b/mods/ENTITIES/mcl_mobs/physics.lua index df33f8424..ff54d6bae 100644 --- a/mods/ENTITIES/mcl_mobs/physics.lua +++ b/mods/ENTITIES/mcl_mobs/physics.lua @@ -159,32 +159,29 @@ end -- collision function borrowed amended from jordan4ibanez open_ai mod function mob_class:collision() 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 x = 0 - local z = 0 + local x, z = 0, 0 local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5 for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do - local ent = object:get_luaentity() 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 mcl_burning.set_on_fire(object, 4) end local pos2 = object:get_pos() - local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z} - local force = (width + 0.5) - vector.distance( - {x = pos.x, y = 0, z = pos.z}, - {x = pos2.x, y = 0, z = pos2.z}) - - x = x + (vec.x * force) - z = z + (vec.z * force) + local vx, vz = pos.x - pos2.x, pos.z - pos2.z + local force = width - (vx*vx+vz*vz)^0.5 + if force > 0 then + 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 + vx * force + z = z + vz * force + end end end - - return({x,z}) + return x, z end 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() if v then --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 return dying end -- move mob in facing direction function mob_class:set_velocity(v) - if not v then return end - - local c_x, c_y = 0, 0 - + local c_x, c_z = 0, 0 -- can mob be pushed, if so calculate direction if self.pushable then - c_x, c_y = unpack(self:collision()) + c_x, c_z = self:collision() end - - -- 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 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) + if v > 0 then + local yaw = (self.object:get_yaw() or 0) + self.rotate + local x = ((-math.sin(yaw) * v) + c_x) * .4 + local z = (( math.cos(yaw) * v) + c_z) * .4 + if not self.acc then + 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 --- calculate mob velocity +-- calculate mob velocity (2d) function mob_class:get_velocity() local v = self.object:get_velocity() - if v then - return (v.x * v.x + v.z * v.z) ^ 0.5 - end - - return 0 + if not v then return 0 end + return (v.x*v.x + v.z*v.z)^0.5 end function mob_class:update_roll() @@ -292,25 +290,26 @@ function mob_class:check_smooth_rotation(dtime) end local delay = self.delay - local yaw = self.object:get_yaw() or 0 - local target_yaw = self.target_yaw + local initial_yaw = self.object:get_yaw() or 0 + local yaw -- resulting yaw for this tick if delay and delay > 1 then - local dif = (target_yaw - yaw + PI) % TWOPI - PI - yaw = (yaw + dif / delay) % TWOPI + local dif = (self.target_yaw - initial_yaw + PI) % TWOPI - PI + yaw = (initial_yaw + dif / delay) % TWOPI self.delay = delay - 1 else - yaw = target_yaw + yaw = self.target_yaw end if self.shaking then yaw = yaw + (random() * 2 - 1) / 72 * dtime 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) - -- TODO: needed? - --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() + self:update_roll() end -- global function to set mob yaw @@ -606,7 +605,7 @@ function mob_class:do_env_damage() -- what is mob standing in? 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_on = node_ok(pos2, "air").name @@ -615,7 +614,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.object:set_velocity(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) @@ -889,7 +888,7 @@ function mob_class:falling(pos, moveresult) new_acceleration = vector.new(0, self.fall_speed, 0) else -- stop accelerating once max fall speed hit - new_acceleration =vector.zero() + new_acceleration = vector.zero() end self.object:set_acceleration(new_acceleration) @@ -953,8 +952,8 @@ function mob_class:check_water_flow() 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.object:set_acceleration(vector.zero()) + self.object:set_velocity(vector.new(newv.x, -0.22, newv.z)) self.physical_state = true self._flowing = true