red_dragon_pon/base/scripts/player/player.gd
2025-07-26 13:56:13 +03:00

169 lines
4.7 KiB
GDScript

extends CharacterBody3D
@export var speed = 100.0
@export var fall_acceleration = 75.0
@export var vertical_sensivity = 0.005
@export var horizontal_sensivity = 0.005
var queue: CommandQueue = CommandQueue.new()
@onready var camera: Camera3D = $"Camera"
@onready var weapon_player: AnimationPlayer = $"HUD/Weapon/AnimationPlayer"
@onready var weapons: WeaponContainer = $"WeaponContainer"
# Placeholder UI
@onready var ammo_label: Label = $"HUD/Ammo"
var current_weapon: Weapon
func _ready() -> void:
queue.command_pushed.connect(on_queue_command_pushed)
queue.command_popped.connect(on_queue_command_popped)
weapons.slot_selected.connect(on_weapon_slot_selected)
get_tree().create_timer(0.02).timeout.connect(on_weapon_slot_selected)
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
func _process(_delta: float) -> void:
if current_weapon == null:
return
var weapon_sides = current_weapon.uses_hands
var weapon_sides_are_free = not queue.sides_are_busy(weapon_sides)
if weapon_sides_are_free:
# Fire logic
var fire_action = Input.is_action_just_pressed('shoot') if \
current_weapon.fire_mode is SingleFireMode else \
Input.is_action_pressed('shoot')
if fire_action:
push_copied_command(CommandQueue.Command.FIRE, weapon_sides)
# Reload logic
var reload_action = Input.is_action_just_pressed('reload')
if reload_action:
if not queue.has_command(CommandQueue.Command.RELOAD):
push_copied_command(CommandQueue.Command.RELOAD, weapon_sides)
for side in CommandQueue.Side.values():
var command = queue.current_command(side)
match side:
CommandQueue.Side.LEFT:
handle_current_left_command(command)
CommandQueue.Side.RIGHT:
handle_current_right_command(command)
func _physics_process(delta: float) -> void:
var direction = Vector3.ZERO
direction.z = Input.get_axis("move_forward", "move_backward")
direction.x = Input.get_axis("move_left", "move_right")
var target_velocity = (transform.basis * direction).normalized() * speed * delta
if not is_on_floor():
target_velocity.y -= fall_acceleration * delta
velocity = target_velocity
move_and_slide()
func _input(event):
if event is InputEventMouseMotion:
var new_rotation = clamp(
camera.rotation.x - event.relative.y * vertical_sensivity,
-PI/2,
PI/2
)
camera.rotation.x = new_rotation
rotation.y -= event.relative.x * horizontal_sensivity
func on_weapon_slot_selected():
if current_weapon != null:
current_weapon.fired.disconnect(on_weapon_fired)
current_weapon.fire_failed.disconnect(finish_task)
weapon_player.remove_animation_library("current")
current_weapon = weapons.current_weapon
print('im here')
current_weapon.fired.connect(on_weapon_fired)
current_weapon.fire_failed.connect(finish_task)
weapon_player.add_animation_library("current", current_weapon.animation_library)
weapon_player.play("current/static")
update_ammo_label()
func on_queue_command_pushed(commands: Dictionary):
for side in commands:
match side:
CommandQueue.Side.LEFT:
handle_new_left_command(commands[side])
CommandQueue.Side.RIGHT:
handle_new_right_command(commands[side])
func push_copied_command(command: CommandQueue.Command, sides: Array[CommandQueue.Side]):
var commands = {}
for side in sides:
commands[side] = command
queue.push(commands)
func finish_task():
queue.pop()
func reset_animation_and_finish_task():
weapon_player.play("current/static")
queue.pop()
func on_queue_command_popped(commands):
for i in CommandQueue.Side.size():
match CommandQueue.Side.values()[i]:
CommandQueue.Side.LEFT:
handle_ended_left_command(commands[i])
CommandQueue.Side.RIGHT:
handle_ended_right_command(commands[i])
func update_ammo_label():
ammo_label.text = "{ammo}/{max}".format({
ammo = current_weapon.ammo,
max = current_weapon.max_ammo
})
func on_weapon_fired():
weapon_player.play("current/fire")
update_ammo_label()
func on_weapon_reload():
weapon_player.play("current/reload")
func reset_animation():
weapon_player.play("current/static")
func handle_new_left_command(command: CommandQueue.Command):
match command:
pass
func handle_new_right_command(command: CommandQueue.Command):
match command:
CommandQueue.Command.RELOAD:
weapon_player.play('current/reload')
func handle_ended_left_command(command: CommandQueue.Command):
match command:
pass
func handle_ended_right_command(command: CommandQueue.Command):
match command:
CommandQueue.Command.FIRE:
current_weapon.end_fire()
CommandQueue.Command.RELOAD:
weapon_player.play('current/static')
current_weapon.reload()
update_ammo_label()
func handle_current_left_command(command: CommandQueue.Command):
match command:
pass
func handle_current_right_command(command: CommandQueue.Command):
match command:
CommandQueue.Command.FIRE:
current_weapon.request_fire()