## SPDX-License-Identifier: GPL-3.0-or-later ## Copyright (c) 2024 interstellardevelopment.org class_name Player extends CharacterBody3D const SPEED: float = 5.0 const JUMP_VELOCITY: float = 4.5 var activated: bool = false var freecam: bool = false var incapacitated: bool = false var interaction: String var revival_target: Player var carrying_gun: bool = false @onready var camera: Camera3D = $Camera3D var camera_rotation: Vector2 = Vector2(0,0) func _ready() -> void: if ($Area3D as Area3D).body_entered.connect(_on_body_entered): pass ($Label3D as Label3D).text = name if name == Game.username: activated = true camera.current = true Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) ($Label3D as Label3D).hide() func _on_body_entered(body: Node3D) -> void: if body is Player and incapacitated: (body as Player).revive_chance(self) func _physics_process(delta: float) -> void: if activated: if !freecam: if not is_on_floor(): velocity += get_gravity() * delta if !incapacitated: if !freecam: if Input.is_action_just_pressed("jump") and is_on_floor(): velocity.y = JUMP_VELOCITY if freecam: if Input.is_action_pressed("jump"): velocity.y = JUMP_VELOCITY elif Input.is_action_pressed("descend"): velocity.y = -JUMP_VELOCITY else: velocity.y = 0 if Input.is_action_just_pressed("freecam"): freecam = !freecam ($CollisionShape3D as CollisionShape3D).disabled = !($CollisionShape3D as CollisionShape3D).disabled if Input.is_action_just_pressed("interact") and interaction != null: if interaction == "revive" and revival_target != null: Networking.revive_sync_call(revival_target) ($InteractDialog as Label).text = "" revival_target = null if interaction == "gun": var guncase: Guncase = get_node("/root/%s/Guncase" % Game.mapname) if !guncase.held: carrying_gun = true ($InteractDialog as Label).text = "" Networking.guncase_sync_call(true, self) else: carrying_gun = false ($InteractDialog as Label).text = "" Networking.guncase_sync_call(false, self) if Input.is_action_just_pressed("shoot") and carrying_gun: Networking.bullet_sync_call(position + (transform.basis * Vector3(0, 0, -1)).normalized(), rotation) var input_dir: Vector2 = Input.get_vector("move_left", "move_right", "move_forwards", "move_backwards") var direction: Vector3 = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() #TODO: Hacky solution -> Also can be exploited to revive everyone in the game constantly. if revival_target != null and position.distance_to(revival_target.position) > 3: ($InteractDialog as Label).text = "" interaction = "" revival_target = null if interaction == "gun": if position.distance_to((get_node("/root/%s/Guncase" % Game.mapname) as Guncase).position) > 3: ($InteractDialog as Label).text = "" interaction = "" if direction: velocity.x = direction.x * SPEED velocity.z = direction.z * SPEED else: velocity.x = move_toward(velocity.x, 0, SPEED) velocity.z = move_toward(velocity.z, 0, SPEED) if move_and_slide(): pass var fps_counter: Label = $Label fps_counter.text = str(Engine.get_frames_per_second()) + " FPS" Networking.player_sync_call(position, rotation) func _input(event: InputEvent) -> void: if event is InputEventMouseMotion and activated: var mouse_event: InputEventMouseMotion = event camera_rotation = mouse_event.relative * 0.01 * 0.5 if camera.rotation.x <= 1.6 && camera_rotation.y <= 0: camera.rotate(Vector3.RIGHT, -camera_rotation.y) elif camera.rotation.x >= -1.6 && camera_rotation.y >= 0: camera.rotate(Vector3.RIGHT, -camera_rotation.y) if camera.rotation.x >= 1.6: camera.rotation.x = 1.6 elif camera.rotation.x <= -1.6: camera.rotation.x = -1.6 rotate(Vector3.DOWN, camera_rotation.x) func incapacitate() -> void: rotation.x = deg_to_rad(90) incapacitated = true if carrying_gun: carrying_gun = false Networking.guncase_sync_call(false, self) func revive_chance(body: Player) -> void: if activated: revival_target = body interaction = "revive" ($InteractDialog as Label).text = "Press E to revive %s." % revival_target.name func revive() -> void: rotation.x = 0 incapacitated = false func gun_chance() -> void: if activated: interaction = "gun" if carrying_gun: ($InteractDialog as Label).text = "Press E to set down gun." else: ($InteractDialog as Label).text = "Press E to pick up gun." func show_gun() -> void: ($Gun as MeshInstance3D).show() func hide_gun() -> void: ($Gun as MeshInstance3D).hide()