Refactor Part II

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

8874
players/molikman.tscn Normal file

File diff suppressed because one or more lines are too long

View 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

View file

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

View 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)

View file

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

60
players/player/player.gd Normal file
View 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

View file

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

View 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

View file

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

View file

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

View file

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

View 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()

View file

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

View 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)

View file

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

View 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

View file

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

View file

@ -0,0 +1,38 @@
extends Area3D
@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
var weapon: WeaponSubStateMachine = body.weapon.duplicate()
weapon_system.add(weapon,weapon.slot)
body.queue_free()
func start_temp_ignore():
if disabled:
return
if is_multiplayer_authority() == false:
return
monitoring = false
get_tree().create_timer(0.5).timeout.connect(stop_temp_ignore)
func stop_temp_ignore():
if disabled:
return
if is_multiplayer_authority() == false:
return
monitoring = true

View file

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

View 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

View file

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

View 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")

View file

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

View 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

View file

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

View 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)

View file

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

View 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")

View file

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

View 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")

View file

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

View 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

View file

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

7
players/spectator.tscn Normal file
View file

@ -0,0 +1,7 @@
[gd_scene load_steps=2 format=3 uid="uid://ckjabjcvgki6n"]
[ext_resource type="Script" uid="uid://cikw7fcykkpd5" path="res://spectator.gd" id="1_jjbhc"]
[node name="Spectator" type="Camera3D"]
transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, 0, 0, 0)
script = ExtResource("1_jjbhc")

View file

@ -0,0 +1,5 @@
[gd_scene format=3 uid="uid://eaali3lbode2"]
[node name="WeaponSpawner" type="MultiplayerSpawner"]
_spawnable_scenes = PackedStringArray("uid://djwjl8xll53vn", "uid://ts4xccpkjd3g", "uid://bxdatd1ilfgmc", "uid://c5q7e5dj86187")
spawn_path = NodePath("..")