diff --git a/exports/Chelimbalo.x86_64 b/exports/Chelimbalo.x86_64 index d965ef6..f6005a4 100755 Binary files a/exports/Chelimbalo.x86_64 and b/exports/Chelimbalo.x86_64 differ diff --git a/levels/prototype_scene.tscn b/levels/prototype_scene.tscn index 9dcb42e..6d2477e 100644 --- a/levels/prototype_scene.tscn +++ b/levels/prototype_scene.tscn @@ -1,10 +1,48 @@ -[gd_scene load_steps=5 format=3 uid="uid://cqrh2cc7m2i7f"] +[gd_scene load_steps=8 format=3 uid="uid://cqrh2cc7m2i7f"] [ext_resource type="Environment" uid="uid://d0cfgtx2yxw13" path="res://environments/prototype_environment.tres" id="1_i6jab"] [ext_resource type="Script" uid="uid://ypgm3aplt78m" path="res://scripts/multiplayer/player_spawner.gd" id="4_pi0y7"] [ext_resource type="Material" uid="uid://bx3f5vx71ynh5" path="res://materials/OrangeMat.tres" id="4_y6i55"] [ext_resource type="Material" uid="uid://mlha6r17v2en" path="res://materials/Bluemat.tres" id="5_bno23"] +[sub_resource type="Animation" id="Animation_y6i55"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("CSGCombiner3D/CSGBox3D7:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(-10.610777, 3.2577968, -10.344306)] +} + +[sub_resource type="Animation" id="Animation_pi0y7"] +resource_name = "main" +length = 5.0 +loop_mode = 2 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("CSGCombiner3D/CSGBox3D7:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 5), +"transitions": PackedFloat32Array(-2, -2), +"update": 0, +"values": [Vector3(-10.610777, 3.2577968, -10.344306), Vector3(-13.402859, 6.188627, 10.213315)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_bno23"] +_data = { +&"RESET": SubResource("Animation_y6i55"), +&"main": SubResource("Animation_pi0y7") +} + [node name="PrototypeScene" type="Node3D"] [node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] @@ -18,22 +56,46 @@ environment = ExtResource("1_i6jab") use_collision = true [node name="CSGBox3D2" type="CSGBox3D" parent="CSGCombiner3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.577414, 2.6, 1.8908081) -use_collision = true -size = Vector3(6.901001, 1, 4.520691) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.774414, 2.211084, -2.7798462) +size = Vector3(1, 3.9007568, 10.341309) +material = ExtResource("5_bno23") + +[node name="CSGBox3D3" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(0.6651913, 0, -0.746673, 0, 1, 0, 0.746673, 0, 0.6651913, -3.2896764, 2.2110848, -14.45882) +size = Vector3(10.241699, 3.9007568, 10.341309) +material = ExtResource("5_bno23") + +[node name="CSGBox3D7" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(0.6651913, 0, -0.746673, 0, 1, 0, 0.746673, 0, 0.6651913, -10.610777, 3.2577968, -10.344306) +size = Vector3(4.6240234, 1.4752808, 4.2929688) +material = ExtResource("5_bno23") + +[node name="CSGBox3D4" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(0.2536462, 0.36299103, -0.8966053, -0.098810926, 0.9317926, 0.3492834, 0.962237, 0, 0.27221313, 17.497704, 2.2110848, -14.45882) +size = Vector3(10.241699, 3.9007568, 10.341309) +material = ExtResource("5_bno23") + +[node name="CSGBox3D5" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(0.2536462, 0.36299103, -0.8966053, -0.098810926, 0.9317926, 0.3492834, 0.962237, 0, 0.27221313, 14.175301, -0.97636676, 16.262775) +size = Vector3(10.241699, 8.579285, 15.858276) +material = ExtResource("5_bno23") + +[node name="CSGBox3D6" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(0.2464775, -0.4244365, -0.87126493, 0.11553718, 0.90545774, -0.40840852, 0.9622371, -1.5334081e-09, 0.27221313, -19.380054, -0.97636676, 16.262775) +size = Vector3(10.241699, 8.579285, 15.858276) material = ExtResource("5_bno23") [node name="CSGBox3D" type="CSGBox3D" parent="CSGCombiner3D"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.774414, 0, 1.8908081) material_override = ExtResource("5_bno23") use_collision = true -size = Vector3(22.206055, 1, 21.818726) +size = Vector3(70.1814, 1, 50.408203) material = ExtResource("4_y6i55") [node name="CSGPolygon3D" type="CSGPolygon3D" parent="CSGCombiner3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.49652505, 4.840562) -polygon = PackedVector2Array(0, 0, -0.061755046, 1.5814729, 2, 0) -depth = 2.45 +transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, -3.3137877, 0.02481842, -3.7979093) +polygon = PackedVector2Array(1.1265539, -0.16863012, -3.9689837, 4.1396155, -6.226393, 4.152759, -7.117619, 0.24168777) +depth = 2.64 material = ExtResource("5_bno23") [node name="Spawner" type="Node3D" parent="."] @@ -43,3 +105,9 @@ script = ExtResource("4_pi0y7") [node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="."] _spawnable_scenes = PackedStringArray("uid://dpsr6ug3pkb40", "uid://cheu6vds21er7") spawn_path = NodePath("..") + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +&"": SubResource("AnimationLibrary_bno23") +} +autoplay = "main" diff --git a/scenes/player.tscn b/scenes/player.tscn index e1b1f38..a367142 100644 --- a/scenes/player.tscn +++ b/scenes/player.tscn @@ -1,12 +1,11 @@ -[gd_scene load_steps=15 format=3 uid="uid://dpsr6ug3pkb40"] +[gd_scene load_steps=14 format=3 uid="uid://dpsr6ug3pkb40"] [ext_resource type="Script" uid="uid://3dphlay25fih" path="res://scripts/player/player.gd" id="1_g2els"] [ext_resource type="Script" uid="uid://dalwlndejfdhm" path="res://scripts/player/crosshair.gd" id="3_dqkch"] [ext_resource type="Script" uid="uid://bjhbdh6xsjgnn" path="res://scripts/player/player_camera.gd" id="3_qhqgy"] [ext_resource type="PackedScene" uid="uid://c3hg4ux4j76j2" path="res://models/molikman_hands.glb" id="4_dqkch"] [ext_resource type="Script" uid="uid://6c14qse4vnra" path="res://scripts/player/player_raycast.gd" id="4_fjrip"] -[ext_resource type="Script" uid="uid://bmecgup3kcua7" path="res://scripts/weapon_system/system.gd" id="4_qlg0r"] -[ext_resource type="Script" uid="uid://c76n6qgu6o4hn" path="res://scripts/weapon_system/gun.gd" id="6_tuyoq"] +[ext_resource type="Script" uid="uid://bmecgup3kcua7" path="res://scripts/weapon_system/weapon_system.gd" id="4_qlg0r"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_u8vuu"] @@ -248,30 +247,9 @@ crosses_offset = 3.0 [node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."] replication_config = SubResource("SceneReplicationConfig_qhqgy") -[node name="WeaponSystem" type="Node" parent="." node_paths=PackedStringArray("default_pistol", "default_knife", "animation_player")] +[node name="WeaponSystem" type="Node" parent="." node_paths=PackedStringArray("default_pistol", "animation_player")] script = ExtResource("4_qlg0r") -default_pistol = NodePath("StartingPistol") -default_knife = NodePath("StartingPistol2") +default_pistol = NodePath("") animation_player = NodePath("../Camera3D/molikman_hands/AnimationPlayer") -[node name="StartingPistol" type="Node" parent="WeaponSystem" node_paths=PackedStringArray("raycast")] -script = ExtResource("6_tuyoq") -max_ammo = 10 -semi_auto = true -emptyable = true -damage = 25 -firerate = 0.1 -prefix = "baked_sp" -raycast = NodePath("../../Camera3D/RayCast3D") - -[node name="StartingPistol2" type="Node" parent="WeaponSystem" node_paths=PackedStringArray("raycast")] -script = ExtResource("6_tuyoq") -max_ammo = 10 -semi_auto = true -emptyable = true -damage = 25 -firerate = 0.1 -prefix = "baked_sp" -raycast = NodePath("../../Camera3D/RayCast3D") - [editable path="Camera3D/molikman_hands"] diff --git a/scenes/weapons/starting_pistol.tscn b/scenes/weapons/starting_pistol.tscn new file mode 100644 index 0000000..12fa1b1 --- /dev/null +++ b/scenes/weapons/starting_pistol.tscn @@ -0,0 +1,28 @@ +[gd_scene load_steps=6 format=3 uid="uid://djwjl8xll53vn"] + +[ext_resource type="Script" uid="uid://e6lqknfl4ngt" path="res://scripts/weapon_system/weapon_substate_machine.gd" id="1_g7s1i"] +[ext_resource type="Script" uid="uid://ofv4e3dsfe8" path="res://scripts/weapon_system/gun/idle_state.gd" id="2_cmn6f"] +[ext_resource type="Script" uid="uid://vj13r83l3xyq" path="res://scripts/weapon_system/gun/semi_auto_shoot_state.gd" id="3_016ti"] +[ext_resource type="Script" uid="uid://hmekwp8444ao" path="res://scripts/weapon_system/gun/reload_state.gd" id="4_hoqxt"] +[ext_resource type="Script" uid="uid://bmj0bwy2tlian" path="res://scripts/weapon_system/gun/intro_state.gd" id="5_ud1dr"] + +[node name="StartingPistol" type="Node" node_paths=PackedStringArray("enter_state")] +script = ExtResource("1_g7s1i") +animation_prefix = &"baked_sp_" +max_ammo = 20 +enter_state = NodePath("Intro") +metadata/_custom_type_script = "uid://e6lqknfl4ngt" + +[node name="Idle" type="Node" parent="."] +script = ExtResource("2_cmn6f") + +[node name="Shoot" type="Node" parent="."] +script = ExtResource("3_016ti") + +[node name="Reload" type="Node" parent="."] +script = ExtResource("4_hoqxt") + +[node name="Intro" type="Node" parent="."] +script = ExtResource("5_ud1dr") + +[node name="FireTimer" type="Timer" parent="."] diff --git a/scripts/player/player.gd b/scripts/player/player.gd index 328c95c..2f13f0b 100644 --- a/scripts/player/player.gd +++ b/scripts/player/player.gd @@ -26,6 +26,8 @@ const MAX_HP = 100 @export var TOGGLE_CROUCH: bool = true @export var WALK_MODIFIER: float = 0.5 + + @export var crouched: bool = false: set(value): if value != crouched and stand_up_area.has_overlapping_bodies() == false: @@ -36,6 +38,8 @@ const MAX_HP = 100 get: return crouched +@onready var TEMP_start_pos = global_position + var potential_crouched: bool = crouched func _enter_tree() -> void: @@ -89,4 +93,5 @@ func _input(event: InputEvent) -> void: crouched = false func die() -> void: - queue_free() + global_position = TEMP_start_pos + hp = MAX_HP diff --git a/scripts/state_machine/machine.gd b/scripts/state_machine/machine.gd index c51e3c8..25c0e77 100644 --- a/scripts/state_machine/machine.gd +++ b/scripts/state_machine/machine.gd @@ -1,6 +1,5 @@ extends Node - class_name StateMachine @export var current_state: State @@ -19,18 +18,36 @@ func on_transition_required(to: StringName): push_warning("Incorrect state request: " + to) return + change_state(states[to]) + +func change_state(to_state: State) -> void: + if current_state != null: + current_state.exit() + current_state = to_state + current_state.enter() + + update_remote_machines.rpc(to_state.name) + +@rpc("authority","call_local","unreliable") +func clear_state(): + if current_state == null: + return current_state.exit() + current_state = null + +@rpc("authority","call_remote","unreliable") +func update_remote_machines(to: StringName) -> void: + if current_state != null: + current_state.exit() current_state = states[to] current_state.enter() func _process(delta: float) -> void: if current_state == null: - push_error("State is not set") return current_state.update(delta) func _physics_process(delta: float) -> void: if current_state == null: - push_error("State is not set") return current_state.physics_update(delta) diff --git a/scripts/state_machine/state.gd b/scripts/state_machine/state.gd index a9e4aca..e999a02 100644 --- a/scripts/state_machine/state.gd +++ b/scripts/state_machine/state.gd @@ -1,12 +1,13 @@ @abstract extends Node - class_name State signal transition(to: StringName) @abstract func enter() -> void @abstract func exit() -> void -@abstract func update(delta: float) -> void -@abstract func physics_update(delta: float) -> void +func update(delta: float) -> void: + pass +func physics_update(delta: float) -> void: + pass diff --git a/scripts/state_machine/substate_machine.gd b/scripts/state_machine/substate_machine.gd new file mode 100644 index 0000000..aefb369 --- /dev/null +++ b/scripts/state_machine/substate_machine.gd @@ -0,0 +1,27 @@ +extends StateMachine + +class_name SubStateMachine + +@export var enter_state: State + +func enter() -> void: + change_state(enter_state) + +func exit() -> void: + clear_state.rpc() + +func update(delta: float) -> void: + if current_state == null: + return + current_state.update(delta) + +func physics_update(delta: float) -> void: + if current_state == null: + return + current_state.physics_update(delta) + +func _process(_delta: float) -> void: + pass + +func _physics_process(_delta: float) -> void: + pass diff --git a/scripts/state_machine/substate_machine.gd.uid b/scripts/state_machine/substate_machine.gd.uid new file mode 100644 index 0000000..889c671 --- /dev/null +++ b/scripts/state_machine/substate_machine.gd.uid @@ -0,0 +1 @@ +uid://btc5vyvccdqfp diff --git a/scripts/weapon_system/gun.gd b/scripts/weapon_system/gun.gd deleted file mode 100644 index 347547a..0000000 --- a/scripts/weapon_system/gun.gd +++ /dev/null @@ -1,93 +0,0 @@ -extends Usable - - -@export var max_ammo: int -@export var semi_auto: bool -@export var emptyable: bool -@export var damage: int - -@export var firerate: float - -@export var prefix: String - -@export var raycast: RayCast3D - -var ammo_amount: int -var fire_timer: Timer -var state_locked: bool - -func _ready() -> void: - fire_timer = Timer.new() - fire_timer.wait_time = firerate - ammo_amount = max_ammo - add_child(fire_timer) - if not semi_auto: - fire_timer.timeout.connect(fire) - -@rpc("authority","call_local","reliable") -func use_begin() -> void: - if fire_timer.is_stopped() == false: - return - fire_timer.start() - fire_timer.one_shot = true if semi_auto else false - fire() - -@rpc("authority","call_local","reliable") -func use_end() -> void: - fire_timer.one_shot = true - -func fire() -> void: - if ammo_amount == 0 or state_locked: - if not semi_auto: - fire_timer.stop() - return - ammo_amount -= 1 - - system.animation_player.stop() - system.animation_player.play(prefix + with_empty_suffix("_shoot")) - system.animation_player.queue(prefix + with_empty_suffix("_idle")) - - if raycast.is_colliding(): - raycast.get_collider().hp -= damage - - -func alternate_state() -> void: - pass - -func switch_mode() -> void: - pass - -func enter() -> void: - system.animation_player.animation_changed.connect(on_animation_changed) - state_locked = true - system.animation_player.stop() - system.animation_player.play(prefix+with_empty_suffix("_intro")) - system.animation_player.queue(prefix+with_empty_suffix("_idle")) - -func exit() -> void: - system.animation_player.animation_changed.disconnect(on_animation_changed) - -func on_animation_changed(old_animation: StringName,_new_animation: StringName) -> void: - if old_animation == prefix + with_empty_suffix("_reload"): - state_locked = false - ammo_amount = max_ammo - if old_animation == prefix + with_empty_suffix("_intro"): - state_locked = false - -func _input(event: InputEvent) -> void: - if not system.is_multiplayer_authority() or not in_use: return - - if event.is_action_pressed("plr_reload"): - init_reload.rpc() - -@rpc("call_local","authority","reliable") -func init_reload(): - if ammo_amount == max_ammo or state_locked: - return - state_locked = true - system.animation_player.play(prefix + with_empty_suffix("_reload")) - system.animation_player.queue(prefix + "_idle") - ammo_amount = max_ammo - -func with_empty_suffix(animation): - return (animation+"_empty") if emptyable and ammo_amount == 0 else animation diff --git a/scripts/weapon_system/gun.gd.uid b/scripts/weapon_system/gun.gd.uid deleted file mode 100644 index f4455e1..0000000 --- a/scripts/weapon_system/gun.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://c76n6qgu6o4hn diff --git a/scripts/weapon_system/gun/idle_state.gd b/scripts/weapon_system/gun/idle_state.gd new file mode 100644 index 0000000..50a47c8 --- /dev/null +++ b/scripts/weapon_system/gun/idle_state.gd @@ -0,0 +1,26 @@ +extends WeaponState + +@export var emptyable: bool + +func enter() -> void: + machine.animation_player.play(with_morphems("idle")) + +func exit() -> void: + pass + +func _input(event: InputEvent) -> void: + if not machine.is_multiplayer_authority(): return + + if event.is_action_pressed("plr_reload"): + init_reload() + +func use_begin() -> void: + transition.emit("Shoot") + +func init_reload(): + if machine.ammo == machine.max_ammo: + return + transition.emit("Reload") + +func with_morphems(animation): + return machine.animation_prefix + (animation+"_empty") if emptyable and machine.ammo == 0 else animation diff --git a/scripts/weapon_system/gun/idle_state.gd.uid b/scripts/weapon_system/gun/idle_state.gd.uid new file mode 100644 index 0000000..c6d0b82 --- /dev/null +++ b/scripts/weapon_system/gun/idle_state.gd.uid @@ -0,0 +1 @@ +uid://ofv4e3dsfe8 diff --git a/scripts/weapon_system/gun/intro_state.gd b/scripts/weapon_system/gun/intro_state.gd new file mode 100644 index 0000000..1ff258b --- /dev/null +++ b/scripts/weapon_system/gun/intro_state.gd @@ -0,0 +1,17 @@ +extends WeaponState + +@export var emptyable: bool + +func enter() -> void: + machine.animation_player.play(with_morphems("intro")) + machine.animation_player.animation_finished.connect(on_animation_finished) + +func exit() -> void: + machine.animation_player.animation_finished.disconnect(on_animation_finished) + +func on_animation_finished(animation): + if animation == with_morphems("intro"): + transition.emit("Idle") + +func with_morphems(animation): + return machine.animation_prefix + (animation+"_empty") if emptyable and machine.ammo == 0 else animation diff --git a/scripts/weapon_system/gun/intro_state.gd.uid b/scripts/weapon_system/gun/intro_state.gd.uid new file mode 100644 index 0000000..a67b51b --- /dev/null +++ b/scripts/weapon_system/gun/intro_state.gd.uid @@ -0,0 +1 @@ +uid://bmj0bwy2tlian diff --git a/scripts/weapon_system/gun/reload_state.gd b/scripts/weapon_system/gun/reload_state.gd new file mode 100644 index 0000000..410da29 --- /dev/null +++ b/scripts/weapon_system/gun/reload_state.gd @@ -0,0 +1,18 @@ +extends WeaponState + +@export var emptyable: bool + +func enter() -> void: + machine.animation_player.play(with_morphems("reload")) + machine.animation_player.animation_finished.connect(on_animation_finished) + +func exit() -> void: + machine.animation_player.animation_finished.disconnect(on_animation_finished) + +func on_animation_finished(animation): + if animation == with_morphems("reload"): + machine.ammo = machine.max_ammo + transition.emit("Idle") + +func with_morphems(animation): + return machine.animation_prefix + (animation+"_empty") if emptyable and machine.ammo == 0 else animation diff --git a/scripts/weapon_system/gun/reload_state.gd.uid b/scripts/weapon_system/gun/reload_state.gd.uid new file mode 100644 index 0000000..881858c --- /dev/null +++ b/scripts/weapon_system/gun/reload_state.gd.uid @@ -0,0 +1 @@ +uid://hmekwp8444ao diff --git a/scripts/weapon_system/gun/semi_auto_shoot_state.gd b/scripts/weapon_system/gun/semi_auto_shoot_state.gd new file mode 100644 index 0000000..d788a95 --- /dev/null +++ b/scripts/weapon_system/gun/semi_auto_shoot_state.gd @@ -0,0 +1,39 @@ +extends WeaponState + +@export var raycast: RayCast3D +@export var emptyable: bool +@export var damage: int + +@export var fire_timer: Timer + +func enter() -> void: + fire() + machine.animation_player.animation_finished.connect(on_animation_finished) + +func exit() -> void: + machine.animation_player.animation_finished.disconnect(on_animation_finished) + +func on_animation_finished(animation): + if animation == with_morphems("shoot"): + transition.emit("Idle") + +func use_begin() -> void: + if fire_timer.time_left > 0: + return + fire() + +func fire() -> void: + if machine.ammo == 0 or fire_timer.time_left > 0: + return + machine.ammo -= 1 + + machine.animation_player.stop() + machine.animation_player.play(with_morphems("shoot")) + + if raycast.is_colliding(): + raycast.get_collider().hp -= damage + + fire_timer.start() + +func with_morphems(animation): + return machine.animation_prefix + (animation+"_empty") if emptyable and machine.ammo == 0 else animation diff --git a/scripts/weapon_system/gun/semi_auto_shoot_state.gd.uid b/scripts/weapon_system/gun/semi_auto_shoot_state.gd.uid new file mode 100644 index 0000000..0f0b519 --- /dev/null +++ b/scripts/weapon_system/gun/semi_auto_shoot_state.gd.uid @@ -0,0 +1 @@ +uid://vj13r83l3xyq diff --git a/scripts/weapon_system/usable.gd b/scripts/weapon_system/usable.gd deleted file mode 100644 index f30c88d..0000000 --- a/scripts/weapon_system/usable.gd +++ /dev/null @@ -1,25 +0,0 @@ -@abstract -extends Node - -class_name Usable - -var system: WeaponSystem -var in_use: bool = false - -@rpc("authority","call_local","reliable") -@abstract func use_begin() -> void -@rpc("authority","call_local","reliable") -@abstract func use_end() -> void -@abstract func alternate_state() -> void -# Need to clarify naming; Switch mode like firemode. For different states use -# alternate_state -@abstract func switch_mode() -> void - -func enter() -> void: - pass -func exit() -> void: - pass -func update(_delta: float) -> void: - pass -func physics_update(_delta: float) -> void: - pass diff --git a/scripts/weapon_system/usable.gd.uid b/scripts/weapon_system/usable.gd.uid deleted file mode 100644 index 08b5c1c..0000000 --- a/scripts/weapon_system/usable.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://qj4m67w7ps7j diff --git a/scripts/weapon_system/weapon_state.gd b/scripts/weapon_system/weapon_state.gd new file mode 100644 index 0000000..b09f416 --- /dev/null +++ b/scripts/weapon_system/weapon_state.gd @@ -0,0 +1,17 @@ +@abstract +extends State + +class_name WeaponState + +var machine: WeaponSubStateMachine + +func use_begin() -> void: + pass +func use_end() -> void: + pass +func alternate_state() -> void: + pass +# Need to clarify naming; Switch mode like firemode. For different states use +# alternate_state +func switch_mode() -> void: + pass diff --git a/scripts/weapon_system/weapon_state.gd.uid b/scripts/weapon_system/weapon_state.gd.uid new file mode 100644 index 0000000..7086af3 --- /dev/null +++ b/scripts/weapon_system/weapon_state.gd.uid @@ -0,0 +1 @@ +uid://fd4tm5wexdk diff --git a/scripts/weapon_system/weapon_substate_machine.gd b/scripts/weapon_system/weapon_substate_machine.gd new file mode 100644 index 0000000..7acfba2 --- /dev/null +++ b/scripts/weapon_system/weapon_substate_machine.gd @@ -0,0 +1,33 @@ +extends SubStateMachine + +class_name WeaponSubStateMachine + +@export var animation_prefix: StringName + +@export var max_ammo: int +@onready var ammo: int = max_ammo + +var system: WeaponSystem +var animation_player: AnimationPlayer + +func _ready() -> void: + for child in get_children(): + if child is WeaponState: + states[child.name] = child + child.machine = self + child.transition.connect(on_transition_required) + else: + push_warning("Child of state machine is not state") + +@rpc("authority","call_local","reliable") +func use_begin() -> void: + current_state.use_begin() +@rpc("authority","call_local","reliable") +func use_end() -> void: + current_state.use_end() +func alternate_state() -> void: + current_state.alternate_state() +# Need to clarify naming; Switch mode like firemode. For different states use +# alternate_state +func switch_mode() -> void: + current_state.switch_mode() diff --git a/scripts/weapon_system/weapon_substate_machine.gd.uid b/scripts/weapon_system/weapon_substate_machine.gd.uid new file mode 100644 index 0000000..d6bb713 --- /dev/null +++ b/scripts/weapon_system/weapon_substate_machine.gd.uid @@ -0,0 +1 @@ +uid://e6lqknfl4ngt diff --git a/scripts/weapon_system/system.gd b/scripts/weapon_system/weapon_system.gd similarity index 64% rename from scripts/weapon_system/system.gd rename to scripts/weapon_system/weapon_system.gd index 2332468..6eccf47 100644 --- a/scripts/weapon_system/system.gd +++ b/scripts/weapon_system/weapon_system.gd @@ -1,16 +1,15 @@ extends Node - class_name WeaponSystem -@export var default_pistol: Usable -@export var default_knife: Usable +@export var default_pistol: WeaponSubStateMachine +@export var default_knife: WeaponSubStateMachine @export var animation_player: AnimationPlayer -var current_usable: Usable +var current_state: WeaponSubStateMachine -var slots: Dictionary[StringName,Usable] = { +var slots: Dictionary[StringName,WeaponSubStateMachine] = { "primary": null, "secondary": default_pistol, "knife": default_knife, @@ -21,61 +20,63 @@ var slots: Dictionary[StringName,Usable] = { "ultimate": null } -signal switched_to(usable: Usable) +signal switched_to(state: WeaponSubStateMachine) func _ready() -> void: for child in get_children(): - if child is Usable: + if child is WeaponSubStateMachine: child.system = self + child.animation_player = animation_player else: push_warning("Child of weapon system is not ability or weapon") - current_usable = default_pistol + current_state = default_pistol slots["knife"] = default_knife slots["secondary"] = default_pistol - current_usable.enter() + current_state.enter() + current_state.in_use = true func can_add(slot: StringName) -> bool: return slots.has(slot) -func add(usable: Usable, slot: StringName) -> void: +func add(state: WeaponSubStateMachine, slot: StringName) -> void: if can_add(slot) == false: return - add_child(usable) + add_child(state) - slots[slot] = usable - usable.system = self + slots[slot] = state + state.system = self func switch(to: StringName): - if slots.has(to) == false or slots[to] == null or slots[to] == current_usable: + if slots.has(to) == false or slots[to] == null or slots[to] == current_state: return - current_usable.exit() - current_usable.in_use = false - current_usable = slots[to] - current_usable.enter() - current_usable.in_use = true + current_state.exit() + current_state.in_use = false + current_state = slots[to] + current_state.enter() + current_state.in_use = true - switched_to.emit(current_usable) + switched_to.emit(current_state) - update_remotes.rpc(to) + #update_remotes.rpc(to) @rpc("authority","call_remote","reliable") func update_remotes(to: StringName): switch(to) func _process(delta: float) -> void: - if current_usable == null: + if current_state == null: push_error("State is not set") return - current_usable.update(delta) + current_state.update(delta) func _physics_process(delta: float) -> void: - if current_usable == null: + if current_state == null: push_error("State is not set") return - current_usable.physics_update(delta) + current_state.physics_update(delta) func _input(event: InputEvent) -> void: if is_multiplayer_authority() == false: return @@ -98,11 +99,11 @@ func _input(event: InputEvent) -> void: switch("knife") if event.is_action_pressed("plr_fire"): - current_usable.use_begin.rpc() + current_state.use_begin.rpc() if event.is_action_released("plr_fire"): - current_usable.use_end.rpc() + current_state.use_end.rpc() if event.is_action_pressed("plr_scope"): - current_usable.alternate_state() + current_state.alternate_state() if event.is_action_pressed("plr_firemode"): - current_usable.switch_mode() + current_state.switch_mode() diff --git a/scripts/weapon_system/system.gd.uid b/scripts/weapon_system/weapon_system.gd.uid similarity index 100% rename from scripts/weapon_system/system.gd.uid rename to scripts/weapon_system/weapon_system.gd.uid