red_dragon_pon/base/scripts/player/command_queue.gd
2025-07-27 12:32:18 +03:00

90 lines
2.5 KiB
GDScript

extends RefCounted
## Queue that represents player's hand interactions with game mechanics
class_name CommandQueue
## Commands that can be pushed to queue
enum Command {
NONE,
FIRE,
STOP_FIRING,
RELOAD,
DRAW_WEAPON,
HOLSTER_WEAPON,
TAKE_ZAZA,
LIGHT_ZAZA,
SMOKE
}
signal command_pushed(commands: Dictionary)
signal command_popped(commands: Array[CommandQueue.Command])
signal command_started(command: Array[CommandQueue.Command])
## Human-readable hand numbers. You could even make extra hands with it, if you wish
enum Side { LEFT, RIGHT }
## Used anywhere you could get null
const DEFAULT_COMMAND = CommandQueue.Command.NONE
## Dictionary filled with queues for each side
var command_queue: Dictionary = {}
func _init() -> void:
for side in Side.values():
var arr: Array[Command] = []
command_queue[side] = arr
## Add command to queue and signal about it
func push(pushed_commands: Dictionary) -> void:
var commands = pushed_commands
if commands.size() < Side.size():
for side in Side.values():
if not commands.has(side):
commands[side] = DEFAULT_COMMAND
for side in commands:
command_queue[side].push_back(commands[side])
command_pushed.emit(commands)
if command_queue[Side.LEFT].size() == 1:
start_command()
## Remove first command from queue and signal about it
func pop() -> void:
# Checking if stack is actually empty (arrays must have same size)
if command_queue[Side.LEFT].size() == 0:
return
var commands = []
for side in Side.values():
commands.push_back(command_queue[side].pop_front())
command_popped.emit(commands)
# Start new command
if command_queue[Side.LEFT].size() > 0:
start_command()
## Get current commands and emit command_started
func start_command() -> void:
var commands = []
for side in Side.values():
commands.push_back(current_command(side))
command_started.emit(commands)
## Returns currently executed command for given side
func current_command(side: CommandQueue.Side) -> CommandQueue.Command:
if command_queue[side].is_empty():
return DEFAULT_COMMAND
var command = command_queue[side].front()
return command
## Returns whether given sides are busy
func sides_are_busy(sides: Array[CommandQueue.Side]) -> bool:
for side in sides:
if current_command(side) == DEFAULT_COMMAND:
return false
return true
## Returns whether command exists in queue on any side
func has_command(command: CommandQueue.Command) -> bool:
for side in command_queue:
if command in command_queue[side]:
return true
return false