Global refactor
This commit is contained in:
parent
3868af29e3
commit
0589ca4e23
180 changed files with 249 additions and 401 deletions
11
systems/debug/inventory_preview.gd
Normal file
11
systems/debug/inventory_preview.gd
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
extends Label
|
||||
|
||||
|
||||
@export var inventory: WeaponSystem
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
var weapons = ""
|
||||
for child in inventory.get_children():
|
||||
if child is WeaponSubStateMachine:
|
||||
weapons += child.name + ", "
|
||||
text = weapons
|
||||
1
systems/debug/inventory_preview.gd.uid
Normal file
1
systems/debug/inventory_preview.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://dmy6ahci16los
|
||||
21
systems/debug/property_shower.gd
Normal file
21
systems/debug/property_shower.gd
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
extends VBoxContainer
|
||||
|
||||
@export var property_array: Dictionary[NodePath,StringName]
|
||||
|
||||
func _ready() -> void:
|
||||
for target in property_array.keys():
|
||||
var hbox = HBoxContainer.new()
|
||||
var name_label = Label.new()
|
||||
var splitted = property_array[target].split(":")
|
||||
name_label.text = splitted[len(splitted)-1]
|
||||
name_label.name = "Name"
|
||||
var value_label = Label.new()
|
||||
value_label.name = "Value"
|
||||
hbox.add_child(name_label,true)
|
||||
hbox.add_child(value_label,true)
|
||||
hbox.name = str(target).replace("/","_").replace(".","")
|
||||
add_child(hbox,true)
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
for target in property_array:
|
||||
get_node(str(target).replace("/","_").replace(".","")+"/Value").text = str(get_node(target).get(property_array[target]))
|
||||
1
systems/debug/property_shower.gd.uid
Normal file
1
systems/debug/property_shower.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://7gmgcaxfh8sb
|
||||
30
systems/interaction_system/interactible.gd
Normal file
30
systems/interaction_system/interactible.gd
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
extends CharacterBody3D
|
||||
|
||||
class_name Interactible
|
||||
|
||||
signal interacted(with: int)
|
||||
signal stopped_interacting(with: int)
|
||||
|
||||
var interacted_id: int = -1
|
||||
|
||||
func _ready() -> void:
|
||||
if not multiplayer.is_server():
|
||||
return
|
||||
Session.player_stopped_interacting.connect(player_stopped_interacting)
|
||||
|
||||
func interaction_start(player_id: int):
|
||||
if not multiplayer.is_server():
|
||||
return
|
||||
interacted.emit(player_id)
|
||||
|
||||
interacted_id = player_id
|
||||
|
||||
func player_stopped_interacting(id: int):
|
||||
if interacted_id == id:
|
||||
interaction_end()
|
||||
|
||||
func interaction_end():
|
||||
if not multiplayer.is_server():
|
||||
return
|
||||
stopped_interacting.emit(interacted_id)
|
||||
interacted_id = -1
|
||||
1
systems/interaction_system/interactible.gd.uid
Normal file
1
systems/interaction_system/interactible.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://d1c4u4aul8oc1
|
||||
13
systems/item_spawner.gd
Normal file
13
systems/item_spawner.gd
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
extends Node3D
|
||||
|
||||
@export var item: PackedScene
|
||||
|
||||
func _ready() -> void:
|
||||
if multiplayer.is_server():
|
||||
Session.round_started.connect(spawn)
|
||||
|
||||
func spawn():
|
||||
if multiplayer.is_server():
|
||||
var node = item.instantiate()
|
||||
add_sibling(node,true)
|
||||
node.global_position = global_position
|
||||
1
systems/item_spawner.gd.uid
Normal file
1
systems/item_spawner.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://dncldab5y4yod
|
||||
16
systems/object_container.gd
Normal file
16
systems/object_container.gd
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
extends Node
|
||||
|
||||
class_name ObjectContainer
|
||||
|
||||
@export var exlusion_list: Array[Node]
|
||||
|
||||
func _ready() -> void:
|
||||
if not multiplayer.is_server(): return
|
||||
Session.object_containers.append(self)
|
||||
|
||||
func despawn():
|
||||
if not multiplayer.is_server(): return
|
||||
for child in get_children():
|
||||
if exlusion_list.has(child):
|
||||
continue
|
||||
child.queue_free()
|
||||
1
systems/object_container.gd.uid
Normal file
1
systems/object_container.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://3i00rp8urth7
|
||||
16
systems/player/collision_team_updater.gd
Normal file
16
systems/player/collision_team_updater.gd
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
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
|
||||
1
systems/player/collision_team_updater.gd.uid
Normal file
1
systems/player/collision_team_updater.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://5gwpjiswnegn
|
||||
35
systems/player/dead_player_spectator.gd
Normal file
35
systems/player/dead_player_spectator.gd
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
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)
|
||||
1
systems/player/dead_player_spectator.gd.uid
Normal file
1
systems/player/dead_player_spectator.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bl8gfrrc512q2
|
||||
60
systems/player/player.gd
Normal file
60
systems/player/player.gd
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
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
|
||||
1
systems/player/player.gd.uid
Normal file
1
systems/player/player.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://3dphlay25fih
|
||||
59
systems/player/player_camera.gd
Normal file
59
systems/player/player_camera.gd
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
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
|
||||
1
systems/player/player_camera.gd.uid
Normal file
1
systems/player/player_camera.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bjhbdh6xsjgnn
|
||||
4
systems/player/player_global.gd
Normal file
4
systems/player/player_global.gd
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
extends Node
|
||||
|
||||
|
||||
var player: CharacterBody3D
|
||||
1
systems/player/player_global.gd.uid
Normal file
1
systems/player/player_global.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://dv3pm11t6p4si
|
||||
182
systems/player/player_input.gd
Normal file
182
systems/player/player_input.gd
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
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()
|
||||
1
systems/player/player_input.gd.uid
Normal file
1
systems/player/player_input.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://dfvnx8f1v6m5g
|
||||
8
systems/player/player_interaction.gd
Normal file
8
systems/player/player_interaction.gd
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
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)
|
||||
1
systems/player/player_interaction.gd.uid
Normal file
1
systems/player/player_interaction.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://dsp1sq46c5i3y
|
||||
31
systems/player/player_movement.gd
Normal file
31
systems/player/player_movement.gd
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
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
|
||||
1
systems/player/player_movement.gd.uid
Normal file
1
systems/player/player_movement.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bs4y647h5rdfr
|
||||
43
systems/player/player_pickup.gd
Normal file
43
systems/player/player_pickup.gd
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
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
|
||||
1
systems/player/player_pickup.gd.uid
Normal file
1
systems/player/player_pickup.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://xsgfbuyje35p
|
||||
12
systems/player/player_raycast.gd
Normal file
12
systems/player/player_raycast.gd
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
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
|
||||
1
systems/player/player_raycast.gd.uid
Normal file
1
systems/player/player_raycast.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://6c14qse4vnra
|
||||
37
systems/player/spectator.gd
Normal file
37
systems/player/spectator.gd
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
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
|
||||
1
systems/player/spectator.gd.uid
Normal file
1
systems/player/spectator.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://cikw7fcykkpd5
|
||||
36
systems/player/states/crouching.gd
Normal file
36
systems/player/states/crouching.gd
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
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")
|
||||
1
systems/player/states/crouching.gd.uid
Normal file
1
systems/player/states/crouching.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bv8sgx78s8hwn
|
||||
12
systems/player/states/death.gd
Normal file
12
systems/player/states/death.gd
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
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
|
||||
1
systems/player/states/death.gd.uid
Normal file
1
systems/player/states/death.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://tb140f8fweug
|
||||
32
systems/player/states/falling.gd
Normal file
32
systems/player/states/falling.gd
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
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)
|
||||
1
systems/player/states/falling.gd.uid
Normal file
1
systems/player/states/falling.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://cq4i0afwesdm3
|
||||
51
systems/player/states/standing.gd
Normal file
51
systems/player/states/standing.gd
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
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")
|
||||
1
systems/player/states/standing.gd.uid
Normal file
1
systems/player/states/standing.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://u0e2b2mvij1k
|
||||
41
systems/player/states/walk.gd
Normal file
41
systems/player/states/walk.gd
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
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")
|
||||
1
systems/player/states/walk.gd.uid
Normal file
1
systems/player/states/walk.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://cwasvwhm5yg0o
|
||||
9
systems/player/team_color_switcher.gd
Normal file
9
systems/player/team_color_switcher.gd
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
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
|
||||
1
systems/player/team_color_switcher.gd.uid
Normal file
1
systems/player/team_color_switcher.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://b2djbdh05pbcn
|
||||
8
systems/registry.gd
Normal file
8
systems/registry.gd
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
extends Node
|
||||
|
||||
var weapons: Dictionary[StringName,WeaponResource]
|
||||
|
||||
func _ready() -> void:
|
||||
for file in ResourceLoader.list_directory("res://weapons/"):
|
||||
if file.ends_with(".tres"):
|
||||
weapons[file.trim_suffix(".tres")] = load("res://weapons/"+ file)
|
||||
1
systems/registry.gd.uid
Normal file
1
systems/registry.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://csoswr6rx8fx6
|
||||
60
systems/state_machine/machine.gd
Normal file
60
systems/state_machine/machine.gd
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
extends Node
|
||||
|
||||
class_name StateMachine
|
||||
|
||||
@export var current_state: State
|
||||
var states: Dictionary[StringName,State] = {}
|
||||
|
||||
func _ready() -> void:
|
||||
for child in get_children():
|
||||
if child is State:
|
||||
states[child.name] = child
|
||||
child.transition.connect(on_transition_required)
|
||||
|
||||
else:
|
||||
push_warning("Child of state machine is not state")
|
||||
current_state.enter()
|
||||
|
||||
func on_transition_required(to: StringName):
|
||||
if is_multiplayer_authority() == false:
|
||||
return
|
||||
if states.has(to) == false:
|
||||
push_warning("Incorrect state request: " + to)
|
||||
return
|
||||
|
||||
change_state(states[to])
|
||||
change_state_to_name.rpc(to)
|
||||
|
||||
func change_state(to_state: State) -> void:
|
||||
if current_state != null:
|
||||
current_state.exit()
|
||||
current_state = to_state
|
||||
current_state.enter()
|
||||
|
||||
@rpc("authority","call_local","reliable")
|
||||
func change_state_to_name(to_name: StringName):
|
||||
if current_state != null:
|
||||
current_state.exit()
|
||||
current_state = states[to_name]
|
||||
current_state.enter()
|
||||
|
||||
@rpc("authority","call_local","unreliable")
|
||||
func clear_state():
|
||||
if current_state == null:
|
||||
return
|
||||
current_state.exit()
|
||||
current_state = null
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if current_state == null:
|
||||
return
|
||||
current_state.update(delta)
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if current_state != null:
|
||||
current_state.state_input(event)
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if current_state == null:
|
||||
return
|
||||
current_state.physics_update(delta)
|
||||
1
systems/state_machine/machine.gd.uid
Normal file
1
systems/state_machine/machine.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://3777rkbebgjm
|
||||
17
systems/state_machine/state.gd
Normal file
17
systems/state_machine/state.gd
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
@abstract
|
||||
extends Node
|
||||
|
||||
class_name State
|
||||
|
||||
@warning_ignore_start("unused_signal","unused_parameter")
|
||||
|
||||
signal transition(to: StringName)
|
||||
|
||||
@abstract func enter() -> void
|
||||
@abstract func exit() -> void
|
||||
func update(delta: float) -> void:
|
||||
pass
|
||||
func physics_update(delta: float) -> void:
|
||||
pass
|
||||
func state_input(event: InputEvent) -> void:
|
||||
pass
|
||||
1
systems/state_machine/state.gd.uid
Normal file
1
systems/state_machine/state.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://cmsphnymgquwq
|
||||
35
systems/state_machine/substate_machine.gd
Normal file
35
systems/state_machine/substate_machine.gd
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
extends StateMachine
|
||||
|
||||
class_name SubStateMachine
|
||||
|
||||
@export var enter_state: State
|
||||
|
||||
func enter() -> void:
|
||||
change_state(enter_state)
|
||||
|
||||
func exit() -> void:
|
||||
if is_multiplayer_authority():
|
||||
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
|
||||
|
||||
func _input(_event: InputEvent) -> void:
|
||||
pass
|
||||
|
||||
func state_input(event: InputEvent) -> void:
|
||||
if current_state != null:
|
||||
current_state.state_input(event)
|
||||
1
systems/state_machine/substate_machine.gd.uid
Normal file
1
systems/state_machine/substate_machine.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://btc5vyvccdqfp
|
||||
9
systems/weapon_system/dropped_weapon.gd
Normal file
9
systems/weapon_system/dropped_weapon.gd
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
extends RigidBody3D
|
||||
|
||||
class_name DroppableWeapon
|
||||
|
||||
const IMPULSE = 10
|
||||
|
||||
@export var slot: StringName
|
||||
@export var weapon: WeaponSubStateMachine
|
||||
@export var team: Session.TEAMS
|
||||
1
systems/weapon_system/dropped_weapon.gd.uid
Normal file
1
systems/weapon_system/dropped_weapon.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://cskgqgkr7pmb0
|
||||
14
systems/weapon_system/starting_weapon_spawner.gd
Normal file
14
systems/weapon_system/starting_weapon_spawner.gd
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
extends Node
|
||||
|
||||
@export var starting_pistol: StringName
|
||||
@export var starting_knife: StringName
|
||||
@export var weapon_spawner: MultiplayerSpawner
|
||||
|
||||
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})
|
||||
queue_free()
|
||||
1
systems/weapon_system/starting_weapon_spawner.gd.uid
Normal file
1
systems/weapon_system/starting_weapon_spawner.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://doevvmbvhlig8
|
||||
9
systems/weapon_system/weapon_resource.gd
Normal file
9
systems/weapon_system/weapon_resource.gd
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
extends Resource
|
||||
|
||||
class_name WeaponResource
|
||||
|
||||
@export var cost: int
|
||||
@export var preview: Texture2D
|
||||
@export var dropped_scene: PackedScene
|
||||
@export var weapon_system_scene: PackedScene
|
||||
@export var slot: StringName
|
||||
1
systems/weapon_system/weapon_resource.gd.uid
Normal file
1
systems/weapon_system/weapon_resource.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bvnn2eiwqbu7t
|
||||
20
systems/weapon_system/weapon_state.gd
Normal file
20
systems/weapon_system/weapon_state.gd
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
@abstract
|
||||
extends State
|
||||
|
||||
class_name WeaponState
|
||||
|
||||
@warning_ignore("unused_signal")
|
||||
signal return_to_previous
|
||||
|
||||
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
|
||||
1
systems/weapon_system/weapon_state.gd.uid
Normal file
1
systems/weapon_system/weapon_state.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://fd4tm5wexdk
|
||||
80
systems/weapon_system/weapon_substate_machine.gd
Normal file
80
systems/weapon_system/weapon_substate_machine.gd
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
extends SubStateMachine
|
||||
|
||||
class_name WeaponSubStateMachine
|
||||
|
||||
@export var animation_prefix: StringName
|
||||
@export var registry_entry: StringName
|
||||
@export var visibility_target: StringName
|
||||
|
||||
@export var max_ammo: int
|
||||
@export var ammo: int = -1:
|
||||
set(value):
|
||||
if value < 0:
|
||||
ammo = 0
|
||||
else:
|
||||
ammo = value
|
||||
ammo_updated.emit()
|
||||
if ammo <= 0 and remaining_ammo <= 0:
|
||||
ammo_depleted.emit()
|
||||
get:
|
||||
return ammo
|
||||
@export var ammo_mags: int = 3
|
||||
@export var remaining_ammo: int = -1:
|
||||
set(value):
|
||||
if value < 0:
|
||||
remaining_ammo = 0
|
||||
else:
|
||||
remaining_ammo = value
|
||||
|
||||
@export var speed_modifier: float = 1.0
|
||||
@export var can_be_previous: bool = true
|
||||
@export var destroy_when_empty: bool = false
|
||||
|
||||
@export var slot: StringName
|
||||
|
||||
signal request_return
|
||||
signal ammo_updated
|
||||
signal ammo_depleted
|
||||
|
||||
var system: WeaponSystem
|
||||
var animation_player: AnimationPlayer
|
||||
var player_camera: PlayerCamera
|
||||
var player: Player
|
||||
|
||||
func _ready() -> void:
|
||||
if remaining_ammo == -1:
|
||||
remaining_ammo = max_ammo * ammo_mags
|
||||
if ammo == -1:
|
||||
ammo = max_ammo
|
||||
for child in get_children():
|
||||
if child is WeaponState:
|
||||
states[child.name] = child
|
||||
child.machine = self
|
||||
child.transition.connect(on_transition_required)
|
||||
child.return_to_previous.connect(request_return.emit)
|
||||
|
||||
func enter() -> void:
|
||||
super()
|
||||
player.weapon_models[visibility_target].show()
|
||||
|
||||
func exit() -> void:
|
||||
super()
|
||||
player.weapon_models[visibility_target].hide()
|
||||
|
||||
@rpc("authority","call_local","reliable")
|
||||
func use_begin() -> void:
|
||||
if current_state != null:
|
||||
current_state.use_begin()
|
||||
|
||||
@rpc("authority","call_local","reliable")
|
||||
func use_end() -> void:
|
||||
if current_state != null:
|
||||
current_state.use_end()
|
||||
func alternate_state() -> void:
|
||||
if current_state != null:
|
||||
current_state.alternate_state()
|
||||
# Need to clarify naming; Switch mode like firemode. For different states use
|
||||
# alternate_state
|
||||
func switch_mode() -> void:
|
||||
if current_state != null:
|
||||
current_state.switch_mode()
|
||||
1
systems/weapon_system/weapon_substate_machine.gd.uid
Normal file
1
systems/weapon_system/weapon_substate_machine.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://e6lqknfl4ngt
|
||||
186
systems/weapon_system/weapon_system.gd
Normal file
186
systems/weapon_system/weapon_system.gd
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
extends Node
|
||||
|
||||
class_name WeaponSystem
|
||||
|
||||
@export var animation_player: AnimationPlayer
|
||||
@export var camera: PlayerCamera
|
||||
@export var player: Player
|
||||
@export var player_input: PlayerInput
|
||||
|
||||
var current_state: WeaponSubStateMachine
|
||||
var last_slot: StringName
|
||||
var disabled: bool
|
||||
|
||||
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)
|
||||
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)
|
||||
player_input.switch_weapon.connect(switch)
|
||||
player_input.alternate_state.connect(alternate_state)
|
||||
player_input.switch_firemode.connect(switch_mode)
|
||||
|
||||
func get_speed_modifier() -> float:
|
||||
if current_state == null:
|
||||
return 1
|
||||
return current_state.speed_modifier
|
||||
|
||||
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:
|
||||
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()
|
||||
|
||||
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()
|
||||
|
||||
@rpc("authority","call_remote","reliable")
|
||||
func switch(to: StringName, exit: bool = true):
|
||||
if slots.has(to) == false or slots[to] == null or slots[to] == current_state or (multiplayer.get_remote_sender_id() != 1 and is_multiplayer_authority() == false):
|
||||
return
|
||||
if current_state != null and exit:
|
||||
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()
|
||||
|
||||
ammo_updated.emit(current_state.ammo,current_state.remaining_ammo)
|
||||
switched_to.emit(current_state)
|
||||
if is_multiplayer_authority():
|
||||
switch.rpc(to,exit)
|
||||
|
||||
func return_to_previous(exit: bool = true):
|
||||
if last_slot != "":
|
||||
switch(last_slot, exit)
|
||||
else:
|
||||
switch("knife", exit)
|
||||
|
||||
func drop_current():
|
||||
drop(current_state)
|
||||
|
||||
func drop(weapon: WeaponSubStateMachine) -> void:
|
||||
if not is_multiplayer_authority():
|
||||
return
|
||||
if slots.find_key(weapon) == "knife":
|
||||
return
|
||||
|
||||
var dropped_weapon: DroppableWeapon = Registry.weapons[weapon.registry_entry].dropped_scene.instantiate()
|
||||
dropped_weapon.weapon.ammo = weapon.ammo
|
||||
dropped_weapon.weapon.remaining_ammo = weapon.remaining_ammo
|
||||
dropped_weapon.weapon.slot = weapon.slot
|
||||
Session.dynamic_objects_parent.add_child(dropped_weapon)
|
||||
dropped_weapon.global_position = camera.global_position
|
||||
dropped_weapon.apply_central_impulse(-camera.global_basis.z * 10 + player.velocity)
|
||||
|
||||
$"../PickupRange".start_temp_ignore()
|
||||
|
||||
slots[slots.find_key(weapon)] = null
|
||||
slots_updated.emit(slots)
|
||||
weapon.queue_free()
|
||||
return_to_previous(false)
|
||||
|
||||
func drop_slot(slot: StringName):
|
||||
if slots.has(slot) == false or slots[slot] == null:
|
||||
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
|
||||
for child in get_children():
|
||||
if child is WeaponSubStateMachine and child.ammo == 0 and child.remaining_ammo == 0 and child.destroy_when_empty:
|
||||
child.queue_free()
|
||||
|
||||
func on_ammo_updated() -> void:
|
||||
ammo_updated.emit(current_state.ammo,current_state.remaining_ammo)
|
||||
|
||||
func disable() -> void:
|
||||
disabled = true
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if current_state == null or disabled:
|
||||
return
|
||||
current_state.update(delta)
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if current_state == null or disabled:
|
||||
return
|
||||
current_state.physics_update(delta)
|
||||
|
||||
func use_begin() -> void:
|
||||
current_state.use_begin.rpc()
|
||||
|
||||
func use_end() -> void:
|
||||
current_state.use_end.rpc()
|
||||
|
||||
func alternate_state() -> void:
|
||||
current_state.alternate_state()
|
||||
|
||||
func switch_mode() -> void:
|
||||
current_state.switch_mode()
|
||||
1
systems/weapon_system/weapon_system.gd.uid
Normal file
1
systems/weapon_system/weapon_system.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bmecgup3kcua7
|
||||
Loading…
Add table
Add a link
Reference in a new issue