Compare commits

..

1 commit

Author SHA1 Message Date
42c95820d7 Start of rewind system 2025-12-21 02:22:41 +05:00
28 changed files with 69 additions and 100 deletions

View file

@ -41,6 +41,3 @@ version_update_desc,"На сервере обнаружена новая (или
Install it?",
video,Видео,Video,
win_rounds,Раундов до победы,Rounds to win,
toggle_walk,Переключение ходьбы,Toggle walking,
toggle_crouch,Переключение приседания,Toggle crouching,
toggle_scope,Переключение прицеливания,Toggle scoping,

1 key ru en ikg
41 win_rounds Раундов до победы Rounds to win
42
43
toggle_scope Переключение прицеливания Toggle scoping

View file

@ -1,7 +1,7 @@
key,ru,en,ikg
au_loading,Подгружаем данные с сервера…,Loading data from server…,
au_err_load,[color=red]Ошибка загрузки данных: {error}[/color] ,[color=red]Error while loading data: {error}[/color],
au_err_install,[color=red]Ошибка загрузки новой версии: {error}[/color],[color=red]Error while downloading new version: {error}[/color],
au_err_load,Ошибка загрузки данных: ,Error while loading data: ,
au_err_install,Ошибка загрузки новой версии: ,Error while downloading new version: ,
au_new_version,Доступна новая версия!,New version available!,
au_current_version,[color=green]У вас самая актуальная версия игры! [/color],[color=green]Your version is the current version! [/color],
au_current_version,У вас самая актуальная версия игры!,Your version is the current version!,
vr_version,Текущая версия игры: ,Game version: ,

1 key ru en ikg
2 au_loading Подгружаем данные с сервера… Loading data from server…
3 au_err_load [color=red]Ошибка загрузки данных: {error}[/color] Ошибка загрузки данных: [color=red]Error while loading data: {error}[/color] Error while loading data:
4 au_err_install [color=red]Ошибка загрузки новой версии: {error}[/color] Ошибка загрузки новой версии: [color=red]Error while downloading new version: {error}[/color] Error while downloading new version:
5 au_new_version Доступна новая версия! New version available!
6 au_current_version [color=green]У вас самая актуальная версия игры! [/color] У вас самая актуальная версия игры! [color=green]Your version is the current version! [/color] Your version is the current version!
7 vr_version Текущая версия игры: Game version:

View file

@ -21,7 +21,7 @@ layout_mode = 2
custom_minimum_size = Vector2(512, 256)
layout_mode = 2
tab_alignment = 1
current_tab = 2
current_tab = 3
[node name="gameplay" type="VBoxContainer" parent="CenterContainer/VBoxContainer/PanelContainer"]
visible = false
@ -38,6 +38,7 @@ layout_mode = 2
text = "fullscreen"
[node name="controls" type="VBoxContainer" parent="CenterContainer/VBoxContainer/PanelContainer"]
visible = false
layout_mode = 2
metadata/_tab_index = 2
@ -53,7 +54,6 @@ unique_name_in_owner = true
custom_minimum_size = Vector2(256, 0)
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
min_value = 0.001
max_value = 0.02
step = 0.001
@ -68,23 +68,7 @@ value = 0.02
allow_greater = true
allow_lesser = true
[node name="ToggleCrouch" type="CheckButton" parent="CenterContainer/VBoxContainer/PanelContainer/controls"]
unique_name_in_owner = true
layout_mode = 2
text = "toggle_crouch"
[node name="ToggleScope" type="CheckButton" parent="CenterContainer/VBoxContainer/PanelContainer/controls"]
unique_name_in_owner = true
layout_mode = 2
text = "toggle_scope"
[node name="ToggleWalk" type="CheckButton" parent="CenterContainer/VBoxContainer/PanelContainer/controls"]
unique_name_in_owner = true
layout_mode = 2
text = "toggle_walk"
[node name="audio" type="VBoxContainer" parent="CenterContainer/VBoxContainer/PanelContainer"]
visible = false
layout_mode = 2
metadata/_tab_index = 3
@ -99,7 +83,6 @@ text = "audio_gameplay"
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 1
max_value = 1.0
step = 0.01
value = 1.0
@ -119,9 +102,6 @@ text = "Покинуть сессию"
[connection signal="toggled" from="CenterContainer/VBoxContainer/PanelContainer/video/FullscreenButton" to="CenterContainer" method="_on_fullscreen_button_toggled"]
[connection signal="value_changed" from="CenterContainer/VBoxContainer/PanelContainer/controls/Sensitivity/SensitivitySlider" to="CenterContainer" method="_on_sensitivity_slider_value_changed"]
[connection signal="value_changed" from="CenterContainer/VBoxContainer/PanelContainer/controls/Sensitivity/SensitivityBox" to="CenterContainer" method="_on_sensitivity_box_value_changed"]
[connection signal="toggled" from="CenterContainer/VBoxContainer/PanelContainer/controls/ToggleCrouch" to="CenterContainer" method="_on_toggle_crouch_toggled"]
[connection signal="toggled" from="CenterContainer/VBoxContainer/PanelContainer/controls/ToggleScope" to="CenterContainer" method="_on_toggle_scope_toggled"]
[connection signal="toggled" from="CenterContainer/VBoxContainer/PanelContainer/controls/ToggleWalk" to="CenterContainer" method="_on_toggle_walk_toggled"]
[connection signal="value_changed" from="CenterContainer/VBoxContainer/PanelContainer/audio/GameplayMainAudio/GameplayMainSlider" to="CenterContainer" method="_on_gameplay_main_slider_value_changed"]
[connection signal="pressed" from="CenterContainer/VBoxContainer/StopSession" to="CenterContainer" method="_on_stop_session_pressed"]
[connection signal="pressed" from="CenterContainer/VBoxContainer/LeaveButton" to="CenterContainer" method="_on_leave_button_pressed"]

View file

@ -9,9 +9,6 @@ func _ready() -> void:
Lobby.lobby_closed.connect(%StopSession.hide)
%SensitivitySlider.set_value_no_signal(ClientSettings.SENSITIVITY)
%SensitivityBox.set_value_no_signal(ClientSettings.SENSITIVITY)
%ToggleCrouch.set_pressed_no_signal(ClientSettings.TOGGLE_CROUCH)
%ToggleScope.set_pressed_no_signal(ClientSettings.TOGGLE_SCOPE)
%ToggleWalk.set_pressed_no_signal(ClientSettings.TOGGLE_WALK)
func _input(event: InputEvent) -> void:
if event.is_action_pressed("menu_settings"):
@ -42,15 +39,3 @@ func _on_leave_button_pressed() -> void:
func _on_stop_session_pressed() -> void:
if multiplayer.is_server():
Session.end_session()
func _on_toggle_crouch_toggled(toggled_on: bool) -> void:
ClientSettings.TOGGLE_CROUCH = toggled_on
func _on_toggle_scope_toggled(toggled_on: bool) -> void:
ClientSettings.TOGGLE_SCOPE = toggled_on
func _on_toggle_walk_toggled(toggled_on: bool) -> void:
ClientSettings.TOGGLE_WALK = toggled_on

View file

@ -1,18 +1,10 @@
extends RichTextLabel
var status: StringName = "au_loading"
var error: int
func _ready() -> void:
AutoUpdate.update_version_text.connect(update_version)
update_version("au_loading")
update_version(tr("au_loading"))
func update_version(version: StringName, new_error = -1):
status = version
error = new_error
text = tr("vr_version") + preload("res://version.tres").version + "\n" + tr(version).format({"error":error})
func _notification(what: int) -> void:
if what == NOTIFICATION_TRANSLATION_CHANGED:
text = tr("vr_version") + preload("res://version.tres").version + "\n" + tr(status).format({"error":error})
func update_version(version: StringName):
text = tr("vr_version") + preload("res://version.tres").version + "\n" + version

View file

@ -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

View file

@ -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:

View file

@ -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]

View file

@ -5,7 +5,7 @@ var popup_scene: PackedScene = preload("uid://5goo8fyxkv33")
var new_version_avaiable: bool
var popup: ConfirmationDialog
signal update_version_text(to: StringName,error: int)
signal update_version_text(to: StringName)
func _ready() -> void:
request_completed.connect(on_request_completed)
@ -18,22 +18,22 @@ func _ready() -> void:
patch_request.download_file = exec_dir.path_join("chelimbalo.pck")
patch_request.request_completed.connect(patch_downloaded)
update_version_text.emit("au_loading")
update_version_text.emit(tr("au_loading"))
request("https://2ndbeam.ru/durenije/chelimbalo/release/deploy_data")
func on_request_completed(result: int, _response_code: int, _headers: PackedStringArray, body: PackedByteArray):
if result != OK:
update_version_text.emit("au_err_load",result)
update_version_text.emit("[color=red]" + tr("au_err_load") + str(result) +"[/color]")
return
var ver_hash = body.get_string_from_ascii().split("\n")[1]
if ver_hash != load("res://version.tres").version:
update_version_text.emit("au_new_version")
update_version_text.emit(tr("au_new_version"))
popup.popup_centered()
else:
update_version_text.emit("au_current_version")
update_version_text.emit("[color=green]"+tr("au_current_version")+"[/color]")
func download_button_pressed() -> void:
popup.get_node("HTTPRequest").request("https://2ndbeam.ru/durenije/chelimbalo/release/chelimbalo.pck")
@ -43,4 +43,4 @@ func patch_downloaded(result: int, _response_code: int, _headers: PackedStringAr
OS.create_process(OS.get_executable_path(),OS.get_cmdline_args())
get_tree().quit()
else:
update_version_text.emit("au_err_install",result)
update_version_text.emit("[color=red]" + tr("au_err_install") + str(result) +"[/color]")

17
systems/rewind.gd Normal file
View file

@ -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

1
systems/rewind.gd.uid Normal file
View file

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

View file

@ -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

View file

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

View file

@ -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:

View file

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

View file

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

View file

@ -25,11 +25,4 @@ ignore_time_scale = true
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
replication_config = SubResource("SceneReplicationConfig_wpexx")
[node name="Timer2" type="Timer" parent="."]
wait_time = 0.06
one_shot = true
autostart = true
ignore_time_scale = true
[connection signal="timeout" from="Timer" to="." method="queue_free"]
[connection signal="timeout" from="Timer2" to="MultiplayerSynchronizer" method="queue_free"]

View file

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

View file

@ -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:

View file

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

View file

@ -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

View file

@ -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:

View file

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