122 lines
3.3 KiB
GDScript
122 lines
3.3 KiB
GDScript
extends KinematicBody2D
|
|
|
|
const BASE_SPEED := 300.0
|
|
const EPSILON := 0.1
|
|
const MAX_STAMINA := 3.0
|
|
const BOOST_COEFF := 50.0
|
|
const STAMINA_RECOVER_RATE := 0.3
|
|
const NET_KEY_TRANSFORM_DELAY := 0.2
|
|
|
|
var velocity := Vector2.ZERO
|
|
var grip := 1.0
|
|
var stamina := MAX_STAMINA
|
|
var speed_boost := 0
|
|
var transform_update_remaining := 0.0
|
|
|
|
puppet var pup_motion := Vector2.ZERO
|
|
puppet var pup_velocity := Vector2.ZERO
|
|
puppet var pup_transform := Transform()
|
|
|
|
onready var scene := $"/root/scene"
|
|
onready var world := $"/root/scene/world"
|
|
onready var camera := $Camera
|
|
onready var netgame := $"/root/Multiplayer"
|
|
|
|
export var is_controlled := false setget set_is_controlled
|
|
|
|
var object_name setget ,get_name
|
|
|
|
func _ready():
|
|
$Camera.current = is_controlled
|
|
|
|
func _physics_process(delta):
|
|
var motion := Vector2.ZERO
|
|
if is_network_master():
|
|
if not scene.writing:
|
|
motion = Vector2(
|
|
Input.get_action_strength("ui_right")-Input.get_action_strength("ui_left"),
|
|
Input.get_action_strength("ui_down")-Input.get_action_strength("ui_up"))
|
|
|
|
# Check sprinting
|
|
var speed := BASE_SPEED
|
|
if Input.is_action_pressed("sprint") and not scene.writing:
|
|
if motion.length() > EPSILON and stamina > 0:
|
|
speed_boost += BOOST_COEFF * delta * ease(stamina/MAX_STAMINA, 1.1)
|
|
stamina -= delta
|
|
update()
|
|
else:
|
|
if stamina < MAX_STAMINA:
|
|
stamina += delta * STAMINA_RECOVER_RATE
|
|
update()
|
|
|
|
# Apply friction to speed boost and the boost itself, if any
|
|
if speed_boost > 0:
|
|
speed_boost /= 2
|
|
speed *= 1.0 + speed_boost
|
|
if speed_boost < EPSILON:
|
|
speed_boost = 0
|
|
|
|
# Set velocity
|
|
velocity = velocity * (1.0-grip) + motion.clamped(1.0) * speed * grip
|
|
rset("pup_motion", motion)
|
|
rset("pup_velocity", velocity)
|
|
rset("pup_transform", global_transform)
|
|
else:
|
|
velocity = pup_velocity
|
|
motion = pup_motion
|
|
if transform_update_remaining <= 0.0:
|
|
transform_update_remaining = NET_KEY_TRANSFORM_DELAY
|
|
global_transform = pup_transform
|
|
else:
|
|
transform_update_remaining -= delta
|
|
|
|
if motion.length() > EPSILON:
|
|
$Sprite/AnimationTree.set("parameters/direction/blend_position", motion)
|
|
|
|
velocity = move_and_slide(velocity)
|
|
|
|
# Check what tile I'm on
|
|
if world.map != null:
|
|
grip = 0.0
|
|
for tilemap in world.map.tilemaps:
|
|
var cell = tilemap.get_cellv(tilemap.world_to_map(transform.origin))
|
|
if cell >= 0:
|
|
grip = 1.0
|
|
|
|
func set_is_controlled(val):
|
|
is_controlled = val
|
|
$Camera.current = val
|
|
|
|
func _draw():
|
|
if is_network_master():
|
|
if stamina+EPSILON < MAX_STAMINA:
|
|
draw_circle_arc_poly(Vector2(-10, -30), 6, 0, stamina/MAX_STAMINA * 360, Color.orange)
|
|
|
|
func draw_circle_arc_poly(center, radius, angle_from, angle_to, color):
|
|
var nb_points := 32
|
|
var points_arc := PoolVector2Array()
|
|
points_arc.push_back(center)
|
|
var colors := PoolColorArray([color])
|
|
|
|
for i in range(nb_points + 1):
|
|
var angle_point = deg2rad(angle_from + i * (angle_to - angle_from) / nb_points - 90)
|
|
points_arc.push_back(center + Vector2(cos(angle_point), sin(angle_point)) * radius)
|
|
draw_polygon(points_arc, colors)
|
|
|
|
func get_info():
|
|
return netgame.player_info[get_network_master()]
|
|
|
|
func get_name():
|
|
var id := get_network_master()
|
|
return netgame.player_info[id].name
|
|
|
|
func inspect():
|
|
if is_network_master():
|
|
return {
|
|
"type": "Crewmember",
|
|
"description": "That's you!"
|
|
}
|
|
return {
|
|
"type": "Crewmember",
|
|
"description": "A fellow crewmember"
|
|
}
|