diff --git a/base/assets/guns/placeholder/placeholder.tres b/base/assets/guns/placeholder/placeholder.tres index 39f8c9c..53cf61c 100644 --- a/base/assets/guns/placeholder/placeholder.tres +++ b/base/assets/guns/placeholder/placeholder.tres @@ -20,23 +20,6 @@ tracks/0/keys = { "values": [null] } -[sub_resource type="Animation" id="Animation_8sdfx"] -resource_name = "shoot" -length = 0.30001 -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.2, 0.3), -"transitions": PackedFloat32Array(1, 1, 1, 1), -"update": 1, -"values": [ExtResource("1_yheqn"), ExtResource("9_6fi3a"), ExtResource("10_mjqfp"), ExtResource("11_0d256")] -} - [sub_resource type="Animation" id="Animation_ma1q3"] resource_name = "static" length = 0.001 @@ -54,9 +37,43 @@ tracks/0/keys = { "values": [ExtResource("1_yheqn")] } +[sub_resource type="Animation" id="Animation_8sdfx"] +resource_name = "shoot" +length = 0.30001 +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.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [ExtResource("9_6fi3a"), ExtResource("10_mjqfp"), ExtResource("11_0d256")] +} +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(0.2, 0.3), +"transitions": PackedFloat32Array(1, 1), +"values": [{ +"args": [], +"method": &"fire_task_finish" +}, { +"args": [], +"method": &"on_fire_animation_end" +}] +} + [resource] _data = { &"RESET": SubResource("Animation_i1xqq"), -&"shoot": SubResource("Animation_8sdfx"), +&"fire": SubResource("Animation_8sdfx"), &"static": SubResource("Animation_ma1q3") } diff --git a/base/scenes/player.tscn b/base/scenes/player.tscn index cccfab7..ee2e42b 100644 --- a/base/scenes/player.tscn +++ b/base/scenes/player.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=4 format=3 uid="uid://dwx5tcatj35gu"] +[gd_scene load_steps=5 format=3 uid="uid://dwx5tcatj35gu"] [ext_resource type="Script" uid="uid://dts8lbivkgsmj" path="res://base/scripts/player/player.gd" id="1_1w3ab"] +[ext_resource type="Texture2D" uid="uid://cfw6p5g680c55" path="res://base/assets/guns/placeholder/shoot1.png" id="2_i1xqq"] [ext_resource type="PackedScene" uid="uid://bb6ovrbusyxpi" path="res://base/scenes/weapons/weapon_base.tscn" id="2_ma1q3"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_jjqxs"] @@ -28,6 +29,7 @@ grow_horizontal = 2 grow_vertical = 2 size_flags_horizontal = 3 size_flags_vertical = 3 +texture = ExtResource("2_i1xqq") stretch_mode = 6 [node name="AnimationPlayer" type="AnimationPlayer" parent="HUD/Weapon"] diff --git a/base/scenes/weapons/weapon_base.tscn b/base/scenes/weapons/weapon_base.tscn index 36dd56c..3688354 100644 --- a/base/scenes/weapons/weapon_base.tscn +++ b/base/scenes/weapons/weapon_base.tscn @@ -1,13 +1,13 @@ [gd_scene load_steps=6 format=3 uid="uid://bb6ovrbusyxpi"] [ext_resource type="Script" uid="uid://bf0q3xe6oavqa" path="res://base/scripts/weapons/weapon_base.gd" id="1_rwatx"] -[ext_resource type="Script" path="res://base/scripts/weapons/fire_mode/single_fire_mode.gd" id="2_bt0tf"] +[ext_resource type="Script" uid="uid://ckexgw71dd5jc" path="res://base/scripts/weapons/fire_mode/single_fire_mode.gd" id="2_bt0tf"] [ext_resource type="Script" uid="uid://bvurg687pt06s" path="res://base/scripts/weapons/barrel.gd" id="2_n0n7m"] [ext_resource type="AnimationLibrary" uid="uid://cw8bt4hqxpk55" path="res://base/assets/guns/placeholder/placeholder.tres" id="2_p83j3"] [sub_resource type="Resource" id="Resource_ij06d"] script = ExtResource("2_bt0tf") -fire_delay = 0.3 +fire_delay = 0.5 metadata/_custom_type_script = "uid://ckexgw71dd5jc" [node name="Weapon" type="Node3D"] diff --git a/base/scripts/player/command_queue.gd b/base/scripts/player/command_queue.gd index 9560afc..397ef1d 100644 --- a/base/scripts/player/command_queue.gd +++ b/base/scripts/player/command_queue.gd @@ -7,7 +7,7 @@ class_name CommandQueue enum Command { NONE, TAKE_WEAPON, - SHOOT, + FIRE, RELOAD, HOLSTER_WEAPON, TAKE_ZAZA, diff --git a/base/scripts/player/player.gd b/base/scripts/player/player.gd index 7685b37..6fc3b46 100644 --- a/base/scripts/player/player.gd +++ b/base/scripts/player/player.gd @@ -11,6 +11,9 @@ 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] + var current_weapon: Weapon func _ready() -> void: @@ -18,6 +21,7 @@ func _ready() -> void: queue.command_popped.connect(on_queue_command_popped) current_weapon = weapons.get_child(0) as Weapon + current_weapon.fired.connect(on_weapon_fired) weapon_player.add_animation_library("current", current_weapon.animation_library) weapon_player.play("current/static") @@ -25,16 +29,13 @@ func _ready() -> void: Input.mouse_mode = Input.MOUSE_MODE_CAPTURED func _process(_delta: float) -> void: - if Input.is_action_pressed("shoot") \ - and queue.current_command(CommandQueue.Side.RIGHT) \ + if queue.current_command(CommandQueue.Side.RIGHT) \ == CommandQueue.DEFAULT_COMMAND: - queue.push([ - CommandQueue.Command.NONE, - CommandQueue.Command.SHOOT - ], [ - CommandQueue.Side.LEFT, - CommandQueue.Side.RIGHT - ]) + 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: + queue.push(ONEHANDED_FIRE_COMMAND, DEFAULT_SIDES) for side in CommandQueue.Side.values(): var command = queue.current_command(side) @@ -74,7 +75,7 @@ func on_queue_command_pushed(sides, commands): CommandQueue.Side.RIGHT: handle_new_right_command(commands[i]) -func shoot_animation_ended(): +func fire_task_finish(): queue.pop() func on_queue_command_popped(commands): @@ -85,6 +86,12 @@ func on_queue_command_popped(commands): CommandQueue.Side.RIGHT: handle_ended_right_command(commands[i]) +func on_weapon_fired(): + weapon_player.play("current/fire") + +func on_fire_animation_end(): + weapon_player.play("current/static") + func handle_new_left_command(command: CommandQueue.Command): match command: CommandQueue.Command.NONE: @@ -94,7 +101,7 @@ func handle_new_left_command(command: CommandQueue.Command): func handle_new_right_command(command: CommandQueue.Command): match command: - CommandQueue.Command.NONE | CommandQueue.Command.SHOOT: + CommandQueue.Command.NONE | CommandQueue.Command.FIRE: pass _: print('New command %s is not implemented for right hand.' % command) @@ -108,10 +115,8 @@ func handle_ended_left_command(command: CommandQueue.Command): func handle_ended_right_command(command: CommandQueue.Command): match command: - CommandQueue.Command.NONE: + CommandQueue.Command.NONE | CommandQueue.Command.FIRE: pass - CommandQueue.Command.SHOOT: - weapon_player.play('current/static') _: print('Ended command %s is not implemented for right hand.' % command) @@ -126,5 +131,7 @@ 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) diff --git a/base/scripts/weapons/barrel.gd b/base/scripts/weapons/barrel.gd index 1d7904a..2cdbaff 100644 --- a/base/scripts/weapons/barrel.gd +++ b/base/scripts/weapons/barrel.gd @@ -2,5 +2,10 @@ extends Node3D class_name Barrel +signal fired() + func can_fire() -> bool: return true + +func fire() -> void: + fired.emit() diff --git a/base/scripts/weapons/fire_mode/auto_fire_mode.gd b/base/scripts/weapons/fire_mode/auto_fire_mode.gd index 0d9f661..8b710ef 100644 --- a/base/scripts/weapons/fire_mode/auto_fire_mode.gd +++ b/base/scripts/weapons/fire_mode/auto_fire_mode.gd @@ -14,15 +14,15 @@ var cooldown : bool = false ## Reference to cooldown scene timer var cooldown_timer : SceneTreeTimer = null -func _on_fire_begin(_tree : SceneTree) -> void: +func _on_fire_begin() -> void: cooldown = false check_unfinished_timer(cooldown_timer,on_cooldown_timeout) -func _process(tree : SceneTree) -> void: +func _process() -> void: if can_fire() : return if _fire(): - on_fire(tree) + on_fire() ## Invoked when cooldown has ended @@ -42,7 +42,7 @@ func can_fire() -> bool: return cooldown ## Invoked when fired -func on_fire(tree : SceneTree) -> void: +func on_fire() -> void: cooldown = true cooldown_timer = tree.create_timer(fire_delay) cooldown_timer.timeout.connect(on_cooldown_timeout) diff --git a/base/scripts/weapons/fire_mode/base_fire_mode.gd b/base/scripts/weapons/fire_mode/base_fire_mode.gd index 5fa443d..2150db3 100644 --- a/base/scripts/weapons/fire_mode/base_fire_mode.gd +++ b/base/scripts/weapons/fire_mode/base_fire_mode.gd @@ -5,7 +5,7 @@ class_name BaseFireMode ## Assigned barrel to shoot out of var barrel : Barrel -var tree : Tree +var tree : SceneTree func _init() -> void: resource_local_to_scene = true @@ -14,6 +14,7 @@ func _init() -> void: ## Returns [color=green]true[/color] if barrel can shoot,[br] ## Returns [color=red]false[/color] if barrel cannot shoot func _fire() -> bool: + barrel.fire() return true diff --git a/base/scripts/weapons/fire_mode/burst_fire_mode.gd b/base/scripts/weapons/fire_mode/burst_fire_mode.gd index 8c45b0f..b7ec6a3 100644 --- a/base/scripts/weapons/fire_mode/burst_fire_mode.gd +++ b/base/scripts/weapons/fire_mode/burst_fire_mode.gd @@ -20,15 +20,15 @@ var reloading : bool = false ## Reference to reload scene timer var reload_timer : SceneTreeTimer = null -func _on_fire_begin(_tree : SceneTree) -> void: - super._on_fire_begin(_tree) +func _on_fire_begin() -> void: + super._on_fire_begin() current_amount = 0 reloading = false check_unfinished_timer(reload_timer,on_reload_timeout) -func on_fire(tree : SceneTree) -> void: - super.on_fire(tree) +func on_fire() -> void: + super.on_fire() current_amount += 1 if current_amount >= burst_amount: reloading = true diff --git a/base/scripts/weapons/fire_mode/single_fire_mode.gd b/base/scripts/weapons/fire_mode/single_fire_mode.gd index a046102..c74afe2 100644 --- a/base/scripts/weapons/fire_mode/single_fire_mode.gd +++ b/base/scripts/weapons/fire_mode/single_fire_mode.gd @@ -13,7 +13,7 @@ class_name SingleFireMode var cooldown : bool = false -func _on_fire_begin(tree) -> void: +func _on_fire_begin() -> void: if cooldown: return diff --git a/base/scripts/weapons/weapon_base.gd b/base/scripts/weapons/weapon_base.gd index 3db1384..e66dded 100644 --- a/base/scripts/weapons/weapon_base.gd +++ b/base/scripts/weapons/weapon_base.gd @@ -2,6 +2,8 @@ extends Node3D class_name Weapon +signal fired() + @onready var barrel = $"Barrel" @export var uses_hands: Array[CommandQueue.Side] @@ -10,6 +12,7 @@ var ammo: int = max_ammo @export var ammo_consumption: int = 1 @export var fire_mode: BaseFireMode + ## Weapon animation library. Should contain "static", "fire", "reload" animations @export var animation_library: AnimationLibrary @@ -17,17 +20,23 @@ var is_firing: bool = false func _ready() -> void: fire_mode.barrel = barrel + fire_mode.tree = get_tree() + barrel.fired.connect(on_barrel_fired) ## Begin to fire func request_fire() -> void: - fire_mode.on_fire_begin(get_tree()) - is_firing = true + fire_mode._on_fire_begin() func _process(_dt) -> void: if is_firing: - fire_mode._process(get_tree()) + fire_mode._process() ## End fire func end_fire() -> void: - fire_mode.on_fire_end(get_tree()) - is_firing = false + if is_firing: + fire_mode._on_fire_end() + is_firing = false + +func on_barrel_fired() -> void: + is_firing = true + fired.emit()