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 export var is_controlled = false setget set_is_controlled 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 hear(_event): pass