# This file is part of open-fpsz. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . class_name PlayerInputController extends Node @export var jetting:bool = false @export var skiing:bool = false @export var direction:Vector2 @export var camera_rotation:Vector3 signal jump signal primary(pressed: bool) signal throw(pressed: bool) var _mouse_sensitivity:float = .0 func _enter_tree() -> void: # @NOTE: This is a workaround for player node being too integrated with the # multiplayer layer and blocks player inputs in singleplayer if not set. set_multiplayer_authority(1) func _unhandled_input(event: InputEvent) -> void: if is_multiplayer_authority() and owner.is_alive(): var mouse_mode: Input.MouseMode = Input.get_mouse_mode() direction = Input.get_vector("left", "right", "forward", "backward") jetting = Input.is_action_pressed("secondary") skiing = Input.is_action_pressed("ski") # isolate mouse events if event is InputEventMouseMotion: if mouse_mode == Input.MOUSE_MODE_CAPTURED: # update camera with mouse position relative to last frame _update_camera(event.relative) elif event is InputEventMouseButton: # @NOTE: there could be a control setting for direction if event.button_index == MOUSE_BUTTON_WHEEL_UP and event.pressed: _cycle.rpc(1) elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN and event.pressed: _cycle.rpc(-1) elif event is InputEventKey: match event.keycode: KEY_1: _select.rpc(0) KEY_2: _select.rpc(1) KEY_3: _select.rpc(2) if event.is_action("primary"): _primary.rpc(event.pressed) if Input.is_action_just_pressed("secondary"): _jump.rpc() if event.is_action("throw") and not event.echo: _throw.rpc(event.pressed) func _update_camera(relative_motion:Vector2) -> void: # reverse y axis if Settings.get_value("controls", "inverted_y_axis"): relative_motion.y *= -1.0 _mouse_sensitivity = Settings.get_value("controls", "mouse_sensitivity") # clamp vertical rotation (head motion) camera_rotation.x -= relative_motion.y * _mouse_sensitivity / 100 camera_rotation.x = clamp(camera_rotation.x, deg_to_rad(-90.0), deg_to_rad(90.0)) # wrap horizontal rotation (to prevent accumulation) camera_rotation.y -= relative_motion.x * _mouse_sensitivity / 100 camera_rotation.y = wrapf(camera_rotation.y, deg_to_rad(0.0), deg_to_rad(360.0)) @rpc("authority", "call_local", "reliable") func _jump() -> void: jump.emit() @rpc("authority", "call_local", "reliable") func _primary(pressed: bool) -> void: primary.emit(pressed) @rpc("authority", "call_local", "reliable") func _cycle(shift:int) -> void: %Inventory.cycle(shift) @rpc("authority", "call_local", "reliable") func _select(index:int) -> void: %Inventory.select(index) @rpc("authority", "call_local", "reliable") func _throw(pressed: bool) -> void: throw.emit(pressed)