Gun reload
This commit is contained in:
parent
a3dfc050f1
commit
12cb74ba2c
6 changed files with 118 additions and 44 deletions
|
@ -1,9 +1,16 @@
|
||||||
[gd_resource type="AnimationLibrary" load_steps=8 format=3 uid="uid://cw8bt4hqxpk55"]
|
[gd_resource type="AnimationLibrary" load_steps=16 format=3 uid="uid://cw8bt4hqxpk55"]
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://cf7avgppv4kfk" path="res://base/assets/sprites/guns/placeholder/static.png" id="1_yheqn"]
|
[ext_resource type="Texture2D" uid="uid://cf7avgppv4kfk" path="res://base/assets/sprites/guns/placeholder/static.png" id="1_yheqn"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://ij02cx0xdckw" path="res://base/assets/sprites/guns/placeholder/reload1.png" id="5_ve5jf"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://baptu307a0dw5" path="res://base/assets/sprites/guns/placeholder/reload2.png" id="6_cr4tl"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://pb6jybpwasxj" path="res://base/assets/sprites/guns/placeholder/reload3.png" id="7_ripfx"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://v2m8ikar64o5" path="res://base/assets/sprites/guns/placeholder/reload4.png" id="8_y82fu"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cfw6p5g680c55" path="res://base/assets/sprites/guns/placeholder/shoot1.png" id="9_6fi3a"]
|
[ext_resource type="Texture2D" uid="uid://cfw6p5g680c55" path="res://base/assets/sprites/guns/placeholder/shoot1.png" id="9_6fi3a"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://b40b8l3yctlax" path="res://base/assets/sprites/guns/placeholder/reload5.png" id="9_7aydm"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bwfkjfpk4dwx0" path="res://base/assets/sprites/guns/placeholder/shoot2.png" id="10_mjqfp"]
|
[ext_resource type="Texture2D" uid="uid://bwfkjfpk4dwx0" path="res://base/assets/sprites/guns/placeholder/shoot2.png" id="10_mjqfp"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://b55h6w4km2c3u" path="res://base/assets/sprites/guns/placeholder/reload6.png" id="10_x8exi"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bp1frp3sm8bic" path="res://base/assets/sprites/guns/placeholder/shoot3.png" id="11_0d256"]
|
[ext_resource type="Texture2D" uid="uid://bp1frp3sm8bic" path="res://base/assets/sprites/guns/placeholder/shoot3.png" id="11_0d256"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://b4fp0oo8qcino" path="res://base/assets/sprites/guns/placeholder/reload7.png" id="11_bkso5"]
|
||||||
|
|
||||||
[sub_resource type="Animation" id="Animation_i1xqq"]
|
[sub_resource type="Animation" id="Animation_i1xqq"]
|
||||||
length = 0.001
|
length = 0.001
|
||||||
|
@ -47,10 +54,41 @@ tracks/1/keys = {
|
||||||
"transitions": PackedFloat32Array(1, 1),
|
"transitions": PackedFloat32Array(1, 1),
|
||||||
"values": [{
|
"values": [{
|
||||||
"args": [],
|
"args": [],
|
||||||
"method": &"fire_task_finish"
|
"method": &"finish_task"
|
||||||
}, {
|
}, {
|
||||||
"args": [],
|
"args": [],
|
||||||
"method": &"on_fire_animation_end"
|
"method": &"reset_animation"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_08xoc"]
|
||||||
|
resource_name = "reload"
|
||||||
|
length = 1.10001
|
||||||
|
step = 0.1
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath(".:texture")
|
||||||
|
tracks/0/interp = 1
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0, 0.1, 0.3, 0.4, 0.7, 0.8, 1),
|
||||||
|
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1),
|
||||||
|
"update": 1,
|
||||||
|
"values": [ExtResource("5_ve5jf"), ExtResource("6_cr4tl"), ExtResource("7_ripfx"), ExtResource("8_y82fu"), ExtResource("9_7aydm"), ExtResource("10_x8exi"), ExtResource("11_bkso5")]
|
||||||
|
}
|
||||||
|
tracks/1/type = "method"
|
||||||
|
tracks/1/imported = false
|
||||||
|
tracks/1/enabled = true
|
||||||
|
tracks/1/path = NodePath("../..")
|
||||||
|
tracks/1/interp = 1
|
||||||
|
tracks/1/loop_wrap = true
|
||||||
|
tracks/1/keys = {
|
||||||
|
"times": PackedFloat32Array(1.1),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"values": [{
|
||||||
|
"args": [],
|
||||||
|
"method": &"finish_task"
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,5 +113,6 @@ tracks/0/keys = {
|
||||||
_data = {
|
_data = {
|
||||||
&"RESET": SubResource("Animation_i1xqq"),
|
&"RESET": SubResource("Animation_i1xqq"),
|
||||||
&"fire": SubResource("Animation_8sdfx"),
|
&"fire": SubResource("Animation_8sdfx"),
|
||||||
|
&"reload": SubResource("Animation_08xoc"),
|
||||||
&"static": SubResource("Animation_ma1q3")
|
&"static": SubResource("Animation_ma1q3")
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,19 @@ stretch_mode = 6
|
||||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="HUD/Weapon"]
|
[node name="AnimationPlayer" type="AnimationPlayer" parent="HUD/Weapon"]
|
||||||
autoplay = "static"
|
autoplay = "static"
|
||||||
|
|
||||||
|
[node name="Ammo" type="Label" parent="HUD"]
|
||||||
|
anchors_preset = 3
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -54.0
|
||||||
|
offset_top = -23.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
grow_vertical = 0
|
||||||
|
theme_override_font_sizes/font_size = 32
|
||||||
|
text = "0/0"
|
||||||
|
|
||||||
[node name="WeaponContainer" type="Node3D" parent="."]
|
[node name="WeaponContainer" type="Node3D" parent="."]
|
||||||
|
|
||||||
[node name="Weapon" parent="WeaponContainer" instance=ExtResource("2_ma1q3")]
|
[node name="Weapon" parent="WeaponContainer" instance=ExtResource("2_ma1q3")]
|
||||||
|
|
|
@ -22,7 +22,7 @@ signal command_popped(commands: Array[CommandQueue.Command])
|
||||||
enum Side { LEFT, RIGHT }
|
enum Side { LEFT, RIGHT }
|
||||||
|
|
||||||
## Used anywhere you could get null
|
## Used anywhere you could get null
|
||||||
const DEFAULT_COMMAND = Command.NONE
|
const DEFAULT_COMMAND = CommandQueue.Command.NONE
|
||||||
|
|
||||||
## Dictionary filled with queues for each side
|
## Dictionary filled with queues for each side
|
||||||
var command_queue: Dictionary = {}
|
var command_queue: Dictionary = {}
|
||||||
|
|
|
@ -11,8 +11,8 @@ var queue: CommandQueue = CommandQueue.new()
|
||||||
@onready var weapon_player: AnimationPlayer = $"HUD/Weapon/AnimationPlayer"
|
@onready var weapon_player: AnimationPlayer = $"HUD/Weapon/AnimationPlayer"
|
||||||
@onready var weapons: Node3D = $"WeaponContainer"
|
@onready var weapons: Node3D = $"WeaponContainer"
|
||||||
|
|
||||||
const DEFAULT_SIDES: Array[CommandQueue.Side] = [CommandQueue.Side.LEFT, CommandQueue.Side.RIGHT]
|
# Placeholder UI
|
||||||
const ONEHANDED_FIRE_COMMAND: Array[CommandQueue.Command] = [CommandQueue.Command.NONE, CommandQueue.Command.FIRE]
|
@onready var ammo_label: Label = $"HUD/Ammo"
|
||||||
|
|
||||||
var current_weapon: Weapon
|
var current_weapon: Weapon
|
||||||
|
|
||||||
|
@ -22,30 +22,31 @@ func _ready() -> void:
|
||||||
|
|
||||||
current_weapon = weapons.get_child(0) as Weapon
|
current_weapon = weapons.get_child(0) as Weapon
|
||||||
current_weapon.fired.connect(on_weapon_fired)
|
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.add_animation_library("current", current_weapon.animation_library)
|
||||||
weapon_player.play("current/static")
|
weapon_player.play("current/static")
|
||||||
|
|
||||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||||
|
|
||||||
|
update_ammo_label()
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
func _process(_delta: float) -> void:
|
||||||
|
|
||||||
var can_queue_fire = true
|
|
||||||
var weapon_sides = current_weapon.uses_hands
|
var weapon_sides = current_weapon.uses_hands
|
||||||
for side in weapon_sides:
|
var weapon_sides_are_free = not queue.sides_are_busy(weapon_sides)
|
||||||
if queue.current_command(side) != CommandQueue.DEFAULT_COMMAND:
|
if weapon_sides_are_free:
|
||||||
can_queue_fire = false
|
# Fire logic
|
||||||
break
|
|
||||||
if can_queue_fire:
|
|
||||||
var fire_action = Input.is_action_just_pressed('shoot') if \
|
var fire_action = Input.is_action_just_pressed('shoot') if \
|
||||||
current_weapon.fire_mode is SingleFireMode else \
|
current_weapon.fire_mode is SingleFireMode else \
|
||||||
Input.is_action_pressed('shoot')
|
Input.is_action_pressed('shoot')
|
||||||
if fire_action:
|
if fire_action:
|
||||||
var fire_commands = {}
|
push_copied_command(CommandQueue.Command.FIRE, weapon_sides)
|
||||||
for side in weapon_sides:
|
# Reload logic
|
||||||
fire_commands[side] = CommandQueue.Command.FIRE
|
var reload_action = Input.is_action_just_pressed('reload')
|
||||||
queue.push(fire_commands)
|
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():
|
for side in CommandQueue.Side.values():
|
||||||
var command = queue.current_command(side)
|
var command = queue.current_command(side)
|
||||||
match side:
|
match side:
|
||||||
|
@ -84,7 +85,18 @@ func on_queue_command_pushed(commands: Dictionary):
|
||||||
CommandQueue.Side.RIGHT:
|
CommandQueue.Side.RIGHT:
|
||||||
handle_new_right_command(commands[side])
|
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()
|
queue.pop()
|
||||||
|
|
||||||
func on_queue_command_popped(commands):
|
func on_queue_command_popped(commands):
|
||||||
|
@ -95,52 +107,49 @@ func on_queue_command_popped(commands):
|
||||||
CommandQueue.Side.RIGHT:
|
CommandQueue.Side.RIGHT:
|
||||||
handle_ended_right_command(commands[i])
|
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():
|
func on_weapon_fired():
|
||||||
weapon_player.play("current/fire")
|
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")
|
weapon_player.play("current/static")
|
||||||
|
|
||||||
func handle_new_left_command(command: CommandQueue.Command):
|
func handle_new_left_command(command: CommandQueue.Command):
|
||||||
match command:
|
match command:
|
||||||
CommandQueue.Command.NONE:
|
pass
|
||||||
pass
|
|
||||||
_:
|
|
||||||
print('New command %s is not implemented for left hand.' % command)
|
|
||||||
|
|
||||||
func handle_new_right_command(command: CommandQueue.Command):
|
func handle_new_right_command(command: CommandQueue.Command):
|
||||||
match command:
|
match command:
|
||||||
CommandQueue.Command.NONE | CommandQueue.Command.FIRE:
|
CommandQueue.Command.RELOAD:
|
||||||
pass
|
weapon_player.play('current/reload')
|
||||||
_:
|
|
||||||
print('New command %s is not implemented for right hand.' % command)
|
|
||||||
|
|
||||||
func handle_ended_left_command(command: CommandQueue.Command):
|
func handle_ended_left_command(command: CommandQueue.Command):
|
||||||
match command:
|
match command:
|
||||||
CommandQueue.Command.NONE:
|
pass
|
||||||
pass
|
|
||||||
_:
|
|
||||||
print('Ended command %s is not implemented for left hand.' % command)
|
|
||||||
|
|
||||||
func handle_ended_right_command(command: CommandQueue.Command):
|
func handle_ended_right_command(command: CommandQueue.Command):
|
||||||
match command:
|
match command:
|
||||||
CommandQueue.Command.NONE | CommandQueue.Command.FIRE:
|
CommandQueue.Command.FIRE:
|
||||||
pass
|
current_weapon.end_fire()
|
||||||
_:
|
CommandQueue.Command.RELOAD:
|
||||||
print('Ended command %s is not implemented for right hand.' % command)
|
weapon_player.play('current/static')
|
||||||
|
current_weapon.reload()
|
||||||
|
update_ammo_label()
|
||||||
|
|
||||||
func handle_current_left_command(command: CommandQueue.Command):
|
func handle_current_left_command(command: CommandQueue.Command):
|
||||||
match command:
|
match command:
|
||||||
CommandQueue.Command.NONE:
|
pass
|
||||||
pass
|
|
||||||
_:
|
|
||||||
print('Current command %s is not implemented for left hand.' % command)
|
|
||||||
|
|
||||||
func handle_current_right_command(command: CommandQueue.Command):
|
func handle_current_right_command(command: CommandQueue.Command):
|
||||||
match command:
|
match command:
|
||||||
CommandQueue.Command.NONE:
|
|
||||||
pass
|
|
||||||
CommandQueue.Command.FIRE:
|
CommandQueue.Command.FIRE:
|
||||||
current_weapon.request_fire()
|
current_weapon.request_fire()
|
||||||
_:
|
|
||||||
print('Current command %s is not implemented for right hand.' % command)
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ extends Node3D
|
||||||
class_name Weapon
|
class_name Weapon
|
||||||
|
|
||||||
signal fired()
|
signal fired()
|
||||||
|
signal fire_failed()
|
||||||
|
|
||||||
@onready var barrel = $"Barrel"
|
@onready var barrel = $"Barrel"
|
||||||
@export var uses_hands: Array[CommandQueue.Side]
|
@export var uses_hands: Array[CommandQueue.Side]
|
||||||
|
@ -25,7 +26,10 @@ func _ready() -> void:
|
||||||
|
|
||||||
## Begin to fire
|
## Begin to fire
|
||||||
func request_fire() -> void:
|
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:
|
func _process(_dt) -> void:
|
||||||
if is_firing:
|
if is_firing:
|
||||||
|
@ -39,4 +43,8 @@ func end_fire() -> void:
|
||||||
|
|
||||||
func on_barrel_fired() -> void:
|
func on_barrel_fired() -> void:
|
||||||
is_firing = true
|
is_firing = true
|
||||||
|
ammo -= ammo_consumption
|
||||||
fired.emit()
|
fired.emit()
|
||||||
|
|
||||||
|
func reload() -> void:
|
||||||
|
ammo = max_ammo
|
||||||
|
|
|
@ -46,6 +46,11 @@ shoot={
|
||||||
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(189, 15),"global_position":Vector2(198, 63),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
|
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(189, 15),"global_position":Vector2(198, 63),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
reload={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":82,"key_label":0,"unicode":114,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
[layer_names]
|
[layer_names]
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue