100 lines
2.7 KiB
GDScript
100 lines
2.7 KiB
GDScript
extends CanvasLayer
|
|
|
|
@export var side_change_speed: float = 15
|
|
@export var screen_inset: float = 100
|
|
|
|
var _cursor_scene := preload("res://scenes/ui/cursor_base.tscn")
|
|
|
|
var _cursors: Dictionary
|
|
|
|
@onready var _single_cursor: Control = $CursorBase
|
|
|
|
|
|
func _ready() -> void:
|
|
Input.mouse_mode = Input.MOUSE_MODE_HIDDEN
|
|
|
|
|
|
func _process(delta: float) -> void:
|
|
if not Referencer.players or not Referencer.main_camera:
|
|
var mouse_pos := get_viewport().get_mouse_position()
|
|
_single_cursor.position = mouse_pos - _single_cursor.size / 2
|
|
_single_cursor.visible = true
|
|
return
|
|
_single_cursor.visible = false
|
|
|
|
call_deferred("_handle_cursors", delta)
|
|
|
|
|
|
func _handle_cursors(delta: float) -> void:
|
|
for player_index in range(Referencer.players_count):
|
|
_handle_cursor(player_index, delta)
|
|
|
|
|
|
func _init_player_cursor(id: int) -> void:
|
|
var cursor_node: Control = _cursor_scene.instantiate() as Control
|
|
add_child(cursor_node)
|
|
_cursors[id] = PlayerCursor.new(
|
|
cursor_node,
|
|
cursor_node.get_node("CursorBat") as Control,
|
|
cursor_node.get_node("CursorArrow") as Control
|
|
)
|
|
|
|
|
|
func _handle_cursor(player_index: int, delta: float) -> void:
|
|
var player := Referencer.players[player_index]
|
|
var id := player.get_instance_id()
|
|
|
|
if not _cursors.has(id):
|
|
_init_player_cursor(id)
|
|
return
|
|
|
|
var cursor_pos_world := player.attack.global_position + player.aiming.aim_offset
|
|
var cursor_pos_screen := Referencer.main_camera.unproject_position(cursor_pos_world)
|
|
|
|
var clamp_corner_min := Vector2.ZERO
|
|
var clamp_corner_max := get_viewport().get_visible_rect().size
|
|
if player.input_mode_is(Inputer.Mode.CONTROLLER):
|
|
clamp_corner_min += Vector2(screen_inset, screen_inset)
|
|
clamp_corner_max -= Vector2(screen_inset, screen_inset)
|
|
|
|
var cursor: PlayerCursor = _cursors[id]
|
|
|
|
cursor.base.position = (
|
|
cursor_pos_screen.clamp(clamp_corner_min, clamp_corner_max)
|
|
- cursor.base.size / 2
|
|
)
|
|
|
|
cursor.side = lerpf(
|
|
cursor.side as float,
|
|
(PI / 2.0) * (1.0 if player.attack.side == PlayerAttack.Side.LEFT else -1.0),
|
|
side_change_speed * delta
|
|
)
|
|
|
|
var aim_offset_normalized := player.aiming.aim_offset.normalized()
|
|
var bat_rotation_point_screen := Referencer.main_camera.unproject_position(
|
|
(
|
|
cursor_pos_world
|
|
+ aim_offset_normalized.rotated(Vector3.UP, cursor.side as float)
|
|
)
|
|
)
|
|
var arrow_rotation_point_screen := Referencer.main_camera.unproject_position(
|
|
cursor_pos_world + aim_offset_normalized
|
|
)
|
|
|
|
cursor.bat.rotation = cursor_pos_screen.angle_to_point(bat_rotation_point_screen)
|
|
cursor.arrow.rotation = cursor_pos_screen.angle_to_point(
|
|
arrow_rotation_point_screen
|
|
)
|
|
|
|
|
|
class PlayerCursor:
|
|
var base: Control
|
|
var bat: Control
|
|
var arrow: Control
|
|
var side: float = 0
|
|
|
|
func _init(_base: Control, _bat: Control, _arrow: Control) -> void:
|
|
base = _base
|
|
bat = _bat
|
|
arrow = _arrow
|