Gun reload

This commit is contained in:
Alexey 2025-07-21 21:10:21 +03:00
commit 12cb74ba2c
6 changed files with 118 additions and 44 deletions

View file

@ -22,7 +22,7 @@ signal command_popped(commands: Array[CommandQueue.Command])
enum Side { LEFT, RIGHT }
## Used anywhere you could get null
const DEFAULT_COMMAND = Command.NONE
const DEFAULT_COMMAND = CommandQueue.Command.NONE
## Dictionary filled with queues for each side
var command_queue: Dictionary = {}

View file

@ -11,8 +11,8 @@ var queue: CommandQueue = CommandQueue.new()
@onready var weapon_player: AnimationPlayer = $"HUD/Weapon/AnimationPlayer"
@onready var weapons: Node3D = $"WeaponContainer"
const DEFAULT_SIDES: Array[CommandQueue.Side] = [CommandQueue.Side.LEFT, CommandQueue.Side.RIGHT]
const ONEHANDED_FIRE_COMMAND: Array[CommandQueue.Command] = [CommandQueue.Command.NONE, CommandQueue.Command.FIRE]
# Placeholder UI
@onready var ammo_label: Label = $"HUD/Ammo"
var current_weapon: Weapon
@ -22,30 +22,31 @@ func _ready() -> void:
current_weapon = weapons.get_child(0) as Weapon
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")
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
update_ammo_label()
func _process(_delta: float) -> void:
var can_queue_fire = true
var weapon_sides = current_weapon.uses_hands
for side in weapon_sides:
if queue.current_command(side) != CommandQueue.DEFAULT_COMMAND:
can_queue_fire = false
break
if can_queue_fire:
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:
var fire_commands = {}
for side in weapon_sides:
fire_commands[side] = CommandQueue.Command.FIRE
queue.push(fire_commands)
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:
@ -84,7 +85,18 @@ func on_queue_command_pushed(commands: Dictionary):
CommandQueue.Side.RIGHT:
handle_new_right_command(commands[side])
func fire_task_finish():
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):
@ -95,52 +107,49 @@ func on_queue_command_popped(commands):
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_fire_animation_end():
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:
CommandQueue.Command.NONE:
pass
_:
print('New command %s is not implemented for left hand.' % command)
pass
func handle_new_right_command(command: CommandQueue.Command):
match command:
CommandQueue.Command.NONE | CommandQueue.Command.FIRE:
pass
_:
print('New command %s is not implemented for right hand.' % command)
CommandQueue.Command.RELOAD:
weapon_player.play('current/reload')
func handle_ended_left_command(command: CommandQueue.Command):
match command:
CommandQueue.Command.NONE:
pass
_:
print('Ended command %s is not implemented for left hand.' % command)
pass
func handle_ended_right_command(command: CommandQueue.Command):
match command:
CommandQueue.Command.NONE | CommandQueue.Command.FIRE:
pass
_:
print('Ended command %s is not implemented for right hand.' % 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:
CommandQueue.Command.NONE:
pass
_:
print('Current command %s is not implemented for left hand.' % command)
pass
func handle_current_right_command(command: CommandQueue.Command):
match command:
CommandQueue.Command.NONE:
pass
CommandQueue.Command.FIRE:
current_weapon.request_fire()
_:
print('Current command %s is not implemented for right hand.' % command)

View file

@ -3,6 +3,7 @@ extends Node3D
class_name Weapon
signal fired()
signal fire_failed()
@onready var barrel = $"Barrel"
@export var uses_hands: Array[CommandQueue.Side]
@ -25,7 +26,10 @@ func _ready() -> void:
## Begin to fire
func request_fire() -> void:
fire_mode._on_fire_begin()
if not is_firing and ammo >= ammo_consumption:
fire_mode._on_fire_begin()
elif ammo < ammo_consumption:
fire_failed.emit()
func _process(_dt) -> void:
if is_firing:
@ -39,4 +43,8 @@ func end_fire() -> void:
func on_barrel_fired() -> void:
is_firing = true
ammo -= ammo_consumption
fired.emit()
func reload() -> void:
ammo = max_ammo