mirror of
https://git.minetest.land/MineClone2/MineClone2.git
synced 2024-12-11 20:23:15 +01:00
movement improvements, door opening
This commit is contained in:
parent
e78f5cdbe9
commit
5b27cb80fe
@ -413,11 +413,7 @@ local function on_step_work(self, dtime, moveresult)
|
||||
|
||||
self:check_water_flow()
|
||||
|
||||
if not self._jumping_cliff then
|
||||
self._can_jump_cliff = self:can_jump_cliff()
|
||||
else
|
||||
self._can_jump_cliff = false
|
||||
end
|
||||
self._can_jump_cliff = not self._jumping_cliff and self:can_jump_cliff()
|
||||
|
||||
self:flop()
|
||||
|
||||
@ -503,26 +499,24 @@ end
|
||||
|
||||
-- main mob function
|
||||
function mob_class:on_step(dtime, moveresult)
|
||||
if not DEVELOPMENT then
|
||||
-- Removed as bundled Lua (5.1 doesn't support xpcall)
|
||||
--local status, retVal = xpcall(on_step_work, on_step_error_handler, self, dtime)
|
||||
local status, retVal = pcall(on_step_work, self, dtime, moveresult)
|
||||
if status then
|
||||
return retVal
|
||||
else
|
||||
warn_user_error ()
|
||||
local pos = self.object:get_pos()
|
||||
if pos then
|
||||
local node = minetest.get_node(pos)
|
||||
if node and node.name == "ignore" then
|
||||
minetest.log("warning", "Pos is ignored: " .. dump(pos))
|
||||
end
|
||||
end
|
||||
log_error (dump(retVal), dump(pos), dump(self))
|
||||
end
|
||||
else
|
||||
return on_step_work (self, dtime, moveresult)
|
||||
if DEVELOPMENT then
|
||||
return on_step_work(self, dtime, moveresult)
|
||||
end
|
||||
-- Removed as bundled Lua (5.1 doesn't support xpcall)
|
||||
--local status, retVal = xpcall(on_step_work, on_step_error_handler, self, dtime)
|
||||
local status, retVal = pcall(on_step_work, self, dtime, moveresult)
|
||||
if status then
|
||||
return retVal
|
||||
end
|
||||
warn_user_error ()
|
||||
local pos = self.object:get_pos()
|
||||
if pos then
|
||||
local node = minetest.get_node(pos)
|
||||
if node and node.name == "ignore" then
|
||||
minetest.log("warning", "Pos is ignored: " .. dump(pos))
|
||||
end
|
||||
end
|
||||
log_error (dump(retVal), dump(pos), dump(self))
|
||||
end
|
||||
|
||||
local timer = 0
|
||||
|
@ -755,8 +755,9 @@ function mob_class:go_to_pos(b)
|
||||
if not b then return end
|
||||
local s = self.object:get_pos()
|
||||
if vector.distance(b,s) < .5 then return true end
|
||||
if b.y > s.y then self:do_jump() end
|
||||
self:turn_in_direction(b.x - s.x, b.z - s.z, 2)
|
||||
self:set_velocity(self.follow_velocity)
|
||||
self:set_velocity(self.walk_velocity)
|
||||
self:set_animation("walk")
|
||||
end
|
||||
|
||||
@ -909,10 +910,10 @@ function mob_class:do_states_walk()
|
||||
-- otherwise randomly turn
|
||||
elseif random() <= 0.3 then
|
||||
local home = self._home or self._bed
|
||||
if home and random() < 0.3 then
|
||||
if home and random() < 0.1 then
|
||||
self:turn_in_direction(home.x - s.x, home.z - s.z, 8)
|
||||
else
|
||||
self:turn_by(PIHALF * (random() - 0.5), 10)
|
||||
self:turn_by(PIQUARTER * (random() - 0.5), 10)
|
||||
end
|
||||
end
|
||||
self:set_velocity(self.walk_velocity)
|
||||
|
@ -42,8 +42,8 @@ function append_paths (wp1, wp2)
|
||||
mcl_log("Cannot append wp's")
|
||||
return
|
||||
end
|
||||
output_table(wp1)
|
||||
output_table(wp2)
|
||||
--output_table(wp1)
|
||||
--output_table(wp2)
|
||||
for _,a in pairs (wp2) do
|
||||
table.insert(wp1, a)
|
||||
end
|
||||
@ -51,18 +51,13 @@ function append_paths (wp1, wp2)
|
||||
end
|
||||
|
||||
local function output_enriched (wp_out)
|
||||
mcl_log("Output enriched path")
|
||||
--mcl_log("Output enriched path")
|
||||
local i = 0
|
||||
for _,outy in pairs (wp_out) do
|
||||
i = i + 1
|
||||
mcl_log("Pos ".. i ..":" .. minetest.pos_to_string(outy["pos"]))
|
||||
|
||||
local action = outy["action"]
|
||||
if action then
|
||||
--mcl_log("Pos ".. i ..":" .. minetest.pos_to_string(outy["pos"]))
|
||||
mcl_log("type: " .. action["type"])
|
||||
mcl_log("action: " .. action["action"])
|
||||
mcl_log("target: " .. minetest.pos_to_string(action["target"]))
|
||||
mcl_log("Pos ".. i ..":" .. minetest.pos_to_string(outy["pos"])..", type: " .. action["type"]..", action: " .. action["action"]..", target: " .. minetest.pos_to_string(action["target"]))
|
||||
end
|
||||
--mcl_log("failed attempts: " .. outy["failed_attempts"])
|
||||
end
|
||||
@ -113,17 +108,17 @@ end
|
||||
local last_pathing_time = os.time()
|
||||
|
||||
function mob_class:ready_to_path(prioritised)
|
||||
mcl_log("Check ready to path")
|
||||
-- mcl_log("Check ready to path")
|
||||
if self._pf_last_failed and (os.time() - self._pf_last_failed) < PATHFINDING_FAIL_WAIT then
|
||||
mcl_log("Not ready to path as last fail is less than threshold: " .. (os.time() - self._pf_last_failed))
|
||||
-- mcl_log("Not ready to path as last fail is less than threshold: " .. (os.time() - self._pf_last_failed))
|
||||
return false
|
||||
else
|
||||
local time_since_path_start = os.time() - last_pathing_time
|
||||
mcl_log("time_since_path_start: " .. tostring(time_since_path_start))
|
||||
if prioritised or (time_since_path_start) > PATHING_START_DELAY then
|
||||
mcl_log("We are ready to pathfind, no previous fail or we are past threshold")
|
||||
mcl_log("We are ready to pathfind, no previous fail or we are past threshold: "..tostring(time_since_path_start))
|
||||
return true
|
||||
end
|
||||
mcl_log("time_since_path_start: " .. tostring(time_since_path_start))
|
||||
end
|
||||
end
|
||||
|
||||
@ -272,13 +267,7 @@ function mob_class:gopath(target, callback_arrived, prioritised)
|
||||
--output_table(wp)
|
||||
self._target = t
|
||||
self.callback_arrived = callback_arrived
|
||||
local current_location = table.remove(wp,1)
|
||||
if current_location and current_location["pos"] then
|
||||
mcl_log("Removing first co-ord? " .. tostring(current_location["pos"]))
|
||||
else
|
||||
mcl_log("Nil pos")
|
||||
end
|
||||
self.current_target = current_location
|
||||
self.current_target = table.remove(wp,1)
|
||||
self.waypoints = wp
|
||||
self.state = PATHFINDING
|
||||
return true
|
||||
@ -300,19 +289,17 @@ function mob_class:interact_with_door(action, target)
|
||||
|
||||
local n = minetest.get_node(target)
|
||||
if n.name:find("_b_") or n.name:find("_t_") then
|
||||
mcl_log("Door")
|
||||
local def = minetest.registered_nodes[n.name]
|
||||
local closed = n.name:find("_b_1") or n.name:find("_t_1")
|
||||
--if self.state == PATHFINDING then
|
||||
if closed and action == "open" and def.on_rightclick then
|
||||
mcl_log("Open door")
|
||||
def.on_rightclick(target,n,self)
|
||||
end
|
||||
if not closed and action == "close" and def.on_rightclick then
|
||||
mcl_log("Close door")
|
||||
def.on_rightclick(target,n,self)
|
||||
end
|
||||
--else
|
||||
local meta = minetest.get_meta(target)
|
||||
local closed = meta:get_int("is_open") == 0
|
||||
if closed and action == "open" and def.on_rightclick then
|
||||
mcl_log("Open door")
|
||||
def.on_rightclick(target,n,self)
|
||||
end
|
||||
if not closed and action == "close" and def.on_rightclick then
|
||||
mcl_log("Close door")
|
||||
def.on_rightclick(target,n,self)
|
||||
end
|
||||
else
|
||||
mcl_log("Not door")
|
||||
end
|
||||
@ -333,6 +320,7 @@ function mob_class:do_pathfind_action(action)
|
||||
end
|
||||
if type and type == "door" then
|
||||
mcl_log("Type is door")
|
||||
self.object:set_velocity(vector.zero())
|
||||
self:interact_with_door(action_val, target)
|
||||
end
|
||||
end
|
||||
@ -343,8 +331,7 @@ function mob_class:check_gowp(dtime)
|
||||
|
||||
-- no destination
|
||||
if not p or not self._target then
|
||||
mcl_log("p: ".. tostring(p))
|
||||
mcl_log("self._target: ".. tostring(self._target))
|
||||
mcl_log("p: ".. tostring(p)..", self._target: ".. tostring(self._target))
|
||||
return
|
||||
end
|
||||
|
||||
@ -374,11 +361,12 @@ function mob_class:check_gowp(dtime)
|
||||
--distance_to_current_target = vector.distance(p,self.current_target["pos"])
|
||||
end
|
||||
-- also check next target, maybe we were too fast
|
||||
local next_target = #self.waypoints > 0 and self.waypoints[1]
|
||||
if next_target and next_target["pos"] and distance_to_current_target < 2 then
|
||||
local next_target = #self.waypoints > 1 and self.waypoints[1]
|
||||
if not self.current_target["action"] and next_target and next_target["pos"] and distance_to_current_target < 1.5 then
|
||||
local dx, dy, dz = next_target["pos"].x-p.x, next_target["pos"].y-p.y, next_target["pos"].z-p.z
|
||||
local distance_to_next_target = (dx*dx+dy*dy*0.25+dz*dz)^0.5 -- reduced weight on y
|
||||
if distance_to_next_target < distance_to_current_target then
|
||||
mcl_log("Skipped one waypoint.")
|
||||
self.current_target = table.remove(self.waypoints, 1) -- pop waypoint already
|
||||
distance_to_current_target = distance_to_next_target
|
||||
end
|
||||
@ -387,7 +375,8 @@ function mob_class:check_gowp(dtime)
|
||||
-- 0.6 is working but too sensitive. sends villager back too frequently. 0.7 is quite good, but not with heights
|
||||
-- 0.8 is optimal for 0.025 frequency checks and also 1... Actually. 0.8 is winning
|
||||
-- 0.9 and 1.0 is also good. Stick with unless door open or closing issues
|
||||
if self.waypoints and #self.waypoints > 0 and ( not self.current_target or not self.current_target["pos"] or distance_to_current_target < 0.8 ) then
|
||||
local threshold = self.current_target["action"] and 0.8 or 1.2
|
||||
if self.waypoints and #self.waypoints > 0 and ( not self.current_target or not self.current_target["pos"] or distance_to_current_target < threshold ) then
|
||||
-- We have waypoints, and are at current_target or have no current target. We need a new current_target.
|
||||
self:do_pathfind_action (self.current_target["action"])
|
||||
|
||||
@ -396,11 +385,15 @@ function mob_class:check_gowp(dtime)
|
||||
|
||||
self.current_target = table.remove(self.waypoints, 1)
|
||||
-- use smoothing
|
||||
if #self.waypoints > 0 then
|
||||
--[[if #self.waypoints > 0 and not self.current_target["action"] then
|
||||
local curwp, nextwp = self.current_target["pos"], self.waypoints[1]["pos"]
|
||||
self:go_to_pos(vector.new(curwp.x*0.5+nextwp.x*0.5,curwp.y*0.5+nextwp.y*0.5,curwp.z*0.5+nextwp.z*0.5))
|
||||
end
|
||||
self:go_to_pos(vector.new(curwp.x*0.7+nextwp.x*0.3,curwp.y,curwp.z*0.7+nextwp.z*0.3))
|
||||
return
|
||||
end]]--
|
||||
self:go_to_pos(self.current_target["pos"])
|
||||
if self.current_target["action"] then
|
||||
self:set_velocity(self.walk_velocity * 0.25)
|
||||
end
|
||||
return
|
||||
elseif self.current_target and self.current_target["pos"] then
|
||||
-- No waypoints left, but have current target and not close enough. Potentially last waypoint to go to.
|
||||
@ -408,7 +401,7 @@ function mob_class:check_gowp(dtime)
|
||||
self.current_target["failed_attempts"] = self.current_target["failed_attempts"] + 1
|
||||
local failed_attempts = self.current_target["failed_attempts"]
|
||||
if failed_attempts >= PATHFINDING_FAIL_THRESHOLD then
|
||||
mcl_log("Failed to reach position (" .. minetest.pos_to_string(self.current_target["pos"]) .. ") too many times. Abandon route. Times tried: " .. failed_attempts)
|
||||
mcl_log("Failed to reach position " .. minetest.pos_to_string(self.current_target["pos"]) .. " too many times. At: "..minetest.pos_to_string(p).." Abandon route. Times tried: " .. failed_attempts .. " current distance "..distance_to_current_target)
|
||||
self.state = "stand"
|
||||
self.current_target = nil
|
||||
self.waypoints = nil
|
||||
@ -421,7 +414,7 @@ function mob_class:check_gowp(dtime)
|
||||
|
||||
--mcl_log("Not at pos with failed attempts ".. failed_attempts ..": ".. minetest.pos_to_string(p) .. "self.current_target: ".. minetest.pos_to_string(self.current_target["pos"]) .. ". Distance: ".. distance_to_current_target)
|
||||
self:go_to_pos(self.current_target["pos"])
|
||||
self:turn_by(2 * (math.random() - 0.5), 2) -- but try turning left or right
|
||||
self:turn_by((math.random() - 0.5), 2) -- but try turning left or right
|
||||
-- Do i just delete current_target, and return so we can find final path.
|
||||
else
|
||||
-- Not at target, no current waypoints or current_target. Through the door and should be able to path to target.
|
||||
@ -462,7 +455,7 @@ function mob_class:check_gowp(dtime)
|
||||
mcl_log("Current p: ".. minetest.pos_to_string(updated_p))
|
||||
|
||||
-- 1.6 is good. is 1.9 better? It could fail less, but will it path to door when it isn't after door
|
||||
if distance_to_cur_targ > 1.9 then
|
||||
if distance_to_cur_targ > 1.6 then
|
||||
mcl_log("not close to current target: ".. minetest.pos_to_string(self.current_target["pos"]))
|
||||
self:go_to_pos(self._current_target)
|
||||
else
|
||||
|
@ -59,9 +59,7 @@ end
|
||||
|
||||
-- Return true if object is in view_range
|
||||
function mob_class:object_in_range(object)
|
||||
if not object then
|
||||
return false
|
||||
end
|
||||
if not object then return false end
|
||||
local factor
|
||||
-- Apply view range reduction for special player armor
|
||||
if object:is_player() then
|
||||
@ -141,12 +139,7 @@ function mob_class:item_drop(cooked, looting_level)
|
||||
end
|
||||
|
||||
if obj and obj:get_luaentity() then
|
||||
|
||||
obj:set_velocity({
|
||||
x = math.random(-10, 10) / 9,
|
||||
y = 6,
|
||||
z = math.random(-10, 10) / 9,
|
||||
})
|
||||
obj:set_velocity(vector.new((math.random() - 0.5) * 1.5, 6, (math.random() - 0.5) * 1.5))
|
||||
elseif obj then
|
||||
obj:remove() -- item does not exist
|
||||
end
|
||||
@ -854,10 +847,7 @@ end
|
||||
-- falling and fall damage
|
||||
-- returns true if mob died
|
||||
function mob_class:falling(pos, moveresult)
|
||||
if self.fly and self.state ~= "die" then
|
||||
return
|
||||
end
|
||||
|
||||
if self.fly and self.state ~= "die" then return end
|
||||
if not self.fall_speed then self.fall_speed = DEFAULT_FALL_SPEED end
|
||||
|
||||
if mcl_portals ~= nil then
|
||||
@ -870,10 +860,10 @@ function mob_class:falling(pos, moveresult)
|
||||
local v = self.object:get_velocity()
|
||||
if v then
|
||||
local new_acceleration
|
||||
if v.y > 0 then
|
||||
-- apply gravity when moving up
|
||||
new_acceleration = vector.new(0, DEFAULT_FALL_SPEED, 0)
|
||||
elseif v.y <= 0 and v.y > self.fall_speed then
|
||||
if v.y > 0 and v.y < -0.5 * DEFAULT_FALL_SPEED then
|
||||
-- when moving up, always use gravity
|
||||
new_acceleration = vector.new(0, 0.5 * DEFAULT_FALL_SPEED, 0)
|
||||
elseif v.y <= 0 and v.y > 0.5 * self.fall_speed then
|
||||
-- fall downwards at set speed
|
||||
if moveresult and moveresult.touching_ground then
|
||||
-- when touching ground, retain a minimal gravity to keep the touching_ground flag
|
||||
@ -886,7 +876,6 @@ function mob_class:falling(pos, moveresult)
|
||||
-- stop accelerating once max fall speed hit
|
||||
new_acceleration = vector.zero()
|
||||
end
|
||||
|
||||
self.object:set_acceleration(new_acceleration)
|
||||
end
|
||||
|
||||
@ -896,14 +885,14 @@ function mob_class:falling(pos, moveresult)
|
||||
|
||||
if registered_node.groups.lava then
|
||||
if acc and self.floats_on_lava == 1 then
|
||||
self.object:set_acceleration(vector.new(0, -self.fall_speed / (math.max(1, v.y) ^ 2), 0))
|
||||
self.object:set_acceleration(vector.new(0, -self.fall_speed / math.max(1, v.y^2), 0))
|
||||
end
|
||||
end
|
||||
|
||||
-- in water then float up
|
||||
if registered_node.groups.water then
|
||||
if acc and self.floats == 1 and minetest.registered_nodes[node_ok(vector.offset(pos,0,self.collisionbox[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))
|
||||
self.object:set_acceleration(vector.new(0, -self.fall_speed / math.max(1, v.y^2), 0))
|
||||
end
|
||||
else
|
||||
-- fall damage onto solid ground
|
||||
@ -927,13 +916,9 @@ end
|
||||
|
||||
function mob_class:check_water_flow()
|
||||
-- Add water flowing for mobs from mcl_item_entity
|
||||
local p, node, nn, def
|
||||
p = self.object:get_pos()
|
||||
node = minetest.get_node_or_nil(p)
|
||||
if node then
|
||||
nn = node.name
|
||||
def = minetest.registered_nodes[nn]
|
||||
end
|
||||
local p = self.object:get_pos()
|
||||
local node = minetest.get_node_or_nil(p)
|
||||
local def = node and minetest.registered_nodes[node.name]
|
||||
|
||||
-- Move item around on flowing liquids
|
||||
if def and def.liquidtype == "flowing" then
|
||||
@ -953,9 +938,7 @@ function mob_class:check_water_flow()
|
||||
|
||||
self.physical_state = true
|
||||
self._flowing = true
|
||||
self.object:set_properties({
|
||||
physical = true
|
||||
})
|
||||
self.object:set_properties({ physical = true })
|
||||
return
|
||||
end
|
||||
elseif self._flowing == true then
|
||||
|
Loading…
Reference in New Issue
Block a user