Refactor Part II

This commit is contained in:
Rendo 2025-12-09 21:02:29 +05:00
commit 3f99f1b8dd
56 changed files with 193 additions and 168 deletions

View file

@ -1,16 +0,0 @@
extends Node
@export var player: Player
@export var layer: bool
@export var inverse: bool
const ATTACK_LAYER: int = 0b10000
const DEFENCE_LAYER: int = 0b100000
func _ready() -> void:
if is_multiplayer_authority() == false: return
var mask = (ATTACK_LAYER if (player.team == Session.TEAMS.DEFENCE != inverse) else DEFENCE_LAYER)
if layer:
get_parent().collision_layer |= mask
else:
get_parent().collision_mask |= mask

View file

@ -1 +0,0 @@
uid://5gwpjiswnegn

View file

@ -1,35 +0,0 @@
extends Camera3D
@export var SPEED = 10.0
var active: bool
func _enter_tree() -> void:
set_multiplayer_authority(int(get_parent().get_parent().name))
func set_active() -> void:
if not is_multiplayer_authority():
return
active = true
current = true
top_level = true
func _process(delta: float) -> void:
if active == false or not is_multiplayer_authority():
return
var xz_plane = Input.get_vector("plr_strafe_l","plr_strafe_r","plr_forward","plr_back")
var y = Input.get_axis("spc_down","spc_up")
var direction = Vector3(xz_plane.x,y,xz_plane.y)
global_position += global_basis * direction * SPEED * delta
func rotate_camera(x,y) -> void:
rotate_y(x)
rotation.x = clamp(rotation.x + y,-PI/2,PI/2)
orthonormalize()
func _input(event: InputEvent) -> void:
if active == false or not is_multiplayer_authority():
return
if event is InputEventMouseMotion:
rotate_camera(-event.relative.x * ClientSettings.SENSITIVITY,-event.relative.y * ClientSettings.SENSITIVITY)

View file

@ -1 +0,0 @@
uid://bl8gfrrc512q2

View file

@ -1,60 +0,0 @@
extends CharacterBody3D
class_name Player
@export var team: Session.TEAMS
@export var weapon_models: Dictionary[StringName,Node3D]
@export var player_id: int = 1:
set(id):
player_id = id
$PlayerInput.set_multiplayer_authority(id)
$Camera3D.set_multiplayer_authority(id)
var passived: bool = false
signal health_changed(to: int)
signal died
const MAX_HP = 100
@export var hp: int = 100:
set(value):
if value < 0:
hp = 0
else:
hp = value
health_changed.emit(hp)
if hp == 0:
die()
get:
return hp
func _physics_process(_delta: float) -> void:
if not multiplayer.is_server():
return
move_and_slide()
func die() -> void:
if (not multiplayer.is_server()):
return
Session.add_dead(team)
died.emit()
die_on_peers.rpc()
passived = true
@rpc("authority","call_remote","reliable")
func die_on_peers():
if multiplayer.get_remote_sender_id() != 1:
return
died.emit()
func passive() -> void:
passived = true
func depassive() -> void:
passived = false
func take_damage(damage: int):
hp -= damage

View file

@ -1 +0,0 @@
uid://3dphlay25fih

View file

@ -1,59 +0,0 @@
extends Camera3D
class_name PlayerCamera
var vertical_compensation : float
var compensation_tween: Tween
var compensate: bool = false
var disabled: bool = false
var compensation_speed: float
@export var compensation_time: float = 1.0
@export var compensation_delay: float = 0.5
func _ready() -> void:
if not is_multiplayer_authority():
return
# Move to level controller when possible
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
current = true
func _process(delta: float) -> void:
if disabled: return
if compensate:
if abs(vertical_compensation) <= 0.001:
vertical_compensation = 0
compensate = false
return
rotate_camera(0,compensation_speed * delta)
func _input(event: InputEvent) -> void:
if not is_multiplayer_authority() or disabled:
return
if Input.mouse_mode == Input.MouseMode.MOUSE_MODE_CAPTURED and event is InputEventMouseMotion:
rotate_camera(-event.relative.x * ClientSettings.SENSITIVITY,-event.relative.y * ClientSettings.SENSITIVITY)
func rotate_camera(x,y) -> void:
get_parent().rotate_y(x)
rotation.x = clamp(rotation.x + y,-PI/2,PI/2)
orthonormalize()
if sign(vertical_compensation) == sign(y):
if abs(vertical_compensation) - abs(y) < 0:
vertical_compensation = 0
else:
vertical_compensation -= y
func recoil(x,y) -> void:
rotate_camera(x,y)
vertical_compensation -= y
if compensation_tween:
compensation_tween.kill()
compensation_tween = create_tween()
compensation_tween.tween_interval(compensation_delay)
compensation_tween.tween_callback(start_compensating)
func start_compensating() -> void:
compensate = true
compensation_speed = vertical_compensation / compensation_time
func disable() -> void:
disabled = true

View file

@ -1 +0,0 @@
uid://bjhbdh6xsjgnn

View file

@ -1,4 +0,0 @@
extends Node
var player: CharacterBody3D

View file

@ -1 +0,0 @@
uid://dv3pm11t6p4si

View file

@ -1,182 +0,0 @@
extends MultiplayerSynchronizer
class_name PlayerInput
const SCOPE: int = 0b1
const CROUCH: int = 0b10
const WALK: int = 0b100
#region SYNC
@export var direction: Vector2
@export var compressed_states: int
#endregion
signal jumped
signal drop
signal switch_weapon(to_slot: StringName)
signal fire_begin
signal fire_end
signal alternate_state
signal switch_firemode
signal reload
signal scope_begin
signal scope_end
signal crouch_begin
signal crouch_end
signal walk_begin
signal walk_end
signal interact_begin
signal interact_end
func _process(_delta: float) -> void:
if not is_multiplayer_authority(): return
direction = Input.get_vector("plr_strafe_r","plr_strafe_l", "plr_back","plr_forward")
func _unhandled_input(event: InputEvent) -> void:
if not is_multiplayer_authority(): return
if event.is_action_pressed("plr_ult"):
switch_on_server.rpc_id(1,"ultimate")
elif event.is_action_pressed("plr_bomb"):
switch_on_server.rpc_id(1,"bomb")
elif event.is_action_pressed("plr_primary"):
switch_on_server.rpc_id(1,"primary")
elif event.is_action_pressed("plr_active_first"):
switch_on_server.rpc_id(1,"ability_first")
elif event.is_action_pressed("plr_active_second"):
switch_on_server.rpc_id(1,"ability_second")
elif event.is_action_pressed("plr_active_third"):
switch_on_server.rpc_id(1,"ability_third")
elif event.is_action_pressed("plr_secondary"):
switch_on_server.rpc_id(1,"secondary")
elif event.is_action_pressed("plr_knife"):
switch_on_server.rpc_id(1,"knife")
if event.is_action_pressed("plr_fire"):
fire_on_server.rpc_id(1,false)
if event.is_action_released("plr_fire"):
fire_on_server.rpc_id(1,true)
if event.is_action_pressed("plr_scope"):
alternate_state_on_server.rpc_id(1)
if event.is_action_pressed("plr_firemode"):
switch_firemode_on_server.rpc_id(1)
if event.is_action_pressed("plr_drop"):
drop_on_server.rpc_id(1)
var crouching: bool = compressed_states & CROUCH
var walking: bool = compressed_states & WALK
var scoping: bool = compressed_states & SCOPE
if event.is_action_pressed("plr_crouch"):
if ClientSettings.TOGGLE_CROUCH:
crouch_on_server.rpc_id(1,crouching)
compressed_states ^= CROUCH
elif not crouching:
compressed_states |= CROUCH
crouch_on_server.rpc_id(1,false)
if event.is_action_released("plr_crouch") and not ClientSettings.TOGGLE_CROUCH and crouching:
compressed_states &= ~CROUCH
crouch_on_server.rpc_id(1,true)
if event.is_action_pressed("plr_walk"):
if ClientSettings.TOGGLE_WALK:
walk_on_server.rpc_id(1,walking)
compressed_states ^= WALK
elif not walking:
compressed_states |= WALK
walk_on_server.rpc_id(1,false)
if event.is_action_released("plr_walk") and not ClientSettings.TOGGLE_WALK and walking:
compressed_states &= ~WALK
walk_on_server.rpc_id(1,true)
if event.is_action_pressed("plr_scope"):
if ClientSettings.TOGGLE_SCOPE:
scope_on_server.rpc_id(1,scoping)
compressed_states ^= SCOPE
elif not scoping:
compressed_states |= SCOPE
scope_on_server.rpc_id(1,false)
if event.is_action_released("plr_scope") and not ClientSettings.TOGGLE_SCOPE and scoping:
compressed_states &= ~SCOPE
scope_on_server.rpc_id(1,true)
if event.is_action_pressed("plr_reload"):
reload_on_server.rpc_id(1)
if event.is_action_pressed("plr_interact"):
interact_on_server.rpc_id(1,false)
if event.is_action_released("plr_interact"):
interact_on_server.rpc_id(1,true)
if event.is_action_pressed("plr_jump"):
jump_on_server.rpc_id(1)
@rpc("authority","call_local","reliable")
func switch_on_server(slot: StringName) -> void:
if not multiplayer.is_server(): return
switch_weapon.emit(slot)
@rpc("authority","call_local","reliable")
func drop_on_server() -> void:
if not multiplayer.is_server(): return
drop.emit()
@rpc("authority","call_local","reliable")
func fire_on_server(end: bool) -> void:
if not multiplayer.is_server(): return
if end:
fire_end.emit()
else:
fire_begin.emit()
@rpc("authority","call_local","reliable")
func alternate_state_on_server() -> void:
if not multiplayer.is_server(): return
alternate_state.emit()
@rpc("authority","call_local","reliable")
func switch_firemode_on_server() -> void:
if not multiplayer.is_server(): return
switch_firemode.emit()
@rpc("authority","call_local","reliable")
func crouch_on_server(end: bool) -> void:
if not multiplayer.is_server(): return
if end:
crouch_end.emit()
else:
crouch_begin.emit()
@rpc("authority","call_local","reliable")
func walk_on_server(end: bool) -> void:
if not multiplayer.is_server(): return
if end:
walk_end.emit()
else:
walk_begin.emit()
@rpc("authority","call_local","reliable")
func scope_on_server(end: bool) -> void:
if not multiplayer.is_server(): return
if end:
scope_end.emit()
else:
scope_begin.emit()
@rpc("authority","call_local","reliable")
func reload_on_server() -> void:
if not multiplayer.is_server(): return
reload.emit()
@rpc("authority","call_local","reliable")
func interact_on_server(end: bool) -> void:
if not multiplayer.is_server(): return
if end:
interact_end.emit()
else:
interact_begin.emit()
@rpc("authority","call_local","reliable")
func jump_on_server() -> void:
if not multiplayer.is_server(): return
jumped.emit()

View file

@ -1 +0,0 @@
uid://dfvnx8f1v6m5g

View file

@ -1,8 +0,0 @@
extends Node
func on_player_start_interacting():
Session.interact(get_parent().player_id)
func on_player_end_interacting():
Session.stop_interact(get_parent().player_id)

View file

@ -1 +0,0 @@
uid://dsp1sq46c5i3y

View file

@ -1,31 +0,0 @@
extends Node
class_name PlayerMovement
@export var player: Player
@export var player_input: PlayerInput
@export var jump_velocity: float
var disabled: bool
func disable() -> void:
disabled = true
func process_movement(max_speed: float,acceleration: float,deceleration: float,delta: float) -> void:
if is_multiplayer_authority() == false:
return
if Session.round_state == Session.ROUND_STATES.BUY or disabled or player.passived:
player.velocity.x = 0
player.velocity.z = 0
return
var input_dir := player_input.direction
var direction := (player.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if direction:
player.velocity.x = clamp(player.velocity.x + direction.x * acceleration * delta,-max_speed*abs(direction.x),max_speed*abs(direction.x))
player.velocity.z = clamp(player.velocity.z + direction.z * acceleration * delta,-max_speed*abs(direction.z),max_speed*abs(direction.z))
else:
player.velocity.x = move_toward(player.velocity.x, 0, deceleration*delta)
player.velocity.z = move_toward(player.velocity.z, 0, deceleration*delta)
func jump() -> void:
player.velocity.y = jump_velocity

View file

@ -1 +0,0 @@
uid://bs4y647h5rdfr

View file

@ -1,43 +0,0 @@
extends Area3D
@export var weapon_spawner: MultiplayerSpawner
@export var weapon_system: WeaponSystem
var disabled: bool
func _ready() -> void:
if is_multiplayer_authority() == false: return
body_entered.connect(on_body_entered)
func disable() -> void:
disabled = true
func on_body_entered(body: Node3D):
if disabled:
return
if body is DroppableWeapon:
if weapon_system.can_add(body.slot) == false or (body.team != Session.TEAMS.UNASSIGNED and get_parent().team != body.team):
return
weapon_spawner.spawn({
"ammo": body.weapon.ammo,
"remaining_ammo": body.weapon.remaining_ammo,
"scene_file_path": body.weapon.scene_file_path,
"slot": body.slot
})
body.queue_free()
func start_temp_ignore():
if disabled:
return
if is_multiplayer_authority() == false:
return
monitoring = false
get_tree().create_timer(0.5).timeout.connect(stop_temp_ignore)
func stop_temp_ignore():
if disabled:
return
if is_multiplayer_authority() == false:
return
monitoring = true

View file

@ -1 +0,0 @@
uid://xsgfbuyje35p

View file

@ -1,12 +0,0 @@
extends RayCast3D
func _ready() -> void:
add_exception($"../..")
func try_deal_damage(damage) -> void:
if is_colliding() == false:
return
var collider = get_collider()
if collider is Player:
collider.hp -= damage

View file

@ -1 +0,0 @@
uid://6c14qse4vnra

View file

@ -1,37 +0,0 @@
extends Camera3D
@export var SPEED = 10.0
func _enter_tree() -> void:
set_multiplayer_authority(int(name))
func _ready() -> void:
if not is_multiplayer_authority():
return
# Move to level controller when possible
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
current = true
func _process(delta: float) -> void:
if not is_multiplayer_authority():
return
var xz_plane = Input.get_vector("plr_strafe_l","plr_strafe_r","plr_forward","plr_back")
var y = Input.get_axis("spc_down","spc_up")
var direction = Vector3(xz_plane.x,y,xz_plane.y)
global_position += global_basis * direction * SPEED * delta
func rotate_camera(x,y) -> void:
rotate_y(x)
rotation.x = clamp(rotation.x + y,-PI/2,PI/2)
orthonormalize()
func _input(event: InputEvent) -> void:
if not is_multiplayer_authority():
return
if event is InputEventMouseMotion:
rotate_camera(-event.relative.x * ClientSettings.SENSITIVITY,-event.relative.y * ClientSettings.SENSITIVITY)
@rpc("any_peer","call_local","reliable")
func set_after_spawn(start_position: Vector3, _team: int):
global_position = start_position

View file

@ -1 +0,0 @@
uid://cikw7fcykkpd5

View file

@ -1,36 +0,0 @@
extends State
@export var max_speed: float = 2.5
@export var acceleration: float = 1.0
@export var deceleration: float = 100.0
@export var toggle: bool = false
@export var stand_up_area: Area3D
@export var player: Player
@export var player_movement: PlayerMovement
@export var player_input: PlayerInput
@export var animation_player: AnimationPlayer
@export var crouch_time: float = 0.1
@export var weapon_system: WeaponSystem
func enter() -> void:
animation_player.play("crouch",-1,1/crouch_time)
player_input.crouch_end.connect(try_end_crouch)
func exit() -> void:
animation_player.play("crouch",-1,-1/crouch_time,true)
player_input.crouch_end.disconnect(try_end_crouch)
func physics_update(delta: float) -> void:
if not is_multiplayer_authority():
return
if not player.is_on_floor():
transition.emit("Fall")
return
player_movement.process_movement(max_speed * weapon_system.get_speed_modifier(),acceleration,deceleration,delta)
func try_end_crouch() -> void:
if player.is_on_floor() and stand_up_area.has_overlapping_bodies() == false:
transition.emit("Stand")

View file

@ -1 +0,0 @@
uid://bv8sgx78s8hwn

View file

@ -1,12 +0,0 @@
extends State
@export var animation_player: AnimationPlayer
func on_death() -> void:
transition.emit("Death")
func enter() -> void:
animation_player.play("die")
func exit() -> void:
pass

View file

@ -1 +0,0 @@
uid://tb140f8fweug

View file

@ -1,32 +0,0 @@
extends State
@export var player: Player
@export var player_movement: PlayerMovement
@export var player_input: PlayerInput
@export var max_speed: float = 5.0
@export var acceleration: float
@export var weapon_system: WeaponSystem
@export var land_sound: MultiplayerAudio3D
func enter() -> void:
pass
func exit() -> void:
pass
func physics_update(delta: float) -> void:
if not is_multiplayer_authority():
return
if player.is_on_floor():
if player_input.compressed_states & PlayerInput.CROUCH:
transition.emit("Crouch")
elif player_input.compressed_states & PlayerInput.WALK:
transition.emit("Walk")
else:
transition.emit("Stand")
land_sound.multiplayer_play()
player.velocity += player.get_gravity() * delta
player_movement.process_movement(max_speed * weapon_system.get_speed_modifier(),acceleration,0,delta)

View file

@ -1 +0,0 @@
uid://cq4i0afwesdm3

View file

@ -1,51 +0,0 @@
extends State
@export var max_speed: float = 5.0
@export var acceleration: float = 2.0
@export var deceleration: float = 200.0
@export var player: Player
@export var player_movement: PlayerMovement
@export var player_input: PlayerInput
@export var weapon_system: WeaponSystem
@export var audio: MultiplayerAudio3D
@export var step_delay: float
@export var step_speed_curve: Curve
var step_time: float
func enter() -> void:
player_input.jumped.connect(on_jumped)
player_input.crouch_begin.connect(begin_crouch)
player_input.walk_begin.connect(begin_walk)
func exit() -> void:
player_input.jumped.disconnect(on_jumped)
player_input.crouch_begin.disconnect(begin_crouch)
player_input.walk_begin.disconnect(begin_walk)
step_time = 0
func physics_update(delta: float) -> void:
if not is_multiplayer_authority():
return
if not player.is_on_floor():
transition.emit("Fall")
return
step_time += delta * step_speed_curve.sample((player.velocity * Vector3(1,0,1)).length_squared()/(max_speed*max_speed))
if step_time >= step_delay:
step_time = 0
audio.multiplayer_play()
player_movement.process_movement(max_speed * weapon_system.get_speed_modifier(),acceleration,deceleration,delta)
func on_jumped() -> void:
if player.is_on_floor():
player_movement.jump()
transition.emit("Fall")
func begin_walk() -> void:
transition.emit("Walk")
func begin_crouch() -> void:
transition.emit("Crouch")

View file

@ -1 +0,0 @@
uid://u0e2b2mvij1k

View file

@ -1,41 +0,0 @@
extends State
@export var max_speed: float = 2.5
@export var acceleration: float = 1.0
@export var deceleration: float = 100.0
@export var JUMP_VELOCITY: float = 4.5
@export var player: Player
@export var player_movement: PlayerMovement
@export var player_input: PlayerInput
@export var weapon_system: WeaponSystem
func enter() -> void:
player_input.crouch_begin.connect(begin_crouch)
player_input.walk_end.connect(end_walk)
player_input.jumped.connect(on_jumped)
func exit() -> void:
player_input.crouch_begin.disconnect(begin_crouch)
player_input.walk_end.disconnect(end_walk)
player_input.jumped.disconnect(on_jumped)
func physics_update(delta: float) -> void:
if not is_multiplayer_authority():
return
if not player.is_on_floor():
transition.emit("Fall")
return
player_movement.process_movement(max_speed * weapon_system.get_speed_modifier(),acceleration,deceleration,delta)
func on_jumped() -> void:
if player.is_on_floor():
player_movement.jump()
transition.emit("Fall")
func end_walk() -> void:
transition.emit("Stand")
func begin_crouch() -> void:
transition.emit("Crouch")

View file

@ -1 +0,0 @@
uid://cwasvwhm5yg0o

View file

@ -1,9 +0,0 @@
extends Node
@export var material: StandardMaterial3D
@export var player: Player
@export var blue_team_texture: Texture2D
func _ready() -> void:
if player.team == Session.TEAMS.DEFENCE:
material.albedo_texture = blue_team_texture

View file

@ -1 +0,0 @@
uid://b2djbdh05pbcn

View file

@ -1,14 +1,14 @@
extends Node
@export var starting_pistol: StringName
@export var starting_knife: StringName
@export var weapon_spawner: MultiplayerSpawner
@export var starting_pistol: PackedScene
@export var starting_knife: PackedScene
@export var weapon_system: WeaponSystem
func _ready() -> void:
deferred_ready.call_deferred()
func deferred_ready() -> void:
if is_multiplayer_authority():
weapon_spawner.spawn({"scene_file_path": starting_pistol})
weapon_spawner.spawn({"scene_file_path": starting_knife})
weapon_system.add(starting_pistol.instantiate(),"secondary")
weapon_system.add(starting_knife.instantiate(),"knife")
queue_free()

View file

@ -25,6 +25,7 @@ class_name WeaponSubStateMachine
remaining_ammo = 0
else:
remaining_ammo = value
ammo_updated.emit()
@export var speed_modifier: float = 1.0
@export var can_be_previous: bool = true
@ -52,6 +53,16 @@ func _ready() -> void:
child.machine = self
child.transition.connect(on_transition_required)
child.return_to_previous.connect(request_return.emit)
var parent = get_parent()
if parent is WeaponSystem:
system = parent
animation_player = system.animation_player
player_camera = system.camera
player = system.player
request_return.connect(system.return_to_previous)
ammo_depleted.connect(system.check_for_empty)
ammo_updated.connect(system.on_ammo_updated)
func enter() -> void:
super()

View file

@ -27,7 +27,6 @@ signal slots_updated(slots: Dictionary[StringName,WeaponSubStateMachine])
signal ammo_updated(ammo: int, remaining_ammo: int)
func _ready() -> void:
$WeaponSpawner.spawn_function = pick_up_weapon
player_input.drop.connect(drop_current)
player_input.fire_begin.connect(use_begin)
player_input.fire_end.connect(use_end)
@ -43,33 +42,32 @@ func get_speed_modifier() -> float:
func can_add(slot: StringName) -> bool:
return slots.has(slot) and slots[slot] == null
@rpc("call_local","reliable")
func add(state: WeaponSubStateMachine, slot: StringName,ignore_parent: bool = false) -> void:
func add(state: WeaponSubStateMachine, slot: StringName) -> void:
if not multiplayer.is_server():
return
if can_add(slot) == false:
return
if ignore_parent == false:
if state.get_parent() == null:
add_child(state, true)
if state.get_parent() != self:
state.get_parent().remove_child(state)
add_child(state,true)
state.ready.emit()
add_child(state, true)
slots[slot] = state
state.system = self
state.animation_player = animation_player
state.player_camera = camera
state.player = player
state.request_return.connect(return_to_previous)
state.ammo_depleted.connect(check_for_empty)
state.ammo_updated.connect(on_ammo_updated)
slots_updated.emit(slots)
if current_state == null:
current_state = state
ammo_updated.emit(current_state.ammo,current_state.remaining_ammo)
state.enter.call_deferred()
func process_spawned_weapon(weapon_node: Node):
var weapon = weapon_node as WeaponSubStateMachine
slots[weapon.slot] = weapon
slots_updated.emit(slots)
if current_state == null:
current_state = weapon
ammo_updated.emit(current_state.ammo,current_state.remaining_ammo)
func get_empty_ability_slot() -> StringName:
if slots["ability_first"] == null:
@ -133,32 +131,6 @@ func drop_slot(slot: StringName):
return
drop(slots[slot])
# Spawn function
# Data should be a dictionary with these keys:
# ammo
# remaining_ammo
# scene_file_path
func pick_up_weapon(data: Variant) -> Node:
if data.has("scene_file_path") == false:
return Node.new()
if data.has_all(["ammo","remaining_ammo"]):
var scene: WeaponSubStateMachine = load(data["scene_file_path"]).instantiate()
scene.ammo = data["ammo"]
scene.remaining_ammo = data["remaining_ammo"]
scene.slot = data["slot"]
scene.set_multiplayer_authority(get_multiplayer_authority())
add(scene,scene.slot,true)
return scene
else:
var scene: WeaponSubStateMachine = load(data["scene_file_path"]).instantiate()
scene.set_multiplayer_authority(get_multiplayer_authority())
add(scene,scene.slot,true)
return scene
func check_for_empty() -> void:
if is_multiplayer_authority() == false:
return
@ -167,7 +139,8 @@ func check_for_empty() -> void:
child.queue_free()
func on_ammo_updated() -> void:
ammo_updated.emit(current_state.ammo,current_state.remaining_ammo)
if current_state != null:
ammo_updated.emit(current_state.ammo,current_state.remaining_ammo)
func disable() -> void:
disabled = true