Merge branch 'multiplayer-rework'
This commit is contained in:
commit
2c9ef1cfe1
38 changed files with 535 additions and 288 deletions
|
|
@ -2,3 +2,6 @@ extends Node
|
|||
|
||||
|
||||
var SENSITIVITY: float = 0.02
|
||||
var TOGGLE_CROUCH: bool = false
|
||||
var TOGGLE_SCOPE: bool = false
|
||||
var TOGGLE_WALK: bool = false
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
extends Control
|
||||
|
||||
var cached_mouse_state: Input.MouseMode
|
||||
|
||||
func _on_check_button_toggled(toggled_on: bool) -> void:
|
||||
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN if toggled_on else DisplayServer.WINDOW_MODE_WINDOWED)
|
||||
|
|
@ -17,7 +18,11 @@ func _on_spin_box_value_changed(value: float) -> void:
|
|||
func _input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("menu_settings"):
|
||||
visible = not visible
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE if visible else Input.MOUSE_MODE_CAPTURED
|
||||
if visible:
|
||||
cached_mouse_state = Input.mouse_mode
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
else:
|
||||
Input.mouse_mode = cached_mouse_state
|
||||
|
||||
|
||||
func _on_gameplay_main_slider_value_changed(value: float) -> void:
|
||||
|
|
|
|||
|
|
@ -78,6 +78,20 @@ func set_teams(attack: Array[int],defence: Array[int],spectators: Array[int]):
|
|||
func switch_team(team: int) -> void:
|
||||
team_switch_notification.rpc(multiplayer.get_unique_id(),team)
|
||||
|
||||
func swap_teams() -> void:
|
||||
if not multiplayer.is_server():
|
||||
return
|
||||
|
||||
var temp_defenders = defence_team.duplicate()
|
||||
|
||||
for attacker in attack_team:
|
||||
server_team_switch.rpc(attacker,Session.TEAMS.DEFENCE)
|
||||
|
||||
for defender in temp_defenders:
|
||||
server_team_switch.rpc(defender,Session.TEAMS.ATTACK)
|
||||
|
||||
update_peers.rpc()
|
||||
|
||||
@rpc("any_peer","call_local","reliable")
|
||||
func team_switch_notification(id: int, team: int) -> void:
|
||||
if (team == Session.TEAMS.DEFENCE and len(defence_team) > 4) or (team == Session.TEAMS.ATTACK and len(attack_team) > 4):
|
||||
|
|
@ -105,6 +119,32 @@ func team_switch_notification(id: int, team: int) -> void:
|
|||
|
||||
update_teams_state.emit()
|
||||
|
||||
@rpc("authority","call_local","reliable")
|
||||
func server_team_switch(id: int, team: int) -> void:
|
||||
if multiplayer.get_remote_sender_id() != 1 and not multiplayer.is_server():
|
||||
return
|
||||
|
||||
if team == Session.TEAMS.DEFENCE:
|
||||
if attack_team.has(id):
|
||||
attack_team.erase(id)
|
||||
if specators_team.has(id):
|
||||
specators_team.erase(id)
|
||||
defence_team.append(id)
|
||||
|
||||
if team == Session.TEAMS.ATTACK:
|
||||
if defence_team.has(id):
|
||||
defence_team.erase(id)
|
||||
if specators_team.has(id):
|
||||
specators_team.erase(id)
|
||||
attack_team.append(id)
|
||||
|
||||
if team == Session.TEAMS.SPECTATE:
|
||||
if attack_team.has(id):
|
||||
attack_team.erase(id)
|
||||
elif defence_team.has(id):
|
||||
defence_team.erase(id)
|
||||
specators_team.append(id)
|
||||
|
||||
@rpc("authority","call_local","reliable")
|
||||
func start_game() -> void:
|
||||
get_tree().change_scene_to_file("res://levels/prototype_scene.tscn")
|
||||
|
|
@ -121,3 +161,7 @@ func get_team() -> Session.TEAMS:
|
|||
if specators_team.has(id):
|
||||
return Session.TEAMS.SPECTATE
|
||||
return Session.TEAMS.UNASSIGNED
|
||||
|
||||
@rpc("authority","call_local","reliable")
|
||||
func update_peers():
|
||||
update_teams_state.emit()
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
extends Node
|
||||
|
||||
class_name PlayerBasedVisibility
|
||||
|
||||
@export var visible_for_others: bool = false
|
||||
@export var reference_player: Player
|
||||
|
||||
func _ready() -> void:
|
||||
get_parent().visible = (get_multiplayer_authority() != multiplayer.get_unique_id()) == visible_for_others
|
||||
get_parent().visible = (reference_player.player_id != multiplayer.get_unique_id()) == visible_for_others
|
||||
|
||||
func reverse() -> void:
|
||||
get_parent().visible = not get_parent().visible
|
||||
|
|
|
|||
182
scripts/multiplayer/player_input.gd
Normal file
182
scripts/multiplayer/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 _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
scripts/multiplayer/player_input.gd.uid
Normal file
1
scripts/multiplayer/player_input.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://dfvnx8f1v6m5g
|
||||
|
|
@ -86,7 +86,7 @@ func _process(_delta: float) -> void:
|
|||
func update_clock(time: float):
|
||||
reference_round_time = time
|
||||
|
||||
@rpc("any_peer","call_remote","reliable")
|
||||
@rpc("authority","call_remote","reliable")
|
||||
func start_session() -> void:
|
||||
if not is_server_request():
|
||||
return
|
||||
|
|
@ -100,7 +100,7 @@ func start_session() -> void:
|
|||
|
||||
start_round()
|
||||
|
||||
@rpc("any_peer","call_remote","reliable")
|
||||
@rpc("authority","call_remote","reliable")
|
||||
func end_session() -> void:
|
||||
if not is_server_request():
|
||||
return
|
||||
|
|
@ -114,7 +114,7 @@ func end_session() -> void:
|
|||
|
||||
session_started = false
|
||||
|
||||
@rpc("any_peer","call_remote","reliable")
|
||||
@rpc("authority","call_remote","reliable")
|
||||
func start_round() -> void:
|
||||
if not is_server_request():
|
||||
return
|
||||
|
|
@ -134,23 +134,26 @@ func start_round() -> void:
|
|||
round_state = ROUND_STATES.BUY
|
||||
round_state_changed.emit.call_deferred(round_state)
|
||||
|
||||
@rpc("any_peer","call_remote","reliable")
|
||||
@rpc("authority","call_remote","reliable")
|
||||
func end_round(win_team: int) -> void:
|
||||
if not is_server_request():
|
||||
return
|
||||
if multiplayer.is_server():
|
||||
get_tree().create_timer(5).timeout.connect(start_round)
|
||||
end_round.rpc(win_team)
|
||||
if current_round == Lobby.half_rounds:
|
||||
Lobby.swap_teams()
|
||||
|
||||
if win_team == TEAMS.DEFENCE:
|
||||
defender_score += 1
|
||||
elif win_team == TEAMS.ATTACK:
|
||||
attacker_score += 1
|
||||
|
||||
|
||||
round_state = ROUND_STATES.AFTER_ROUND
|
||||
round_state_changed.emit(round_state)
|
||||
|
||||
@rpc("any_peer","call_remote","reliable")
|
||||
@rpc("authority","call_remote","reliable")
|
||||
func begin_main_stage() -> void:
|
||||
if not is_server_request():
|
||||
return
|
||||
|
|
@ -161,7 +164,7 @@ func begin_main_stage() -> void:
|
|||
round_state = ROUND_STATES.ROUND
|
||||
round_state_changed.emit(round_state)
|
||||
|
||||
@rpc("any_peer","call_remote","reliable")
|
||||
@rpc("authority","call_remote","reliable")
|
||||
func begin_bomb_stage() -> void:
|
||||
if not is_server_request():
|
||||
return
|
||||
|
|
@ -179,7 +182,6 @@ func defuse_win() -> void:
|
|||
bomb_timer.stop()
|
||||
end_round(TEAMS.DEFENCE)
|
||||
|
||||
@rpc("any_peer","call_local","reliable")
|
||||
func add_dead(team: int):
|
||||
if multiplayer.is_server() == false:
|
||||
return
|
||||
|
|
@ -204,12 +206,7 @@ func is_server_request() -> bool:
|
|||
## ammo, remaining_ammo, slot - data for dropped weapon [br]
|
||||
## for more, see dyn_objects_spawner.gd
|
||||
func spawn(data: Dictionary) -> void:
|
||||
spawn_internal.rpc_id(1,data)
|
||||
|
||||
@rpc("any_peer","call_local","reliable")
|
||||
func spawn_internal(data: Dictionary) -> void:
|
||||
if multiplayer.is_server() == false:
|
||||
printerr(str(multiplayer.get_remote_sender_id())+" tried to spawn internally on "+str(multiplayer.get_unique_id()))
|
||||
return
|
||||
|
||||
var object = dynamic_objects_spawner.spawn(data)
|
||||
|
|
@ -217,25 +214,14 @@ func spawn_internal(data: Dictionary) -> void:
|
|||
if data.has("position"):
|
||||
object.global_position = data.position
|
||||
|
||||
func despawn(path: NodePath):
|
||||
despawn_internal.rpc_id(1,path)
|
||||
|
||||
@rpc("any_peer","call_local","reliable")
|
||||
func despawn_internal(path: NodePath) -> void:
|
||||
func despawn(path: NodePath) -> void:
|
||||
if multiplayer.is_server() == false:
|
||||
printerr(str(multiplayer.get_remote_sender_id())+" tried to despawn internally on "+str(multiplayer.get_unique_id()))
|
||||
return
|
||||
|
||||
get_node(path).queue_free()
|
||||
|
||||
func shoot(damage: int,distance: float = 100) -> void:
|
||||
if multiplayer.get_unique_id() == 1:
|
||||
shoot_internal(1,damage,distance)
|
||||
else:
|
||||
shoot_internal.rpc_id(1,multiplayer.get_unique_id(),damage,distance)
|
||||
|
||||
@rpc("any_peer","call_local","reliable")
|
||||
func shoot_internal(id:int , damage: int, distance: float) -> void:
|
||||
func shoot(id:int , damage: int, distance: float) -> void:
|
||||
if multiplayer.is_server() == false:
|
||||
return
|
||||
|
||||
|
|
@ -258,16 +244,10 @@ func shoot_internal(id:int , damage: int, distance: float) -> void:
|
|||
var collision = space.intersect_ray(ray)
|
||||
|
||||
if collision != {} and collision["collider"] is Player:
|
||||
collision["collider"].take_damage.rpc_id(int(collision["collider"].name),damage)
|
||||
collision["collider"].take_damage(damage)
|
||||
|
||||
func interact() -> void:
|
||||
if multiplayer.get_unique_id() == 1:
|
||||
interact_internal(1)
|
||||
else:
|
||||
interact_internal.rpc_id(1,multiplayer.get_unique_id())
|
||||
|
||||
@rpc("any_peer","call_local","reliable")
|
||||
func interact_internal(id:int) -> void:
|
||||
func interact(id: int) -> void:
|
||||
if multiplayer.is_server() == false:
|
||||
return
|
||||
|
||||
|
|
@ -285,27 +265,20 @@ func interact_internal(id:int) -> void:
|
|||
if collision != {} and collision["collider"] is Interactible:
|
||||
collision["collider"].interaction_start(id)
|
||||
|
||||
func stop_interact():
|
||||
if multiplayer.get_unique_id() == 1:
|
||||
stop_interact_internal(1)
|
||||
else:
|
||||
stop_interact_internal.rpc_id(1,multiplayer.get_unique_id())
|
||||
|
||||
@rpc("any_peer","call_local","reliable")
|
||||
func stop_interact_internal(id: int) -> void:
|
||||
func stop_interact(id: int) -> void:
|
||||
if multiplayer.is_server() == false:
|
||||
return
|
||||
player_stopped_interacting.emit(id)
|
||||
|
||||
func is_on_site() -> bool:
|
||||
func is_on_site(id: int) -> bool:
|
||||
for plant in plants:
|
||||
if plant.is_player_on_site(multiplayer.get_unique_id()):
|
||||
if plant.is_player_on_site(id):
|
||||
return true
|
||||
return false
|
||||
|
||||
func get_site() -> PlantSite:
|
||||
func get_site(id: int) -> PlantSite:
|
||||
for plant in plants:
|
||||
if plant.is_player_on_site(multiplayer.get_unique_id()):
|
||||
if plant.is_player_on_site(id):
|
||||
return plant
|
||||
return null
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ func _exit_tree() -> void:
|
|||
Session.round_started.disconnect(spawn)
|
||||
|
||||
func spawn():
|
||||
if not multiplayer.is_server():
|
||||
return
|
||||
match team:
|
||||
Session.TEAMS.ATTACK:
|
||||
for attacker in Lobby.attack_team:
|
||||
|
|
@ -36,18 +38,22 @@ func spawn_player(id: int) -> void:
|
|||
elif team == Session.TEAMS.ATTACK:
|
||||
Session.attackers_alive += 1
|
||||
|
||||
deferred_setup.bind(inst,team).call_deferred()
|
||||
var distance = randf_range(0,spawn_radius)
|
||||
var angle = randf_range(0,TAU)
|
||||
var new_position = global_position + Vector3.RIGHT.rotated(Vector3.UP,angle) * distance
|
||||
inst.player_id = id
|
||||
inst.team = team
|
||||
get_parent().add_child(inst)
|
||||
inst.global_position = new_position
|
||||
|
||||
func spawn_spectator(id: int) -> void:
|
||||
var spectator: PackedScene = load("res://scenes/spectator.tscn")
|
||||
var inst = spectator.instantiate()
|
||||
|
||||
inst.name = str(id)
|
||||
deferred_setup.bind(inst,Session.TEAMS.SPECTATE).call_deferred()
|
||||
|
||||
func deferred_setup(what: Node3D, new_team: Session.TEAMS):
|
||||
get_parent().add_child(what,true)
|
||||
var distance = randf_range(0,spawn_radius)
|
||||
var angle = randf_range(0,TAU)
|
||||
var new_position = global_position + Vector3.RIGHT.rotated(Vector3.UP,angle) * distance
|
||||
what.set_after_spawn.rpc_id(int(what.name),new_position,new_team)
|
||||
inst.team = team
|
||||
get_parent().add_child(inst)
|
||||
inst.global_position = new_position
|
||||
|
|
@ -7,17 +7,10 @@ extends Node
|
|||
const ATTACK_LAYER: int = 0b10000
|
||||
const DEFENCE_LAYER: int = 0b100000
|
||||
|
||||
func on_spawned() -> void:
|
||||
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
|
||||
global_update.rpc(layer,mask)
|
||||
|
||||
@rpc
|
||||
func global_update(new_layer,mask) -> void:
|
||||
if new_layer:
|
||||
get_parent().collision_layer |= mask
|
||||
else:
|
||||
get_parent().collision_mask |= mask
|
||||
|
|
|
|||
|
|
@ -4,9 +4,8 @@ extends Camera3D
|
|||
|
||||
var active: bool
|
||||
|
||||
func _ready() -> void:
|
||||
if not is_multiplayer_authority():
|
||||
return
|
||||
func _enter_tree() -> void:
|
||||
set_multiplayer_authority(int(get_parent().get_parent().name))
|
||||
|
||||
func set_active() -> void:
|
||||
if not is_multiplayer_authority():
|
||||
|
|
|
|||
|
|
@ -4,10 +4,14 @@ 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 spawned
|
||||
signal health_changed(to: int)
|
||||
signal died
|
||||
|
||||
|
|
@ -26,52 +30,24 @@ const MAX_HP = 100
|
|||
get:
|
||||
return hp
|
||||
|
||||
func _enter_tree() -> void:
|
||||
set_multiplayer_authority(str(name).to_int())
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
if not is_multiplayer_authority():
|
||||
if not multiplayer.is_server():
|
||||
return
|
||||
|
||||
move_and_slide()
|
||||
|
||||
func die() -> void:
|
||||
if (not is_multiplayer_authority()):
|
||||
if (not multiplayer.is_server()):
|
||||
return
|
||||
Session.add_dead.rpc(team)
|
||||
Session.add_dead(team)
|
||||
died.emit()
|
||||
passived = true
|
||||
|
||||
@rpc("any_peer","call_local","reliable")
|
||||
func passive() -> void:
|
||||
passived = true
|
||||
|
||||
@rpc("any_peer","call_local","reliable")
|
||||
func depassive() -> void:
|
||||
passived = false
|
||||
|
||||
@rpc("any_peer","call_local","reliable")
|
||||
func kill_request() -> void:
|
||||
if multiplayer.get_remote_sender_id() != 1:
|
||||
return
|
||||
|
||||
die()
|
||||
|
||||
@rpc("any_peer","call_local","reliable")
|
||||
func set_after_spawn(start_position: Vector3,new_team: int):
|
||||
global_position = start_position
|
||||
team = new_team as Session.TEAMS
|
||||
spawned.emit()
|
||||
|
||||
@rpc("any_peer","call_local","reliable")
|
||||
func take_damage(damage: int):
|
||||
hp -= damage
|
||||
$DamageAudio.multiplayer_play()
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if not is_multiplayer_authority():
|
||||
return
|
||||
if event.is_action_pressed("plr_interact"):
|
||||
Session.interact()
|
||||
if event.is_action_released("plr_interact"):
|
||||
Session.stop_interact()
|
||||
|
|
|
|||
8
scripts/player/player_interaction.gd
Normal file
8
scripts/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
scripts/player/player_interaction.gd.uid
Normal file
1
scripts/player/player_interaction.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://dsp1sq46c5i3y
|
||||
|
|
@ -3,6 +3,9 @@ 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:
|
||||
|
|
@ -15,7 +18,7 @@ func process_movement(max_speed: float,acceleration: float,deceleration: float,d
|
|||
player.velocity.x = 0
|
||||
player.velocity.z = 0
|
||||
return
|
||||
var input_dir := Input.get_vector("plr_strafe_r","plr_strafe_l", "plr_back","plr_forward")
|
||||
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))
|
||||
|
|
@ -23,3 +26,6 @@ func process_movement(max_speed: float,acceleration: float,deceleration: float,d
|
|||
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
|
||||
|
|
|
|||
|
|
@ -8,22 +8,22 @@ extends State
|
|||
@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 Input.is_action_just_pressed("plr_jump") and player.is_on_floor() and toggle:
|
||||
transition.emit("Stand")
|
||||
return
|
||||
|
||||
if not player.is_on_floor():
|
||||
transition.emit("Fall")
|
||||
|
|
@ -31,7 +31,6 @@ func physics_update(delta: float) -> void:
|
|||
|
||||
player_movement.process_movement(max_speed * weapon_system.get_speed_modifier(),acceleration,deceleration,delta)
|
||||
|
||||
func state_input(event: InputEvent) -> void:
|
||||
if (toggle == true and event.is_action_pressed("plr_crouch")) or (toggle == false and event.is_action_released("plr_crouch")):
|
||||
if stand_up_area.has_overlapping_bodies() == false:
|
||||
transition.emit("Stand")
|
||||
func try_end_crouch() -> void:
|
||||
if player.is_on_floor() and stand_up_area.has_overlapping_bodies() == false:
|
||||
transition.emit("Stand")
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ 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
|
||||
|
|
@ -18,7 +19,12 @@ func physics_update(delta: float) -> void:
|
|||
if not is_multiplayer_authority():
|
||||
return
|
||||
if player.is_on_floor():
|
||||
transition.emit("Stand")
|
||||
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
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ extends State
|
|||
@export var max_speed: float = 5.0
|
||||
@export var acceleration: float = 2.0
|
||||
@export var deceleration: float = 200.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
|
||||
@export var audio: MultiplayerAudio3D
|
||||
@export var step_delay: float
|
||||
|
|
@ -14,18 +14,19 @@ extends State
|
|||
var step_time: float
|
||||
|
||||
func enter() -> void:
|
||||
pass
|
||||
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 Input.is_action_just_pressed("plr_jump") and player.is_on_floor():
|
||||
player.velocity.y = JUMP_VELOCITY * sign(weapon_system.get_speed_modifier())
|
||||
transition.emit("Fall")
|
||||
return
|
||||
|
||||
if not player.is_on_floor():
|
||||
transition.emit("Fall")
|
||||
|
|
@ -38,9 +39,13 @@ func physics_update(delta: float) -> void:
|
|||
|
||||
player_movement.process_movement(max_speed * weapon_system.get_speed_modifier(),acceleration,deceleration,delta)
|
||||
|
||||
func state_input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("plr_crouch"):
|
||||
transition.emit("Crouch")
|
||||
|
||||
if event.is_action_pressed("plr_walk"):
|
||||
transition.emit("Walk")
|
||||
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")
|
||||
|
|
|
|||
|
|
@ -6,21 +6,22 @@ extends State
|
|||
@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:
|
||||
pass
|
||||
player_input.crouch_begin.connect(begin_crouch)
|
||||
player_input.walk_end.connect(end_walk)
|
||||
player_input.jumped.connect(on_jumped)
|
||||
|
||||
func exit() -> void:
|
||||
pass
|
||||
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 Input.is_action_just_pressed("plr_jump") and player.is_on_floor():
|
||||
player.velocity.y = JUMP_VELOCITY
|
||||
transition.emit("Fall")
|
||||
return
|
||||
|
||||
if not player.is_on_floor():
|
||||
transition.emit("Fall")
|
||||
|
|
@ -28,9 +29,13 @@ func physics_update(delta: float) -> void:
|
|||
|
||||
player_movement.process_movement(max_speed * weapon_system.get_speed_modifier(),acceleration,deceleration,delta)
|
||||
|
||||
func state_input(event: InputEvent) -> void:
|
||||
if event.is_action_released("plr_walk"):
|
||||
transition.emit("Stand")
|
||||
|
||||
if event.is_action_pressed("plr_crouch"):
|
||||
transition.emit("Crouch")
|
||||
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")
|
||||
|
|
|
|||
|
|
@ -5,8 +5,5 @@ extends Node
|
|||
@export var blue_team_texture: Texture2D
|
||||
|
||||
func _ready() -> void:
|
||||
get_tree().create_timer(1).timeout.connect(on_player_spawned)
|
||||
|
||||
func on_player_spawned() -> void:
|
||||
if player.team == Session.TEAMS.DEFENCE:
|
||||
material.albedo_texture = blue_team_texture
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ func _ready() -> void:
|
|||
|
||||
else:
|
||||
push_warning("Child of state machine is not state")
|
||||
current_state.enter()
|
||||
|
||||
func on_transition_required(to: StringName):
|
||||
if is_multiplayer_authority() == false:
|
||||
|
|
@ -30,7 +31,7 @@ func change_state(to_state: State) -> void:
|
|||
current_state = to_state
|
||||
current_state.enter()
|
||||
|
||||
@rpc
|
||||
@rpc("authority","call_local","reliable")
|
||||
func change_state_to_name(to_name: StringName):
|
||||
if current_state != null:
|
||||
current_state.exit()
|
||||
|
|
|
|||
|
|
@ -40,10 +40,10 @@ func interaction_start(player_id: int):
|
|||
super(player_id)
|
||||
defuse_timer.start()
|
||||
$DefuseAudio.multiplayer_play()
|
||||
Session.player_nodes[player_id].passive.rpc_id(player_id)
|
||||
Session.player_nodes[player_id].passive()
|
||||
|
||||
func interaction_end():
|
||||
Session.player_nodes[interacted_id].depassive.rpc_id(interacted_id)
|
||||
Session.player_nodes[interacted_id].depassive()
|
||||
|
||||
super()
|
||||
defuse_timer.stop()
|
||||
|
|
|
|||
|
|
@ -7,6 +7,6 @@ func enter() -> void:
|
|||
func exit() -> void:
|
||||
pass
|
||||
|
||||
func state_input(event: InputEvent) -> void:
|
||||
if event.is_action("plr_bomb") and Session.is_on_site():
|
||||
func use_begin() -> void:
|
||||
if Session.is_on_site(machine.player.player_id):
|
||||
transition.emit("Plant")
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ extends WeaponState
|
|||
func enter():
|
||||
machine.animation_player.play(machine.animation_prefix+"plant")
|
||||
machine.animation_player.animation_finished.connect(on_animation_finished)
|
||||
machine.speed_modifier = 0.0
|
||||
machine.player.get_node("PlantAudio").multiplayer_play()
|
||||
if is_multiplayer_authority():
|
||||
machine.speed_modifier = 0.0
|
||||
machine.player.get_node("PlantAudio").multiplayer_play()
|
||||
|
||||
func exit():
|
||||
machine.animation_player.animation_finished.disconnect(on_animation_finished)
|
||||
|
|
@ -14,15 +15,13 @@ func on_animation_finished(animation: StringName):
|
|||
if is_multiplayer_authority() == false:
|
||||
return
|
||||
if animation == machine.animation_prefix + "plant":
|
||||
|
||||
Session.spawn({"type": "object","spawn_name": "active_bomb", "position": machine.player_camera.get_parent().global_position,"plant": Session.get_site().name})
|
||||
Session.spawn({"type": "object","spawn_name": "active_bomb", "position": machine.player_camera.get_parent().global_position,"plant": Session.get_site(machine.player.player_id).name})
|
||||
|
||||
machine.ammo -= 1
|
||||
return_to_previous.emit()
|
||||
|
||||
func state_input(event: InputEvent) -> void:
|
||||
func use_end() -> void:
|
||||
if is_multiplayer_authority() == false:
|
||||
return
|
||||
if event.is_action_released("plr_bomb"):
|
||||
transition.emit("Idle")
|
||||
machine.player.get_node("PlantAudio").multiplayer_stop()
|
||||
transition.emit("Idle")
|
||||
machine.player.get_node("PlantAudio").multiplayer_stop()
|
||||
|
|
|
|||
|
|
@ -4,15 +4,10 @@ extends WeaponState
|
|||
|
||||
func enter() -> void:
|
||||
machine.animation_player.play(with_morphems("idle"))
|
||||
machine.player.get_node("PlayerInput").reload.connect(init_reload)
|
||||
|
||||
func exit() -> void:
|
||||
pass
|
||||
|
||||
func state_input(event: InputEvent) -> void:
|
||||
if not machine.is_multiplayer_authority() or Input.mouse_mode != Input.MouseMode.MOUSE_MODE_CAPTURED: return
|
||||
|
||||
if event.is_action_pressed("plr_reload"):
|
||||
init_reload.rpc()
|
||||
machine.player.get_node("PlayerInput").reload.disconnect(init_reload)
|
||||
|
||||
func use_begin() -> void:
|
||||
if machine.ammo > 0:
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ func use_begin() -> void:
|
|||
func fire() -> void:
|
||||
if machine.ammo == 0 or fire_timer.time_left > 0:
|
||||
return
|
||||
machine.player.get_node("ShootAudio").multiplayer_play()
|
||||
machine.ammo -= 1
|
||||
bullets_shot += 1
|
||||
|
||||
|
|
@ -39,7 +38,8 @@ func fire() -> void:
|
|||
machine.animation_player.play(with_morphems("shoot"))
|
||||
|
||||
if is_multiplayer_authority():
|
||||
Session.shoot(damage,shoot_distance)
|
||||
Session.shoot(int(machine.player.name),damage,shoot_distance)
|
||||
machine.player.get_node("ShootAudio").multiplayer_play()
|
||||
|
||||
fire_timer.start()
|
||||
machine.player_camera.recoil(horizontal_curve.sample(bullets_shot),vertical_curve.sample(bullets_shot))
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ func exit() -> void:
|
|||
|
||||
func attack() -> void:
|
||||
if is_multiplayer_authority():
|
||||
Session.shoot(damage,1.5)
|
||||
Session.shoot(int(machine.player.name),damage,1.5)
|
||||
|
||||
func on_animation_finished(animation):
|
||||
if animation == machine.animation_prefix + "attack":
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ func exit() -> void:
|
|||
|
||||
func attack() -> void:
|
||||
if is_multiplayer_authority():
|
||||
Session.shoot(damage,1.5)
|
||||
Session.shoot(int(machine.player.name),damage,1.5)
|
||||
|
||||
func on_animation_finished(animation):
|
||||
if animation == machine.animation_prefix + "heavy_attack":
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ func exit() -> void:
|
|||
@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()
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ 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
|
||||
|
|
@ -27,6 +28,12 @@ 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:
|
||||
|
|
@ -64,8 +71,9 @@ func add(state: WeaponSubStateMachine, slot: StringName,ignore_parent: bool = fa
|
|||
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 is_multiplayer_authority() == false:
|
||||
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()
|
||||
|
|
@ -78,8 +86,8 @@ func switch(to: StringName, exit: bool = true):
|
|||
|
||||
ammo_updated.emit(current_state.ammo,current_state.remaining_ammo)
|
||||
switched_to.emit(current_state)
|
||||
|
||||
update_remotes.rpc(to,exit)
|
||||
if is_multiplayer_authority():
|
||||
switch.rpc(to,exit)
|
||||
|
||||
func return_to_previous(exit: bool = true):
|
||||
if last_slot != "":
|
||||
|
|
@ -87,19 +95,12 @@ func return_to_previous(exit: bool = true):
|
|||
else:
|
||||
switch("knife", exit)
|
||||
|
||||
@rpc("authority","call_remote","reliable")
|
||||
func update_remotes(to: StringName,exit: bool):
|
||||
if current_state != null and exit:
|
||||
current_state.exit()
|
||||
current_state = slots[to]
|
||||
current_state.enter()
|
||||
|
||||
switched_to.emit(current_state)
|
||||
|
||||
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 drop_data: Dictionary = {}
|
||||
|
|
@ -174,39 +175,14 @@ func _physics_process(delta: float) -> void:
|
|||
return
|
||||
current_state.physics_update(delta)
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if is_multiplayer_authority() == false or disabled: 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 not Session.round_state == Session.ROUND_STATES.BUY and not player.passived:
|
||||
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_current()
|
||||
|
||||
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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue