From 42c95820d7acf51565ad9bc12136259a614d306c Mon Sep 17 00:00:00 2001 From: Rendo Date: Sun, 21 Dec 2025 02:22:41 +0500 Subject: [PATCH] Start of rewind system --- players/molikman.tscn | 3 ++- players/player/player_input.gd | 14 +++++++------- project.godot | 1 + systems/rewind.gd | 17 +++++++++++++++++ systems/rewind.gd.uid | 1 + systems/weapon_system/weapon_state.gd | 16 ++++++++-------- .../weapon_system/weapon_substate_machine.gd | 8 ++++---- systems/weapon_system/weapon_system.gd | 8 ++++---- weapons/bomb/bomb_idle_state.gd | 2 +- weapons/bomb/bomb_main_state.gd | 2 +- weapons/gun/idle_state.gd | 2 +- weapons/gun/semi_pellet_shoot_state.gd | 4 +++- weapons/gun/semi_shoot_state.gd | 2 +- weapons/knife/knife_attack.gd | 4 ++-- weapons/knife/knife_idle.gd | 2 +- weapons/molikman/molik/idle_state.gd | 2 +- 16 files changed, 55 insertions(+), 33 deletions(-) create mode 100644 systems/rewind.gd create mode 100644 systems/rewind.gd.uid diff --git a/players/molikman.tscn b/players/molikman.tscn index 210fd7e..20b4220 100644 --- a/players/molikman.tscn +++ b/players/molikman.tscn @@ -12472,7 +12472,7 @@ properties/1/path = NodePath("PlayerInput:compressed_states") properties/1/spawn = true properties/1/replication_mode = 1 -[node name="Player" type="CharacterBody3D" node_paths=PackedStringArray("weapon_models")] +[node name="Player" type="CharacterBody3D" node_paths=PackedStringArray("weapon_models") groups=["Player"]] collision_layer = 2 collision_mask = 3 script = ExtResource("1_l07l8") @@ -13675,6 +13675,7 @@ offset_top = -0.2800293 offset_right = -0.32000732 grow_vertical = 0 mouse_filter = 2 +theme_type_variation = &"HPBar" step = 1.0 value = 100.0 fill_mode = 3 diff --git a/players/player/player_input.gd b/players/player/player_input.gd index 16c4ed2..386c33b 100644 --- a/players/player/player_input.gd +++ b/players/player/player_input.gd @@ -14,8 +14,8 @@ const WALK: int = 0b100 signal jumped signal drop signal switch_weapon(to_slot: StringName) -signal fire_begin -signal fire_end +signal fire_begin(timestamp: float) +signal fire_end(timestamp: float) signal alternate_state signal switch_firemode signal reload @@ -53,9 +53,9 @@ func _unhandled_input(event: InputEvent) -> void: switch_on_server.rpc_id(1,"knife") if event.is_action_pressed("plr_fire"): - fire_on_server.rpc_id(1,false) + fire_on_server.rpc_id(1,false,Rewind.timestamp) if event.is_action_released("plr_fire"): - fire_on_server.rpc_id(1,true) + fire_on_server.rpc_id(1,true,Rewind.timestamp) if event.is_action_pressed("plr_scope"): alternate_state_on_server.rpc_id(1) if event.is_action_pressed("plr_firemode"): @@ -126,12 +126,12 @@ func drop_on_server() -> void: drop.emit() @rpc("authority","call_local","reliable") -func fire_on_server(end: bool) -> void: +func fire_on_server(end: bool, timestamp: float) -> void: if not multiplayer.is_server(): return if end: - fire_end.emit() + fire_end.emit(timestamp) else: - fire_begin.emit() + fire_begin.emit(timestamp) @rpc("authority","call_local","reliable") func alternate_state_on_server() -> void: diff --git a/project.godot b/project.godot index 0b5e30b..e06ca20 100644 --- a/project.godot +++ b/project.godot @@ -29,6 +29,7 @@ Registry="*res://systems/registry.gd" Shop="*res://gui/buy_menu/shop.gd" MouseConfiner="*res://gui/mouse_confiner.gd" AutoUpdate="*res://systems/auto_update.gd" +Rewind="*res://systems/rewind.gd" [debug] diff --git a/systems/rewind.gd b/systems/rewind.gd new file mode 100644 index 0000000..a5d29ef --- /dev/null +++ b/systems/rewind.gd @@ -0,0 +1,17 @@ +extends Node + +const timestamp_range:float = 200.0 #MSEC +const timestamps_amount: int = 200 + +var timestamp: float = 0 + +func _process(delta: float) -> void: + if not is_multiplayer_authority(): + return + if Session.session_started_flag: + timestamp += delta + sync_time.rpc(timestamp) + +@rpc +func sync_time(new_timestamp: float) -> void: + timestamp = new_timestamp diff --git a/systems/rewind.gd.uid b/systems/rewind.gd.uid new file mode 100644 index 0000000..3d6a572 --- /dev/null +++ b/systems/rewind.gd.uid @@ -0,0 +1 @@ +uid://bafcih3g8gi2q diff --git a/systems/weapon_system/weapon_state.gd b/systems/weapon_system/weapon_state.gd index ce25367..fed1121 100644 --- a/systems/weapon_system/weapon_state.gd +++ b/systems/weapon_system/weapon_state.gd @@ -8,23 +8,23 @@ signal return_to_previous var machine: WeaponSubStateMachine -func _use_begin() -> void: +func _use_begin(timestamp: float) -> void: pass @rpc("authority","call_remote","reliable") -func use_begin() -> void: - _use_begin() +func use_begin(timestamp: float) -> void: + _use_begin(timestamp) if is_multiplayer_authority(): - use_begin.rpc() + use_begin.rpc(timestamp) -func _use_end(): +func _use_end(timestamp: float): pass @rpc("authority","call_remote","reliable") -func use_end() -> void: - _use_end() +func use_end(timestamp: float) -> void: + _use_end(timestamp) if is_multiplayer_authority(): - use_end.rpc() + use_end.rpc(timestamp) func _alternate_state() -> void: pass diff --git a/systems/weapon_system/weapon_substate_machine.gd b/systems/weapon_system/weapon_substate_machine.gd index 02ae1f4..fc75ecc 100644 --- a/systems/weapon_system/weapon_substate_machine.gd +++ b/systems/weapon_system/weapon_substate_machine.gd @@ -70,12 +70,12 @@ func _enter() -> void: func _exit() -> void: super() -func use_begin() -> void: +func use_begin(timestamp: float) -> void: if current_state != null: - current_state.use_begin() -func use_end() -> void: + current_state.use_begin(timestamp) +func use_end(timestamp: float) -> void: if current_state != null: - current_state.use_end() + current_state.use_end(timestamp) func alternate_state() -> void: if current_state != null: current_state.alternate_state() diff --git a/systems/weapon_system/weapon_system.gd b/systems/weapon_system/weapon_system.gd index a99b2e2..101344c 100644 --- a/systems/weapon_system/weapon_system.gd +++ b/systems/weapon_system/weapon_system.gd @@ -218,17 +218,17 @@ func _physics_process(delta: float) -> void: return current_state.physics_update(delta) -func use_begin() -> void: +func use_begin(timestamp: float) -> void: if not multiplayer.is_server() or Session.round_state == Session.ROUND_STATES.BUY or disabled: return if current_state != null: - current_state.use_begin() + current_state.use_begin(timestamp) -func use_end() -> void: +func use_end(timestamp: float) -> void: if not multiplayer.is_server() or Session.round_state == Session.ROUND_STATES.BUY or disabled: return if current_state != null: - current_state.use_end() + current_state.use_end(timestamp) func alternate_state() -> void: if not multiplayer.is_server() or Session.round_state == Session.ROUND_STATES.BUY or disabled: diff --git a/weapons/bomb/bomb_idle_state.gd b/weapons/bomb/bomb_idle_state.gd index 514d0e1..b3a099e 100644 --- a/weapons/bomb/bomb_idle_state.gd +++ b/weapons/bomb/bomb_idle_state.gd @@ -7,6 +7,6 @@ func _enter() -> void: func _exit() -> void: pass -func _use_begin() -> void: +func _use_begin(_timestamp: float) -> void: if Session.is_on_site(machine.player.player_id): transition.emit("Plant") diff --git a/weapons/bomb/bomb_main_state.gd b/weapons/bomb/bomb_main_state.gd index 610b9d0..80d90f6 100644 --- a/weapons/bomb/bomb_main_state.gd +++ b/weapons/bomb/bomb_main_state.gd @@ -26,7 +26,7 @@ func on_animation_finished(animation: StringName): machine.ammo -= 1 return_to_previous.emit() -func use_end() -> void: +func use_end(_timestamp: float) -> void: if is_multiplayer_authority() == false: return transition.emit("Idle") diff --git a/weapons/gun/idle_state.gd b/weapons/gun/idle_state.gd index e865b05..ad35586 100644 --- a/weapons/gun/idle_state.gd +++ b/weapons/gun/idle_state.gd @@ -11,7 +11,7 @@ func _exit() -> void: if is_multiplayer_authority(): machine.player.get_node("PlayerInput").reload.disconnect(init_reload) -func _use_begin() -> void: +func _use_begin(timestamp: float) -> void: if machine.ammo > 0: transition.emit("Shoot") diff --git a/weapons/gun/semi_pellet_shoot_state.gd b/weapons/gun/semi_pellet_shoot_state.gd index 80d89dd..08d37f5 100644 --- a/weapons/gun/semi_pellet_shoot_state.gd +++ b/weapons/gun/semi_pellet_shoot_state.gd @@ -14,6 +14,7 @@ extends WeaponState @export var fire_timer: Timer var bullets_shot: int = 0 +var cached_timestamp: float = 0 func _enter() -> void: fire() @@ -27,9 +28,10 @@ func on_animation_finished(animation): if animation == machine.animation_prefix + with_morphems("shoot"): transition.emit("Idle") -func _use_begin() -> void: +func _use_begin(timestamp: float) -> void: if fire_timer.time_left > 0: return + cached_timestamp = timestamp fire() func fire() -> void: diff --git a/weapons/gun/semi_shoot_state.gd b/weapons/gun/semi_shoot_state.gd index b0783d9..da7dfae 100644 --- a/weapons/gun/semi_shoot_state.gd +++ b/weapons/gun/semi_shoot_state.gd @@ -26,7 +26,7 @@ func on_animation_finished(animation): if animation == machine.animation_prefix + with_morphems("shoot"): transition.emit("Idle") -func _use_begin() -> void: +func _use_begin(timestamp: float) -> void: if fire_timer.time_left > 0: return fire() diff --git a/weapons/knife/knife_attack.gd b/weapons/knife/knife_attack.gd index 091c750..18ebee4 100644 --- a/weapons/knife/knife_attack.gd +++ b/weapons/knife/knife_attack.gd @@ -24,8 +24,8 @@ func on_animation_finished(animation): attack() machine.animation_player.play(machine.animation_prefix + "attack") -func _use_begin() -> void: +func _use_begin(_timestamp: float) -> void: end_it = false -func _use_end() -> void: +func _use_end(_timestamp: float) -> void: end_it = true diff --git a/weapons/knife/knife_idle.gd b/weapons/knife/knife_idle.gd index ce038c7..6aa71b2 100644 --- a/weapons/knife/knife_idle.gd +++ b/weapons/knife/knife_idle.gd @@ -6,7 +6,7 @@ func _enter() -> void: func _exit() -> void: pass -func _use_begin() -> void: +func _use_begin(_timestamp: float) -> void: transition.emit("Attack") func _alternate_state() -> void: diff --git a/weapons/molikman/molik/idle_state.gd b/weapons/molikman/molik/idle_state.gd index 77780f2..8d31a91 100644 --- a/weapons/molikman/molik/idle_state.gd +++ b/weapons/molikman/molik/idle_state.gd @@ -6,6 +6,6 @@ func _enter() -> void: func _exit() -> void: pass -func _use_begin() -> void: +func _use_begin(timestamp: float) -> void: if machine.ammo > 0: transition.emit("Throw")