add core:player component
This commit is contained in:
parent
854dcf2a50
commit
93e7ae159a
@ -6,6 +6,7 @@
|
||||
"jump_force": 8.0
|
||||
}
|
||||
},
|
||||
"core:player",
|
||||
"base:player_animator"
|
||||
],
|
||||
"hitbox": [0.6, 1.8, 0.6]
|
||||
|
||||
@ -18,7 +18,7 @@ function on_render()
|
||||
if pid == -1 then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local rx, ry, rz = player.get_rot(pid, pid ~= hud.get_player())
|
||||
rig:set_matrix(headIndex, mat4.rotate({1, 0, 0}, ry))
|
||||
rig:set_matrix(bodyIndex, mat4.rotate({0, 1, 0}, rx))
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
local body = entity.rigidbody
|
||||
local tsf = entity.transform
|
||||
local rig = entity.skeleton
|
||||
|
||||
local props = {}
|
||||
|
||||
@ -23,9 +24,12 @@ def_prop("movement_speed", 3.0)
|
||||
def_prop("run_speed_mul", 1.5)
|
||||
def_prop("crouch_speed_mul", 0.35)
|
||||
def_prop("flight_speed_mul", 4.0)
|
||||
def_prop("cheat_speed_mul", 5.0)
|
||||
def_prop("gravity_scale", 1.0)
|
||||
|
||||
direction = {0, 0, -1}
|
||||
|
||||
local flight = false
|
||||
|
||||
function jump(multiplier)
|
||||
if body:is_grounded() then
|
||||
local vel = body:get_vel()
|
||||
@ -37,13 +41,13 @@ end
|
||||
function elevate(speed, delta, vel)
|
||||
vel = vel or body:get_vel()
|
||||
body:set_vel(
|
||||
vec3.add(vel, {0, speed * delta, 0}, vel))
|
||||
vec3.add(vel, {0, speed * delta * props.movement_speed, 0}, vel))
|
||||
end
|
||||
|
||||
function lower(speed, delta, vel)
|
||||
vel = vel or body:get_vel()
|
||||
body:set_vel(
|
||||
vec3.add(vel, {0, -speed * delta, 0}, vel))
|
||||
vec3.add(vel, {0, -speed * delta * props.movement_speed, 0}, vel))
|
||||
end
|
||||
|
||||
function move_horizontal(speed, dir, vel)
|
||||
@ -57,119 +61,90 @@ 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
|
||||
|
||||
function go(dir, speed_multiplier, sprint, crouch, vel)
|
||||
local speed = props.movement_speed * speed_multiplier
|
||||
if flight then
|
||||
speed = speed * props.flight_speed_mul
|
||||
elseif issprint then
|
||||
end
|
||||
if sprint then
|
||||
speed = speed * props.run_speed_mul
|
||||
elseif iscrouch and grounded then
|
||||
elseif crouch 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")
|
||||
move_horizontal(speed, dir, vel)
|
||||
end
|
||||
|
||||
local prev_angle = 0.0
|
||||
local headIndex = rig:index("head")
|
||||
|
||||
|
||||
-- todo: move somewhere
|
||||
local watchtimer = math.random(0, 1000)
|
||||
local function update_head()
|
||||
watchtimer = watchtimer + 1
|
||||
|
||||
local pos = tsf:get_pos()
|
||||
local viewdir = vec3.normalize(vec3.sub({player.get_pos(hud.get_player())}, pos))
|
||||
local isfront = vec3.dot(viewdir, direction) > 0.0
|
||||
|
||||
local headrot = mat4.idt()
|
||||
local curdir = mat4.mul(mat4.mul(tsf:get_rot(), rig:get_matrix(headIndex)), {0, 0, -1})
|
||||
|
||||
if not isfront or not (watchtimer % 300 < 100) then
|
||||
viewdir = mat4.mul(tsf:get_rot(), {0, 0, -1})
|
||||
end
|
||||
|
||||
vec3.mix(curdir, viewdir, 0.2, viewdir)
|
||||
|
||||
headrot = mat4.inverse(mat4.look_at({0,0,0}, viewdir, {0, 1, 0}))
|
||||
headrot = mat4.mul(mat4.inverse(tsf:get_rot()), headrot)
|
||||
rig:set_matrix(headIndex, headrot)
|
||||
end
|
||||
|
||||
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)}))
|
||||
pathfinding.set_target(vec3.add(pos,
|
||||
{math.random(-15, 15), math.random(-2, 2), 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(
|
||||
direction = 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)
|
||||
local upper = direction[2] > 0
|
||||
direction[2] = 0.0
|
||||
local t = delta * 6.0
|
||||
local angle = (vec2.angle({direction[3], direction[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
|
||||
vec3.normalize(direction, direction)
|
||||
move_horizontal(speed, direction, vel)
|
||||
if upper and body:is_grounded() then
|
||||
jump(1.0)
|
||||
end
|
||||
end
|
||||
|
||||
function is_flight() return flight end
|
||||
|
||||
function set_flight(flag) flight = flag end
|
||||
|
||||
function on_physics_update(tps)
|
||||
local delta = (1.0 / tps)
|
||||
local pid = entity:get_player()
|
||||
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
|
||||
|
||||
update_head()
|
||||
local pathfinding = entity:get_component("core:pathfinding")
|
||||
if pathfinding then
|
||||
follow_waypoints(pathfinding, delta)
|
||||
end
|
||||
|
||||
local grounded = body:is_grounded()
|
||||
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
|
||||
)
|
||||
end
|
||||
|
||||
@ -41,13 +41,18 @@ function next_waypoint()
|
||||
return route[#route]
|
||||
end
|
||||
|
||||
local frameid = 0
|
||||
local refresh_internal = 100
|
||||
local frameid = math.random(0, refresh_internal)
|
||||
|
||||
function set_refresh_interval(interval)
|
||||
refresh_internal = interval
|
||||
end
|
||||
|
||||
function on_update()
|
||||
if not started then
|
||||
if body:is_grounded() then
|
||||
frameid = frameid + 1
|
||||
if target and frameid % 100 == 1 then
|
||||
if target and (frameid % refresh_internal == 1 or not route) then
|
||||
pathfinding.make_route_async(agent, tsf:get_pos(), target)
|
||||
started = true
|
||||
end
|
||||
|
||||
59
res/scripts/components/player.lua
Normal file
59
res/scripts/components/player.lua
Normal file
@ -0,0 +1,59 @@
|
||||
local body = entity.rigidbody
|
||||
local mob = entity:require_component("core:mob")
|
||||
|
||||
local cheat_speed_mul = 5.0
|
||||
|
||||
local function process_player_inputs(pid, delta)
|
||||
if not hud or hud.is_inventory_open() or menu.page ~= "" then
|
||||
return
|
||||
end
|
||||
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 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')
|
||||
mob.set_flight(player.is_flight(pid))
|
||||
body:set_body_type(player.is_noclip(pid) and "kinematic" or "dynamic")
|
||||
body:set_crouching(iscrouch)
|
||||
|
||||
local vel = body:get_vel()
|
||||
local speed = ischeat and cheat_speed_mul or 1.0
|
||||
|
||||
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
|
||||
mob.go(dir, speed, issprint, iscrouch, vel)
|
||||
end
|
||||
|
||||
if mob.is_flight() then
|
||||
if isjump then
|
||||
mob.elevate(speed * 24, delta)
|
||||
elseif iscrouch then
|
||||
mob.lower(speed * 24, delta)
|
||||
end
|
||||
elseif isjump then
|
||||
mob.jump()
|
||||
end
|
||||
end
|
||||
|
||||
function on_physics_update(tps)
|
||||
local delta = (1.0 / tps)
|
||||
local pid = entity:get_player()
|
||||
if pid ~= -1 then
|
||||
process_player_inputs(pid, delta)
|
||||
end
|
||||
end
|
||||
Loading…
x
Reference in New Issue
Block a user