test mobs

This commit is contained in:
MihailRis 2025-09-01 01:39:31 +03:00
parent c06636053d
commit 88641e032a
5 changed files with 142 additions and 79 deletions

View File

@ -1,4 +1,5 @@
local body = entity.rigidbody local body = entity.rigidbody
local tsf = entity.transform
local props = {} local props = {}
@ -56,79 +57,119 @@ function move_horizontal(speed, dir, vel)
body:set_vel(vel) body:set_vel(vel)
end end
local function process_player_inputs(pid, delta)
if not hud or hud.is_inventory_open() or menu.page ~= "" then
return
end
-- todo: replace with entity direction
local cam = cameras.get("core:first-person")
local front = cam:get_front()
local right = cam:get_right()
front[2] = 0.0
vec3.normalize(front, front)
local grounded = body:is_grounded()
local isjump = input.is_active('movement.jump')
local issprint = input.is_active('movement.sprint')
local iscrouch = input.is_active('movement.crouch')
local isforward = input.is_active('movement.forward')
local ischeat = input.is_active('movement.cheat')
local isback = input.is_active('movement.back')
local isleft = input.is_active('movement.left')
local isright = input.is_active('movement.right')
local flight = player.is_flight(pid)
local noclip = player.is_noclip(pid)
local vel = body:get_vel()
local speed = props.movement_speed
if flight then
speed = speed * props.flight_speed_mul
elseif issprint then
speed = speed * props.run_speed_mul
elseif iscrouch and grounded then
speed = speed * props.crouch_speed_mul
end
body:set_crouching(iscrouch)
if ischeat then
speed = speed * props.cheat_speed_mul
end
local dir = {0, 0, 0}
if isforward then
vec3.add(dir, front, dir)
end
if isback then
vec3.sub(dir, front, dir)
end
if isright then
vec3.add(dir, right, dir)
end
if isleft then
vec3.sub(dir, right, dir)
end
if vec3.length(dir) > 0.0 then
move_horizontal(speed, dir, vel)
end
if flight then
if isjump then
elevate(speed * 8.0, delta)
elseif iscrouch then
lower(speed * 8.0, delta)
end
elseif isjump then
jump()
end
body:set_vdamping(flight)
body:set_gravity_scale({0, flight and 0.0 or props.gravity_scale, 0})
body:set_linear_damping(
(flight or not grounded) and props.air_damping or props.ground_damping
)
body:set_body_type(noclip and "kinematic" or "dynamic")
end
local prev_angle = 0.0
local function follow_waypoints(pathfinding, delta)
local pos = tsf:get_pos()
pathfinding.set_target(vec3.add(pos, {math.random(-15, 15), 1, math.random(-15, 15)}))
local waypoint = pathfinding.next_waypoint()
if not waypoint then
return
end
local speed = props.movement_speed
local vel = body:get_vel()
local dir = vec3.sub(
vec3.add(waypoint, {0.5, 0, 0.5}),
{pos[1], math.floor(pos[2]), pos[3]}
)
local upper = dir[2] > 0
dir[2] = 0.0
local t = delta * 16.0
local angle = (vec2.angle({dir[3], dir[1]}) + 180) * t + prev_angle * (1 - t)
tsf:set_rot(mat4.rotate({0, 1, 0}, angle))
prev_angle = angle
vec3.normalize(dir, dir)
move_horizontal(speed, dir, vel)
if body:is_grounded() and upper then
jump(1.0)
end
end
function on_physics_update(tps) function on_physics_update(tps)
local delta = (1.0 / tps) local delta = (1.0 / tps)
local pid = entity:get_player() local pid = entity:get_player()
if pid and hud and not hud.is_inventory_open() and not menu.page ~= "" then if pid ~= -1 then
-- todo: replace with entity direction process_player_inputs(pid, delta)
local cam = cameras.get("core:first-person") else
local front = cam:get_front() local pathfinding = entity:get_component("core:pathfinding")
local right = cam:get_right() if pathfinding then
front[2] = 0.0 follow_waypoints(pathfinding, delta)
vec3.normalize(front, front)
local grounded = body:is_grounded()
local isjump = input.is_active('movement.jump')
local issprint = input.is_active('movement.sprint')
local iscrouch = input.is_active('movement.crouch')
local isforward = input.is_active('movement.forward')
local ischeat = input.is_active('movement.cheat')
local isback = input.is_active('movement.back')
local isleft = input.is_active('movement.left')
local isright = input.is_active('movement.right')
local flight = player.is_flight(pid)
local noclip = player.is_noclip(pid)
local vel = body:get_vel()
local speed = props.movement_speed
if flight then
speed = speed * props.flight_speed_mul
elseif issprint then
speed = speed * props.run_speed_mul
elseif iscrouch and grounded then
speed = speed * props.crouch_speed_mul
end end
body:set_crouching(iscrouch)
if ischeat then
speed = speed * props.cheat_speed_mul
end
local dir = {0, 0, 0}
if isforward then
vec3.add(dir, front, dir)
end
if isback then
vec3.sub(dir, front, dir)
end
if isright then
vec3.add(dir, right, dir)
end
if isleft then
vec3.sub(dir, right, dir)
end
if vec3.length(dir) > 0.0 then
move_horizontal(speed, dir, vel)
end
if flight then
if isjump then
elevate(speed * 8.0, delta)
elseif iscrouch then
lower(speed * 8.0, delta)
end
elseif isjump then
jump()
end
body:set_vdamping(flight)
body:set_gravity_scale({0, flight and 0.0 or props.gravity_scale, 0})
body:set_linear_damping(
(flight or not grounded) and props.air_damping or props.ground_damping
)
body:set_body_type(noclip and "kinematic" or "dynamic")
end end
end end

View File

@ -3,9 +3,10 @@ local route
local started local started
local tsf = entity.transform local tsf = entity.transform
local body = entity.rigidbody
agent = pathfinding.create_agent() agent = pathfinding.create_agent()
pathfinding.set_max_visited(agent, 1e4) pathfinding.set_max_visited(agent, 1e3)
pathfinding.avoid_tag(agent, "core:liquid", 8) pathfinding.avoid_tag(agent, "core:liquid", 8)
function set_target(new_target) function set_target(new_target)
@ -24,11 +25,32 @@ function get_route()
return route return route
end end
function next_waypoint()
if not route or #route == 0 then
return
end
local waypoint = route[#route]
local pos = tsf:get_pos()
local dst = vec2.length({
math.floor(waypoint[1] - math.floor(pos[1])),
math.floor(waypoint[3] - math.floor(pos[3]))
})
if dst < 1.0 then
table.remove(route, #route)
end
return route[#route]
end
local frameid = 0
function on_update() function on_update()
if not started then if not started then
if target then if body:is_grounded() then
pathfinding.make_route_async(agent, tsf:get_pos(), target) frameid = frameid + 1
started = true if target and frameid % 100 == 1 then
pathfinding.make_route_async(agent, tsf:get_pos(), target)
started = true
end
end end
else else
local new_route = pathfinding.pull_route(agent) local new_route = pathfinding.pull_route(agent)

View File

@ -49,7 +49,7 @@ static int l_make_route(lua::State* L) {
auto start = lua::tovec3(L, 2); auto start = lua::tovec3(L, 2);
auto target = lua::tovec3(L, 3); auto target = lua::tovec3(L, 3);
agent->state = {}; agent->state = {};
agent->start = start; agent->start = glm::floor(start);
agent->target = target; agent->target = target;
auto route = level->pathfinding->perform(*agent); auto route = level->pathfinding->perform(*agent);
if (!route.found) { if (!route.found) {
@ -65,7 +65,7 @@ static int l_make_route_async(lua::State* L) {
auto start = lua::tovec3(L, 2); auto start = lua::tovec3(L, 2);
auto target = lua::tovec3(L, 3); auto target = lua::tovec3(L, 3);
agent->state = {}; agent->state = {};
agent->start = start; agent->start = glm::floor(start);
agent->target = target; agent->target = target;
level->pathfinding->perform(*agent, 0); level->pathfinding->perform(*agent, 0);
} }
@ -78,7 +78,7 @@ static int l_pull_route(lua::State* L) {
if (!agent->state.finished) { if (!agent->state.finished) {
return 0; return 0;
} }
if (!route.found) { if (!route.found && !agent->mayBeIncomplete) {
return lua::createtable(L, 0, 0); return lua::createtable(L, 0, 0);
} }
return push_route(L, route); return push_route(L, route);

View File

@ -87,7 +87,7 @@ struct GraphicsSettings {
struct PathfindingSettings { struct PathfindingSettings {
/// @brief Max visited blocks by an agent per async tick /// @brief Max visited blocks by an agent per async tick
IntegerSetting stepsPerAsyncAgent {256, 1, 2048}; IntegerSetting stepsPerAsyncAgent {128, 1, 2048};
}; };
struct DebugSettings { struct DebugSettings {

View File

@ -200,7 +200,7 @@ Route Pathfinding::perform(Agent& agent, int maxVisited) {
} }
state.finished = true; state.finished = true;
agent.state = std::move(state); agent.state = std::move(state);
return {}; return finish_route(agent, std::move(agent.state));
} }
Agent* Pathfinding::getAgent(int id) { Agent* Pathfinding::getAgent(int id) {