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