168 lines
4.4 KiB
GDScript
168 lines
4.4 KiB
GDScript
extends Node
|
|
|
|
class_name WeaponSystem
|
|
|
|
@export var default_pistol: WeaponSubStateMachine
|
|
@export var default_knife: WeaponSubStateMachine
|
|
|
|
@export var animation_player: AnimationPlayer
|
|
@export var camera: PlayerCamera
|
|
@export var player: Player
|
|
|
|
var current_state: WeaponSubStateMachine
|
|
var last_slot: StringName
|
|
|
|
var slots: Dictionary[StringName,WeaponSubStateMachine] = {
|
|
"primary": null,
|
|
"secondary": null,
|
|
"knife": null,
|
|
"bomb": null,
|
|
"ability_first": null,
|
|
"ability_second": null,
|
|
"ability_third": null,
|
|
"ultimate": null
|
|
}
|
|
|
|
signal switched_to(state: WeaponSubStateMachine)
|
|
|
|
func _ready() -> void:
|
|
current_state = default_pistol
|
|
add(default_pistol,"secondary")
|
|
add(default_knife,"knife")
|
|
current_state.enter()
|
|
$WeaponSpawner.spawn_function = pick_up_weapon
|
|
$WeaponSpawner.spawned.connect(on_weapon_added)
|
|
|
|
func can_add(slot: StringName) -> bool:
|
|
return slots.has(slot) and slots[slot] == null
|
|
|
|
@rpc("call_local","reliable")
|
|
func add(state: WeaponSubStateMachine, slot: StringName) -> void:
|
|
if can_add(slot) == false:
|
|
return
|
|
|
|
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()
|
|
|
|
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)
|
|
|
|
func switch(to: StringName):
|
|
if slots.has(to) == false or slots[to] == null or slots[to] == current_state or is_multiplayer_authority() == false:
|
|
return
|
|
current_state.exit()
|
|
if current_state.can_be_previous:
|
|
last_slot = slots.find_key(current_state)
|
|
else:
|
|
last_slot = ""
|
|
current_state = slots[to]
|
|
current_state.enter()
|
|
|
|
switched_to.emit(current_state)
|
|
|
|
update_remotes.rpc(to)
|
|
|
|
func drop():
|
|
if slots.find_key(current_state) == "knife":
|
|
return
|
|
var drop_data: Dictionary = {}
|
|
drop_data.scene = current_state.droppable
|
|
drop_data.ammo = current_state.ammo
|
|
drop_data.remaining_ammo = current_state.remaining_ammo
|
|
drop_data.slot = current_state.slot
|
|
drop_data.position = camera.global_position
|
|
drop_data.impulse = -camera.global_basis.z * 10
|
|
|
|
Session.spawn(drop_data)
|
|
|
|
$"../PickupRange".start_temp_ignore()
|
|
|
|
Session.despawn(current_state.get_path())
|
|
return_to_previous()
|
|
|
|
# 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("ammo") == false or data.has("remaining_ammo") == false or data.has("scene_file_path") == false or data.has("slot") == false:
|
|
return null
|
|
var scene: WeaponSubStateMachine = load(data["scene_file_path"]).instantiate()
|
|
scene.ammo = data["ammo"]
|
|
scene.remaining_ammo = data["remaining_ammo"]
|
|
scene.slot = data["slot"]
|
|
return scene
|
|
|
|
func on_weapon_added(weapon: Node):
|
|
add(weapon,weapon.slot)
|
|
|
|
func return_to_previous():
|
|
if last_slot != "":
|
|
switch(last_slot)
|
|
else:
|
|
switch("knife")
|
|
|
|
@rpc("authority","call_remote","reliable")
|
|
func update_remotes(to: StringName):
|
|
current_state.exit()
|
|
current_state = slots[to]
|
|
current_state.enter()
|
|
|
|
switched_to.emit(current_state)
|
|
|
|
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)
|
|
|
|
func _input(event: InputEvent) -> void:
|
|
if is_multiplayer_authority() == false: return
|
|
|
|
if current_state != null:
|
|
current_state.state_input(event)
|
|
|
|
if event.is_action_pressed("plr_ult"):
|
|
switch("ultimate")
|
|
elif event.is_action_pressed("plr_bomb"):
|
|
switch("bomb")
|
|
elif event.is_action_pressed("plr_primary"):
|
|
switch("primary")
|
|
elif event.is_action_pressed("plr_active_first"):
|
|
switch("ability_first")
|
|
elif event.is_action_pressed("plr_active_second"):
|
|
switch("ability_second")
|
|
elif event.is_action_pressed("plr_active_third"):
|
|
switch("ability_third")
|
|
elif event.is_action_pressed("plr_secondary"):
|
|
switch("secondary")
|
|
elif event.is_action_pressed("plr_knife"):
|
|
switch("knife")
|
|
|
|
if event.is_action_pressed("plr_fire"):
|
|
current_state.use_begin.rpc()
|
|
if event.is_action_released("plr_fire"):
|
|
current_state.use_end.rpc()
|
|
if event.is_action_pressed("plr_scope"):
|
|
current_state.alternate_state()
|
|
if event.is_action_pressed("plr_firemode"):
|
|
current_state.switch_mode()
|
|
|
|
if event.is_action_pressed("plr_drop"):
|
|
drop()
|
|
|