Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions scripts/test-godot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ GODOT_BIN="${GODOT_BIN:-godot}"
TEST_SCRIPTS=(
"res://tests/unit/runtime_options_test.gd"
"res://tests/unit/bootstrap_test.gd"
"res://tests/replay_input_display_test.gd"
"res://tests/world_record_announcement_test.gd"
"res://tests/offline_playtest_smoke.gd"
"res://tests/aim_menu_smoke.gd"
Expand Down
22 changes: 22 additions & 0 deletions src/maps/map_ui.gd
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ signal return_control_to_player
@export var replay_slider: HSlider
@export var replay_container: Control
@export var replay_v: VBoxContainer
@export var replay_input_display: ReplayInputDisplay
@export var game_info: Container
@export var ammo_label: Label
@export var leaderboard: Container
Expand All @@ -33,10 +34,31 @@ func set_frame(frame: int, total: int) -> void:
replay_slider.value = frame
replay_slider.max_value = total - 1

func set_replay_inputs(
forward_input: bool,
back_input: bool,
left_input: bool,
right_input: bool,
shoot_input: bool,
ads_input: bool,
reload_input: bool,
) -> void:
replay_input_display.set_inputs(
forward_input,
back_input,
left_input,
right_input,
shoot_input,
ads_input,
reload_input,
)

func set_replay_visible(value: bool) -> void:
replay_container.visible = value
replay_v.visible = value
map.recorder.controller.visible = value
if not value:
replay_input_display.reset()

func is_replay_visible() -> bool:
return replay_container.visible
Expand Down
13 changes: 9 additions & 4 deletions src/maps/map_ui.tscn
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[gd_scene load_steps=13 format=3 uid="uid://bnati2e7fo1g"]
[gd_scene load_steps=14 format=3 uid="uid://bnati2e7fo1g"]

[ext_resource type="Script" uid="uid://vuacki0u3vnw" path="res://src/maps/map_ui.gd" id="1_jnrmt"]
[ext_resource type="Theme" uid="uid://3as6f5nxctip" path="res://src/main_theme.tres" id="2_uralg"]
Expand All @@ -10,21 +10,23 @@
[ext_resource type="Texture2D" uid="uid://dqvbiit5bj0rm" path="res://src/textures/plat_medal.png" id="9_k6ak5"]
[ext_resource type="Texture2D" uid="uid://doueeo1np6if1" path="res://src/textures/author_medal.png" id="10_dxk01"]
[ext_resource type="FontFile" uid="uid://reim7hyo6sqy" path="res://src/fonts/OpenSans-Regular.ttf" id="11_5vm7s"]
[ext_resource type="PackedScene" path="res://src/maps/replay_input_display.tscn" id="12_pfxlv"]

[sub_resource type="Theme" id="Theme_of3v1"]
default_font_size = 15

[sub_resource type="Theme" id="Theme_nvgh5"]
default_font = ExtResource("11_5vm7s")

[node name="MapUi" type="CanvasLayer" node_paths=PackedStringArray("keybind_info_label", "done_replay_btn", "tick_label", "replay_slider", "replay_container", "replay_v", "game_info", "ammo_label", "leaderboard")]
[node name="MapUi" type="CanvasLayer" node_paths=PackedStringArray("keybind_info_label", "done_replay_btn", "tick_label", "replay_slider", "replay_container", "replay_v", "replay_input_display", "game_info", "ammo_label", "leaderboard")]
script = ExtResource("1_jnrmt")
keybind_info_label = NodePath("ReplayContainer/V/KeybindInfo")
done_replay_btn = NodePath("ReplayContainer/V/Done")
tick_label = NodePath("ReplayContainer/V/Label")
replay_slider = NodePath("ReplayContainer/V/Slider")
replay_container = NodePath("ReplayContainer")
replay_v = NodePath("ReplayContainer/V")
replay_input_display = NodePath("ReplayContainer/V/ReplayInputDisplay")
game_info = NodePath("UiContainer/GameInfo")
ammo_label = NodePath("UiContainer/BottomLeft/V/Ammo")
leaderboard = NodePath("UiContainer/GameInfo/Leaderboard")
Expand Down Expand Up @@ -327,7 +329,7 @@ anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -150.0
offset_top = -147.0
offset_top = -215.0
offset_right = 150.0
grow_horizontal = 2
grow_vertical = 0
Expand All @@ -336,12 +338,15 @@ grow_vertical = 0
custom_minimum_size = Vector2(300, 0)
layout_mode = 2
offset_right = 300.0
offset_bottom = 147.0
offset_bottom = 215.0
grow_horizontal = 2
grow_vertical = 0
theme = ExtResource("2_uralg")
alignment = 1

[node name="ReplayInputDisplay" parent="ReplayContainer/V" instance=ExtResource("12_pfxlv")]
layout_mode = 2

[node name="Label" type="Label" parent="ReplayContainer/V"]
layout_mode = 2
text = "Frame: 0 / 999"
Expand Down
98 changes: 98 additions & 0 deletions src/maps/replay_input_display.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
class_name ReplayInputDisplay
extends HBoxContainer

const ACTIVE_BG := Color(0.94, 0.93, 0.89, 1.0)
const ACTIVE_BORDER := Color(0.18, 0.18, 0.18, 1.0)
const ACTIVE_FONT := Color(0.10, 0.10, 0.10, 1.0)
const INACTIVE_BG := Color(0.12, 0.14, 0.17, 1.0)
const INACTIVE_BORDER := Color(0.30, 0.33, 0.37, 1.0)
const INACTIVE_FONT := Color(0.78, 0.81, 0.84, 1.0)

var _input_states := {
&"forward": false,
&"back": false,
&"left": false,
&"right": false,
&"shoot": false,
&"ads": false,
&"reload": false,
}

var _key_panels: Dictionary = { }
var _key_labels: Dictionary = { }
var _active_panel_style: StyleBoxFlat
var _inactive_panel_style: StyleBoxFlat

func _ready() -> void:
_active_panel_style = _create_panel_style(ACTIVE_BG, ACTIVE_BORDER)
_inactive_panel_style = _create_panel_style(INACTIVE_BG, INACTIVE_BORDER)

_register_decorative_panel($"Movement/TopLeftSpacer")
_register_key(&"forward", $"Movement/W")
_register_decorative_panel($"Movement/TopRightSpacer")
_register_key(&"back", $"Movement/S")
_register_key(&"left", $"Movement/A")
_register_key(&"right", $"Movement/D")
_register_key(&"shoot", $"Combat/Shoot")
_register_key(&"ads", $"Combat/Ads")
_register_key(&"reload", $"Combat/Reload")

reset()

func set_inputs(
forward_input: bool,
back_input: bool,
left_input: bool,
right_input: bool,
shoot_input: bool,
ads_input: bool,
reload_input: bool,
) -> void:
_input_states[&"forward"] = forward_input
_input_states[&"back"] = back_input
_input_states[&"left"] = left_input
_input_states[&"right"] = right_input
_input_states[&"shoot"] = shoot_input
_input_states[&"ads"] = ads_input
_input_states[&"reload"] = reload_input
_apply_visual_state()

func reset() -> void:
set_inputs(false, false, false, false, false, false, false)

func is_input_active(input_name: StringName) -> bool:
return _input_states.get(input_name, false)

func _register_key(action_name: StringName, panel: PanelContainer) -> void:
var label := panel.get_node_or_null("Label") as Label
_key_panels[action_name] = panel
_key_labels[action_name] = label

func _register_decorative_panel(panel: PanelContainer) -> void:
if panel != null:
panel.add_theme_stylebox_override("panel", _inactive_panel_style)

func _apply_visual_state() -> void:
for action_name in _key_panels.keys():
var panel := _key_panels[action_name] as PanelContainer
var label := _key_labels.get(action_name) as Label
var active := _input_states.get(action_name, false)

if panel != null:
panel.add_theme_stylebox_override("panel", _active_panel_style if active else _inactive_panel_style)
if label != null:
label.add_theme_color_override("font_color", ACTIVE_FONT if active else INACTIVE_FONT)

func _create_panel_style(bg_color: Color, border_color: Color) -> StyleBoxFlat:
var style := StyleBoxFlat.new()
style.bg_color = bg_color
style.border_color = border_color
style.border_width_left = 1
style.border_width_top = 1
style.border_width_right = 1
style.border_width_bottom = 1
style.content_margin_left = 5
style.content_margin_top = 3
style.content_margin_right = 5
style.content_margin_bottom = 3
return style
106 changes: 106 additions & 0 deletions src/maps/replay_input_display.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
[gd_scene load_steps=2 format=3]

[ext_resource type="Script" path="res://src/maps/replay_input_display.gd" id="1_ry1dp"]

[node name="ReplayInputDisplay" type="HBoxContainer"]
custom_minimum_size = Vector2(0, 64)
layout_mode = 2
theme_override_constants/separation = 12
alignment = 1
script = ExtResource("1_ry1dp")

[node name="Movement" type="GridContainer" parent="."]
layout_mode = 2
theme_override_constants/h_separation = 4
theme_override_constants/v_separation = 4
columns = 3

[node name="TopLeftSpacer" type="PanelContainer" parent="Movement"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2

[node name="W" type="PanelContainer" parent="Movement"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2

[node name="Label" type="Label" parent="Movement/W"]
layout_mode = 2
theme_override_font_sizes/font_size = 15
text = "W"
horizontal_alignment = 1
vertical_alignment = 1

[node name="TopRightSpacer" type="PanelContainer" parent="Movement"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2

[node name="A" type="PanelContainer" parent="Movement"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2

[node name="Label" type="Label" parent="Movement/A"]
layout_mode = 2
theme_override_font_sizes/font_size = 15
text = "A"
horizontal_alignment = 1
vertical_alignment = 1

[node name="S" type="PanelContainer" parent="Movement"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2

[node name="Label" type="Label" parent="Movement/S"]
layout_mode = 2
theme_override_font_sizes/font_size = 15
text = "S"
horizontal_alignment = 1
vertical_alignment = 1

[node name="D" type="PanelContainer" parent="Movement"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2

[node name="Label" type="Label" parent="Movement/D"]
layout_mode = 2
theme_override_font_sizes/font_size = 15
text = "D"
horizontal_alignment = 1
vertical_alignment = 1

[node name="Combat" type="HBoxContainer" parent="."]
layout_mode = 2
theme_override_constants/separation = 4
alignment = 1

[node name="Shoot" type="PanelContainer" parent="Combat"]
custom_minimum_size = Vector2(46, 30)
layout_mode = 2

[node name="Label" type="Label" parent="Combat/Shoot"]
layout_mode = 2
theme_override_font_sizes/font_size = 15
text = "LMB"
horizontal_alignment = 1
vertical_alignment = 1

[node name="Ads" type="PanelContainer" parent="Combat"]
custom_minimum_size = Vector2(46, 30)
layout_mode = 2

[node name="Label" type="Label" parent="Combat/Ads"]
layout_mode = 2
theme_override_font_sizes/font_size = 15
text = "RMB"
horizontal_alignment = 1
vertical_alignment = 1

[node name="Reload" type="PanelContainer" parent="Combat"]
custom_minimum_size = Vector2(30, 30)
layout_mode = 2

[node name="Label" type="Label" parent="Combat/Reload"]
layout_mode = 2
theme_override_font_sizes/font_size = 15
text = "R"
horizontal_alignment = 1
vertical_alignment = 1
11 changes: 11 additions & 0 deletions src/recorder.gd
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,17 @@ func set_frame(value: int) -> void:
else:
map.map_ui.set_speed(speed)
map.map_ui.set_timer(current_frame * dt)
map \
.map_ui \
.set_replay_inputs(
frame.forward_input,
frame.back_input,
frame.left_input,
frame.right_input,
frame.shoot_input,
frame.ads_input,
frame.reload_input,
)

if prev_frame.weapon_index != frame.weapon_index:
controller.weapon_handler.set_weapon(Global.game_manager.get_weapon_from_index(frame.weapon_index), is_ghost)
Expand Down
Loading
Loading