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 | # Godot-specific ignores | ||||||
| .import/ | .import/ | ||||||
|  | override.cfg | ||||||
| export.cfg | export.cfg | ||||||
| export_presets.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] | [autoload] | ||||||
| 
 | 
 | ||||||
| ClubCatalog="*res://src/equipment/clubs/club_catalog.tscn" | ClubCatalog="*res://src/equipment/clubs/club_catalog.tscn" | ||||||
|  | GameSettings="*res://src/game/game_settings.gd" | ||||||
| 
 | 
 | ||||||
| [debug] | [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) | "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] | [layer_names] | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -13,6 +13,9 @@ var _loading_resources := {} | |||||||
| 
 | 
 | ||||||
| static var group := "GameGroup"  # hey i'm group | static var group := "GameGroup"  # hey i'm group | ||||||
| 
 | 
 | ||||||
|  | ## Typesafe accessor for GameSettings singleton | ||||||
|  | static var settings := GameSettings as GameSettingsType | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class Promise: | class Promise: | ||||||
| 	var _callbacks: Array[Callable] = [] | 	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 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 control_disabled := false | ||||||
| 
 | 
 | ||||||
| var reset_enabled := false: | var reset_enabled := false: | ||||||
| @ -223,9 +206,15 @@ func _unhandled_input(event: InputEvent) -> void: | |||||||
| func camera_motion(motion: Vector2) -> void: | func camera_motion(motion: Vector2) -> void: | ||||||
| 	if not control_disabled and phase == Phase.AIM: | 	if not control_disabled and phase == Phase.AIM: | ||||||
| 		# Can only control camera while aiming | 		# 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 = 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_MIN, | ||||||
| 			PITCH_MAX | 			PITCH_MAX | ||||||
| 		) | 		) | ||||||
| @ -493,9 +482,11 @@ func _process(delta: float) -> void: | |||||||
| 	## Visual updates | 	## Visual updates | ||||||
| 	# Rotation | 	# Rotation | ||||||
| 	direction.rotation.y = lerp_angle( | 	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 lags behind camera control | ||||||
| 	arrow_pivot.rotation.y = lerp_angle( | 	arrow_pivot.rotation.y = lerp_angle( | ||||||
|  | |||||||
| @ -3,23 +3,6 @@ class_name FreeCamera extends CharacterBody3D | |||||||
| const SPRINT_MULT := 3.0 | const SPRINT_MULT := 3.0 | ||||||
| const PITCH_LIMIT := deg_to_rad(85.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) | @onready var _target := Vector2(rotation.x, rotation.y) | ||||||
| 
 | 
 | ||||||
| static var scene := preload("res://src/ui/camera/free_camera/free_camera.tscn") | 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: | 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 = 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, | ||||||
| 		PITCH_LIMIT, | 		PITCH_LIMIT, | ||||||
| 	) | 	) | ||||||
| @ -44,15 +33,15 @@ func camera_motion(motion: Vector2) -> void: | |||||||
| 
 | 
 | ||||||
| func _physics_process(delta: float) -> void: | func _physics_process(delta: float) -> void: | ||||||
| 	# Rotation | 	# Rotation | ||||||
| 	rotation.y = lerp_angle(rotation.y, _target.y, delta * x_acceleration) | 	rotation.y = lerp_angle(rotation.y, _target.y, delta * Game.settings.x_acceleration) | ||||||
| 	rotation.x = lerp_angle(rotation.x, _target.x, delta * y_acceleration) | 	rotation.x = lerp_angle(rotation.x, _target.x, delta * Game.settings.y_acceleration) | ||||||
| 
 | 
 | ||||||
| 	# Handle spatial movement | 	# Handle spatial movement | ||||||
| 	var xz_input := Input.get_vector("camera_left", "camera_right", "camera_forward", "camera_back") | 	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 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 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"): | 	if Input.is_action_pressed("camera_sprint"): | ||||||
| 		speed *= SPRINT_MULT | 		speed *= SPRINT_MULT | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ class_name OrbitalCamera extends Node3D | |||||||
| 
 | 
 | ||||||
| const POSITION_ACCELERATION := 4.0 | const POSITION_ACCELERATION := 4.0 | ||||||
| const BASIS_ACCELERATION := 4.0 | const BASIS_ACCELERATION := 4.0 | ||||||
| const TARGETER_ACCELERATION := 7.0 | const TARGETER_ACCELERATION := 4.0 | ||||||
| 
 | 
 | ||||||
| @export var target: Node3D | @export var target: Node3D | ||||||
| @export var offset := Vector3(0, 1, 0) | @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) | 	var actions := InputMap.action_get_events(action) | ||||||
| 	if actions: | 	if actions: | ||||||
| 		var primary := actions[0] | 		var primary := actions[0] | ||||||
| 		input_symbol = _get_input_symbol(primary) | 		input_symbol = PromptMap.from_event(primary) | ||||||
| 
 | 
 | ||||||
| 	text = PROMPT_FORMAT.format( | 	text = PROMPT_FORMAT.format( | ||||||
| 		[ | 		[ | ||||||
| @ -34,16 +34,3 @@ func _update() -> void: | |||||||
| 			label if label else UNKNOWN_LABEL_SYM | 			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"] | [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"] | [node name="InputPrompt" type="Label"] | ||||||
| anchors_preset = 15 | anchors_preset = 15 | ||||||
| @ -11,4 +11,3 @@ grow_vertical = 2 | |||||||
| theme_type_variation = &"InputPrompt" | theme_type_variation = &"InputPrompt" | ||||||
| text = "❓ - [unknown]" | text = "❓ - [unknown]" | ||||||
| script = ExtResource("1_qq6w5") | 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. | ## Start playing a screen shake effect. | ||||||
| func screen_shake(intensity: float, duration: float = 0.2) -> void: | 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 | 		return | ||||||
| 
 | 
 | ||||||
| 	var tween := get_tree().create_tween() | 	var tween := get_tree().create_tween() | ||||||
| @ -24,7 +24,7 @@ func screen_shake(intensity: float, duration: float = 0.2) -> void: | |||||||
| 
 | 
 | ||||||
| ## Rumble the screen indefinitely. | ## Rumble the screen indefinitely. | ||||||
| func set_rumble(intensity: float) -> void: | 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 | 		return | ||||||
| 
 | 
 | ||||||
| 	rumbler.intensity = intensity | 	rumbler.intensity = intensity | ||||||
| @ -52,7 +52,7 @@ func hit_lag_huge() -> void: | |||||||
| 
 | 
 | ||||||
| ## Stop processing for some number of frames. | ## Stop processing for some number of frames. | ||||||
| func hit_lag(frames: int = 1) -> void: | 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 | 		return | ||||||
| 
 | 
 | ||||||
| 	_hit_lag_frames = frames | 	_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://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"] | [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://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"] | [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] | [resource] | ||||||
| default_font = ExtResource("3_cee6l") | default_font = ExtResource("3_cee6l") | ||||||
| default_font_size = 18 | 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/base_type = &"Label" | ||||||
| ClubSelectLabel/colors/font_color = Color(1, 0.933333, 0.894118, 1) | ClubSelectLabel/colors/font_color = Color(1, 0.933333, 0.894118, 1) | ||||||
| ClubSelectLabel/colors/font_outline_color = Color(0, 0, 0, 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/colors/font_shadow_color = Color(0.2, 0.2, 0.2, 1) | ||||||
| ClubSelectLabelDisabled/font_sizes/font_size = 84 | ClubSelectLabelDisabled/font_sizes/font_size = 84 | ||||||
| ClubSelectLabelDisabled/fonts/font = ExtResource("1_3rv2b") | 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/base_type = &"Label" | ||||||
| InputPrompt/colors/font_color = Color(1, 1, 0.870588, 1) | InputPrompt/colors/font_color = Color(1, 1, 0.870588, 1) | ||||||
| InputPrompt/constants/outline_size = 8 | InputPrompt/constants/outline_size = 8 | ||||||
| InputPrompt/font_sizes/font_size = 32 | InputPrompt/font_sizes/font_size = 32 | ||||||
| InputPrompt/fonts/font = ExtResource("2_8kux8") | 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/colors/font_outline_color = Color(0, 0, 0, 1) | ||||||
| PauseMenuButton/constants/outline_size = 6 | PauseMenuButton/constants/outline_size = 6 | ||||||
| PauseMenuButton/font_sizes/font_size = 32 | 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/colors/font_outline_color = Color(1, 0.901961, 0.509804, 1) | ||||||
| QuantityLabel/constants/outline_size = 6 | QuantityLabel/constants/outline_size = 6 | ||||||
| QuantityLabel/font_sizes/font_size = 22 | 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/base_type = &"RichTextLabel" | ||||||
| ShotFeedback/colors/font_shadow_color = Color(0, 0, 0, 1) | ShotFeedback/colors/font_shadow_color = Color(0, 0, 0, 1) | ||||||
| ShotFeedback/constants/shadow_offset_x = 6 | ShotFeedback/constants/shadow_offset_x = 6 | ||||||
| ShotFeedback/constants/shadow_offset_y = 4 | ShotFeedback/constants/shadow_offset_y = 4 | ||||||
| ShotFeedback/font_sizes/normal_font_size = 272 | ShotFeedback/font_sizes/normal_font_size = 272 | ||||||
| ShotFeedback/fonts/normal_font = ExtResource("1_eha6a") | ShotFeedback/fonts/normal_font = ExtResource("1_eha6a") | ||||||
|  | UIButton/base_type = &"Button" | ||||||
|  | UIButton/styles/normal = SubResource("StyleBoxFlat_ynsl8") | ||||||
|  | |||||||
| @ -1,17 +1,18 @@ | |||||||
| extends Control | extends Control | ||||||
| ## Menu shown in-game when the user presses pause. | ## 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 menu_list: VBoxContainer = %MenuList | ||||||
| @onready var quit_confirm: CenterContainer = %QuitConfirm | @onready var quit_confirm: CenterContainer = %QuitConfirm | ||||||
|  | @onready var settings_container: MarginContainer = %SettingsContainer | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| func _ready() -> void: | func _ready() -> void: | ||||||
| 	print_debug("Pause menu _ready()") |  | ||||||
| 	Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) | 	Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| func _exit_tree() -> void: | func _exit_tree() -> void: | ||||||
| 	print_debug("Pause menu _exit_tree()") |  | ||||||
| 	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) | 	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -30,12 +31,14 @@ func _hide() -> void: | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| func resume() -> void: | func resume() -> void: | ||||||
| 	print_debug("Pause menu resume()") |  | ||||||
| 	queue_free() | 	queue_free() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| func settings() -> void: | 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: | func quit() -> void: | ||||||
|  | |||||||
| @ -60,9 +60,25 @@ text = "Settings" | |||||||
| [node name="QuitButton" type="Button" parent="MarginContainer/MenuList"] | [node name="QuitButton" type="Button" parent="MarginContainer/MenuList"] | ||||||
| layout_mode = 2 | layout_mode = 2 | ||||||
| theme_type_variation = &"PauseMenuButton" | 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" | 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="."] | [node name="QuitConfirm" type="CenterContainer" parent="."] | ||||||
| unique_name_in_owner = true | unique_name_in_owner = true | ||||||
| visible = false | visible = false | ||||||
| @ -88,7 +104,9 @@ layout_mode = 2 | |||||||
| 
 | 
 | ||||||
| [node name="Label" type="Label" parent="QuitConfirm/PanelContainer/MarginContainer/VBoxContainer"] | [node name="Label" type="Label" parent="QuitConfirm/PanelContainer/MarginContainer/VBoxContainer"] | ||||||
| layout_mode = 2 | layout_mode = 2 | ||||||
|  | theme_override_font_sizes/font_size = 24 | ||||||
| text = "Quit to desktop?" | text = "Quit to desktop?" | ||||||
|  | horizontal_alignment = 1 | ||||||
| 
 | 
 | ||||||
| [node name="HBoxContainer" type="HBoxContainer" parent="QuitConfirm/PanelContainer/MarginContainer/VBoxContainer"] | [node name="HBoxContainer" type="HBoxContainer" parent="QuitConfirm/PanelContainer/MarginContainer/VBoxContainer"] | ||||||
| layout_mode = 2 | layout_mode = 2 | ||||||
| @ -97,11 +115,13 @@ theme_override_constants/separation = 16 | |||||||
| [node name="CancelButton" type="Button" parent="QuitConfirm/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"] | [node name="CancelButton" type="Button" parent="QuitConfirm/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"] | ||||||
| layout_mode = 2 | layout_mode = 2 | ||||||
| size_flags_horizontal = 3 | size_flags_horizontal = 3 | ||||||
|  | theme_type_variation = &"CancelButton" | ||||||
| text = "Cancel" | text = "Cancel" | ||||||
| 
 | 
 | ||||||
| [node name="ConfirmQuitButton" type="Button" parent="QuitConfirm/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"] | [node name="ConfirmQuitButton" type="Button" parent="QuitConfirm/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"] | ||||||
| layout_mode = 2 | layout_mode = 2 | ||||||
| size_flags_horizontal = 3 | size_flags_horizontal = 3 | ||||||
|  | theme_type_variation = &"AlertButton" | ||||||
| text = "Quit" | text = "Quit" | ||||||
| 
 | 
 | ||||||
| [connection signal="pressed" from="MarginContainer/MenuList/ResumeButton" to="." method="resume"] | [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="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="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://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"] | [sub_resource type="Animation" id="Animation_3xds6"] | ||||||
| resource_name = "RESET" | resource_name = "RESET" | ||||||
| @ -654,6 +654,33 @@ fill_from = Vector2(0, 0.4) | |||||||
| fill_to = Vector2(1, 0.6) | fill_to = Vector2(1, 0.6) | ||||||
| metadata/_snap_enabled = true | 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"] | [sub_resource type="Animation" id="Animation_ornnh"] | ||||||
| resource_name = "idle" | resource_name = "idle" | ||||||
| length = 6.0 | length = 6.0 | ||||||
| @ -683,39 +710,26 @@ tracks/1/keys = { | |||||||
| "values": [0.0, 2.0] | "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"] | [sub_resource type="AnimationLibrary" id="AnimationLibrary_bdkm3"] | ||||||
| _data = { | _data = { | ||||||
| "RESET": SubResource("Animation_3dab1"), | "RESET": SubResource("Animation_3dab1"), | ||||||
| "idle": SubResource("Animation_ornnh") | "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"] | [sub_resource type="Animation" id="Animation_ll1u8"] | ||||||
| resource_name = "show" | resource_name = "show" | ||||||
| length = 0.4 | length = 0.4 | ||||||
| @ -731,20 +745,6 @@ tracks/0/keys = { | |||||||
| "times": PackedFloat32Array(0, 0.4) | "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"] | [sub_resource type="AnimationLibrary" id="AnimationLibrary_o70c6"] | ||||||
| _data = { | _data = { | ||||||
| "RESET": SubResource("Animation_qjs4v"), | "RESET": SubResource("Animation_qjs4v"), | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| class_name PromptMap | class_name PromptMap | ||||||
| ## Tools for mapping input events to PromptFont glyphs. | ## Tools for mapping input events to PromptFont glyphs. | ||||||
| 
 | 
 | ||||||
|  | const COMPOSE_FMT := "{0}+{1}" | ||||||
| const UNKNOWN_INPUT_SYMBOL := PromptFont.ICON_QUESTION | const UNKNOWN_INPUT_SYMBOL := PromptFont.ICON_QUESTION | ||||||
| 
 | 
 | ||||||
| ## Keyboard key map | ## Keyboard key map | ||||||
| @ -12,6 +13,7 @@ const KEYBOARD := { | |||||||
| 	KEY_CTRL: PromptFont.KEYBOARD_CONTROL, | 	KEY_CTRL: PromptFont.KEYBOARD_CONTROL, | ||||||
| 	KEY_ALT: PromptFont.KEYBOARD_ALT, | 	KEY_ALT: PromptFont.KEYBOARD_ALT, | ||||||
| 	KEY_SHIFT: PromptFont.KEYBOARD_SHIFT, | 	KEY_SHIFT: PromptFont.KEYBOARD_SHIFT, | ||||||
|  | 	KEY_META: PromptFont.KEYBOARD_SUPER, | ||||||
| 	KEY_TAB: PromptFont.KEYBOARD_TAB, | 	KEY_TAB: PromptFont.KEYBOARD_TAB, | ||||||
| 	KEY_CAPSLOCK: PromptFont.KEYBOARD_CAPS, | 	KEY_CAPSLOCK: PromptFont.KEYBOARD_CAPS, | ||||||
| 	KEY_BACKSPACE: PromptFont.KEYBOARD_BACKSPACE, | 	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. | ## Get the symbol representing the given keyboard input event. | ||||||
| ## | ## | ||||||
| ## If there is no such symbol available, returns the key label. | ## 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( | 		return OS.get_keycode_string( | ||||||
| 			DisplayServer.keyboard_get_keycode_from_physical(event.physical_keycode) | 			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. | ## Get the symbol representing the given mouse button event. | ||||||
| static func mouse_button(event: InputEventMouseButton) -> String: | 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. | ## 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. | ## Symbols specific to Nintendo Switch joycons will be used where possible. | ||||||
| static func nintendo_axis(event: InputEventJoypadMotion) -> String: | static func nintendo_axis(event: InputEventJoypadMotion) -> String: | ||||||
| 	return NINTENDO_AXIS.get(event.axis, gamepad_axis(event)) | 	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="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"] | [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="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="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="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"] | [sub_resource type="Resource" id="Resource_rdjhi"] | ||||||
| script = ExtResource("5_h6mje") | 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"]] | [node name="World" type="Node" groups=["WorldGroup"]] | ||||||
| script = ExtResource("1_ybjyx") | script = ExtResource("1_ybjyx") | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user