Compare commits
6 Commits
6f1defb3da
...
main
Author | SHA1 | Date | |
---|---|---|---|
96b5bae9d0 | |||
2b58781907 | |||
39aca9aa3f | |||
aea5158d6e | |||
6d75b33775 | |||
3ccf4ebabb |
@@ -86,7 +86,7 @@ func _enter_tree():
|
|||||||
_parse_input_actions()
|
_parse_input_actions()
|
||||||
|
|
||||||
func _exit_tree():
|
func _exit_tree():
|
||||||
Mapper.queue_free()
|
Mapper = null
|
||||||
|
|
||||||
func _parse_input_actions():
|
func _parse_input_actions():
|
||||||
_custom_input_actions.clear()
|
_custom_input_actions.clear()
|
||||||
@@ -189,10 +189,13 @@ func refresh():
|
|||||||
func get_joypad_type(controller: int = _last_controller) -> ControllerSettings.Devices:
|
func get_joypad_type(controller: int = _last_controller) -> ControllerSettings.Devices:
|
||||||
return Mapper._get_joypad_type(controller, _settings.joypad_fallback)
|
return Mapper._get_joypad_type(controller, _settings.joypad_fallback)
|
||||||
|
|
||||||
func parse_path(path: String, input_type = _last_input_type, last_controller = _last_controller) -> Texture:
|
func get_last_input_type() -> InputType:
|
||||||
|
return _last_input_type
|
||||||
|
|
||||||
|
func parse_path(path: String, input_type = _last_input_type, last_controller = _last_controller, forced_controller_icon_style = ControllerSettings.Devices.NONE) -> Texture:
|
||||||
if typeof(input_type) == TYPE_NIL:
|
if typeof(input_type) == TYPE_NIL:
|
||||||
return null
|
return null
|
||||||
var root_paths := _expand_path(path, input_type, last_controller)
|
var root_paths := _expand_path(path, input_type, last_controller, forced_controller_icon_style)
|
||||||
for root_path in root_paths:
|
for root_path in root_paths:
|
||||||
if _load_icon(root_path):
|
if _load_icon(root_path):
|
||||||
continue
|
continue
|
||||||
@@ -228,6 +231,7 @@ func parse_event_modifiers(event: InputEvent) -> Array[Texture]:
|
|||||||
for icon_path in _expand_path(modifier, InputType.KEYBOARD_MOUSE, -1):
|
for icon_path in _expand_path(modifier, InputType.KEYBOARD_MOUSE, -1):
|
||||||
if _load_icon(icon_path) == OK:
|
if _load_icon(icon_path) == OK:
|
||||||
icons.push_back(_cached_icons[icon_path])
|
icons.push_back(_cached_icons[icon_path])
|
||||||
|
break
|
||||||
|
|
||||||
return icons
|
return icons
|
||||||
|
|
||||||
@@ -270,7 +274,7 @@ func get_matching_event(path: String, input_type: InputType = _last_input_type,
|
|||||||
else:
|
else:
|
||||||
events = InputMap.action_get_events(path)
|
events = InputMap.action_get_events(path)
|
||||||
|
|
||||||
var fallback = null
|
var fallbacks = []
|
||||||
for event in events:
|
for event in events:
|
||||||
if not is_instance_valid(event): continue
|
if not is_instance_valid(event): continue
|
||||||
|
|
||||||
@@ -283,13 +287,15 @@ func get_matching_event(path: String, input_type: InputType = _last_input_type,
|
|||||||
# Use the first device specific mapping if there is one.
|
# Use the first device specific mapping if there is one.
|
||||||
if event.device == controller:
|
if event.device == controller:
|
||||||
return event
|
return event
|
||||||
# Otherwise use the first "all devices" mapping.
|
# Otherwise, we create a fallback prioritizing events with 'ALL_DEVICE'
|
||||||
elif fallback == null and event.device < 0:
|
if event.device < 0: # All-device event
|
||||||
fallback = event
|
fallbacks.push_front(event)
|
||||||
|
else:
|
||||||
|
fallbacks.push_back(event)
|
||||||
|
|
||||||
return fallback
|
return fallbacks[0] if not fallbacks.is_empty() else null
|
||||||
|
|
||||||
func _expand_path(path: String, input_type: int, controller: int) -> Array:
|
func _expand_path(path: String, input_type: int, controller: int, forced_controller_icon_style = ControllerSettings.Devices.NONE) -> Array:
|
||||||
var paths := []
|
var paths := []
|
||||||
var base_paths := [
|
var base_paths := [
|
||||||
_settings.custom_asset_dir + "/",
|
_settings.custom_asset_dir + "/",
|
||||||
@@ -298,20 +304,20 @@ func _expand_path(path: String, input_type: int, controller: int) -> Array:
|
|||||||
for base_path in base_paths:
|
for base_path in base_paths:
|
||||||
if base_path.is_empty():
|
if base_path.is_empty():
|
||||||
continue
|
continue
|
||||||
base_path += _convert_path_to_asset_file(path, input_type, controller)
|
base_path += _convert_path_to_asset_file(path, input_type, controller, forced_controller_icon_style)
|
||||||
|
|
||||||
paths.push_back(base_path + "." + _base_extension)
|
paths.push_back(base_path + "." + _base_extension)
|
||||||
return paths
|
return paths
|
||||||
|
|
||||||
func _convert_path_to_asset_file(path: String, input_type: int, controller: int) -> String:
|
func _convert_path_to_asset_file(path: String, input_type: int, controller: int, forced_controller_icon_style = ControllerSettings.Devices.NONE) -> String:
|
||||||
match get_path_type(path):
|
match get_path_type(path):
|
||||||
PathType.INPUT_ACTION:
|
PathType.INPUT_ACTION:
|
||||||
var event := get_matching_event(path, input_type, controller)
|
var event := get_matching_event(path, input_type, controller)
|
||||||
if event:
|
if event:
|
||||||
return _convert_event_to_path(event)
|
return _convert_event_to_path(event, controller, forced_controller_icon_style)
|
||||||
return path
|
return path
|
||||||
PathType.JOYPAD_PATH:
|
PathType.JOYPAD_PATH:
|
||||||
return Mapper._convert_joypad_path(path, controller, _settings.joypad_fallback)
|
return Mapper._convert_joypad_path(path, controller, _settings.joypad_fallback, forced_controller_icon_style)
|
||||||
PathType.SPECIFIC_PATH, _:
|
PathType.SPECIFIC_PATH, _:
|
||||||
return path
|
return path
|
||||||
|
|
||||||
@@ -372,7 +378,7 @@ func _convert_asset_file_to_tts(path: String) -> String:
|
|||||||
_:
|
_:
|
||||||
return path
|
return path
|
||||||
|
|
||||||
func _convert_event_to_path(event: InputEvent):
|
func _convert_event_to_path(event: InputEvent, controller: int = _last_controller, forced_controller_icon_style = ControllerSettings.Devices.NONE):
|
||||||
if event is InputEventKey:
|
if event is InputEventKey:
|
||||||
# If this is a physical key, convert to localized scancode
|
# If this is a physical key, convert to localized scancode
|
||||||
if event.keycode == 0:
|
if event.keycode == 0:
|
||||||
@@ -381,9 +387,9 @@ func _convert_event_to_path(event: InputEvent):
|
|||||||
elif event is InputEventMouseButton:
|
elif event is InputEventMouseButton:
|
||||||
return _convert_mouse_button_to_path(event.button_index)
|
return _convert_mouse_button_to_path(event.button_index)
|
||||||
elif event is InputEventJoypadButton:
|
elif event is InputEventJoypadButton:
|
||||||
return _convert_joypad_button_to_path(event.button_index, event.device)
|
return _convert_joypad_button_to_path(event.button_index, controller, forced_controller_icon_style)
|
||||||
elif event is InputEventJoypadMotion:
|
elif event is InputEventJoypadMotion:
|
||||||
return _convert_joypad_motion_to_path(event.axis, event.device)
|
return _convert_joypad_motion_to_path(event.axis, controller, forced_controller_icon_style)
|
||||||
|
|
||||||
func _convert_key_to_path(scancode: int):
|
func _convert_key_to_path(scancode: int):
|
||||||
match scancode:
|
match scancode:
|
||||||
@@ -615,7 +621,7 @@ func _convert_mouse_button_to_path(button_index: int):
|
|||||||
_:
|
_:
|
||||||
return "mouse/sample"
|
return "mouse/sample"
|
||||||
|
|
||||||
func _convert_joypad_button_to_path(button_index: int, controller: int):
|
func _convert_joypad_button_to_path(button_index: int, controller: int, forced_controller_icon_style = ControllerSettings.Devices.NONE):
|
||||||
var path
|
var path
|
||||||
match button_index:
|
match button_index:
|
||||||
JOY_BUTTON_A:
|
JOY_BUTTON_A:
|
||||||
@@ -652,9 +658,9 @@ func _convert_joypad_button_to_path(button_index: int, controller: int):
|
|||||||
path = "joypad/share"
|
path = "joypad/share"
|
||||||
_:
|
_:
|
||||||
return ""
|
return ""
|
||||||
return Mapper._convert_joypad_path(path, controller, _settings.joypad_fallback)
|
return Mapper._convert_joypad_path(path, controller, _settings.joypad_fallback, forced_controller_icon_style)
|
||||||
|
|
||||||
func _convert_joypad_motion_to_path(axis: int, controller: int):
|
func _convert_joypad_motion_to_path(axis: int, controller: int, forced_controller_icon_style = ControllerSettings.Devices.NONE):
|
||||||
var path : String
|
var path : String
|
||||||
match axis:
|
match axis:
|
||||||
JOY_AXIS_LEFT_X, JOY_AXIS_LEFT_Y:
|
JOY_AXIS_LEFT_X, JOY_AXIS_LEFT_Y:
|
||||||
@@ -667,7 +673,7 @@ func _convert_joypad_motion_to_path(axis: int, controller: int):
|
|||||||
path = "joypad/rt"
|
path = "joypad/rt"
|
||||||
_:
|
_:
|
||||||
return ""
|
return ""
|
||||||
return Mapper._convert_joypad_path(path, controller, _settings.joypad_fallback)
|
return Mapper._convert_joypad_path(path, controller, _settings.joypad_fallback, forced_controller_icon_style)
|
||||||
|
|
||||||
func _load_icon(path: String) -> int:
|
func _load_icon(path: String) -> int:
|
||||||
if _cached_icons.has(path): return OK
|
if _cached_icons.has(path): return OK
|
||||||
|
@@ -1 +1 @@
|
|||||||
uid://cxxl7e1hu587n
|
uid://b06g4dpg627b5
|
||||||
|
@@ -3,6 +3,7 @@ extends Resource
|
|||||||
class_name ControllerSettings
|
class_name ControllerSettings
|
||||||
|
|
||||||
enum Devices {
|
enum Devices {
|
||||||
|
NONE = -1,
|
||||||
LUNA,
|
LUNA,
|
||||||
OUYA,
|
OUYA,
|
||||||
PS3,
|
PS3,
|
1
addons/controller_icons/ControllerSettings.gd.uid
Normal file
1
addons/controller_icons/ControllerSettings.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://bih8ls5msy63l
|
21
addons/controller_icons/LICENSE
Normal file
21
addons/controller_icons/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 Ricardo Subtil
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
@@ -1,8 +1,8 @@
|
|||||||
extends Node
|
extends RefCounted
|
||||||
class_name ControllerMapper
|
class_name ControllerMapper
|
||||||
|
|
||||||
func _convert_joypad_path(path: String, device: int, fallback: ControllerSettings.Devices) -> String:
|
func _convert_joypad_path(path: String, device: int, fallback: ControllerSettings.Devices, force_controller_icon_style = ControllerSettings.Devices.NONE) -> String:
|
||||||
match _get_joypad_type(device, fallback):
|
match _get_joypad_type(device, fallback, force_controller_icon_style):
|
||||||
ControllerSettings.Devices.LUNA:
|
ControllerSettings.Devices.LUNA:
|
||||||
return _convert_joypad_to_luna(path)
|
return _convert_joypad_to_luna(path)
|
||||||
ControllerSettings.Devices.PS3:
|
ControllerSettings.Devices.PS3:
|
||||||
@@ -32,7 +32,9 @@ func _convert_joypad_path(path: String, device: int, fallback: ControllerSetting
|
|||||||
_:
|
_:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
func _get_joypad_type(device, fallback):
|
func _get_joypad_type(device, fallback, force_controller_icon_style):
|
||||||
|
if force_controller_icon_style != ControllerSettings.Devices.NONE:
|
||||||
|
return force_controller_icon_style
|
||||||
var available = Input.get_connected_joypads()
|
var available = Input.get_connected_joypads()
|
||||||
if available.is_empty():
|
if available.is_empty():
|
||||||
return fallback
|
return fallback
|
||||||
@@ -264,7 +266,7 @@ func _convert_joypad_to_steamdeck(path: String):
|
|||||||
"rt":
|
"rt":
|
||||||
return path.replace("/rt", "/r2")
|
return path.replace("/rt", "/r2")
|
||||||
"select":
|
"select":
|
||||||
return path.replace("/select", "/square")
|
return path.replace("/select", "/inventory")
|
||||||
"start":
|
"start":
|
||||||
return path.replace("/start", "/menu")
|
return path.replace("/start", "/menu")
|
||||||
"home":
|
"home":
|
||||||
|
@@ -1 +1 @@
|
|||||||
uid://dtgqdoflwmo0b
|
uid://5wx82aghglqr
|
||||||
|
@@ -1 +0,0 @@
|
|||||||
uid://dygveqy02jjgx
|
|
BIN
addons/controller_icons/assets/steamdeck/inventory.png
Normal file
BIN
addons/controller_icons/assets/steamdeck/inventory.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,34 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://ds5yo8kn81uem"
|
||||||
|
path="res://.godot/imported/inventory.png-2e96b194d1562d723597b2d307313c1b.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/controller_icons/assets/steamdeck/inventory.png"
|
||||||
|
dest_files=["res://.godot/imported/inventory.png-2e96b194d1562d723597b2d307313c1b.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
@@ -1 +1 @@
|
|||||||
uid://lm0qpml4w2mx
|
uid://jcpjcl10iatx
|
||||||
|
@@ -1 +1 @@
|
|||||||
uid://dkn6l8tlu56d8
|
uid://xp37xj8kduow
|
||||||
|
@@ -1 +1 @@
|
|||||||
uid://sg5ntoaywgfd
|
uid://r1qngdbv7gh4
|
||||||
|
@@ -1 +1 @@
|
|||||||
uid://125nay2twqlr
|
uid://bsynmd02318ph
|
||||||
|
@@ -1 +1 @@
|
|||||||
uid://d1hrxvtfr4t5w
|
uid://da3havxu352nb
|
||||||
|
@@ -68,6 +68,20 @@ enum ShowMode {
|
|||||||
show_mode = _show_mode
|
show_mode = _show_mode
|
||||||
_load_texture_path()
|
_load_texture_path()
|
||||||
|
|
||||||
|
|
||||||
|
## Forces the icon to show a specific controller style, regardless of the
|
||||||
|
## currently used controller type.
|
||||||
|
##[br][br]
|
||||||
|
## This will override force_device if set to a value other than NONE.
|
||||||
|
##[br][br]
|
||||||
|
## This is only relevant for paths using input actions, and has no effect on
|
||||||
|
## other scenarios.
|
||||||
|
|
||||||
|
@export var force_controller_icon_style: ControllerSettings.Devices = ControllerSettings.Devices.NONE:
|
||||||
|
set(_force_controller_icon_style):
|
||||||
|
force_controller_icon_style = _force_controller_icon_style
|
||||||
|
_load_texture_path()
|
||||||
|
|
||||||
enum ForceType {
|
enum ForceType {
|
||||||
NONE, ## Icon will swap according to the used input method.
|
NONE, ## Icon will swap according to the used input method.
|
||||||
KEYBOARD_MOUSE, ## Icon will always show the keyboard/mouse action.
|
KEYBOARD_MOUSE, ## Icon will always show the keyboard/mouse action.
|
||||||
@@ -84,6 +98,34 @@ enum ForceType {
|
|||||||
force_type = _force_type
|
force_type = _force_type
|
||||||
_load_texture_path()
|
_load_texture_path()
|
||||||
|
|
||||||
|
enum ForceDevice {
|
||||||
|
DEVICE_0,
|
||||||
|
DEVICE_1,
|
||||||
|
DEVICE_2,
|
||||||
|
DEVICE_3,
|
||||||
|
DEVICE_4,
|
||||||
|
DEVICE_5,
|
||||||
|
DEVICE_6,
|
||||||
|
DEVICE_7,
|
||||||
|
DEVICE_8,
|
||||||
|
DEVICE_9,
|
||||||
|
DEVICE_10,
|
||||||
|
DEVICE_11,
|
||||||
|
DEVICE_12,
|
||||||
|
DEVICE_13,
|
||||||
|
DEVICE_14,
|
||||||
|
DEVICE_15,
|
||||||
|
ANY # No device will be forced
|
||||||
|
}
|
||||||
|
|
||||||
|
## Forces the icon to use the textures for the device connected at the specified index.
|
||||||
|
## For example, if a PlayStation 5 controller is connected at device_index 0,
|
||||||
|
## the icon will always show PlayStation 5 textures.
|
||||||
|
@export var force_device: ForceDevice = ForceDevice.ANY:
|
||||||
|
set(_force_device):
|
||||||
|
force_device = _force_device
|
||||||
|
_load_texture_path()
|
||||||
|
|
||||||
@export_subgroup("Text Rendering")
|
@export_subgroup("Text Rendering")
|
||||||
## Custom LabelSettings. If set, overrides the addon's global label settings.
|
## Custom LabelSettings. If set, overrides the addon's global label settings.
|
||||||
@export var custom_label_settings: LabelSettings:
|
@export var custom_label_settings: LabelSettings:
|
||||||
@@ -167,7 +209,8 @@ func _load_texture_path_impl():
|
|||||||
if ControllerIcons.get_path_type(path) == ControllerIcons.PathType.INPUT_ACTION:
|
if ControllerIcons.get_path_type(path) == ControllerIcons.PathType.INPUT_ACTION:
|
||||||
var event := ControllerIcons.get_matching_event(path, input_type)
|
var event := ControllerIcons.get_matching_event(path, input_type)
|
||||||
textures.append_array(ControllerIcons.parse_event_modifiers(event))
|
textures.append_array(ControllerIcons.parse_event_modifiers(event))
|
||||||
var tex := ControllerIcons.parse_path(path, input_type)
|
var target_device = force_device if force_device != ForceDevice.ANY else ControllerIcons._last_controller
|
||||||
|
var tex := ControllerIcons.parse_path(path, input_type, target_device, force_controller_icon_style)
|
||||||
if tex:
|
if tex:
|
||||||
textures.append(tex)
|
textures.append(tex)
|
||||||
_textures = textures
|
_textures = textures
|
||||||
|
@@ -1 +1 @@
|
|||||||
uid://ddxpo5u73ssi2
|
uid://cxab4gf8nejc2
|
||||||
|
@@ -1 +1 @@
|
|||||||
uid://k2tud3diool
|
uid://dlwwg6hbxcg6r
|
||||||
|
@@ -1 +1 @@
|
|||||||
uid://bpos4yaigyeqr
|
uid://dns2c4458ekvc
|
||||||
|
@@ -1 +1 @@
|
|||||||
uid://dmp4w4ojx7klt
|
uid://cispm18xp24wt
|
||||||
|
@@ -1 +1 @@
|
|||||||
uid://bu8t48xqekc8o
|
uid://c6lqhrewwbp61
|
||||||
|
@@ -1 +1 @@
|
|||||||
uid://da1ors8v36hv3
|
uid://texv8inbqrdh
|
||||||
|
@@ -1 +1 @@
|
|||||||
uid://dt82cmmp3uy7l
|
uid://wnl1k7337x2u
|
||||||
|
@@ -3,5 +3,5 @@
|
|||||||
name="Controller Icons"
|
name="Controller Icons"
|
||||||
description="Provides icons for all major controllers and keyboard, with automatic icon remapping."
|
description="Provides icons for all major controllers and keyboard, with automatic icon remapping."
|
||||||
author="rsubtil"
|
author="rsubtil"
|
||||||
version="3.1.4"
|
version="3.1.5"
|
||||||
script="plugin.gd"
|
script="plugin.gd"
|
||||||
|
@@ -1 +1 @@
|
|||||||
uid://cajvrhetudhyg
|
uid://xvjobdx0h3gi
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
[gd_resource type="Resource" script_class="ControllerSettings" load_steps=2 format=3 uid="uid://dolsrvh5w47et"]
|
[gd_resource type="Resource" script_class="ControllerSettings" load_steps=2 format=3 uid="uid://dolsrvh5w47et"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://addons/controller_icons/Settings.gd" id="1"]
|
[ext_resource type="Script" path="res://addons/controller_icons/ControllerSettings.gd" id="1"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1")
|
script = ExtResource("1")
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
|
@tool
|
||||||
class_name EntityMovement extends Node
|
class_name EntityMovement extends Node
|
||||||
|
|
||||||
const SPEED = 64.0
|
|
||||||
const FRICTION = 0.01
|
const FRICTION = 0.01
|
||||||
|
|
||||||
enum FacingDirection {
|
enum FacingDirection {
|
||||||
@@ -24,61 +24,65 @@ const FacingDirAngle = {
|
|||||||
FacingDirection.WEST: -PI / 2
|
FacingDirection.WEST: -PI / 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var _inputDir:Vector2 = Vector2.ZERO
|
||||||
|
var _facingDir:FacingDirection = FacingDirection.SOUTH
|
||||||
|
var _running:bool = false
|
||||||
|
|
||||||
@export var body:CharacterBody3D
|
@export var body:CharacterBody3D
|
||||||
@export var rotate:Node3D
|
@export var rotate:Node3D
|
||||||
@export var sprite:AnimatedSprite3D
|
@export var sprite:AnimatedSprite3D
|
||||||
|
@export var walkSpeed:float = 48.0
|
||||||
|
@export var runSpeed:float = 64.0
|
||||||
|
@export var facingDir:FacingDirection = FacingDirection.SOUTH:
|
||||||
|
set(value):
|
||||||
|
_facingDir = value
|
||||||
|
_updateSprite()
|
||||||
|
get:
|
||||||
|
return _facingDir
|
||||||
|
|
||||||
var facingDir:FacingDirection = FacingDirection.SOUTH
|
#
|
||||||
var inputDir:Vector2 = Vector2.ZERO
|
# Private Methods
|
||||||
|
#
|
||||||
func _enter_tree() -> void:
|
func _updateSprite() -> void:
|
||||||
if !sprite:
|
if !sprite || sprite.animation == FacingDirWalkAnimations[facingDir]:
|
||||||
return
|
return
|
||||||
for dir in FacingDirWalkAnimations:
|
|
||||||
if sprite.animation != FacingDirWalkAnimations[dir]:
|
|
||||||
continue
|
|
||||||
facingDir = dir
|
|
||||||
break
|
|
||||||
|
|
||||||
func canMove() -> bool:
|
|
||||||
return true
|
|
||||||
|
|
||||||
func applyFacingDir() -> void:
|
|
||||||
if !sprite || inputDir.length() <= 0.01:
|
|
||||||
return
|
|
||||||
|
|
||||||
if inputDir.y > 0:
|
|
||||||
if facingDir != FacingDirection.NORTH && inputDir.x != 0:
|
|
||||||
if inputDir.x > 0 && facingDir == FacingDirection.EAST:
|
|
||||||
facingDir = FacingDirection.EAST
|
|
||||||
elif inputDir.x < 0 && facingDir == FacingDirection.WEST:
|
|
||||||
facingDir = FacingDirection.WEST
|
|
||||||
else:
|
|
||||||
facingDir = FacingDirection.NORTH
|
|
||||||
else:
|
|
||||||
facingDir = FacingDirection.NORTH
|
|
||||||
elif inputDir.y < 0:
|
|
||||||
if facingDir != FacingDirection.SOUTH && inputDir.x != 0:
|
|
||||||
if inputDir.x > 0 && facingDir == FacingDirection.EAST:
|
|
||||||
facingDir = FacingDirection.EAST
|
|
||||||
elif inputDir.x < 0 && facingDir == FacingDirection.WEST:
|
|
||||||
facingDir = FacingDirection.WEST
|
|
||||||
else:
|
|
||||||
facingDir = FacingDirection.SOUTH
|
|
||||||
else:
|
|
||||||
facingDir = FacingDirection.SOUTH
|
|
||||||
elif inputDir.x > 0:
|
|
||||||
facingDir = FacingDirection.EAST
|
|
||||||
else:
|
|
||||||
facingDir = FacingDirection.WEST
|
|
||||||
|
|
||||||
sprite.animation = FacingDirWalkAnimations[facingDir]
|
sprite.animation = FacingDirWalkAnimations[facingDir]
|
||||||
|
|
||||||
func applyGravity() -> void:
|
|
||||||
|
func _applyFacingDir() -> void:
|
||||||
|
if !sprite || _inputDir.length() <= 0.01:
|
||||||
|
return
|
||||||
|
|
||||||
|
if _inputDir.y > 0:
|
||||||
|
if facingDir != FacingDirection.NORTH && _inputDir.x != 0:
|
||||||
|
if _inputDir.x > 0 && facingDir == FacingDirection.EAST:
|
||||||
|
facingDir = FacingDirection.EAST
|
||||||
|
elif _inputDir.x < 0 && facingDir == FacingDirection.WEST:
|
||||||
|
facingDir = FacingDirection.WEST
|
||||||
|
else:
|
||||||
|
facingDir = FacingDirection.NORTH
|
||||||
|
else:
|
||||||
|
facingDir = FacingDirection.NORTH
|
||||||
|
elif _inputDir.y < 0:
|
||||||
|
if facingDir != FacingDirection.SOUTH && _inputDir.x != 0:
|
||||||
|
if _inputDir.x > 0 && facingDir == FacingDirection.EAST:
|
||||||
|
facingDir = FacingDirection.EAST
|
||||||
|
elif _inputDir.x < 0 && facingDir == FacingDirection.WEST:
|
||||||
|
facingDir = FacingDirection.WEST
|
||||||
|
else:
|
||||||
|
facingDir = FacingDirection.SOUTH
|
||||||
|
else:
|
||||||
|
facingDir = FacingDirection.SOUTH
|
||||||
|
elif _inputDir.x > 0:
|
||||||
|
facingDir = FacingDirection.EAST
|
||||||
|
else:
|
||||||
|
facingDir = FacingDirection.WEST
|
||||||
|
|
||||||
|
func _applyGravity() -> void:
|
||||||
if !body.is_on_floor():
|
if !body.is_on_floor():
|
||||||
body.velocity += PHYSICS.GRAVITY * get_process_delta_time()
|
body.velocity += PHYSICS.GRAVITY * get_process_delta_time()
|
||||||
|
|
||||||
func applyMovement() -> void:
|
func _applyMovement() -> void:
|
||||||
if !canMove():
|
if !canMove():
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -98,7 +102,7 @@ func applyMovement() -> void:
|
|||||||
right = right.normalized()
|
right = right.normalized()
|
||||||
|
|
||||||
var directionAdjusted = (
|
var directionAdjusted = (
|
||||||
forward * inputDir.y + right * inputDir.x
|
forward * _inputDir.y + right * _inputDir.x
|
||||||
).normalized()
|
).normalized()
|
||||||
if directionAdjusted.length() <= 0.01:
|
if directionAdjusted.length() <= 0.01:
|
||||||
return
|
return
|
||||||
@@ -107,19 +111,38 @@ func applyMovement() -> void:
|
|||||||
var targetRot = atan2(directionAdjusted.x, directionAdjusted.z)
|
var targetRot = atan2(directionAdjusted.x, directionAdjusted.z)
|
||||||
rotate.rotation.y = targetRot
|
rotate.rotation.y = targetRot
|
||||||
|
|
||||||
body.velocity.x = directionAdjusted.x * SPEED
|
var speed = walkSpeed
|
||||||
body.velocity.z = directionAdjusted.z * SPEED
|
if _running:
|
||||||
|
speed = runSpeed
|
||||||
|
|
||||||
func applyFriction(delta:float) -> void:
|
body.velocity.x = directionAdjusted.x * speed
|
||||||
|
body.velocity.z = directionAdjusted.z * speed
|
||||||
|
|
||||||
|
func _applyFriction(delta:float) -> void:
|
||||||
body.velocity.x *= delta * FRICTION
|
body.velocity.x *= delta * FRICTION
|
||||||
body.velocity.z *= delta * FRICTION
|
body.velocity.z *= delta * FRICTION
|
||||||
|
|
||||||
|
#
|
||||||
|
# Protected Methods
|
||||||
|
#
|
||||||
|
func canMove() -> bool:
|
||||||
|
return true
|
||||||
|
|
||||||
|
#
|
||||||
|
# Callbacks
|
||||||
|
#
|
||||||
|
func _enter_tree() -> void:
|
||||||
|
_updateSprite()
|
||||||
|
|
||||||
func _physics_process(delta:float) -> void:
|
func _physics_process(delta:float) -> void:
|
||||||
|
if Engine.is_editor_hint():
|
||||||
|
return
|
||||||
|
|
||||||
if !body:
|
if !body:
|
||||||
return
|
return
|
||||||
|
|
||||||
applyGravity()
|
_applyGravity()
|
||||||
applyFriction(delta)
|
_applyFriction(delta)
|
||||||
applyMovement()
|
_applyMovement()
|
||||||
applyFacingDir()
|
_applyFacingDir()
|
||||||
body.move_and_slide()
|
body.move_and_slide()
|
@@ -1,6 +1,38 @@
|
|||||||
|
@tool
|
||||||
class_name NPC extends CharacterBody3D
|
class_name NPC extends CharacterBody3D
|
||||||
|
|
||||||
@export var interactEvent:EventResource
|
@export var _movement:NPCMovement
|
||||||
|
|
||||||
func _onInteract(playerEntity: Player) -> void:
|
@export var facingDirection:EntityMovement.FacingDirection:
|
||||||
|
set(value):
|
||||||
|
if _movement:
|
||||||
|
_movement.facingDir = value
|
||||||
|
get:
|
||||||
|
if _movement:
|
||||||
|
return _movement.facingDir
|
||||||
|
return EntityMovement.FacingDirection.SOUTH
|
||||||
|
|
||||||
|
@export var walkSpeed:float = 48.0:
|
||||||
|
set(value):
|
||||||
|
if _movement:
|
||||||
|
_movement.walkSpeed = value
|
||||||
|
get:
|
||||||
|
if _movement:
|
||||||
|
return _movement.walkSpeed
|
||||||
|
return 48.0
|
||||||
|
|
||||||
|
@export var runSpeed:float = 64.0:
|
||||||
|
set(value):
|
||||||
|
if _movement:
|
||||||
|
_movement.runSpeed = value
|
||||||
|
get:
|
||||||
|
if _movement:
|
||||||
|
return _movement.runSpeed
|
||||||
|
return 64.0
|
||||||
|
|
||||||
|
func onInteract(player:Player) -> void:
|
||||||
|
print("Interacted with NPC")
|
||||||
|
pass
|
||||||
|
|
||||||
|
func _enter_tree() -> void:
|
||||||
pass
|
pass
|
||||||
|
@@ -62,8 +62,9 @@ animations = [{
|
|||||||
[sub_resource type="SphereShape3D" id="SphereShape3D_x8luf"]
|
[sub_resource type="SphereShape3D" id="SphereShape3D_x8luf"]
|
||||||
radius = 8.5
|
radius = 8.5
|
||||||
|
|
||||||
[node name="NPC" type="CharacterBody3D"]
|
[node name="NPC" type="CharacterBody3D" node_paths=PackedStringArray("_movement")]
|
||||||
script = ExtResource("1_00k55")
|
script = ExtResource("1_00k55")
|
||||||
|
_movement = NodePath("Scripts/NPCMovement")
|
||||||
|
|
||||||
[node name="Scripts" type="Node" parent="."]
|
[node name="Scripts" type="Node" parent="."]
|
||||||
|
|
||||||
@@ -86,10 +87,10 @@ axis = 1
|
|||||||
double_sided = false
|
double_sided = false
|
||||||
texture_filter = 0
|
texture_filter = 0
|
||||||
sprite_frames = SubResource("SpriteFrames_1seh5")
|
sprite_frames = SubResource("SpriteFrames_1seh5")
|
||||||
animation = &"walk_west"
|
animation = &"walk_south"
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 8.5, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 8.5, 0)
|
||||||
shape = SubResource("SphereShape3D_x8luf")
|
shape = SubResource("SphereShape3D_x8luf")
|
||||||
|
|
||||||
[connection signal="interactEvent" from="InteractableArea" to="." method="_onInteract"]
|
[connection signal="interactEvent" from="InteractableArea" to="." method="onInteract"]
|
||||||
|
@@ -1 +1,2 @@
|
|||||||
class_name NPCMovement extends "res://entities/EntityMovement.gd"
|
@tool
|
||||||
|
class_name NPCMovement extends "res://entity/EntityMovement.gd"
|
@@ -1 +1,31 @@
|
|||||||
|
@tool
|
||||||
class_name Player extends CharacterBody3D
|
class_name Player extends CharacterBody3D
|
||||||
|
|
||||||
|
@export var _movement:PlayerMovement
|
||||||
|
|
||||||
|
@export var facingDirection:EntityMovement.FacingDirection:
|
||||||
|
set(value):
|
||||||
|
if _movement:
|
||||||
|
_movement.facingDir = value
|
||||||
|
get:
|
||||||
|
if _movement:
|
||||||
|
return _movement.facingDir
|
||||||
|
return EntityMovement.FacingDirection.SOUTH
|
||||||
|
|
||||||
|
@export var walkSpeed:float = 48.0:
|
||||||
|
set(value):
|
||||||
|
if _movement:
|
||||||
|
_movement.walkSpeed = value
|
||||||
|
get:
|
||||||
|
if _movement:
|
||||||
|
return _movement.walkSpeed
|
||||||
|
return 48.0
|
||||||
|
|
||||||
|
@export var runSpeed:float = 64.0:
|
||||||
|
set(value):
|
||||||
|
if _movement:
|
||||||
|
_movement.runSpeed = value
|
||||||
|
get:
|
||||||
|
if _movement:
|
||||||
|
return _movement.runSpeed
|
||||||
|
return 64.0
|
||||||
|
@@ -64,8 +64,9 @@ animations = [{
|
|||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_g13of"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_g13of"]
|
||||||
size = Vector3(10, 16, 8)
|
size = Vector3(10, 16, 8)
|
||||||
|
|
||||||
[node name="Player" type="CharacterBody3D"]
|
[node name="Player" type="CharacterBody3D" node_paths=PackedStringArray("_movement")]
|
||||||
script = ExtResource("1_24gqh")
|
script = ExtResource("1_24gqh")
|
||||||
|
_movement = NodePath("Scripts/PlayerMovement")
|
||||||
|
|
||||||
[node name="Scripts" type="Node" parent="."]
|
[node name="Scripts" type="Node" parent="."]
|
||||||
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
@tool
|
||||||
class_name PlayerCamera extends Node
|
class_name PlayerCamera extends Node
|
||||||
|
|
||||||
const CAMERA_PIXELS_PER_UNIT = 1.0
|
const CAMERA_PIXELS_PER_UNIT = 1.0
|
||||||
@@ -8,6 +9,9 @@ const CAMERA_PIXEL_SCALE = 1.0
|
|||||||
@export var offset:Vector3 = Vector3(0, 0, 12)
|
@export var offset:Vector3 = Vector3(0, 0, 12)
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
|
if !camera || !target:
|
||||||
|
return
|
||||||
|
|
||||||
# I tried a few things but this is most consistent for both backbuffer and
|
# I tried a few things but this is most consistent for both backbuffer and
|
||||||
# framebuffer viewports.
|
# framebuffer viewports.
|
||||||
var viewportHeight = get_viewport().get_visible_rect().size.y;
|
var viewportHeight = get_viewport().get_visible_rect().size.y;
|
||||||
|
@@ -10,4 +10,4 @@ func _process(delta: float) -> void:
|
|||||||
if Input.is_action_just_pressed("interact"):
|
if Input.is_action_just_pressed("interact"):
|
||||||
interaction.interact()
|
interaction.interact()
|
||||||
|
|
||||||
movement.inputDir = Input.get_vector("move_left", "move_right", "move_back", "move_forward").normalized()
|
movement._inputDir = Input.get_vector("move_left", "move_right", "move_back", "move_forward").normalized()
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
class_name PlayerMovement extends "res://entities/EntityMovement.gd"
|
@tool
|
||||||
|
class_name PlayerMovement extends "res://entity/EntityMovement.gd"
|
||||||
|
|
||||||
func canMove() -> bool:
|
func canMove() -> bool:
|
||||||
if PAUSE.isMovementPaused():
|
if PAUSE.isMovementPaused():
|
||||||
|
12
map/TestMap.gd
Normal file
12
map/TestMap.gd
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
extends Node3D
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
UI.MADTALK.start_dialog("bare_minimum")
|
||||||
|
|
||||||
|
func _input(event):
|
||||||
|
if (
|
||||||
|
(event is InputEventKey) and (event.pressed) and (not event.echo) and (event.keycode in [KEY_SPACE, KEY_ENTER, KEY_KP_ENTER])
|
||||||
|
) or (
|
||||||
|
(event is InputEventMouseButton) and (event.pressed) and (event.button_index == MOUSE_BUTTON_LEFT)
|
||||||
|
):
|
||||||
|
UI.MADTALK.dialog_acknowledge()
|
1
map/TestMap.gd.uid
Normal file
1
map/TestMap.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://xe6pcuq741xi
|
@@ -1,15 +1,18 @@
|
|||||||
[gd_scene load_steps=4 format=3 uid="uid://d0ywgijpuqy0r"]
|
[gd_scene load_steps=5 format=3 uid="uid://d0ywgijpuqy0r"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://xe6pcuq741xi" path="res://map/TestMap.gd" id="1_6ms5s"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cluuhtfjeodwb" path="res://map/TestMapBase.tscn" id="1_ox0si"]
|
[ext_resource type="PackedScene" uid="uid://cluuhtfjeodwb" path="res://map/TestMapBase.tscn" id="1_ox0si"]
|
||||||
[ext_resource type="PackedScene" uid="uid://2ch34sio36nv" path="res://entity/player/Player.tscn" id="2_0d2qr"]
|
[ext_resource type="PackedScene" uid="uid://2ch34sio36nv" path="res://entity/player/Player.tscn" id="2_0d2qr"]
|
||||||
[ext_resource type="PackedScene" uid="uid://kabs7mopalmo" path="res://entity/npc/NPC.tscn" id="3_0vfw4"]
|
[ext_resource type="PackedScene" uid="uid://kabs7mopalmo" path="res://entity/npc/NPC.tscn" id="3_0vfw4"]
|
||||||
|
|
||||||
[node name="TestMap" type="Node3D"]
|
[node name="TestMap" type="Node3D"]
|
||||||
|
script = ExtResource("1_6ms5s")
|
||||||
|
|
||||||
[node name="TestMapBase" parent="." instance=ExtResource("1_ox0si")]
|
[node name="TestMapBase" parent="." instance=ExtResource("1_ox0si")]
|
||||||
|
|
||||||
[node name="Player" parent="." instance=ExtResource("2_0d2qr")]
|
[node name="Player" parent="." instance=ExtResource("2_0d2qr")]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14.3947, 1.94879, -13.1025)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 27.142, 1.94879, -59.112)
|
||||||
|
facingDirection = 1
|
||||||
|
|
||||||
[node name="NPC" parent="." instance=ExtResource("3_0vfw4")]
|
[node name="NPC" parent="." instance=ExtResource("3_0vfw4")]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.30029, 4.06806, 0.563562)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.30029, 4.06806, 0.563562)
|
||||||
|
@@ -11,6 +11,7 @@ func _exit_tree() -> void:
|
|||||||
push_error("RootScene should not be removed from the scene tree. This is a bug.")
|
push_error("RootScene should not be removed from the scene tree. This is a bug.")
|
||||||
|
|
||||||
func onSceneChange(newScene:SceneSingleton.SceneType) -> void:
|
func onSceneChange(newScene:SceneSingleton.SceneType) -> void:
|
||||||
|
print("overworld", overworld)
|
||||||
remove_child(overworld)
|
remove_child(overworld)
|
||||||
remove_child(initial)
|
remove_child(initial)
|
||||||
|
|
||||||
|
@@ -24,6 +24,8 @@ UI="*res://singleton/UI.tscn"
|
|||||||
QUEST="*res://singleton/Quest.tscn"
|
QUEST="*res://singleton/Quest.tscn"
|
||||||
OVERWORLD="*res://singleton/Overworld.gd"
|
OVERWORLD="*res://singleton/Overworld.gd"
|
||||||
SCENE="*res://singleton/Scene.gd"
|
SCENE="*res://singleton/Scene.gd"
|
||||||
|
MadTalkGlobals="*res://addons/madtalk/runtime/MadTalkGlobals.tscn"
|
||||||
|
ControllerIcons="*res://addons/controller_icons/ControllerIcons.gd"
|
||||||
|
|
||||||
[debug]
|
[debug]
|
||||||
|
|
||||||
@@ -45,7 +47,7 @@ project/assembly_name="Dawn Godot"
|
|||||||
|
|
||||||
[editor_plugins]
|
[editor_plugins]
|
||||||
|
|
||||||
enabled=PackedStringArray("res://addons/controller_icons/plugin.cfg")
|
enabled=PackedStringArray("res://addons/controller_icons/plugin.cfg", "res://addons/madtalk/plugin.cfg")
|
||||||
|
|
||||||
[filesystem]
|
[filesystem]
|
||||||
|
|
||||||
|
@@ -18,7 +18,7 @@ func _exit_tree() -> void:
|
|||||||
TRANSITION.fadeOutEnd.disconnect(onFadeOutEnd)
|
TRANSITION.fadeOutEnd.disconnect(onFadeOutEnd)
|
||||||
TRANSITION.fadeInEnd.disconnect(onFadeInEnd)
|
TRANSITION.fadeInEnd.disconnect(onFadeInEnd)
|
||||||
|
|
||||||
func _process(delta:float) -> void:
|
func _process(_delta:float) -> void:
|
||||||
if(!isMapChanging()):
|
if(!isMapChanging()):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@@ -2,3 +2,4 @@ class_name UISingleton extends Control
|
|||||||
|
|
||||||
@export var TEXTBOX: VNTextbox
|
@export var TEXTBOX: VNTextbox
|
||||||
@export var PAUSE: PauseMenu
|
@export var PAUSE: PauseMenu
|
||||||
|
@onready var MADTALK:Node = $VNTextbox/MadTalk;
|
||||||
|
@@ -16,9 +16,7 @@ TEXTBOX = NodePath("VNTextbox")
|
|||||||
PAUSE = NodePath("PauseMenu")
|
PAUSE = NodePath("PauseMenu")
|
||||||
|
|
||||||
[node name="PauseMenu" parent="." instance=ExtResource("2_atyu8")]
|
[node name="PauseMenu" parent="." instance=ExtResource("2_atyu8")]
|
||||||
visible = false
|
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
|
|
||||||
[node name="VNTextbox" parent="." instance=ExtResource("1_1mtk3")]
|
[node name="VNTextbox" parent="." instance=ExtResource("1_1mtk3")]
|
||||||
visible = false
|
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
|
@@ -1,44 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name AdvancedRichText extends RichTextLabel
|
|
||||||
|
|
||||||
@export_multiline var advancedText:String = "":
|
|
||||||
get():
|
|
||||||
return advancedText
|
|
||||||
set(value):
|
|
||||||
advancedText = value
|
|
||||||
_parseAdvancedText()
|
|
||||||
|
|
||||||
@export var translate:bool = true:
|
|
||||||
set(value):
|
|
||||||
translate = value
|
|
||||||
_parseAdvancedText()
|
|
||||||
get():
|
|
||||||
return translate
|
|
||||||
|
|
||||||
func _init() -> void:
|
|
||||||
self._parseAdvancedText()
|
|
||||||
|
|
||||||
func _enter_tree() -> void:
|
|
||||||
self._parseAdvancedText()
|
|
||||||
|
|
||||||
func _parseAdvancedText() -> void:
|
|
||||||
if advancedText.is_empty():
|
|
||||||
self.text = ""
|
|
||||||
return
|
|
||||||
var key = advancedText
|
|
||||||
if self.translate:
|
|
||||||
key = tr(key)
|
|
||||||
self.text = processInputTags(key)
|
|
||||||
|
|
||||||
func processInputTags(text:String) -> String:
|
|
||||||
var regex = RegEx.new()
|
|
||||||
regex.compile(r"\[input action=(.*?)\](.*?)\[/input\]")
|
|
||||||
var result = text
|
|
||||||
for match in regex.search_all(text):
|
|
||||||
var action = match.get_string(1).to_lower()
|
|
||||||
var height:int = 32
|
|
||||||
# var device = get_current_device_type()
|
|
||||||
# var icon_path = get_icon_for_action(action, device)
|
|
||||||
var img_tag = "[img height=%d valign=center,center]res://textures/input/%s.tres[/img]" % [ height, action ]
|
|
||||||
result = result.replace(match.get_string(0), img_tag)
|
|
||||||
return result
|
|
@@ -1,8 +1,9 @@
|
|||||||
[gd_scene load_steps=4 format=3 uid="uid://bkx3l0kckf4a8"]
|
[gd_scene load_steps=5 format=3 uid="uid://bkx3l0kckf4a8"]
|
||||||
|
|
||||||
[ext_resource type="Theme" uid="uid://dm7ee4aqjr2dl" path="res://ui/UI Theme.tres" id="1_wx4lp"]
|
[ext_resource type="Theme" uid="uid://dm7ee4aqjr2dl" path="res://ui/UI Theme.tres" id="1_wx4lp"]
|
||||||
[ext_resource type="Script" uid="uid://h8lw23ypcfty" path="res://ui/component/VNTextbox.gd" id="2_uo1gm"]
|
[ext_resource type="Script" uid="uid://h8lw23ypcfty" path="res://ui/component/VNTextbox.gd" id="2_uo1gm"]
|
||||||
[ext_resource type="Script" uid="uid://bjj6upgk1uvxd" path="res://ui/component/AdvancedRichText.gd" id="3_m60k3"]
|
[ext_resource type="Script" uid="uid://c6av3xe4m2ujl" path="res://addons/madtalk/runtime/madtalk_runtime.gd" id="3_2x6s1"]
|
||||||
|
[ext_resource type="Script" uid="uid://bjj6upgk1uvxd" path="res://ui/component/advancedrichtext/AdvancedRichText.gd" id="3_m60k3"]
|
||||||
|
|
||||||
[node name="VNTextbox" type="PanelContainer"]
|
[node name="VNTextbox" type="PanelContainer"]
|
||||||
anchors_preset = 12
|
anchors_preset = 12
|
||||||
@@ -15,6 +16,12 @@ grow_vertical = 0
|
|||||||
theme = ExtResource("1_wx4lp")
|
theme = ExtResource("1_wx4lp")
|
||||||
script = ExtResource("2_uo1gm")
|
script = ExtResource("2_uo1gm")
|
||||||
|
|
||||||
|
[node name="MadTalk" type="Node" parent="."]
|
||||||
|
script = ExtResource("3_2x6s1")
|
||||||
|
DialogMainControl = NodePath("..")
|
||||||
|
DialogMessageBox = NodePath("../MarginContainer")
|
||||||
|
DialogMessageLabel = NodePath("../MarginContainer/Label")
|
||||||
|
|
||||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
theme = ExtResource("1_wx4lp")
|
theme = ExtResource("1_wx4lp")
|
||||||
@@ -27,12 +34,8 @@ theme_override_constants/margin_bottom = 4
|
|||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
theme = ExtResource("1_wx4lp")
|
theme = ExtResource("1_wx4lp")
|
||||||
bbcode_enabled = true
|
bbcode_enabled = true
|
||||||
text = "TEST
|
text = "To get through tight spaces, press[input action=down][/input]"
|
||||||
TEST
|
fit_content = true
|
||||||
TEST
|
|
||||||
TEST"
|
|
||||||
script = ExtResource("3_m60k3")
|
script = ExtResource("3_m60k3")
|
||||||
advancedText = "TEST
|
userText = "To get through tight spaces, press[input action=down][/input]"
|
||||||
TEST
|
finalText = "To get through tight spaces, press[img height=12 valign=center,center]res://ui/input/down.tres[/img]"
|
||||||
TEST
|
|
||||||
TEST"
|
|
||||||
|
104
ui/component/advancedrichtext/AdvancedRichText.gd
Normal file
104
ui/component/advancedrichtext/AdvancedRichText.gd
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
@tool
|
||||||
|
class_name AdvancedRichText extends RichTextLabel
|
||||||
|
|
||||||
|
@export_multiline var userText:String = "" # The text the user is asking for
|
||||||
|
@export_multiline var finalText:String = "" # The final text after processing (translation, wrapping, etc.)
|
||||||
|
|
||||||
|
# Hides the original RichTextLabel text property
|
||||||
|
func _set(property: StringName, value) -> bool:
|
||||||
|
if property == "text":
|
||||||
|
userText = value
|
||||||
|
_recalcText()
|
||||||
|
return true
|
||||||
|
elif property == "richtextlabel_text":
|
||||||
|
text = value
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
func _get(property: StringName):
|
||||||
|
if property == "text":
|
||||||
|
return userText
|
||||||
|
elif property == "richtextlabel_text":
|
||||||
|
return text
|
||||||
|
return null
|
||||||
|
|
||||||
|
@export var translate:bool = true:
|
||||||
|
set(value):
|
||||||
|
translate = value
|
||||||
|
_recalcText()
|
||||||
|
get():
|
||||||
|
return translate
|
||||||
|
|
||||||
|
@export var smartWrap:bool = true:
|
||||||
|
set(value):
|
||||||
|
smartWrap = value
|
||||||
|
_recalcText()
|
||||||
|
get():
|
||||||
|
return smartWrap
|
||||||
|
|
||||||
|
func _init() -> void:
|
||||||
|
_recalcText()
|
||||||
|
|
||||||
|
func _enter_tree() -> void:
|
||||||
|
_recalcText()
|
||||||
|
self.resized.connect(_recalcText)
|
||||||
|
|
||||||
|
func _exit_tree() -> void:
|
||||||
|
self.resized.disconnect(_recalcText)
|
||||||
|
|
||||||
|
func _recalcText() -> void:
|
||||||
|
if userText.is_empty():
|
||||||
|
self.richtextlabel_text = ""
|
||||||
|
return
|
||||||
|
|
||||||
|
# Translate if needed
|
||||||
|
var textTranslated = userText
|
||||||
|
if self.translate:
|
||||||
|
textTranslated = tr(textTranslated)
|
||||||
|
|
||||||
|
# Replace input bb tags.
|
||||||
|
var regex = RegEx.new()
|
||||||
|
regex.compile(r"\[input action=(.*?)\](.*?)\[/input\]")
|
||||||
|
var inputIconText = textTranslated
|
||||||
|
for match in regex.search_all(textTranslated):
|
||||||
|
var action = match.get_string(1).to_lower()
|
||||||
|
var height:int = get_theme_font_size("normal_font_size")
|
||||||
|
# var device = get_current_device_type()
|
||||||
|
# var icon_path = get_icon_for_action(action, device)
|
||||||
|
var img_tag = "[img height=%d valign=center,center]res://ui/input/%s.tres[/img]" % [ height, action ]
|
||||||
|
inputIconText = inputIconText.replace(match.get_string(0), img_tag)
|
||||||
|
|
||||||
|
# Perform smart wrapping
|
||||||
|
var wrappedText = inputIconText
|
||||||
|
if smartWrap:
|
||||||
|
var unwrappedText = wrappedText.strip_edges()
|
||||||
|
|
||||||
|
self.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART;
|
||||||
|
self.richtextlabel_text = unwrappedText
|
||||||
|
self.visible_characters = -1;
|
||||||
|
self.fit_content = true;
|
||||||
|
var newlineIndexes = [];
|
||||||
|
|
||||||
|
# Determine where the wrapped newlines are
|
||||||
|
var line = 0;
|
||||||
|
var wasNewLine = false;
|
||||||
|
for i in range(0, unwrappedText.length()):
|
||||||
|
var tLine = self.get_character_line(i);
|
||||||
|
if tLine == line || tLine == -1:
|
||||||
|
wasNewLine = false
|
||||||
|
if unwrappedText[i] == "\n":
|
||||||
|
wasNewLine = true
|
||||||
|
continue;
|
||||||
|
if !wasNewLine:
|
||||||
|
newlineIndexes.append(i);
|
||||||
|
line = tLine;
|
||||||
|
|
||||||
|
# Create fake pre-wrapped text.
|
||||||
|
wrappedText = "";
|
||||||
|
for i in range(0, unwrappedText.length()):
|
||||||
|
if newlineIndexes.find(i) != -1 and i != 0:
|
||||||
|
wrappedText += "\n";
|
||||||
|
wrappedText += unwrappedText[i];
|
||||||
|
|
||||||
|
finalText = wrappedText
|
||||||
|
self.richtextlabel_text = wrappedText
|
@@ -1,6 +1,6 @@
|
|||||||
[gd_resource type="Texture2D" script_class="ControllerIconTexture" load_steps=2 format=3 uid="uid://vb20551utmet"]
|
[gd_resource type="Texture2D" script_class="ControllerIconTexture" load_steps=2 format=3 uid="uid://vb20551utmet"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://ddxpo5u73ssi2" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_iw3l5"]
|
[ext_resource type="Script" uid="uid://cxab4gf8nejc2" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_iw3l5"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
resource_local_to_scene = false
|
resource_local_to_scene = false
|
||||||
@@ -8,5 +8,6 @@ resource_name = ""
|
|||||||
script = ExtResource("1_iw3l5")
|
script = ExtResource("1_iw3l5")
|
||||||
path = "debug"
|
path = "debug"
|
||||||
show_mode = 0
|
show_mode = 0
|
||||||
|
force_controller_icon_style = -1
|
||||||
force_type = 0
|
force_type = 0
|
||||||
metadata/_custom_type_script = "uid://ddxpo5u73ssi2"
|
force_device = 16
|
||||||
|
@@ -1,12 +1,13 @@
|
|||||||
[gd_resource type="Texture2D" script_class="ControllerIconTexture" load_steps=2 format=3 uid="uid://cyfh2wyhh1cjg"]
|
[gd_resource type="Texture2D" script_class="ControllerIconTexture" load_steps=2 format=3 uid="uid://cyfh2wyhh1cjg"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://ddxpo5u73ssi2" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_p6b3a"]
|
[ext_resource type="Script" uid="uid://cxab4gf8nejc2" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_p6b3a"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
resource_local_to_scene = false
|
resource_local_to_scene = false
|
||||||
resource_name = ""
|
resource_name = ""
|
||||||
script = ExtResource("1_p6b3a")
|
script = ExtResource("1_p6b3a")
|
||||||
path = "down"
|
path = "move_back"
|
||||||
show_mode = 0
|
show_mode = 0
|
||||||
|
force_controller_icon_style = -1
|
||||||
force_type = 0
|
force_type = 0
|
||||||
metadata/_custom_type_script = "uid://ddxpo5u73ssi2"
|
force_device = 16
|
||||||
|
@@ -1,12 +1,13 @@
|
|||||||
[gd_resource type="Texture2D" script_class="ControllerIconTexture" load_steps=2 format=3 uid="uid://b3ii1cu3mc7jc"]
|
[gd_resource type="Texture2D" script_class="ControllerIconTexture" load_steps=2 format=3 uid="uid://b3ii1cu3mc7jc"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://ddxpo5u73ssi2" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_ngf5d"]
|
[ext_resource type="Script" uid="uid://cxab4gf8nejc2" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_ngf5d"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
resource_local_to_scene = false
|
resource_local_to_scene = false
|
||||||
resource_name = ""
|
resource_name = ""
|
||||||
script = ExtResource("1_ngf5d")
|
script = ExtResource("1_ngf5d")
|
||||||
path = "up"
|
path = "interact"
|
||||||
show_mode = 0
|
show_mode = 0
|
||||||
|
force_controller_icon_style = -1
|
||||||
force_type = 0
|
force_type = 0
|
||||||
metadata/_custom_type_script = "uid://ddxpo5u73ssi2"
|
force_device = 16
|
||||||
|
@@ -1,12 +1,13 @@
|
|||||||
[gd_resource type="Texture2D" script_class="ControllerIconTexture" load_steps=2 format=3 uid="uid://thb0gnik8oo3"]
|
[gd_resource type="Texture2D" script_class="ControllerIconTexture" load_steps=2 format=3 uid="uid://thb0gnik8oo3"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://ddxpo5u73ssi2" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_fijpq"]
|
[ext_resource type="Script" uid="uid://cxab4gf8nejc2" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_fijpq"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
resource_local_to_scene = false
|
resource_local_to_scene = false
|
||||||
resource_name = ""
|
resource_name = ""
|
||||||
script = ExtResource("1_fijpq")
|
script = ExtResource("1_fijpq")
|
||||||
path = "left"
|
path = "move_left"
|
||||||
show_mode = 0
|
show_mode = 0
|
||||||
|
force_controller_icon_style = -1
|
||||||
force_type = 0
|
force_type = 0
|
||||||
metadata/_custom_type_script = "uid://ddxpo5u73ssi2"
|
force_device = 16
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
[gd_resource type="Texture2D" script_class="ControllerIconTexture" load_steps=2 format=3 uid="uid://byijoyarhygot"]
|
[gd_resource type="Texture2D" script_class="ControllerIconTexture" load_steps=2 format=3 uid="uid://byijoyarhygot"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://ddxpo5u73ssi2" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_o0qtj"]
|
[ext_resource type="Script" uid="uid://cxab4gf8nejc2" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_o0qtj"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
resource_local_to_scene = false
|
resource_local_to_scene = false
|
||||||
@@ -8,5 +8,6 @@ resource_name = ""
|
|||||||
script = ExtResource("1_o0qtj")
|
script = ExtResource("1_o0qtj")
|
||||||
path = "pause"
|
path = "pause"
|
||||||
show_mode = 0
|
show_mode = 0
|
||||||
|
force_controller_icon_style = -1
|
||||||
force_type = 0
|
force_type = 0
|
||||||
metadata/_custom_type_script = "uid://ddxpo5u73ssi2"
|
force_device = 16
|
||||||
|
@@ -1,12 +1,13 @@
|
|||||||
[gd_resource type="Texture2D" script_class="ControllerIconTexture" load_steps=2 format=3 uid="uid://dajlk4u1q8rsp"]
|
[gd_resource type="Texture2D" script_class="ControllerIconTexture" load_steps=2 format=3 uid="uid://dajlk4u1q8rsp"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://ddxpo5u73ssi2" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_guxqd"]
|
[ext_resource type="Script" uid="uid://cxab4gf8nejc2" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_guxqd"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
resource_local_to_scene = false
|
resource_local_to_scene = false
|
||||||
resource_name = ""
|
resource_name = ""
|
||||||
script = ExtResource("1_guxqd")
|
script = ExtResource("1_guxqd")
|
||||||
path = "right"
|
path = "move_right"
|
||||||
show_mode = 0
|
show_mode = 0
|
||||||
|
force_controller_icon_style = -1
|
||||||
force_type = 0
|
force_type = 0
|
||||||
metadata/_custom_type_script = "uid://ddxpo5u73ssi2"
|
force_device = 16
|
||||||
|
@@ -1,12 +1,13 @@
|
|||||||
[gd_resource type="Texture2D" script_class="ControllerIconTexture" load_steps=2 format=3 uid="uid://blut4glc4n0ck"]
|
[gd_resource type="Texture2D" script_class="ControllerIconTexture" load_steps=2 format=3 uid="uid://blut4glc4n0ck"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://ddxpo5u73ssi2" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_y6k0e"]
|
[ext_resource type="Script" uid="uid://cxab4gf8nejc2" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_y6k0e"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
resource_local_to_scene = false
|
resource_local_to_scene = false
|
||||||
resource_name = ""
|
resource_name = ""
|
||||||
script = ExtResource("1_y6k0e")
|
script = ExtResource("1_y6k0e")
|
||||||
path = "left"
|
path = "move_left"
|
||||||
show_mode = 0
|
show_mode = 0
|
||||||
|
force_controller_icon_style = -1
|
||||||
force_type = 0
|
force_type = 0
|
||||||
metadata/_custom_type_script = "uid://ddxpo5u73ssi2"
|
force_device = 16
|
||||||
|
Reference in New Issue
Block a user