generated from krampus/template-godot4
	Compare commits
	
		
			3 Commits
		
	
	
		
			bfe2ca46d4
			...
			01df07eb11
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 01df07eb11 | |||
| ce2996a703 | |||
| 94d1ac8abf | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -3,6 +3,7 @@ | ||||
| 
 | ||||
| # Godot-specific ignores | ||||
| .import/ | ||||
| override.cfg | ||||
| export.cfg | ||||
| export_presets.cfg | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										24
									
								
								assets/text/text.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								assets/text/text.csv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| keys,en | ||||
| ACTION_camera_forward,"Forward (free camera)" | ||||
| ACTION_camera_back,"Backward (free camera)" | ||||
| ACTION_camera_left,"Left (free camera)" | ||||
| ACTION_camera_right,"Right (free camera)" | ||||
| ACTION_camera_up,"Up (free camera)" | ||||
| ACTION_camera_down,"Down (free camera)" | ||||
| ACTION_camera_sprint,"Sprint (free camera)" | ||||
| ACTION_camera_cancel,"Reset free camera" | ||||
| ACTION_shot_zoom_in,"Zoom in" | ||||
| ACTION_shot_zoom_out,"Zoom out" | ||||
| ACTION_shot_accept,Shoot | ||||
| ACTION_shot_cancel,"Cancel shot" | ||||
| ACTION_shot_reset,"Reset shot" | ||||
| ACTION_select_driver,"Select driver" | ||||
| ACTION_select_iron,"Select iron" | ||||
| ACTION_select_wedge,"Select wedge" | ||||
| ACTION_select_special,"Select special" | ||||
| ACTION_select_putter,"Select putter" | ||||
| ACTION_club_next,"Select next club" | ||||
| ACTION_club_previous,"Select previous club" | ||||
| ACTION_pause,Pause | ||||
| ACTION_ball_next,"Select next ball" | ||||
| ACTION_ball_previous,"Select previous ball" | ||||
| 
 | 
							
								
								
									
										17
									
								
								assets/text/text.csv.import
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								assets/text/text.csv.import
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| [remap] | ||||
| 
 | ||||
| importer="csv_translation" | ||||
| type="Translation" | ||||
| uid="uid://cqh1mly60nrmw" | ||||
| 
 | ||||
| [deps] | ||||
| 
 | ||||
| files=["res://assets/text/text.en.translation"] | ||||
| 
 | ||||
| source_file="res://assets/text/text.csv" | ||||
| dest_files=["res://assets/text/text.en.translation"] | ||||
| 
 | ||||
| [params] | ||||
| 
 | ||||
| compress=true | ||||
| delimiter=0 | ||||
| @ -19,6 +19,7 @@ run/max_fps=60 | ||||
| [autoload] | ||||
| 
 | ||||
| ClubCatalog="*res://src/equipment/clubs/club_catalog.tscn" | ||||
| GameSettings="*res://src/game/game_settings.gd" | ||||
| 
 | ||||
| [debug] | ||||
| 
 | ||||
| @ -197,6 +198,20 @@ ball_previous={ | ||||
| "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":true,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194306,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) | ||||
| ] | ||||
| } | ||||
| club_next={ | ||||
| "deadzone": 0.5, | ||||
| "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(105, 13),"global_position":Vector2(114, 59),"factor":1.0,"button_index":8,"canceled":false,"pressed":true,"double_click":false,"script":null) | ||||
| ] | ||||
| } | ||||
| club_previous={ | ||||
| "deadzone": 0.5, | ||||
| "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(277, 2),"global_position":Vector2(286, 48),"factor":1.0,"button_index":9,"canceled":false,"pressed":true,"double_click":false,"script":null) | ||||
| ] | ||||
| } | ||||
| 
 | ||||
| [internationalization] | ||||
| 
 | ||||
| locale/translations=PackedStringArray("res://assets/text/text.en.translation") | ||||
| 
 | ||||
| [layer_names] | ||||
| 
 | ||||
|  | ||||
| @ -13,6 +13,9 @@ var _loading_resources := {} | ||||
| 
 | ||||
| static var group := "GameGroup"  # hey i'm group | ||||
| 
 | ||||
| ## Typesafe accessor for GameSettings singleton | ||||
| static var settings := GameSettings as GameSettingsType | ||||
| 
 | ||||
| 
 | ||||
| class Promise: | ||||
| 	var _callbacks: Array[Callable] = [] | ||||
|  | ||||
							
								
								
									
										29
									
								
								src/game/game_settings.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/game/game_settings.gd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| class_name GameSettingsType extends Node | ||||
| ## Container for project settings, for quick runtime access. | ||||
| 
 | ||||
| var free_camera_speed: float | ||||
| var x_sensitivity: float | ||||
| var y_sensitivity: float | ||||
| var x_acceleration: float | ||||
| var y_acceleration: float | ||||
| var invert_pitch: bool | ||||
| var enable_screen_shake: bool | ||||
| var enable_hit_lag: bool | ||||
| 
 | ||||
| 
 | ||||
| func _init() -> void: | ||||
| 	ProjectSettings.settings_changed.connect(_read_settings) | ||||
| 
 | ||||
| 
 | ||||
| func _read_settings() -> void: | ||||
| 	free_camera_speed = ProjectSettings.get_setting("game/config/controls/camera/free_camera_speed") | ||||
| 	x_sensitivity = ProjectSettings.get_setting("game/config/controls/camera/x_axis_sensitivity") | ||||
| 	y_sensitivity = ProjectSettings.get_setting("game/config/controls/camera/y_axis_sensitivity") | ||||
| 	x_acceleration = ProjectSettings.get_setting("game/config/controls/camera/x_axis_acceleration") | ||||
| 	y_acceleration = ProjectSettings.get_setting("game/config/controls/camera/y_axis_acceleration") | ||||
| 	invert_pitch = ProjectSettings.get_setting("game/config/controls/camera/invert_pitch") | ||||
| 
 | ||||
| 	enable_screen_shake = ProjectSettings.get_setting( | ||||
| 		"game/config/accessibility/enable_screen_shake" | ||||
| 	) | ||||
| 	enable_hit_lag = ProjectSettings.get_setting("game/config/accessibility/enable_hit_lag") | ||||
| @ -69,23 +69,6 @@ const EXPLOSIVE_FORCE_FACTOR := 0.12 | ||||
| 
 | ||||
| var player: WorldPlayer | ||||
| 
 | ||||
| var base_speed: float = ProjectSettings.get_setting("game/config/controls/camera/free_camera_speed") | ||||
| 
 | ||||
| var x_sensitivity: float = ProjectSettings.get_setting( | ||||
| 	"game/config/controls/camera/x_axis_sensitivity" | ||||
| ) | ||||
| var x_acceleration: float = ProjectSettings.get_setting( | ||||
| 	"game/config/controls/camera/x_axis_acceleration" | ||||
| ) | ||||
| var y_sensitivity: float = ProjectSettings.get_setting( | ||||
| 	"game/config/controls/camera/y_axis_sensitivity" | ||||
| ) | ||||
| var y_acceleration: float = ProjectSettings.get_setting( | ||||
| 	"game/config/controls/camera/y_axis_acceleration" | ||||
| ) | ||||
| 
 | ||||
| var invert_pitch: bool = ProjectSettings.get_setting("game/config/controls/camera/invert_pitch") | ||||
| 
 | ||||
| var control_disabled := false | ||||
| 
 | ||||
| var reset_enabled := false: | ||||
| @ -223,9 +206,15 @@ func _unhandled_input(event: InputEvent) -> void: | ||||
| func camera_motion(motion: Vector2) -> void: | ||||
| 	if not control_disabled and phase == Phase.AIM: | ||||
| 		# Can only control camera while aiming | ||||
| 		_target_rotation.y = _target_rotation.y - deg_to_rad(motion.x * x_sensitivity) | ||||
| 		_target_rotation.y = _target_rotation.y - deg_to_rad(motion.x * Game.settings.x_sensitivity) | ||||
| 		_target_rotation.x = clampf( | ||||
| 			_target_rotation.x - deg_to_rad(motion.y * y_sensitivity) * (-1 if invert_pitch else 1), | ||||
| 			( | ||||
| 				_target_rotation.x | ||||
| 				- ( | ||||
| 					deg_to_rad(motion.y * Game.settings.y_sensitivity) | ||||
| 					* (-1 if Game.settings.invert_pitch else 1) | ||||
| 				) | ||||
| 			), | ||||
| 			PITCH_MIN, | ||||
| 			PITCH_MAX | ||||
| 		) | ||||
| @ -493,9 +482,11 @@ func _process(delta: float) -> void: | ||||
| 	## Visual updates | ||||
| 	# Rotation | ||||
| 	direction.rotation.y = lerp_angle( | ||||
| 		direction.rotation.y, _target_rotation.y, delta * x_acceleration | ||||
| 		direction.rotation.y, _target_rotation.y, delta * Game.settings.x_acceleration | ||||
| 	) | ||||
| 	pitch.rotation.x = lerp_angle( | ||||
| 		pitch.rotation.x, _target_rotation.x, delta * Game.settings.y_acceleration | ||||
| 	) | ||||
| 	pitch.rotation.x = lerp_angle(pitch.rotation.x, _target_rotation.x, delta * y_acceleration) | ||||
| 
 | ||||
| 	# Arrow lags behind camera control | ||||
| 	arrow_pivot.rotation.y = lerp_angle( | ||||
|  | ||||
| @ -3,23 +3,6 @@ class_name FreeCamera extends CharacterBody3D | ||||
| const SPRINT_MULT := 3.0 | ||||
| const PITCH_LIMIT := deg_to_rad(85.0) | ||||
| 
 | ||||
| var base_speed: float = ProjectSettings.get_setting("game/config/controls/camera/free_camera_speed") | ||||
| 
 | ||||
| var x_sensitivity: float = ProjectSettings.get_setting( | ||||
| 	"game/config/controls/camera/x_axis_sensitivity" | ||||
| ) | ||||
| var x_acceleration: float = ProjectSettings.get_setting( | ||||
| 	"game/config/controls/camera/x_axis_acceleration" | ||||
| ) | ||||
| var y_sensitivity: float = ProjectSettings.get_setting( | ||||
| 	"game/config/controls/camera/y_axis_sensitivity" | ||||
| ) | ||||
| var y_acceleration: float = ProjectSettings.get_setting( | ||||
| 	"game/config/controls/camera/y_axis_acceleration" | ||||
| ) | ||||
| 
 | ||||
| var invert_pitch: bool = ProjectSettings.get_setting("game/config/controls/camera/invert_pitch") | ||||
| 
 | ||||
| @onready var _target := Vector2(rotation.x, rotation.y) | ||||
| 
 | ||||
| static var scene := preload("res://src/ui/camera/free_camera/free_camera.tscn") | ||||
| @ -34,9 +17,15 @@ func _unhandled_input(event: InputEvent) -> void: | ||||
| 
 | ||||
| 
 | ||||
| func camera_motion(motion: Vector2) -> void: | ||||
| 	_target.y = _target.y - deg_to_rad(motion.x * x_sensitivity) | ||||
| 	_target.y = _target.y - deg_to_rad(motion.x * Game.settings.x_sensitivity) | ||||
| 	_target.x = clampf( | ||||
| 		_target.x - deg_to_rad(motion.y * y_sensitivity) * (-1 if invert_pitch else 1), | ||||
| 		( | ||||
| 			_target.x | ||||
| 			- ( | ||||
| 				deg_to_rad(motion.y * Game.settings.y_sensitivity) | ||||
| 				* (-1 if Game.settings.invert_pitch else 1) | ||||
| 			) | ||||
| 		), | ||||
| 		-PITCH_LIMIT, | ||||
| 		PITCH_LIMIT, | ||||
| 	) | ||||
| @ -44,15 +33,15 @@ func camera_motion(motion: Vector2) -> void: | ||||
| 
 | ||||
| func _physics_process(delta: float) -> void: | ||||
| 	# Rotation | ||||
| 	rotation.y = lerp_angle(rotation.y, _target.y, delta * x_acceleration) | ||||
| 	rotation.x = lerp_angle(rotation.x, _target.x, delta * y_acceleration) | ||||
| 	rotation.y = lerp_angle(rotation.y, _target.y, delta * Game.settings.x_acceleration) | ||||
| 	rotation.x = lerp_angle(rotation.x, _target.x, delta * Game.settings.y_acceleration) | ||||
| 
 | ||||
| 	# Handle spatial movement | ||||
| 	var xz_input := Input.get_vector("camera_left", "camera_right", "camera_forward", "camera_back") | ||||
| 	var y_input := Input.get_vector("camera_down", "camera_up", "camera_down", "camera_up") | ||||
| 	var direction := (transform.basis * Vector3(xz_input.x, y_input.y, xz_input.y)).normalized() | ||||
| 
 | ||||
| 	var speed := base_speed | ||||
| 	var speed := Game.settings.free_camera_speed | ||||
| 	if Input.is_action_pressed("camera_sprint"): | ||||
| 		speed *= SPRINT_MULT | ||||
| 
 | ||||
|  | ||||
| @ -2,7 +2,7 @@ class_name OrbitalCamera extends Node3D | ||||
| 
 | ||||
| const POSITION_ACCELERATION := 4.0 | ||||
| const BASIS_ACCELERATION := 4.0 | ||||
| const TARGETER_ACCELERATION := 7.0 | ||||
| const TARGETER_ACCELERATION := 4.0 | ||||
| 
 | ||||
| @export var target: Node3D | ||||
| @export var offset := Vector3(0, 1, 0) | ||||
|  | ||||
							
								
								
									
										19
									
								
								src/ui/elements/checker_container.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/ui/elements/checker_container.gd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| @tool | ||||
| class_name CheckerContainer extends PanelContainer | ||||
| ## PanelContainer that sets its theme based on its parent parity | ||||
| 
 | ||||
| @export var even_variation := "CheckerContainerEven" | ||||
| @export var odd_variation := "CheckerContainerOdd" | ||||
| 
 | ||||
| 
 | ||||
| func _ready() -> void: | ||||
| 	get_parent().child_order_changed.connect(_recompute) | ||||
| 
 | ||||
| 
 | ||||
| func _is_even_child() -> bool: | ||||
| 	var parent := get_parent() | ||||
| 	return parent.get_children().find(self) % 2 if parent else false | ||||
| 
 | ||||
| 
 | ||||
| func _recompute() -> void: | ||||
| 	theme_type_variation = even_variation if _is_even_child() else odd_variation | ||||
| @ -26,7 +26,7 @@ func _update() -> void: | ||||
| 	var actions := InputMap.action_get_events(action) | ||||
| 	if actions: | ||||
| 		var primary := actions[0] | ||||
| 		input_symbol = _get_input_symbol(primary) | ||||
| 		input_symbol = PromptMap.from_event(primary) | ||||
| 
 | ||||
| 	text = PROMPT_FORMAT.format( | ||||
| 		[ | ||||
| @ -34,16 +34,3 @@ func _update() -> void: | ||||
| 			label if label else UNKNOWN_LABEL_SYM | ||||
| 		] | ||||
| 	) | ||||
| 
 | ||||
| 
 | ||||
| func _get_input_symbol(event: InputEvent) -> String: | ||||
| 	if event is InputEventKey: | ||||
| 		return PromptMap.key(event as InputEventKey) | ||||
| 	elif event is InputEventMouseButton: | ||||
| 		return PromptMap.mouse_button(event as InputEventMouseButton) | ||||
| 	elif event is InputEventJoypadButton: | ||||
| 		return PromptMap.gamepad_button(event as InputEventJoypadButton) | ||||
| 	elif event is InputEventJoypadMotion: | ||||
| 		return PromptMap.gamepad_axis(event as InputEventJoypadMotion) | ||||
| 	else: | ||||
| 		return PromptMap.UNKNOWN_INPUT_SYMBOL | ||||
| @ -1,6 +1,6 @@ | ||||
| [gd_scene load_steps=2 format=3 uid="uid://b47goj32i6sdh"] | ||||
| 
 | ||||
| [ext_resource type="Script" path="res://src/ui/input_prompt/input_prompt.gd" id="1_qq6w5"] | ||||
| [ext_resource type="Script" path="res://src/ui/elements/input_prompt/input_prompt.gd" id="1_qq6w5"] | ||||
| 
 | ||||
| [node name="InputPrompt" type="Label"] | ||||
| anchors_preset = 15 | ||||
| @ -11,4 +11,3 @@ grow_vertical = 2 | ||||
| theme_type_variation = &"InputPrompt" | ||||
| text = "❓ - [unknown]" | ||||
| script = ExtResource("1_qq6w5") | ||||
| action = "" | ||||
							
								
								
									
										97
									
								
								src/ui/elements/numeric_slider/numeric_slider.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								src/ui/elements/numeric_slider/numeric_slider.gd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,97 @@ | ||||
| @tool | ||||
| class_name NumericSlider extends HBoxContainer | ||||
| ## HSlider with an attached SpinBox | ||||
| 
 | ||||
| signal value_changed(value: float) | ||||
| 
 | ||||
| @export_category("Shared Range Properties") | ||||
| 
 | ||||
| @export var min_value := 0.0: | ||||
| 	set(v): | ||||
| 		_set_shared("min_value", v) | ||||
| 		min_value = v | ||||
| 
 | ||||
| @export var max_value := 100.0: | ||||
| 	set(v): | ||||
| 		_set_shared("max_value", v) | ||||
| 		max_value = v | ||||
| 
 | ||||
| @export var step := 1.0: | ||||
| 	set(v): | ||||
| 		_set_shared("step", v) | ||||
| 		step = v | ||||
| 
 | ||||
| @export var page := 0: | ||||
| 	set(v): | ||||
| 		_set_shared("page", v) | ||||
| 		page = v | ||||
| 
 | ||||
| @export var value: float: | ||||
| 	get: | ||||
| 		return _value | ||||
| 	set(v): | ||||
| 		_value = v | ||||
| 		value_changed.emit(v) | ||||
| 
 | ||||
| @export var exp_edit := false: | ||||
| 	set(v): | ||||
| 		_set_shared("exp_edit", v) | ||||
| 		exp_edit = v | ||||
| 
 | ||||
| @export var rounded := false: | ||||
| 	set(v): | ||||
| 		_set_shared("rounded", v) | ||||
| 		rounded = v | ||||
| 
 | ||||
| @export var allow_greater := false: | ||||
| 	set(v): | ||||
| 		_set_shared("allow_greater", v) | ||||
| 		allow_greater = v | ||||
| 
 | ||||
| @export var allow_lesser := false: | ||||
| 	set(v): | ||||
| 		_set_shared("allow_lesser", v) | ||||
| 		allow_lesser = v | ||||
| 
 | ||||
| var _value := 0.0: | ||||
| 	set(v): | ||||
| 		if slider: | ||||
| 			slider.set_value_no_signal(v) | ||||
| 		if spin_box: | ||||
| 			spin_box.set_value_no_signal(v) | ||||
| 		_value = v | ||||
| 
 | ||||
| @onready var slider: HSlider = $HSlider | ||||
| @onready var spin_box: SpinBox = $SpinBox | ||||
| 
 | ||||
| 
 | ||||
| func _ready() -> void: | ||||
| 	# Force propagation of properties to shared range elements | ||||
| 	min_value = min_value | ||||
| 	max_value = max_value | ||||
| 	step = step | ||||
| 	page = page | ||||
| 	_value = _value | ||||
| 	exp_edit = exp_edit | ||||
| 	rounded = rounded | ||||
| 	allow_greater = allow_greater | ||||
| 	allow_lesser = allow_lesser | ||||
| 
 | ||||
| 
 | ||||
| func set_value_no_signal(new_value: float) -> void: | ||||
| 	_value = new_value | ||||
| 
 | ||||
| 
 | ||||
| func _set_shared(property: String, new_value: Variant) -> void: | ||||
| 	if slider: | ||||
| 		slider.set(property, new_value) | ||||
| 	if spin_box: | ||||
| 		spin_box.set(property, new_value) | ||||
| 
 | ||||
| 
 | ||||
| func _on_spin_box_value_changed(new_value: float) -> void: | ||||
| 	value = new_value | ||||
| 
 | ||||
| 
 | ||||
| func _on_slider_value_changed(new_value: float) -> void: | ||||
| 	value = new_value | ||||
							
								
								
									
										27
									
								
								src/ui/elements/numeric_slider/numeric_slider.tscn
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/ui/elements/numeric_slider/numeric_slider.tscn
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| [gd_scene load_steps=2 format=3 uid="uid://dqqcyi26d3bpg"] | ||||
| 
 | ||||
| [ext_resource type="Script" path="res://src/ui/elements/numeric_slider/numeric_slider.gd" id="1_kcr4o"] | ||||
| 
 | ||||
| [node name="NumericSlider" type="HBoxContainer"] | ||||
| anchors_preset = 14 | ||||
| anchor_top = 0.5 | ||||
| anchor_right = 1.0 | ||||
| anchor_bottom = 0.5 | ||||
| offset_top = -8.0 | ||||
| offset_bottom = 10.0 | ||||
| grow_horizontal = 2 | ||||
| grow_vertical = 2 | ||||
| script = ExtResource("1_kcr4o") | ||||
| 
 | ||||
| [node name="HSlider" type="HSlider" parent="."] | ||||
| layout_mode = 2 | ||||
| size_flags_horizontal = 3 | ||||
| size_flags_vertical = 4 | ||||
| 
 | ||||
| [node name="SpinBox" type="SpinBox" parent="."] | ||||
| custom_minimum_size = Vector2(120, 0) | ||||
| layout_mode = 2 | ||||
| alignment = 2 | ||||
| 
 | ||||
| [connection signal="value_changed" from="HSlider" to="." method="_on_slider_value_changed"] | ||||
| [connection signal="value_changed" from="SpinBox" to="." method="_on_spin_box_value_changed"] | ||||
							
								
								
									
										29
									
								
								src/ui/elements/text_checkbox/text_checkbox.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/ui/elements/text_checkbox/text_checkbox.gd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| @tool | ||||
| extends CheckBox | ||||
| ## Checkbox which updates its label based on check state. | ||||
| 
 | ||||
| @export var true_text := "On": | ||||
| 	set(value): | ||||
| 		true_text = value | ||||
| 		_refresh() | ||||
| 
 | ||||
| @export var false_text := "Off": | ||||
| 	set(value): | ||||
| 		false_text = value | ||||
| 		_refresh() | ||||
| 
 | ||||
| 
 | ||||
| func _ready() -> void: | ||||
| 	_refresh() | ||||
| 
 | ||||
| 
 | ||||
| func _set_text(value: bool) -> void: | ||||
| 	text = true_text if value else false_text | ||||
| 
 | ||||
| 
 | ||||
| func _refresh() -> void: | ||||
| 	_set_text(button_pressed) | ||||
| 
 | ||||
| 
 | ||||
| func _on_toggled(toggled_on: bool) -> void: | ||||
| 	_set_text(toggled_on) | ||||
							
								
								
									
										10
									
								
								src/ui/elements/text_checkbox/text_checkbox.tscn
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/ui/elements/text_checkbox/text_checkbox.tscn
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| [gd_scene load_steps=2 format=3 uid="uid://b7ce38k7rx466"] | ||||
| 
 | ||||
| [ext_resource type="Script" path="res://src/ui/elements/text_checkbox/text_checkbox.gd" id="1_6mma0"] | ||||
| 
 | ||||
| [node name="TextCheckbox" type="CheckBox"] | ||||
| size_flags_horizontal = 0 | ||||
| text = "Off" | ||||
| script = ExtResource("1_6mma0") | ||||
| 
 | ||||
| [connection signal="toggled" from="." to="." method="_on_toggled"] | ||||
| @ -13,7 +13,7 @@ var _hit_lag_frames := -1 | ||||
| 
 | ||||
| ## Start playing a screen shake effect. | ||||
| func screen_shake(intensity: float, duration: float = 0.2) -> void: | ||||
| 	if not ProjectSettings.get_setting("game/config/accessibility/enable_screen_shake"): | ||||
| 	if not Game.settings.enable_screen_shake: | ||||
| 		return | ||||
| 
 | ||||
| 	var tween := get_tree().create_tween() | ||||
| @ -24,7 +24,7 @@ func screen_shake(intensity: float, duration: float = 0.2) -> void: | ||||
| 
 | ||||
| ## Rumble the screen indefinitely. | ||||
| func set_rumble(intensity: float) -> void: | ||||
| 	if not ProjectSettings.get_setting("game/config/accessibility/enable_screen_shake"): | ||||
| 	if not Game.settings.enable_screen_shake: | ||||
| 		return | ||||
| 
 | ||||
| 	rumbler.intensity = intensity | ||||
| @ -52,7 +52,7 @@ func hit_lag_huge() -> void: | ||||
| 
 | ||||
| ## Stop processing for some number of frames. | ||||
| func hit_lag(frames: int = 1) -> void: | ||||
| 	if not ProjectSettings.get_setting("game/config/accessibility/enable_hit_lag"): | ||||
| 	if not Game.settings.enable_hit_lag: | ||||
| 		return | ||||
| 
 | ||||
| 	_hit_lag_frames = frames | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| [gd_resource type="Theme" load_steps=6 format=3 uid="uid://diodjft5u2cck"] | ||||
| [gd_resource type="Theme" load_steps=9 format=3 uid="uid://diodjft5u2cck"] | ||||
| 
 | ||||
| [ext_resource type="FontFile" uid="uid://dsa0oh7c0h4pu" path="res://assets/fonts/Racing_Sans_One/RacingSansOne-Regular.ttf" id="1_3rv2b"] | ||||
| [ext_resource type="FontFile" uid="uid://comihs66wounx" path="res://assets/fonts/Dokdo/Dokdo-Regular.ttf" id="1_eha6a"] | ||||
| @ -6,9 +6,60 @@ | ||||
| [ext_resource type="FontFile" uid="uid://dyog4ex5nqfat" path="res://assets/fonts/promptfont/promptfont.otf" id="2_8kux8"] | ||||
| [ext_resource type="FontFile" uid="uid://s4c1kf0rk2mb" path="res://assets/fonts/Geo/Geo-Regular.ttf" id="3_cee6l"] | ||||
| 
 | ||||
| [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_rq1no"] | ||||
| content_margin_left = 0.0 | ||||
| content_margin_top = 0.0 | ||||
| content_margin_right = 0.0 | ||||
| content_margin_bottom = 0.0 | ||||
| bg_color = Color(0.1, 0.1, 0.1, 0.6) | ||||
| corner_radius_top_left = 3 | ||||
| corner_radius_top_right = 3 | ||||
| corner_radius_bottom_right = 3 | ||||
| corner_radius_bottom_left = 3 | ||||
| corner_detail = 5 | ||||
| 
 | ||||
| [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ja4y7"] | ||||
| content_margin_left = 0.0 | ||||
| content_margin_top = 0.0 | ||||
| content_margin_right = 0.0 | ||||
| content_margin_bottom = 0.0 | ||||
| bg_color = Color(0.2, 0.2, 0.2, 0.6) | ||||
| corner_radius_top_left = 3 | ||||
| corner_radius_top_right = 3 | ||||
| corner_radius_bottom_right = 3 | ||||
| corner_radius_bottom_left = 3 | ||||
| corner_detail = 5 | ||||
| 
 | ||||
| [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ynsl8"] | ||||
| content_margin_left = 36.0 | ||||
| content_margin_top = 8.0 | ||||
| content_margin_right = 36.0 | ||||
| content_margin_bottom = 8.0 | ||||
| bg_color = Color(0.1, 0.1, 0.1, 0.6) | ||||
| corner_radius_top_left = 3 | ||||
| corner_radius_top_right = 3 | ||||
| corner_radius_bottom_right = 3 | ||||
| corner_radius_bottom_left = 3 | ||||
| corner_detail = 5 | ||||
| 
 | ||||
| [resource] | ||||
| default_font = ExtResource("3_cee6l") | ||||
| default_font_size = 18 | ||||
| AlertButton/base_type = &"UIButton" | ||||
| AlertButton/colors/font_color = Color(0.819608, 0.196078, 0.196078, 1) | ||||
| AlertButton/colors/font_outline_color = Color(0, 0, 0, 1) | ||||
| AlertButton/constants/outline_size = 6 | ||||
| AlertButton/font_sizes/font_size = 24 | ||||
| AlertButton/fonts/font = ExtResource("2_5ty6u") | ||||
| CancelButton/base_type = &"UIButton" | ||||
| CancelButton/colors/font_outline_color = Color(0, 0, 0, 1) | ||||
| CancelButton/constants/outline_size = 6 | ||||
| CancelButton/font_sizes/font_size = 24 | ||||
| CancelButton/fonts/font = ExtResource("2_5ty6u") | ||||
| CheckerContainerEven/base_type = &"PanelContainer" | ||||
| CheckerContainerEven/styles/panel = SubResource("StyleBoxFlat_rq1no") | ||||
| CheckerContainerOdd/base_type = &"PanelContainer" | ||||
| CheckerContainerOdd/styles/panel = SubResource("StyleBoxFlat_ja4y7") | ||||
| ClubSelectLabel/base_type = &"Label" | ||||
| ClubSelectLabel/colors/font_color = Color(1, 0.933333, 0.894118, 1) | ||||
| ClubSelectLabel/colors/font_outline_color = Color(0, 0, 0, 1) | ||||
| @ -24,12 +75,17 @@ ClubSelectLabelDisabled/colors/font_outline_color = Color(0.2, 0.2, 0.2, 1) | ||||
| ClubSelectLabelDisabled/colors/font_shadow_color = Color(0.2, 0.2, 0.2, 1) | ||||
| ClubSelectLabelDisabled/font_sizes/font_size = 84 | ||||
| ClubSelectLabelDisabled/fonts/font = ExtResource("1_3rv2b") | ||||
| HeaderLarge/font_sizes/font_size = 28 | ||||
| HeaderMedium/font_sizes/font_size = 24 | ||||
| HeaderSmall/font_sizes/font_size = 20 | ||||
| HeaderXLarge/base_type = &"Label" | ||||
| HeaderXLarge/font_sizes/font_size = 36 | ||||
| InputPrompt/base_type = &"Label" | ||||
| InputPrompt/colors/font_color = Color(1, 1, 0.870588, 1) | ||||
| InputPrompt/constants/outline_size = 8 | ||||
| InputPrompt/font_sizes/font_size = 32 | ||||
| InputPrompt/fonts/font = ExtResource("2_8kux8") | ||||
| PauseMenuButton/base_type = &"Button" | ||||
| PauseMenuButton/base_type = &"UIButton" | ||||
| PauseMenuButton/colors/font_outline_color = Color(0, 0, 0, 1) | ||||
| PauseMenuButton/constants/outline_size = 6 | ||||
| PauseMenuButton/font_sizes/font_size = 32 | ||||
| @ -39,9 +95,29 @@ QuantityLabel/colors/font_color = Color(0.819608, 0.196078, 0.196078, 1) | ||||
| QuantityLabel/colors/font_outline_color = Color(1, 0.901961, 0.509804, 1) | ||||
| QuantityLabel/constants/outline_size = 6 | ||||
| QuantityLabel/font_sizes/font_size = 22 | ||||
| SettingsInputLabel/base_type = &"Label" | ||||
| SettingsInputLabel/colors/font_color = Color(1, 1, 0.870588, 1) | ||||
| SettingsInputLabel/colors/font_outline_color = Color(0, 0, 0, 1) | ||||
| SettingsInputLabel/constants/outline_size = 6 | ||||
| SettingsInputLabel/font_sizes/font_size = 36 | ||||
| SettingsInputLabel/fonts/font = ExtResource("2_5ty6u") | ||||
| SettingsList/base_type = &"VBoxContainer" | ||||
| SettingsList/constants/separation = 4 | ||||
| SettingsListMargin/base_type = &"MarginContainer" | ||||
| SettingsListMargin/constants/margin_bottom = 8 | ||||
| SettingsListMargin/constants/margin_left = 8 | ||||
| SettingsListMargin/constants/margin_right = 8 | ||||
| SettingsListMargin/constants/margin_top = 8 | ||||
| SettingsPageContainer/base_type = &"MarginContainer" | ||||
| SettingsPageContainer/constants/margin_bottom = 72 | ||||
| SettingsPageContainer/constants/margin_left = 72 | ||||
| SettingsPageContainer/constants/margin_right = 72 | ||||
| SettingsPageContainer/constants/margin_top = 72 | ||||
| ShotFeedback/base_type = &"RichTextLabel" | ||||
| ShotFeedback/colors/font_shadow_color = Color(0, 0, 0, 1) | ||||
| ShotFeedback/constants/shadow_offset_x = 6 | ||||
| ShotFeedback/constants/shadow_offset_y = 4 | ||||
| ShotFeedback/font_sizes/normal_font_size = 272 | ||||
| ShotFeedback/fonts/normal_font = ExtResource("1_eha6a") | ||||
| UIButton/base_type = &"Button" | ||||
| UIButton/styles/normal = SubResource("StyleBoxFlat_ynsl8") | ||||
|  | ||||
| @ -1,17 +1,18 @@ | ||||
| extends Control | ||||
| ## Menu shown in-game when the user presses pause. | ||||
| 
 | ||||
| const SETTINGS_SCENE := preload("res://src/ui/menus/settings_menu/settings_menu.tscn") | ||||
| 
 | ||||
| @onready var menu_list: VBoxContainer = %MenuList | ||||
| @onready var quit_confirm: CenterContainer = %QuitConfirm | ||||
| @onready var settings_container: MarginContainer = %SettingsContainer | ||||
| 
 | ||||
| 
 | ||||
| func _ready() -> void: | ||||
| 	print_debug("Pause menu _ready()") | ||||
| 	Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) | ||||
| 
 | ||||
| 
 | ||||
| func _exit_tree() -> void: | ||||
| 	print_debug("Pause menu _exit_tree()") | ||||
| 	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) | ||||
| 
 | ||||
| 
 | ||||
| @ -30,12 +31,14 @@ func _hide() -> void: | ||||
| 
 | ||||
| 
 | ||||
| func resume() -> void: | ||||
| 	print_debug("Pause menu resume()") | ||||
| 	queue_free() | ||||
| 
 | ||||
| 
 | ||||
| func settings() -> void: | ||||
| 	pass  # TODO | ||||
| 	var instance: Control = SETTINGS_SCENE.instantiate() | ||||
| 	settings_container.add_child(instance) | ||||
| 	instance.tree_exited.connect(_unhide) | ||||
| 	_hide() | ||||
| 
 | ||||
| 
 | ||||
| func quit() -> void: | ||||
|  | ||||
| @ -60,9 +60,25 @@ text = "Settings" | ||||
| [node name="QuitButton" type="Button" parent="MarginContainer/MenuList"] | ||||
| layout_mode = 2 | ||||
| theme_type_variation = &"PauseMenuButton" | ||||
| theme_override_colors/font_color = Color(1, 0.36, 0.36, 1) | ||||
| theme_override_colors/font_color = Color(0.819608, 0.196078, 0.196078, 1) | ||||
| text = "Quit" | ||||
| 
 | ||||
| [node name="SettingsContainer" type="MarginContainer" parent="."] | ||||
| unique_name_in_owner = true | ||||
| layout_mode = 1 | ||||
| anchors_preset = 8 | ||||
| anchor_left = 0.5 | ||||
| anchor_top = 0.5 | ||||
| anchor_right = 0.5 | ||||
| anchor_bottom = 0.5 | ||||
| offset_left = -640.0 | ||||
| offset_top = -360.0 | ||||
| offset_right = 640.0 | ||||
| offset_bottom = 360.0 | ||||
| grow_horizontal = 2 | ||||
| grow_vertical = 2 | ||||
| mouse_filter = 2 | ||||
| 
 | ||||
| [node name="QuitConfirm" type="CenterContainer" parent="."] | ||||
| unique_name_in_owner = true | ||||
| visible = false | ||||
| @ -88,7 +104,9 @@ layout_mode = 2 | ||||
| 
 | ||||
| [node name="Label" type="Label" parent="QuitConfirm/PanelContainer/MarginContainer/VBoxContainer"] | ||||
| layout_mode = 2 | ||||
| theme_override_font_sizes/font_size = 24 | ||||
| text = "Quit to desktop?" | ||||
| horizontal_alignment = 1 | ||||
| 
 | ||||
| [node name="HBoxContainer" type="HBoxContainer" parent="QuitConfirm/PanelContainer/MarginContainer/VBoxContainer"] | ||||
| layout_mode = 2 | ||||
| @ -97,11 +115,13 @@ theme_override_constants/separation = 16 | ||||
| [node name="CancelButton" type="Button" parent="QuitConfirm/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"] | ||||
| layout_mode = 2 | ||||
| size_flags_horizontal = 3 | ||||
| theme_type_variation = &"CancelButton" | ||||
| text = "Cancel" | ||||
| 
 | ||||
| [node name="ConfirmQuitButton" type="Button" parent="QuitConfirm/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"] | ||||
| layout_mode = 2 | ||||
| size_flags_horizontal = 3 | ||||
| theme_type_variation = &"AlertButton" | ||||
| text = "Quit" | ||||
| 
 | ||||
| [connection signal="pressed" from="MarginContainer/MenuList/ResumeButton" to="." method="resume"] | ||||
|  | ||||
| @ -0,0 +1,33 @@ | ||||
| class_name ControlBinding extends CheckerContainer | ||||
| ## Input for rebinding an action. | ||||
| 
 | ||||
| const ACTION_KEY_FMT := "ACTION_{0}" | ||||
| const SCENE := preload("res://src/ui/menus/settings_menu/control_binding/control_binding.tscn") | ||||
| 
 | ||||
| @export var key: StringName | ||||
| 
 | ||||
| @onready var action: Label = %Action | ||||
| @onready var binding: Label = %Binding | ||||
| 
 | ||||
| 
 | ||||
| func _ready() -> void: | ||||
| 	# gdlint:ignore = private-method-call | ||||
| 	super._ready() | ||||
| 
 | ||||
| 	# Set action label text | ||||
| 	var loc_action := tr(ACTION_KEY_FMT.format([key])) | ||||
| 	# Fall back to just the key if no localization exists | ||||
| 	@warning_ignore("incompatible_ternary") | ||||
| 	action.text = loc_action if loc_action else key | ||||
| 
 | ||||
| 	# Set the binding label | ||||
| 	var actions := InputMap.action_get_events(key) | ||||
| 	if actions: | ||||
| 		var primary := actions[0] | ||||
| 		binding.text = PromptMap.from_event(primary) | ||||
| 
 | ||||
| 
 | ||||
| static func create(_key: StringName) -> ControlBinding: | ||||
| 	var instance: ControlBinding = SCENE.instantiate() | ||||
| 	instance.key = _key | ||||
| 	return instance | ||||
| @ -0,0 +1,48 @@ | ||||
| [gd_scene load_steps=2 format=3 uid="uid://dwvpddd7id1h"] | ||||
| 
 | ||||
| [ext_resource type="Script" path="res://src/ui/menus/settings_menu/control_binding/control_binding.gd" id="1_7mwhu"] | ||||
| 
 | ||||
| [node name="ControlBinding" type="PanelContainer"] | ||||
| theme_type_variation = &"CheckerContainerOdd" | ||||
| script = ExtResource("1_7mwhu") | ||||
| 
 | ||||
| [node name="MarginContainer" type="MarginContainer" parent="."] | ||||
| layout_mode = 2 | ||||
| theme_override_constants/margin_left = 8 | ||||
| theme_override_constants/margin_top = 8 | ||||
| theme_override_constants/margin_right = 8 | ||||
| theme_override_constants/margin_bottom = 8 | ||||
| 
 | ||||
| [node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"] | ||||
| layout_mode = 2 | ||||
| theme_override_constants/separation = 48 | ||||
| alignment = 2 | ||||
| 
 | ||||
| [node name="Action" type="Label" parent="MarginContainer/HBoxContainer"] | ||||
| unique_name_in_owner = true | ||||
| layout_mode = 2 | ||||
| theme_type_variation = &"SettingsInputLabel" | ||||
| text = "Action" | ||||
| 
 | ||||
| [node name="Button" type="Button" parent="MarginContainer/HBoxContainer"] | ||||
| unique_name_in_owner = true | ||||
| custom_minimum_size = Vector2(300, 42) | ||||
| layout_mode = 2 | ||||
| 
 | ||||
| [node name="Binding" type="Label" parent="MarginContainer/HBoxContainer/Button"] | ||||
| unique_name_in_owner = true | ||||
| layout_mode = 1 | ||||
| anchors_preset = 8 | ||||
| anchor_left = 0.5 | ||||
| anchor_top = 0.5 | ||||
| anchor_right = 0.5 | ||||
| anchor_bottom = 0.5 | ||||
| offset_left = -13.0 | ||||
| offset_top = -19.5 | ||||
| offset_right = 13.0 | ||||
| offset_bottom = 19.5 | ||||
| grow_horizontal = 2 | ||||
| grow_vertical = 2 | ||||
| theme_type_variation = &"InputPrompt" | ||||
| text = "unset" | ||||
| horizontal_alignment = 1 | ||||
| @ -0,0 +1,12 @@ | ||||
| extends Setting | ||||
| ## Setting with checkbox representing a boolean value. | ||||
| 
 | ||||
| @onready var checkbox: CheckBox = %TextCheckbox | ||||
| 
 | ||||
| 
 | ||||
| func initialize_value(value: Variant) -> void: | ||||
| 	checkbox.button_pressed = value as bool | ||||
| 
 | ||||
| 
 | ||||
| func get_value() -> Variant: | ||||
| 	return checkbox.button_pressed | ||||
| @ -0,0 +1,12 @@ | ||||
| [gd_scene load_steps=4 format=3 uid="uid://bpmpj4n6xp17l"] | ||||
| 
 | ||||
| [ext_resource type="PackedScene" uid="uid://dcah6r3ku60g6" path="res://src/ui/menus/settings_menu/settings/setting/setting.tscn" id="1_5t42f"] | ||||
| [ext_resource type="Script" path="res://src/ui/menus/settings_menu/settings/checkbox_setting/checkbox_setting.gd" id="2_mwq55"] | ||||
| [ext_resource type="PackedScene" uid="uid://b7ce38k7rx466" path="res://src/ui/elements/text_checkbox/text_checkbox.tscn" id="3_fosy2"] | ||||
| 
 | ||||
| [node name="CheckboxSetting" instance=ExtResource("1_5t42f")] | ||||
| script = ExtResource("2_mwq55") | ||||
| 
 | ||||
| [node name="TextCheckbox" parent="PanelContainer/MarginContainer" index="0" instance=ExtResource("3_fosy2")] | ||||
| unique_name_in_owner = true | ||||
| layout_mode = 2 | ||||
| @ -0,0 +1,9 @@ | ||||
| [gd_scene load_steps=2 format=3 uid="uid://dpry41u0ctikn"] | ||||
| 
 | ||||
| [ext_resource type="PackedScene" uid="uid://dcah6r3ku60g6" path="res://src/ui/menus/settings_menu/settings/setting/setting.tscn" id="1_km84n"] | ||||
| 
 | ||||
| [node name="DropdownSetting" instance=ExtResource("1_km84n")] | ||||
| 
 | ||||
| [node name="OptionButton" type="OptionButton" parent="PanelContainer/MarginContainer" index="0"] | ||||
| layout_mode = 2 | ||||
| item_count = 1 | ||||
| @ -0,0 +1,12 @@ | ||||
| extends Setting | ||||
| ## Setting with numeric slider representing a floating-point value | ||||
| 
 | ||||
| @onready var slider: NumericSlider = %NumericSlider | ||||
| 
 | ||||
| 
 | ||||
| func initialize_value(value: Variant) -> void: | ||||
| 	slider.value = value as float | ||||
| 
 | ||||
| 
 | ||||
| func get_value() -> Variant: | ||||
| 	return slider.value | ||||
| @ -0,0 +1,12 @@ | ||||
| [gd_scene load_steps=4 format=3 uid="uid://dut1lj8ju37sq"] | ||||
| 
 | ||||
| [ext_resource type="PackedScene" uid="uid://dcah6r3ku60g6" path="res://src/ui/menus/settings_menu/settings/setting/setting.tscn" id="1_t2sut"] | ||||
| [ext_resource type="Script" path="res://src/ui/menus/settings_menu/settings/numeric_setting/numeric_setting.gd" id="2_3nkup"] | ||||
| [ext_resource type="PackedScene" uid="uid://dqqcyi26d3bpg" path="res://src/ui/elements/numeric_slider/numeric_slider.tscn" id="2_piwkl"] | ||||
| 
 | ||||
| [node name="NumericSetting" instance=ExtResource("1_t2sut")] | ||||
| script = ExtResource("2_3nkup") | ||||
| 
 | ||||
| [node name="NumericSlider" parent="PanelContainer/MarginContainer" index="0" instance=ExtResource("2_piwkl")] | ||||
| unique_name_in_owner = true | ||||
| layout_mode = 2 | ||||
							
								
								
									
										25
									
								
								src/ui/menus/settings_menu/settings/setting/setting.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/ui/menus/settings_menu/settings/setting/setting.gd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| class_name Setting extends HBoxContainer | ||||
| ## Base class for settings menu inputs | ||||
| 
 | ||||
| @export var key: StringName | ||||
| 
 | ||||
| 
 | ||||
| func _ready() -> void: | ||||
| 	if not Engine.is_editor_hint(): | ||||
| 		initialize_value(ProjectSettings.get_setting(key)) | ||||
| 
 | ||||
| 
 | ||||
| ## Initialize the value of this setting from project settings. | ||||
| func initialize_value(_value: Variant) -> void: | ||||
| 	pass  # Implemented in derived type | ||||
| 
 | ||||
| 
 | ||||
| ## Apply the set value of this setting to project settings. | ||||
| func apply() -> void: | ||||
| 	ProjectSettings.set_setting(key, get_value()) | ||||
| 
 | ||||
| 
 | ||||
| ## Get the raw value of this setting. | ||||
| func get_value() -> Variant: | ||||
| 	# Implemented in derived type | ||||
| 	return null | ||||
							
								
								
									
										26
									
								
								src/ui/menus/settings_menu/settings/setting/setting.tscn
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/ui/menus/settings_menu/settings/setting/setting.tscn
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| [gd_scene load_steps=2 format=3 uid="uid://dcah6r3ku60g6"] | ||||
| 
 | ||||
| [ext_resource type="Script" path="res://src/ui/menus/settings_menu/settings/setting/setting.gd" id="1_rrash"] | ||||
| 
 | ||||
| [node name="Setting" type="HBoxContainer"] | ||||
| script = ExtResource("1_rrash") | ||||
| 
 | ||||
| [node name="Spacer" type="HSeparator" parent="."] | ||||
| custom_minimum_size = Vector2(32, 0) | ||||
| layout_mode = 2 | ||||
| 
 | ||||
| [node name="SettingLabel" type="Label" parent="."] | ||||
| layout_mode = 2 | ||||
| size_flags_horizontal = 3 | ||||
| text = "Label" | ||||
| 
 | ||||
| [node name="PanelContainer" type="PanelContainer" parent="."] | ||||
| layout_mode = 2 | ||||
| size_flags_horizontal = 3 | ||||
| 
 | ||||
| [node name="MarginContainer" type="MarginContainer" parent="PanelContainer"] | ||||
| layout_mode = 2 | ||||
| theme_override_constants/margin_left = 4 | ||||
| theme_override_constants/margin_top = 2 | ||||
| theme_override_constants/margin_right = 4 | ||||
| theme_override_constants/margin_bottom = 2 | ||||
							
								
								
									
										47
									
								
								src/ui/menus/settings_menu/settings_menu.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/ui/menus/settings_menu/settings_menu.gd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | ||||
| extends MarginContainer | ||||
| ## Menu allowing the user to adjust game configuration. | ||||
| 
 | ||||
| const SETTINGS_GROUP := "Settings" | ||||
| const SETTINGS_FILE := "override.cfg" | ||||
| 
 | ||||
| @onready var control_binding_list: VBoxContainer = %ControlBindingList | ||||
| 
 | ||||
| 
 | ||||
| func _ready() -> void: | ||||
| 	populate_control_bindings() | ||||
| 
 | ||||
| 
 | ||||
| func _get_settings_elements() -> Array[Setting]: | ||||
| 	var elements: Array[Setting] = [] | ||||
| 	elements.assign(get_tree().get_nodes_in_group(SETTINGS_GROUP)) | ||||
| 	return elements | ||||
| 
 | ||||
| 
 | ||||
| func populate_control_bindings() -> void: | ||||
| 	InputMap.get | ||||
| 	for action: StringName in InputMap.get_actions(): | ||||
| 		if not action.begins_with("ui_"): | ||||
| 			control_binding_list.add_child(ControlBinding.create(action)) | ||||
| 
 | ||||
| 
 | ||||
| ## Close menu without applying settings. | ||||
| func cancel() -> void: | ||||
| 	queue_free() | ||||
| 
 | ||||
| 
 | ||||
| ## Apply all settings. | ||||
| func apply() -> void: | ||||
| 	for setting: Setting in _get_settings_elements(): | ||||
| 		setting.apply() | ||||
| 
 | ||||
| 
 | ||||
| ## Write all applied settings to disk. | ||||
| func save_settings() -> void: | ||||
| 	ProjectSettings.save_custom(SETTINGS_FILE) | ||||
| 
 | ||||
| 
 | ||||
| ## Apply settings and close menu. | ||||
| func accept() -> void: | ||||
| 	apply() | ||||
| 	save_settings() | ||||
| 	queue_free() | ||||
							
								
								
									
										308
									
								
								src/ui/menus/settings_menu/settings_menu.tscn
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										308
									
								
								src/ui/menus/settings_menu/settings_menu.tscn
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,308 @@ | ||||
| [gd_scene load_steps=4 format=3 uid="uid://d3eaqw2rdurct"] | ||||
| 
 | ||||
| [ext_resource type="Script" path="res://src/ui/menus/settings_menu/settings_menu.gd" id="1_lbcn7"] | ||||
| [ext_resource type="PackedScene" uid="uid://bpmpj4n6xp17l" path="res://src/ui/menus/settings_menu/settings/checkbox_setting/checkbox_setting.tscn" id="2_f274v"] | ||||
| [ext_resource type="PackedScene" uid="uid://dut1lj8ju37sq" path="res://src/ui/menus/settings_menu/settings/numeric_setting/numeric_setting.tscn" id="3_jox8e"] | ||||
| 
 | ||||
| [node name="SettingsMenu" type="MarginContainer"] | ||||
| anchors_preset = 15 | ||||
| anchor_right = 1.0 | ||||
| anchor_bottom = 1.0 | ||||
| grow_horizontal = 2 | ||||
| grow_vertical = 2 | ||||
| script = ExtResource("1_lbcn7") | ||||
| 
 | ||||
| [node name="TabContainer" type="TabContainer" parent="."] | ||||
| layout_mode = 2 | ||||
| current_tab = 3 | ||||
| 
 | ||||
| [node name="Game" type="MarginContainer" parent="TabContainer"] | ||||
| visible = false | ||||
| layout_mode = 2 | ||||
| theme_type_variation = &"SettingsPageContainer" | ||||
| metadata/_tab_index = 0 | ||||
| 
 | ||||
| [node name="VBoxContainer" type="VBoxContainer" parent="TabContainer/Game"] | ||||
| layout_mode = 2 | ||||
| 
 | ||||
| [node name="HBoxContainer" type="HBoxContainer" parent="TabContainer/Game/VBoxContainer"] | ||||
| layout_mode = 2 | ||||
| 
 | ||||
| [node name="Icon" type="Label" parent="TabContainer/Game/VBoxContainer/HBoxContainer"] | ||||
| layout_mode = 2 | ||||
| theme_type_variation = &"InputPrompt" | ||||
| text = "⚙" | ||||
| 
 | ||||
| [node name="Label" type="Label" parent="TabContainer/Game/VBoxContainer/HBoxContainer"] | ||||
| layout_mode = 2 | ||||
| size_flags_vertical = 8 | ||||
| theme_type_variation = &"HeaderXLarge" | ||||
| text = "Game Configuration" | ||||
| 
 | ||||
| [node name="ScrollContainer" type="ScrollContainer" parent="TabContainer/Game/VBoxContainer"] | ||||
| layout_mode = 2 | ||||
| size_flags_horizontal = 3 | ||||
| size_flags_vertical = 3 | ||||
| 
 | ||||
| [node name="MarginContainer" type="MarginContainer" parent="TabContainer/Game/VBoxContainer/ScrollContainer"] | ||||
| layout_mode = 2 | ||||
| size_flags_horizontal = 3 | ||||
| size_flags_vertical = 3 | ||||
| theme_type_variation = &"SettingsListMargin" | ||||
| 
 | ||||
| [node name="SettingsList" type="VBoxContainer" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer"] | ||||
| layout_mode = 2 | ||||
| 
 | ||||
| [node name="AccessibilityHeading" type="HBoxContainer" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList"] | ||||
| layout_mode = 2 | ||||
| 
 | ||||
| [node name="Label" type="Label" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/AccessibilityHeading"] | ||||
| layout_mode = 2 | ||||
| theme_type_variation = &"HeaderMedium" | ||||
| text = "Accessibility" | ||||
| 
 | ||||
| [node name="HSeparator" type="HSeparator" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/AccessibilityHeading"] | ||||
| layout_mode = 2 | ||||
| size_flags_horizontal = 3 | ||||
| 
 | ||||
| [node name="ScreenShake" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList" groups=["Settings"] instance=ExtResource("2_f274v")] | ||||
| layout_mode = 2 | ||||
| key = &"game/config/accessibility/enable_screen_shake" | ||||
| 
 | ||||
| [node name="SettingLabel" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/ScreenShake" index="1"] | ||||
| text = "Enable Screen Shake" | ||||
| 
 | ||||
| [node name="HitLag" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList" groups=["Settings"] instance=ExtResource("2_f274v")] | ||||
| layout_mode = 2 | ||||
| key = &"game/config/accessibility/enable_hit_lag" | ||||
| 
 | ||||
| [node name="SettingLabel" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/HitLag" index="1"] | ||||
| text = "Enable Hit Lag Effect" | ||||
| 
 | ||||
| [node name="CameraHeading" type="HBoxContainer" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList"] | ||||
| layout_mode = 2 | ||||
| 
 | ||||
| [node name="Label" type="Label" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/CameraHeading"] | ||||
| layout_mode = 2 | ||||
| theme_type_variation = &"HeaderMedium" | ||||
| text = "Camera" | ||||
| 
 | ||||
| [node name="HSeparator" type="HSeparator" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/CameraHeading"] | ||||
| layout_mode = 2 | ||||
| size_flags_horizontal = 3 | ||||
| 
 | ||||
| [node name="FreeCameraSpeed" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList" groups=["Settings"] instance=ExtResource("3_jox8e")] | ||||
| layout_mode = 2 | ||||
| key = &"game/config/controls/camera/free_camera_speed" | ||||
| 
 | ||||
| [node name="SettingLabel" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/FreeCameraSpeed" index="1"] | ||||
| text = "Free Camera Speed" | ||||
| 
 | ||||
| [node name="NumericSlider" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/FreeCameraSpeed/PanelContainer/MarginContainer" index="0"] | ||||
| step = 0.1 | ||||
| 
 | ||||
| [node name="HSlider" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/FreeCameraSpeed/PanelContainer/MarginContainer/NumericSlider" index="0"] | ||||
| step = 0.1 | ||||
| 
 | ||||
| [node name="SpinBox" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/FreeCameraSpeed/PanelContainer/MarginContainer/NumericSlider" index="1"] | ||||
| step = 0.1 | ||||
| suffix = "m/s" | ||||
| 
 | ||||
| [node name="SensitivityX" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList" groups=["Settings"] instance=ExtResource("3_jox8e")] | ||||
| layout_mode = 2 | ||||
| key = &"game/config/controls/camera/x_axis_sensitivity" | ||||
| 
 | ||||
| [node name="SettingLabel" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/SensitivityX" index="1"] | ||||
| text = "Sensitivity, Horizontal" | ||||
| 
 | ||||
| [node name="NumericSlider" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/SensitivityX/PanelContainer/MarginContainer" index="0"] | ||||
| max_value = 4.0 | ||||
| step = 0.01 | ||||
| 
 | ||||
| [node name="SensitivityY" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList" groups=["Settings"] instance=ExtResource("3_jox8e")] | ||||
| layout_mode = 2 | ||||
| key = &"game/config/controls/camera/y_axis_sensitivity" | ||||
| 
 | ||||
| [node name="SettingLabel" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/SensitivityY" index="1"] | ||||
| text = "Sensitivity, Vertical" | ||||
| 
 | ||||
| [node name="NumericSlider" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/SensitivityY/PanelContainer/MarginContainer" index="0"] | ||||
| max_value = 4.0 | ||||
| step = 0.01 | ||||
| 
 | ||||
| [node name="AccelerationX" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList" groups=["Settings"] instance=ExtResource("3_jox8e")] | ||||
| layout_mode = 2 | ||||
| key = &"game/config/controls/camera/x_axis_acceleration" | ||||
| 
 | ||||
| [node name="SettingLabel" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/AccelerationX" index="1"] | ||||
| text = "Acceleration, Horizontal" | ||||
| 
 | ||||
| [node name="NumericSlider" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/AccelerationX/PanelContainer/MarginContainer" index="0"] | ||||
| step = 0.1 | ||||
| 
 | ||||
| [node name="AccelerationY" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList" groups=["Settings"] instance=ExtResource("3_jox8e")] | ||||
| layout_mode = 2 | ||||
| key = &"game/config/controls/camera/y_axis_acceleration" | ||||
| 
 | ||||
| [node name="SettingLabel" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/AccelerationY" index="1"] | ||||
| text = "Acceleration, Vertical" | ||||
| 
 | ||||
| [node name="NumericSlider" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/AccelerationY/PanelContainer/MarginContainer" index="0"] | ||||
| step = 0.1 | ||||
| 
 | ||||
| [node name="InvertPitch" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList" groups=["Settings"] instance=ExtResource("2_f274v")] | ||||
| layout_mode = 2 | ||||
| key = &"game/config/controls/camera/invert_pitch" | ||||
| 
 | ||||
| [node name="SettingLabel" parent="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/InvertPitch" index="1"] | ||||
| text = "Invert Pitch" | ||||
| 
 | ||||
| [node name="Graphics" type="MarginContainer" parent="TabContainer"] | ||||
| visible = false | ||||
| layout_mode = 2 | ||||
| theme_type_variation = &"SettingsPageContainer" | ||||
| metadata/_tab_index = 1 | ||||
| 
 | ||||
| [node name="VBoxContainer" type="VBoxContainer" parent="TabContainer/Graphics"] | ||||
| layout_mode = 2 | ||||
| 
 | ||||
| [node name="HBoxContainer" type="HBoxContainer" parent="TabContainer/Graphics/VBoxContainer"] | ||||
| layout_mode = 2 | ||||
| 
 | ||||
| [node name="Icon" type="Label" parent="TabContainer/Graphics/VBoxContainer/HBoxContainer"] | ||||
| layout_mode = 2 | ||||
| theme_type_variation = &"InputPrompt" | ||||
| text = "🖵 | ||||
| " | ||||
| 
 | ||||
| [node name="Label" type="Label" parent="TabContainer/Graphics/VBoxContainer/HBoxContainer"] | ||||
| layout_mode = 2 | ||||
| size_flags_vertical = 8 | ||||
| theme_type_variation = &"HeaderXLarge" | ||||
| text = "Graphics & Display" | ||||
| 
 | ||||
| [node name="ScrollContainer" type="ScrollContainer" parent="TabContainer/Graphics/VBoxContainer"] | ||||
| layout_mode = 2 | ||||
| size_flags_horizontal = 3 | ||||
| size_flags_vertical = 3 | ||||
| 
 | ||||
| [node name="MarginContainer" type="MarginContainer" parent="TabContainer/Graphics/VBoxContainer/ScrollContainer"] | ||||
| layout_mode = 2 | ||||
| size_flags_horizontal = 3 | ||||
| size_flags_vertical = 3 | ||||
| theme_type_variation = &"SettingsListMargin" | ||||
| 
 | ||||
| [node name="SettingsList" type="VBoxContainer" parent="TabContainer/Graphics/VBoxContainer/ScrollContainer/MarginContainer"] | ||||
| layout_mode = 2 | ||||
| 
 | ||||
| [node name="Audio" type="MarginContainer" parent="TabContainer"] | ||||
| visible = false | ||||
| layout_mode = 2 | ||||
| theme_type_variation = &"SettingsPageContainer" | ||||
| metadata/_tab_index = 2 | ||||
| 
 | ||||
| [node name="VBoxContainer" type="VBoxContainer" parent="TabContainer/Audio"] | ||||
| layout_mode = 2 | ||||
| 
 | ||||
| [node name="HBoxContainer" type="HBoxContainer" parent="TabContainer/Audio/VBoxContainer"] | ||||
| layout_mode = 2 | ||||
| 
 | ||||
| [node name="Icon" type="Label" parent="TabContainer/Audio/VBoxContainer/HBoxContainer"] | ||||
| layout_mode = 2 | ||||
| theme_type_variation = &"InputPrompt" | ||||
| text = "🕬" | ||||
| 
 | ||||
| [node name="Label" type="Label" parent="TabContainer/Audio/VBoxContainer/HBoxContainer"] | ||||
| layout_mode = 2 | ||||
| size_flags_vertical = 8 | ||||
| theme_type_variation = &"HeaderXLarge" | ||||
| text = "Audio Settings" | ||||
| 
 | ||||
| [node name="ScrollContainer" type="ScrollContainer" parent="TabContainer/Audio/VBoxContainer"] | ||||
| layout_mode = 2 | ||||
| size_flags_horizontal = 3 | ||||
| size_flags_vertical = 3 | ||||
| 
 | ||||
| [node name="MarginContainer" type="MarginContainer" parent="TabContainer/Audio/VBoxContainer/ScrollContainer"] | ||||
| layout_mode = 2 | ||||
| size_flags_horizontal = 3 | ||||
| size_flags_vertical = 3 | ||||
| theme_type_variation = &"SettingsListMargin" | ||||
| 
 | ||||
| [node name="SettingsList" type="VBoxContainer" parent="TabContainer/Audio/VBoxContainer/ScrollContainer/MarginContainer"] | ||||
| layout_mode = 2 | ||||
| 
 | ||||
| [node name="Controls" type="MarginContainer" parent="TabContainer"] | ||||
| layout_mode = 2 | ||||
| theme_type_variation = &"SettingsPageContainer" | ||||
| metadata/_tab_index = 3 | ||||
| 
 | ||||
| [node name="VBoxContainer" type="VBoxContainer" parent="TabContainer/Controls"] | ||||
| layout_mode = 2 | ||||
| 
 | ||||
| [node name="HBoxContainer" type="HBoxContainer" parent="TabContainer/Controls/VBoxContainer"] | ||||
| layout_mode = 2 | ||||
| 
 | ||||
| [node name="Icon" type="Label" parent="TabContainer/Controls/VBoxContainer/HBoxContainer"] | ||||
| layout_mode = 2 | ||||
| theme_type_variation = &"InputPrompt" | ||||
| text = "" | ||||
| 
 | ||||
| [node name="Label" type="Label" parent="TabContainer/Controls/VBoxContainer/HBoxContainer"] | ||||
| layout_mode = 2 | ||||
| size_flags_vertical = 8 | ||||
| theme_type_variation = &"HeaderXLarge" | ||||
| text = "Control Bindings" | ||||
| 
 | ||||
| [node name="ScrollContainer" type="ScrollContainer" parent="TabContainer/Controls/VBoxContainer"] | ||||
| layout_mode = 2 | ||||
| size_flags_horizontal = 3 | ||||
| size_flags_vertical = 3 | ||||
| 
 | ||||
| [node name="MarginContainer" type="MarginContainer" parent="TabContainer/Controls/VBoxContainer/ScrollContainer"] | ||||
| layout_mode = 2 | ||||
| size_flags_horizontal = 3 | ||||
| size_flags_vertical = 3 | ||||
| theme_type_variation = &"SettingsListMargin" | ||||
| 
 | ||||
| [node name="ControlBindingList" type="VBoxContainer" parent="TabContainer/Controls/VBoxContainer/ScrollContainer/MarginContainer"] | ||||
| unique_name_in_owner = true | ||||
| layout_mode = 2 | ||||
| 
 | ||||
| [node name="SouthEast" type="MarginContainer" parent="."] | ||||
| layout_mode = 2 | ||||
| size_flags_horizontal = 8 | ||||
| size_flags_vertical = 8 | ||||
| theme_override_constants/margin_left = 16 | ||||
| theme_override_constants/margin_top = 16 | ||||
| theme_override_constants/margin_right = 16 | ||||
| theme_override_constants/margin_bottom = 16 | ||||
| 
 | ||||
| [node name="HBoxContainer" type="HBoxContainer" parent="SouthEast"] | ||||
| layout_mode = 2 | ||||
| theme_override_constants/separation = 16 | ||||
| 
 | ||||
| [node name="CancelButton" type="Button" parent="SouthEast/HBoxContainer"] | ||||
| layout_mode = 2 | ||||
| theme_type_variation = &"CancelButton" | ||||
| text = "Cancel | ||||
| " | ||||
| 
 | ||||
| [node name="AcceptButton" type="Button" parent="SouthEast/HBoxContainer"] | ||||
| layout_mode = 2 | ||||
| theme_type_variation = &"AlertButton" | ||||
| text = "Accept | ||||
| " | ||||
| 
 | ||||
| [connection signal="pressed" from="SouthEast/HBoxContainer/CancelButton" to="." method="cancel"] | ||||
| [connection signal="pressed" from="SouthEast/HBoxContainer/AcceptButton" to="." method="accept"] | ||||
| 
 | ||||
| [editable path="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/ScreenShake"] | ||||
| [editable path="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/HitLag"] | ||||
| [editable path="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/FreeCameraSpeed"] | ||||
| [editable path="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/FreeCameraSpeed/PanelContainer/MarginContainer/NumericSlider"] | ||||
| [editable path="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/SensitivityX"] | ||||
| [editable path="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/SensitivityY"] | ||||
| [editable path="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/AccelerationX"] | ||||
| [editable path="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/AccelerationY"] | ||||
| [editable path="TabContainer/Game/VBoxContainer/ScrollContainer/MarginContainer/SettingsList/InvertPitch"] | ||||
| @ -13,7 +13,7 @@ | ||||
| [ext_resource type="FontFile" uid="uid://dsa0oh7c0h4pu" path="res://assets/fonts/Racing_Sans_One/RacingSansOne-Regular.ttf" id="8_bejx4"] | ||||
| [ext_resource type="Texture2D" uid="uid://tancoet1lih5" path="res://assets/ui/ball_icons/basic_icon.png" id="8_tt8i3"] | ||||
| [ext_resource type="PackedScene" uid="uid://dmciuk3pbjsae" path="res://src/ui/shot_hud/life_bar/life_bar.tscn" id="9_w1fiw"] | ||||
| [ext_resource type="PackedScene" uid="uid://b47goj32i6sdh" path="res://src/ui/input_prompt/input_prompt.tscn" id="14_ik4gg"] | ||||
| [ext_resource type="PackedScene" uid="uid://b47goj32i6sdh" path="res://src/ui/elements/input_prompt/input_prompt.tscn" id="14_ik4gg"] | ||||
| 
 | ||||
| [sub_resource type="Animation" id="Animation_3xds6"] | ||||
| resource_name = "RESET" | ||||
| @ -654,6 +654,33 @@ fill_from = Vector2(0, 0.4) | ||||
| fill_to = Vector2(1, 0.6) | ||||
| metadata/_snap_enabled = true | ||||
| 
 | ||||
| [sub_resource type="Animation" id="Animation_3dab1"] | ||||
| length = 0.001 | ||||
| tracks/0/type = "value" | ||||
| tracks/0/imported = false | ||||
| tracks/0/enabled = true | ||||
| tracks/0/path = NodePath("Glint:anchor_left") | ||||
| tracks/0/interp = 1 | ||||
| tracks/0/loop_wrap = true | ||||
| tracks/0/keys = { | ||||
| "times": PackedFloat32Array(0), | ||||
| "transitions": PackedFloat32Array(1), | ||||
| "update": 0, | ||||
| "values": [-1.0] | ||||
| } | ||||
| tracks/1/type = "value" | ||||
| tracks/1/imported = false | ||||
| tracks/1/enabled = true | ||||
| tracks/1/path = NodePath("Glint:anchor_right") | ||||
| tracks/1/interp = 1 | ||||
| tracks/1/loop_wrap = true | ||||
| tracks/1/keys = { | ||||
| "times": PackedFloat32Array(0), | ||||
| "transitions": PackedFloat32Array(1), | ||||
| "update": 0, | ||||
| "values": [0.0] | ||||
| } | ||||
| 
 | ||||
| [sub_resource type="Animation" id="Animation_ornnh"] | ||||
| resource_name = "idle" | ||||
| length = 6.0 | ||||
| @ -683,39 +710,26 @@ tracks/1/keys = { | ||||
| "values": [0.0, 2.0] | ||||
| } | ||||
| 
 | ||||
| [sub_resource type="Animation" id="Animation_3dab1"] | ||||
| length = 0.001 | ||||
| tracks/0/type = "value" | ||||
| tracks/0/imported = false | ||||
| tracks/0/enabled = true | ||||
| tracks/0/path = NodePath("Glint:anchor_left") | ||||
| tracks/0/interp = 1 | ||||
| tracks/0/loop_wrap = true | ||||
| tracks/0/keys = { | ||||
| "times": PackedFloat32Array(0), | ||||
| "transitions": PackedFloat32Array(1), | ||||
| "update": 0, | ||||
| "values": [-1.0] | ||||
| } | ||||
| tracks/1/type = "value" | ||||
| tracks/1/imported = false | ||||
| tracks/1/enabled = true | ||||
| tracks/1/path = NodePath("Glint:anchor_right") | ||||
| tracks/1/interp = 1 | ||||
| tracks/1/loop_wrap = true | ||||
| tracks/1/keys = { | ||||
| "times": PackedFloat32Array(0), | ||||
| "transitions": PackedFloat32Array(1), | ||||
| "update": 0, | ||||
| "values": [0.0] | ||||
| } | ||||
| 
 | ||||
| [sub_resource type="AnimationLibrary" id="AnimationLibrary_bdkm3"] | ||||
| _data = { | ||||
| "RESET": SubResource("Animation_3dab1"), | ||||
| "idle": SubResource("Animation_ornnh") | ||||
| } | ||||
| 
 | ||||
| [sub_resource type="Animation" id="Animation_qjs4v"] | ||||
| length = 0.001 | ||||
| tracks/0/type = "bezier" | ||||
| tracks/0/imported = false | ||||
| tracks/0/enabled = true | ||||
| tracks/0/path = NodePath(".:position:y") | ||||
| tracks/0/interp = 1 | ||||
| tracks/0/loop_wrap = true | ||||
| tracks/0/keys = { | ||||
| "handle_modes": PackedInt32Array(0), | ||||
| "points": PackedFloat32Array(-55, -0.25, 0, 0.25, 0), | ||||
| "times": PackedFloat32Array(0) | ||||
| } | ||||
| 
 | ||||
| [sub_resource type="Animation" id="Animation_ll1u8"] | ||||
| resource_name = "show" | ||||
| length = 0.4 | ||||
| @ -731,20 +745,6 @@ tracks/0/keys = { | ||||
| "times": PackedFloat32Array(0, 0.4) | ||||
| } | ||||
| 
 | ||||
| [sub_resource type="Animation" id="Animation_qjs4v"] | ||||
| length = 0.001 | ||||
| tracks/0/type = "bezier" | ||||
| tracks/0/imported = false | ||||
| tracks/0/enabled = true | ||||
| tracks/0/path = NodePath(".:position:y") | ||||
| tracks/0/interp = 1 | ||||
| tracks/0/loop_wrap = true | ||||
| tracks/0/keys = { | ||||
| "handle_modes": PackedInt32Array(0), | ||||
| "points": PackedFloat32Array(-55, -0.25, 0, 0.25, 0), | ||||
| "times": PackedFloat32Array(0) | ||||
| } | ||||
| 
 | ||||
| [sub_resource type="AnimationLibrary" id="AnimationLibrary_o70c6"] | ||||
| _data = { | ||||
| "RESET": SubResource("Animation_qjs4v"), | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| class_name PromptMap | ||||
| ## Tools for mapping input events to PromptFont glyphs. | ||||
| 
 | ||||
| const COMPOSE_FMT := "{0}+{1}" | ||||
| const UNKNOWN_INPUT_SYMBOL := PromptFont.ICON_QUESTION | ||||
| 
 | ||||
| ## Keyboard key map | ||||
| @ -12,6 +13,7 @@ const KEYBOARD := { | ||||
| 	KEY_CTRL: PromptFont.KEYBOARD_CONTROL, | ||||
| 	KEY_ALT: PromptFont.KEYBOARD_ALT, | ||||
| 	KEY_SHIFT: PromptFont.KEYBOARD_SHIFT, | ||||
| 	KEY_META: PromptFont.KEYBOARD_SUPER, | ||||
| 	KEY_TAB: PromptFont.KEYBOARD_TAB, | ||||
| 	KEY_CAPSLOCK: PromptFont.KEYBOARD_CAPS, | ||||
| 	KEY_BACKSPACE: PromptFont.KEYBOARD_BACKSPACE, | ||||
| @ -203,6 +205,20 @@ const NINTENDO_AXIS := { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static func _compose_modifiers(event: InputEventWithModifiers, base: String) -> String: | ||||
| 	# Control -> Alt -> Shift -> Super/Meta | ||||
| 	var composed := base | ||||
| 	if event.meta_pressed: | ||||
| 		composed = COMPOSE_FMT.format([PromptFont.KEYBOARD_SUPER, composed]) | ||||
| 	if event.shift_pressed: | ||||
| 		composed = COMPOSE_FMT.format([PromptFont.KEYBOARD_SHIFT, composed]) | ||||
| 	if event.alt_pressed: | ||||
| 		composed = COMPOSE_FMT.format([PromptFont.KEYBOARD_ALT, composed]) | ||||
| 	if event.ctrl_pressed: | ||||
| 		composed = COMPOSE_FMT.format([PromptFont.KEYBOARD_CONTROL, composed]) | ||||
| 	return composed | ||||
| 
 | ||||
| 
 | ||||
| ## Get the symbol representing the given keyboard input event. | ||||
| ## | ||||
| ## If there is no such symbol available, returns the key label. | ||||
| @ -211,12 +227,12 @@ static func key(event: InputEventKey) -> String: | ||||
| 		return OS.get_keycode_string( | ||||
| 			DisplayServer.keyboard_get_keycode_from_physical(event.physical_keycode) | ||||
| 		) | ||||
| 	return KEYBOARD[event.physical_keycode] | ||||
| 	return _compose_modifiers(event, KEYBOARD[event.physical_keycode] as String) | ||||
| 
 | ||||
| 
 | ||||
| ## Get the symbol representing the given mouse button event. | ||||
| static func mouse_button(event: InputEventMouseButton) -> String: | ||||
| 	return MOUSE.get(event.button_index, UNKNOWN_INPUT_SYMBOL) | ||||
| 	return _compose_modifiers(event, MOUSE.get(event.button_index, UNKNOWN_INPUT_SYMBOL) as String) | ||||
| 
 | ||||
| 
 | ||||
| ## Get the symbol representing the given gamepad button event. | ||||
| @ -269,3 +285,16 @@ static func nintendo_button(event: InputEventJoypadButton) -> String: | ||||
| ## Symbols specific to Nintendo Switch joycons will be used where possible. | ||||
| static func nintendo_axis(event: InputEventJoypadMotion) -> String: | ||||
| 	return NINTENDO_AXIS.get(event.axis, gamepad_axis(event)) | ||||
| 
 | ||||
| 
 | ||||
| ## Get the symbol representing the given event. | ||||
| static func from_event(event: InputEvent) -> String: | ||||
| 	if event is InputEventKey: | ||||
| 		return key(event as InputEventKey) | ||||
| 	if event is InputEventMouseButton: | ||||
| 		return mouse_button(event as InputEventMouseButton) | ||||
| 	if event is InputEventJoypadButton: | ||||
| 		return gamepad_button(event as InputEventJoypadButton) | ||||
| 	if event is InputEventJoypadMotion: | ||||
| 		return gamepad_axis(event as InputEventJoypadMotion) | ||||
| 	return UNKNOWN_INPUT_SYMBOL | ||||
| @ -1,4 +1,4 @@ | ||||
| [gd_scene load_steps=9 format=3 uid="uid://cwnwcd8kushl3"] | ||||
| [gd_scene load_steps=8 format=3 uid="uid://cwnwcd8kushl3"] | ||||
| 
 | ||||
| [ext_resource type="Script" path="res://src/world/world.gd" id="1_ybjyx"] | ||||
| [ext_resource type="PackedScene" uid="uid://bm2o3mex10v11" path="res://levels/debug_level/debug_level.tscn" id="2_0xu5a"] | ||||
| @ -6,11 +6,10 @@ | ||||
| [ext_resource type="Script" path="res://src/ui/world_ui.gd" id="2_imewa"] | ||||
| [ext_resource type="Resource" uid="uid://crock3revdn73" path="res://src/player/debug_player.tres" id="3_pyw81"] | ||||
| [ext_resource type="Script" path="res://src/world/play_manager/round_robin_manager.gd" id="5_h6mje"] | ||||
| [ext_resource type="Resource" uid="uid://b5j0lmo4jayk4" path="res://src/player/debug_orange.tres" id="5_ym50e"] | ||||
| 
 | ||||
| [sub_resource type="Resource" id="Resource_rdjhi"] | ||||
| script = ExtResource("5_h6mje") | ||||
| players = Array[ExtResource("2_e743i")]([ExtResource("3_pyw81"), ExtResource("5_ym50e")]) | ||||
| players = Array[ExtResource("2_e743i")]([ExtResource("3_pyw81")]) | ||||
| 
 | ||||
| [node name="World" type="Node" groups=["WorldGroup"]] | ||||
| script = ExtResource("1_ybjyx") | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user