From 88641e032adf0836152daff10cc84cb7854b33e4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 1 Sep 2025 01:39:31 +0300 Subject: [PATCH] test mobs --- res/scripts/components/mob.lua | 181 +++++++++++------- res/scripts/components/pathfinding.lua | 30 ++- .../scripting/lua/libs/libpathfinding.cpp | 6 +- src/settings.hpp | 2 +- src/voxels/Pathfinding.cpp | 2 +- 5 files changed, 142 insertions(+), 79 deletions(-) diff --git a/res/scripts/components/mob.lua b/res/scripts/components/mob.lua index 840aba42..b423e30c 100644 --- a/res/scripts/components/mob.lua +++ b/res/scripts/components/mob.lua @@ -1,4 +1,5 @@ local body = entity.rigidbody +local tsf = entity.transform local props = {} @@ -56,79 +57,119 @@ function move_horizontal(speed, dir, vel) body:set_vel(vel) 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) local delta = (1.0 / tps) local pid = entity:get_player() - if pid and hud and not hud.is_inventory_open() and not menu.page ~= "" then - -- 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 + if pid ~= -1 then + process_player_inputs(pid, delta) + else + local pathfinding = entity:get_component("core:pathfinding") + if pathfinding then + follow_waypoints(pathfinding, delta) 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 diff --git a/res/scripts/components/pathfinding.lua b/res/scripts/components/pathfinding.lua index d5d68cd4..39ec5af7 100644 --- a/res/scripts/components/pathfinding.lua +++ b/res/scripts/components/pathfinding.lua @@ -3,9 +3,10 @@ local route local started local tsf = entity.transform +local body = entity.rigidbody agent = pathfinding.create_agent() -pathfinding.set_max_visited(agent, 1e4) +pathfinding.set_max_visited(agent, 1e3) pathfinding.avoid_tag(agent, "core:liquid", 8) function set_target(new_target) @@ -24,11 +25,32 @@ function get_route() return route 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() if not started then - if target then - pathfinding.make_route_async(agent, tsf:get_pos(), target) - started = true + if body:is_grounded() then + frameid = frameid + 1 + if target and frameid % 100 == 1 then + pathfinding.make_route_async(agent, tsf:get_pos(), target) + started = true + end end else local new_route = pathfinding.pull_route(agent) diff --git a/src/logic/scripting/lua/libs/libpathfinding.cpp b/src/logic/scripting/lua/libs/libpathfinding.cpp index 0381f6f8..e5a94abe 100644 --- a/src/logic/scripting/lua/libs/libpathfinding.cpp +++ b/src/logic/scripting/lua/libs/libpathfinding.cpp @@ -49,7 +49,7 @@ static int l_make_route(lua::State* L) { auto start = lua::tovec3(L, 2); auto target = lua::tovec3(L, 3); agent->state = {}; - agent->start = start; + agent->start = glm::floor(start); agent->target = target; auto route = level->pathfinding->perform(*agent); if (!route.found) { @@ -65,7 +65,7 @@ static int l_make_route_async(lua::State* L) { auto start = lua::tovec3(L, 2); auto target = lua::tovec3(L, 3); agent->state = {}; - agent->start = start; + agent->start = glm::floor(start); agent->target = target; level->pathfinding->perform(*agent, 0); } @@ -78,7 +78,7 @@ static int l_pull_route(lua::State* L) { if (!agent->state.finished) { return 0; } - if (!route.found) { + if (!route.found && !agent->mayBeIncomplete) { return lua::createtable(L, 0, 0); } return push_route(L, route); diff --git a/src/settings.hpp b/src/settings.hpp index 966e9758..52827d1c 100644 --- a/src/settings.hpp +++ b/src/settings.hpp @@ -87,7 +87,7 @@ struct GraphicsSettings { struct PathfindingSettings { /// @brief Max visited blocks by an agent per async tick - IntegerSetting stepsPerAsyncAgent {256, 1, 2048}; + IntegerSetting stepsPerAsyncAgent {128, 1, 2048}; }; struct DebugSettings { diff --git a/src/voxels/Pathfinding.cpp b/src/voxels/Pathfinding.cpp index a7a43e0b..999711f0 100644 --- a/src/voxels/Pathfinding.cpp +++ b/src/voxels/Pathfinding.cpp @@ -200,7 +200,7 @@ Route Pathfinding::perform(Agent& agent, int maxVisited) { } state.finished = true; agent.state = std::move(state); - return {}; + return finish_route(agent, std::move(agent.state)); } Agent* Pathfinding::getAgent(int id) {