Add components
BIN
Fonts/Qubi.ttf
Normal file
40
Fonts/Qubi.ttf.import
Normal file
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="font_data_dynamic"
|
||||
type="FontFile"
|
||||
uid="uid://byubry1acvlug"
|
||||
path="res://.godot/imported/Qubi.ttf-ef2072390941155281c267608c0b0094.fontdata"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://Fonts/Qubi.ttf"
|
||||
dest_files=["res://.godot/imported/Qubi.ttf-ef2072390941155281c267608c0b0094.fontdata"]
|
||||
|
||||
[params]
|
||||
|
||||
Rendering=null
|
||||
antialiasing=1
|
||||
generate_mipmaps=false
|
||||
disable_embedded_bitmaps=true
|
||||
multichannel_signed_distance_field=false
|
||||
msdf_pixel_range=8
|
||||
msdf_size=48
|
||||
allow_system_fallback=true
|
||||
force_autohinter=false
|
||||
hinting=0
|
||||
subpixel_positioning=1
|
||||
oversampling=0.0
|
||||
Fallbacks=null
|
||||
fallbacks=[]
|
||||
Compress=null
|
||||
compress=true
|
||||
preload=[{
|
||||
"chars": [],
|
||||
"glyphs": [],
|
||||
"name": "New Configuration",
|
||||
"size": Vector2i(16, 0),
|
||||
"variation_embolden": 0.0
|
||||
}]
|
||||
language_support={}
|
||||
script_support={}
|
||||
opentype_features={}
|
BIN
Fonts/Qubio.ttf
Normal file
34
Fonts/Qubio.ttf.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="font_data_dynamic"
|
||||
type="FontFile"
|
||||
uid="uid://chmfli1xm8oe1"
|
||||
path="res://.godot/imported/Qubio.ttf-32f8479b52e99fe78535ddaada4aa1d7.fontdata"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://Fonts/Qubio.ttf"
|
||||
dest_files=["res://.godot/imported/Qubio.ttf-32f8479b52e99fe78535ddaada4aa1d7.fontdata"]
|
||||
|
||||
[params]
|
||||
|
||||
Rendering=null
|
||||
antialiasing=1
|
||||
generate_mipmaps=false
|
||||
disable_embedded_bitmaps=true
|
||||
multichannel_signed_distance_field=false
|
||||
msdf_pixel_range=8
|
||||
msdf_size=48
|
||||
allow_system_fallback=true
|
||||
force_autohinter=false
|
||||
hinting=0
|
||||
subpixel_positioning=1
|
||||
oversampling=0.0
|
||||
Fallbacks=null
|
||||
fallbacks=[]
|
||||
Compress=null
|
||||
compress=true
|
||||
preload=[]
|
||||
language_support={}
|
||||
script_support={}
|
||||
opentype_features={}
|
7
Fonts/Theme.tres
Normal file
|
@ -0,0 +1,7 @@
|
|||
[gd_resource type="Theme" load_steps=2 format=3 uid="uid://ck7603ob4gflc"]
|
||||
|
||||
[ext_resource type="FontFile" uid="uid://byubry1acvlug" path="res://Fonts/Qubi.ttf" id="1_y7uny"]
|
||||
|
||||
[resource]
|
||||
default_font = ExtResource("1_y7uny")
|
||||
default_font_size = 8
|
3
Main.tscn
Normal file
|
@ -0,0 +1,3 @@
|
|||
[gd_scene format=3 uid="uid://bs6ojoud4mvb8"]
|
||||
|
||||
[node name="Main" type="Node2D"]
|
7
addons/laia_highlighter/plugin.cfg
Normal file
|
@ -0,0 +1,7 @@
|
|||
[plugin]
|
||||
|
||||
name="Laia Highlighter"
|
||||
description="A highlighter to highting laia scripting files"
|
||||
author="Ategon"
|
||||
version="v1.0.0"
|
||||
script="plugin.gd"
|
81
addons/laia_highlighter/plugin.gd
Normal file
|
@ -0,0 +1,81 @@
|
|||
@tool
|
||||
extends EditorPlugin
|
||||
|
||||
|
||||
var dialogue_highlighter:DialogueHighlighter
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
dialogue_highlighter = DialogueHighlighter.new()
|
||||
var script_editor = EditorInterface.get_script_editor()
|
||||
print(script_editor)
|
||||
print(dialogue_highlighter)
|
||||
script_editor.register_syntax_highlighter(dialogue_highlighter)
|
||||
print(script_editor.get_current_script())
|
||||
print(script_editor.get_open_scripts())
|
||||
script_editor.goto_line(20)
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
if is_instance_valid(dialogue_highlighter):
|
||||
var script_editor = EditorInterface.get_script_editor()
|
||||
script_editor.unregister_syntax_highlighter(dialogue_highlighter)
|
||||
dialogue_highlighter = null
|
||||
|
||||
|
||||
class DialogueHighlighter extends EditorSyntaxHighlighter:
|
||||
func _get_name() -> String:
|
||||
return "Laia"
|
||||
|
||||
func _get_supported_languages() -> PackedStringArray:
|
||||
return ["TextFile"]
|
||||
|
||||
func _get_line_syntax_highlighting(line: int) -> Dictionary:
|
||||
var color_map = {}
|
||||
var text_editor = get_text_edit()
|
||||
var str = text_editor.get_line(line)
|
||||
|
||||
# Comment
|
||||
if str.strip_edges().begins_with("#"):
|
||||
color_map[0] = { "color": Color.WEB_GRAY }
|
||||
return color_map
|
||||
|
||||
# Key
|
||||
var regex3 = RegEx.new()
|
||||
regex3.compile("([a-zA-Z0-9_]+:).*")
|
||||
var result3 = regex3.search(str)
|
||||
|
||||
if result3:
|
||||
color_map[result3.get_start(1)] = { "color": Color.SEA_GREEN }
|
||||
color_map[result3.get_end(1)] = { "color": Color.WHITE }
|
||||
|
||||
# Array
|
||||
var regex = RegEx.new()
|
||||
regex.compile("([a-zA-Z0-9_\\-])+\\[\\]")
|
||||
var result = regex.search(str)
|
||||
|
||||
if result:
|
||||
color_map[result.get_start()] = { "color": Color.CYAN }
|
||||
color_map[result.get_end(1)] = { "color": Color.LIGHT_CYAN }
|
||||
|
||||
# Enum
|
||||
var regex4 = RegEx.new()
|
||||
regex4.compile("[a-zA-Z0-9_]+(\\.[a-zA-Z0-9_]+)")
|
||||
var result4 = regex4.search(str)
|
||||
|
||||
if result4:
|
||||
color_map[result4.get_start()] = { "color": Color.ORANGE }
|
||||
color_map[result4.get_start(1)] = { "color": Color.ORANGE_RED }
|
||||
color_map[result4.get_end()] = { "color": Color.WHITE }
|
||||
|
||||
# Color
|
||||
var regex2 = RegEx.new()
|
||||
regex2.compile("#[a-zA-Z0-9]+")
|
||||
var result2 = regex2.search(str)
|
||||
|
||||
if result2:
|
||||
color_map[result2.get_start()] = { "color": Color(result2.get_string()) }
|
||||
|
||||
|
||||
|
||||
return color_map
|
164
components/Achievements/Achievements.tscn
Normal file
|
@ -0,0 +1,164 @@
|
|||
[gd_scene load_steps=11 format=3 uid="uid://c8nsgn4idu8ay"]
|
||||
|
||||
[ext_resource type="Script" path="res://components/Achievements/achievements.gd" id="1_fj2tg"]
|
||||
[ext_resource type="Texture2D" uid="uid://dat440dg86mjl" path="res://components/Achievements/back.png" id="2_1q85v"]
|
||||
[ext_resource type="Theme" uid="uid://ck7603ob4gflc" path="res://Fonts/Theme.tres" id="2_p5tbu"]
|
||||
[ext_resource type="PackedScene" uid="uid://dykc1mgg5uopw" path="res://components/Cursor/MouseHandler.tscn" id="2_vij8n"]
|
||||
[ext_resource type="Texture2D" uid="uid://bypm21lqwg7g0" path="res://components/Achievements/Village 6.png" id="4_1mson"]
|
||||
[ext_resource type="Texture2D" uid="uid://ur6oiwg6ksns" path="res://components/Achievements/award.svg" id="4_7grt2"]
|
||||
[ext_resource type="Texture2D" uid="uid://dcj0xniur7dk1" path="res://components/Achievements/thumbnail-mask.png" id="6_dwjjq"]
|
||||
[ext_resource type="AudioStream" uid="uid://dxac8e02mctgp" path="res://components/Achievements/achievement.wav" id="8_74gug"]
|
||||
[ext_resource type="AudioStream" uid="uid://4m4dwlrv78l" path="res://components/Achievements/achievement-back.ogg" id="9_c3xir"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_yajw4"]
|
||||
size = Vector2(180, 32)
|
||||
|
||||
[node name="Achievements" type="Node"]
|
||||
script = ExtResource("1_fj2tg")
|
||||
|
||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||
|
||||
[node name="Popup" type="Control" parent="CanvasLayer"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 3
|
||||
anchor_left = 1.0
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -140.0
|
||||
offset_top = -42.0
|
||||
offset_right = 40.0
|
||||
offset_bottom = -12.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 0
|
||||
|
||||
[node name="MouseHandler" parent="CanvasLayer/Popup" instance=ExtResource("2_vij8n")]
|
||||
position = Vector2(62, 15)
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="CanvasLayer/Popup/MouseHandler"]
|
||||
position = Vector2(29, 0)
|
||||
shape = SubResource("RectangleShape2D_yajw4")
|
||||
|
||||
[node name="Shadow" type="TextureRect" parent="CanvasLayer/Popup"]
|
||||
modulate = Color(0, 0, 0, 1)
|
||||
show_behind_parent = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 3
|
||||
anchor_left = 1.0
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -178.0
|
||||
offset_top = -29.0
|
||||
offset_right = 2.0
|
||||
offset_bottom = 2.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 0
|
||||
size_flags_horizontal = 8
|
||||
size_flags_vertical = 8
|
||||
theme = ExtResource("2_p5tbu")
|
||||
texture = ExtResource("2_1q85v")
|
||||
expand_mode = 1
|
||||
|
||||
[node name="Popup" type="TextureRect" parent="CanvasLayer/Popup"]
|
||||
clip_children = 2
|
||||
layout_mode = 1
|
||||
anchors_preset = 6
|
||||
anchor_left = 1.0
|
||||
anchor_top = 0.5
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -180.0
|
||||
offset_top = -15.0
|
||||
offset_bottom = 15.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 8
|
||||
size_flags_vertical = 8
|
||||
texture = ExtResource("2_1q85v")
|
||||
expand_mode = 1
|
||||
|
||||
[node name="Title" type="RichTextLabel" parent="CanvasLayer/Popup/Popup"]
|
||||
modulate = Color(0.752941, 0.478431, 0.129412, 1)
|
||||
layout_mode = 1
|
||||
anchors_preset = 4
|
||||
anchor_top = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = 46.0
|
||||
offset_top = -11.0
|
||||
offset_right = 217.0
|
||||
offset_bottom = 7.0
|
||||
grow_vertical = 2
|
||||
theme_override_colors/font_shadow_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/normal_font_size = 7
|
||||
text = "Achievement Text"
|
||||
|
||||
[node name="Body" type="RichTextLabel" parent="CanvasLayer/Popup/Popup"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 4
|
||||
anchor_top = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = 37.0
|
||||
offset_top = 2.0
|
||||
offset_right = 223.0
|
||||
offset_bottom = 18.0
|
||||
grow_vertical = 2
|
||||
theme_override_colors/default_color = Color(0.607843, 0.607843, 0.607843, 1)
|
||||
theme_override_colors/font_shadow_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/normal_font_size = 7
|
||||
text = "Achievement Body"
|
||||
|
||||
[node name="AwardShadow" type="TextureRect" parent="CanvasLayer/Popup/Popup"]
|
||||
modulate = Color(0, 0, 0, 1)
|
||||
layout_mode = 0
|
||||
offset_left = 36.0
|
||||
offset_top = 6.0
|
||||
offset_right = 45.0
|
||||
offset_bottom = 15.0
|
||||
texture = ExtResource("4_7grt2")
|
||||
expand_mode = 2
|
||||
|
||||
[node name="Award" type="TextureRect" parent="CanvasLayer/Popup/Popup"]
|
||||
modulate = Color(0.752941, 0.478431, 0.129412, 1)
|
||||
layout_mode = 0
|
||||
offset_left = 34.5
|
||||
offset_top = 4.5
|
||||
offset_right = 43.5
|
||||
offset_bottom = 13.5
|
||||
texture = ExtResource("4_7grt2")
|
||||
expand_mode = 2
|
||||
|
||||
[node name="ThumbnailMask" type="TextureRect" parent="CanvasLayer/Popup"]
|
||||
clip_children = 1
|
||||
layout_mode = 1
|
||||
anchors_preset = 4
|
||||
anchor_top = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = 3.0
|
||||
offset_top = -12.0
|
||||
offset_right = 32.0
|
||||
offset_bottom = 12.0
|
||||
grow_vertical = 2
|
||||
texture = ExtResource("6_dwjjq")
|
||||
expand_mode = 1
|
||||
|
||||
[node name="Thumbnail" type="TextureRect" parent="CanvasLayer/Popup/ThumbnailMask"]
|
||||
layout_mode = 0
|
||||
offset_right = 29.0
|
||||
offset_bottom = 24.0
|
||||
texture = ExtResource("4_1mson")
|
||||
expand_mode = 1
|
||||
|
||||
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
|
||||
stream = ExtResource("8_74gug")
|
||||
volume_db = -9.043
|
||||
|
||||
[node name="AudioStreamPlayer2" type="AudioStreamPlayer" parent="."]
|
||||
stream = ExtResource("9_c3xir")
|
||||
volume_db = -17.441
|
||||
|
||||
[connection signal="clicked" from="CanvasLayer/Popup/MouseHandler" to="." method="_on_mouse_handler_clicked"]
|
||||
[connection signal="hovered" from="CanvasLayer/Popup/MouseHandler" to="." method="_on_mouse_handler_hovered"]
|
||||
[connection signal="unhovered" from="CanvasLayer/Popup/MouseHandler" to="." method="_on_mouse_handler_unhovered"]
|
||||
|
||||
[editable path="CanvasLayer/Popup/MouseHandler"]
|
BIN
components/Achievements/Village 6.png
Normal file
After Width: | Height: | Size: 2 MiB |
34
components/Achievements/Village 6.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bypm21lqwg7g0"
|
||||
path="res://.godot/imported/Village 6.png-38dba7a44eb73e6643b934b25a9dbbf9.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Achievements/Village 6.png"
|
||||
dest_files=["res://.godot/imported/Village 6.png-38dba7a44eb73e6643b934b25a9dbbf9.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
|
BIN
components/Achievements/achievement-back.ogg
Normal file
19
components/Achievements/achievement-back.ogg.import
Normal file
|
@ -0,0 +1,19 @@
|
|||
[remap]
|
||||
|
||||
importer="oggvorbisstr"
|
||||
type="AudioStreamOggVorbis"
|
||||
uid="uid://4m4dwlrv78l"
|
||||
path="res://.godot/imported/achievement-back.ogg-e15f114c4307f4746154a747d47f126e.oggvorbisstr"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Achievements/achievement-back.ogg"
|
||||
dest_files=["res://.godot/imported/achievement-back.ogg-e15f114c4307f4746154a747d47f126e.oggvorbisstr"]
|
||||
|
||||
[params]
|
||||
|
||||
loop=false
|
||||
loop_offset=0
|
||||
bpm=0
|
||||
beat_count=0
|
||||
bar_beats=4
|
BIN
components/Achievements/achievement.wav
Normal file
24
components/Achievements/achievement.wav.import
Normal file
|
@ -0,0 +1,24 @@
|
|||
[remap]
|
||||
|
||||
importer="wav"
|
||||
type="AudioStreamWAV"
|
||||
uid="uid://dxac8e02mctgp"
|
||||
path="res://.godot/imported/achievement.wav-eb6c9e09c6c75764f5cf65335ad5f16a.sample"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Achievements/achievement.wav"
|
||||
dest_files=["res://.godot/imported/achievement.wav-eb6c9e09c6c75764f5cf65335ad5f16a.sample"]
|
||||
|
||||
[params]
|
||||
|
||||
force/8_bit=false
|
||||
force/mono=false
|
||||
force/max_rate=false
|
||||
force/max_rate_hz=44100
|
||||
edit/trim=false
|
||||
edit/normalize=false
|
||||
edit/loop_mode=0
|
||||
edit/loop_begin=0
|
||||
edit/loop_end=-1
|
||||
compress/mode=0
|
261
components/Achievements/achievements.gd
Normal file
|
@ -0,0 +1,261 @@
|
|||
extends Base
|
||||
## Achievement handler to check and unlock achievements
|
||||
##
|
||||
## An achievement handler that will check the available achievements defined in
|
||||
## both the game files and the mods. When called with triggers will check to see
|
||||
## if that trigger value unlocks achievements.
|
||||
|
||||
signal achievement_unlocked(achievement: String)
|
||||
|
||||
const CACHE_TIME = 60000
|
||||
const POPUP_POP_TIME = 1000
|
||||
const POPUP_LINGER_TIME = 5000
|
||||
const POPUP_HIDE_TIME = 1000
|
||||
const POPUP_BREAK = 1000
|
||||
const POPUP_HOVER_TIME = 250
|
||||
|
||||
@onready var popup = $"CanvasLayer/Popup"
|
||||
@onready var popup_title = $"CanvasLayer/Popup/Popup/Title"
|
||||
@onready var popup_body = $"CanvasLayer/Popup/Popup/Body"
|
||||
@onready var audio = $"AudioStreamPlayer"
|
||||
@onready var audio2 = $"AudioStreamPlayer2"
|
||||
|
||||
enum AchievementState {
|
||||
ENTERING,
|
||||
SHOWN,
|
||||
HOVERED,
|
||||
EXITING,
|
||||
HIDDEN
|
||||
}
|
||||
|
||||
var queue = []
|
||||
var cached_percents = {}
|
||||
var last_percent_pull: int
|
||||
var showing_popup = false
|
||||
var starting_popup_pos
|
||||
var starting_popup_size
|
||||
var popup_tween
|
||||
var popup_timer = 0
|
||||
var popup_time = 6
|
||||
#var entering = false
|
||||
#var exiting = false
|
||||
#var hovered = false
|
||||
|
||||
var achievement_state = AchievementState.HIDDEN
|
||||
var hovered = false
|
||||
|
||||
|
||||
|
||||
func _ready():
|
||||
#_log_category = "ACH"
|
||||
#_log_icon = "res://components/Logger/scroll-text.svg"
|
||||
#_log_color = "#a166a1"
|
||||
super()
|
||||
_info("Achievements is active")
|
||||
starting_popup_pos = popup.position
|
||||
starting_popup_size = popup.size
|
||||
popup.position.x = starting_popup_pos.x + starting_popup_size.x
|
||||
popup.modulate = Color.TRANSPARENT
|
||||
popup.scale = Vector2(0.5, 0.5)
|
||||
if _triggerer:
|
||||
_triggerer.listen("any", _on_trigger)
|
||||
|
||||
|
||||
func _on_trigger(data: Dictionary) -> void:
|
||||
_check_trigger(data.trigger, "Trigger")
|
||||
|
||||
|
||||
func _process(delta):
|
||||
popup_timer += delta
|
||||
|
||||
if popup_timer > popup_time and achievement_state == AchievementState.SHOWN:
|
||||
_exit_popup()
|
||||
|
||||
|
||||
if not queue.is_empty() and not showing_popup:
|
||||
_show_popup(queue.pop_front())
|
||||
|
||||
if popup_tween and not popup_tween.is_running():
|
||||
if hovered and achievement_state == AchievementState.SHOWN:
|
||||
achievement_state = AchievementState.HOVERED
|
||||
|
||||
popup_tween = create_tween()
|
||||
popup_tween.set_parallel()
|
||||
popup_tween.set_trans(Tween.TRANS_QUAD)
|
||||
popup_tween.tween_property(popup, "scale", Vector2(1.05, 1.05), float(POPUP_HOVER_TIME) / 1000)
|
||||
popup_tween.tween_property(popup, "position:x", starting_popup_pos.x - 20, float(POPUP_HOVER_TIME) / 1000)
|
||||
if not hovered and achievement_state == AchievementState.HOVERED:
|
||||
achievement_state = AchievementState.SHOWN
|
||||
|
||||
popup_tween = create_tween()
|
||||
popup_tween.set_parallel()
|
||||
popup_tween.set_trans(Tween.TRANS_QUAD)
|
||||
popup_tween.tween_property(popup, "scale", Vector2(1, 1), float(POPUP_HOVER_TIME) / 1000)
|
||||
popup_tween.tween_property(popup, "position:x", starting_popup_pos.x, float(POPUP_HOVER_TIME) / 1000)
|
||||
|
||||
|
||||
func _exit_popup():
|
||||
achievement_state = AchievementState.EXITING
|
||||
audio2.play()
|
||||
|
||||
if popup_tween: popup_tween.kill()
|
||||
popup_tween = create_tween()
|
||||
|
||||
popup_tween.set_ease(Tween.EASE_IN)
|
||||
popup_tween.set_trans(Tween.TRANS_BACK)
|
||||
popup_tween.set_parallel()
|
||||
popup_tween.tween_property(popup, "modulate", Color.TRANSPARENT, POPUP_POP_TIME / 1000)
|
||||
popup_tween.tween_property(popup, "scale", Vector2(0.5, 0.5), POPUP_POP_TIME / 1000)
|
||||
popup_tween.tween_property(popup, "position:x", starting_popup_pos.x + starting_popup_size.x, POPUP_HIDE_TIME / 1000)
|
||||
popup_tween.tween_interval(POPUP_BREAK / 1000)
|
||||
popup_tween.chain()
|
||||
popup_tween.tween_callback(func(): showing_popup = false)
|
||||
|
||||
_info("Hiding achievement popup")
|
||||
|
||||
|
||||
func _on_data_persisted(key: String, value, category: PersisterEnums.Scope):
|
||||
_check_trigger(key, "Data", value)
|
||||
|
||||
|
||||
## Get all of the achievement info
|
||||
func get_achievements() -> Dictionary:
|
||||
if not _data:
|
||||
if (_logger): _logger.warn("Could not find data autoload when getting achievements")
|
||||
return {}
|
||||
|
||||
if not _data.data.has("achievements"):
|
||||
if (_logger): _logger.warn("Could not find achievement data")
|
||||
return {}
|
||||
|
||||
var local_ach_data = _data.data.achievements.duplicate()
|
||||
|
||||
var percents = _get_achievement_percents()
|
||||
|
||||
for achievement in _data.data.achievements:
|
||||
if percents.keys().has(achievement):
|
||||
local_ach_data.percent = percents[achievement]
|
||||
|
||||
return _data.data.achievements
|
||||
|
||||
|
||||
## Get achievement info given the achievement slug
|
||||
func get_achievement(achievement: String) -> Dictionary:
|
||||
if not _data:
|
||||
if _logger: _logger.warn("Could not find data autoload when getting achievement %s" % [achievement])
|
||||
return {}
|
||||
|
||||
if not _data.data.has("achievements"):
|
||||
if _logger: _logger.warn("Could not find achievement data")
|
||||
return {}
|
||||
|
||||
if not _data.data.achievements.has(achievement):
|
||||
if _logger: _logger.warn("Could not find achievement %s" % [achievement])
|
||||
return {}
|
||||
|
||||
var achievement_data = _data.data.achievements[achievement].duplicate()
|
||||
|
||||
# TODO: Add in achievement percent
|
||||
|
||||
return achievement_data
|
||||
|
||||
|
||||
func _show_popup(achievement: String) -> void:
|
||||
var achievement_data = get_achievement(achievement)
|
||||
achievement_state = AchievementState.ENTERING
|
||||
popup_timer = 0
|
||||
|
||||
if achievement_data.is_empty():
|
||||
if _logger: _logger.error("Could not get achievement %s info when trying to show" % [achievement])
|
||||
return
|
||||
|
||||
popup_title.text = achievement_data.name
|
||||
popup_body.text = achievement_data.description
|
||||
|
||||
showing_popup = true
|
||||
popup.position.x = starting_popup_pos.x + starting_popup_size.x
|
||||
popup.modulate = Color.TRANSPARENT
|
||||
popup.scale = Vector2(0.5, 0.5)
|
||||
#popup.position.y = starting_popup_pos.y + starting_popup_size.y
|
||||
|
||||
if popup_tween:
|
||||
popup_tween.kill()
|
||||
|
||||
audio.play()
|
||||
|
||||
popup_tween = create_tween()
|
||||
popup_tween.set_parallel()
|
||||
popup_tween.set_ease(Tween.EASE_OUT)
|
||||
popup_tween.set_trans(Tween.TRANS_BACK)
|
||||
popup_tween.tween_property(popup, "modulate", Color.WHITE, POPUP_POP_TIME / 1000)
|
||||
popup_tween.tween_property(popup, "scale", Vector2(1, 1), POPUP_POP_TIME / 1000)
|
||||
popup_tween.tween_property(popup, "position:x", starting_popup_pos.x, POPUP_POP_TIME / 1000)
|
||||
popup_tween.chain()
|
||||
popup_tween.tween_callback(func():
|
||||
achievement_state = AchievementState.SHOWN
|
||||
)
|
||||
|
||||
_info("Showing achievement %s popup" % [achievement])
|
||||
|
||||
|
||||
func _get_achievement_percents() -> Dictionary:
|
||||
if not last_percent_pull:
|
||||
return _get_percents_from_db()
|
||||
|
||||
if last_percent_pull + CACHE_TIME <= Time.get_ticks_msec():
|
||||
return cached_percents
|
||||
|
||||
return _get_percents_from_db()
|
||||
|
||||
|
||||
func _get_percents_from_db() -> Dictionary:
|
||||
last_percent_pull = Time.get_ticks_msec()
|
||||
return {}
|
||||
|
||||
|
||||
func _send_to_db(achievement: String) -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _check_trigger(key: String, type: String, value = null):
|
||||
if not _data:
|
||||
if (_logger): _logger.warn("Could not find data autoload when checking trigger")
|
||||
return
|
||||
|
||||
if not _data.data.has("achievements"):
|
||||
return
|
||||
|
||||
for achievement in _data.data.achievements:
|
||||
# If the persister does not have the achievement already
|
||||
if not _persister.get_value(achievement):
|
||||
var ach_data = _data.data.achievements[achievement]
|
||||
|
||||
var valid = false
|
||||
|
||||
match type:
|
||||
"Data":
|
||||
if ach_data.has("key") and ach_data.key == key:
|
||||
valid = ach_data.value <= value
|
||||
"Trigger":
|
||||
if ach_data.has("trigger") and ach_data.trigger == key:
|
||||
valid = true
|
||||
|
||||
if valid:
|
||||
achievement_unlocked.emit(achievement)
|
||||
_persister.persist_data(achievement, true, PersisterEnums.Scope.PERMANENT)
|
||||
_info("Added achievement %s to queue" % [achievement])
|
||||
queue.push_back(achievement)
|
||||
_send_to_db(achievement)
|
||||
|
||||
|
||||
func _on_mouse_handler_hovered():
|
||||
hovered = true
|
||||
|
||||
|
||||
func _on_mouse_handler_clicked():
|
||||
if achievement_state != AchievementState.EXITING:
|
||||
_exit_popup()
|
||||
|
||||
|
||||
func _on_mouse_handler_unhovered():
|
||||
hovered = false
|
1
components/Achievements/award.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-award"><path d="m15.477 12.89 1.515 8.526a.5.5 0 0 1-.81.47l-3.58-2.687a1 1 0 0 0-1.197 0l-3.586 2.686a.5.5 0 0 1-.81-.469l1.514-8.526"/><circle cx="12" cy="8" r="6"/></svg>
|
After Width: | Height: | Size: 368 B |
37
components/Achievements/award.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://ur6oiwg6ksns"
|
||||
path="res://.godot/imported/award.svg-6bd80af369d65193b7f216d026b9ff51.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Achievements/award.svg"
|
||||
dest_files=["res://.godot/imported/award.svg-6bd80af369d65193b7f216d026b9ff51.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
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
BIN
components/Achievements/back.png
Normal file
After Width: | Height: | Size: 9.4 KiB |
34
components/Achievements/back.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dat440dg86mjl"
|
||||
path="res://.godot/imported/back.png-7865ce000d117e80cc752a23c0588205.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Achievements/back.png"
|
||||
dest_files=["res://.godot/imported/back.png-7865ce000d117e80cc752a23c0588205.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
|
8
components/Achievements/information.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
name: Achievements
|
||||
short: Achievement handler to check and unlock achievements
|
||||
description: An achievement handler that will check the available achievements
|
||||
defined in both the game files and the mods. When called with triggers will
|
||||
check to see if that trigger value unlocks achievements.
|
||||
accent: #a166a1
|
||||
log_category: ACH
|
||||
icon: res://components/Logger/scroll-text.svg
|
BIN
components/Achievements/particle.aseprite
Normal file
BIN
components/Achievements/particle.png
Normal file
After Width: | Height: | Size: 131 B |
34
components/Achievements/particle.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://brmlpo1rv8m47"
|
||||
path="res://.godot/imported/particle.png-659e7c73fd80f7940a2d61abac8f1984.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Achievements/particle.png"
|
||||
dest_files=["res://.godot/imported/particle.png-659e7c73fd80f7940a2d61abac8f1984.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
|
BIN
components/Achievements/popup-background.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
34
components/Achievements/popup-background.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dpmrungfff7jd"
|
||||
path="res://.godot/imported/popup-background.png-1f543826c612308bac959317015a3a98.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Achievements/popup-background.png"
|
||||
dest_files=["res://.godot/imported/popup-background.png-1f543826c612308bac959317015a3a98.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
|
BIN
components/Achievements/thumbnail-mask.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
34
components/Achievements/thumbnail-mask.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dcj0xniur7dk1"
|
||||
path="res://.godot/imported/thumbnail-mask.png-9e7311d6f1141413915356d4bb61948c.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Achievements/thumbnail-mask.png"
|
||||
dest_files=["res://.godot/imported/thumbnail-mask.png-9e7311d6f1141413915356d4bb61948c.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
|
6
components/Audio/Audio.tscn
Normal file
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://cjcs6jhw45bj4"]
|
||||
|
||||
[ext_resource type="Script" path="res://components/Audio/audio.gd" id="1_c2epj"]
|
||||
|
||||
[node name="Audio" type="Node"]
|
||||
script = ExtResource("1_c2epj")
|
99
components/Audio/audio.gd
Normal file
|
@ -0,0 +1,99 @@
|
|||
@icon("res://components/Audio/music.svg")
|
||||
extends Base
|
||||
|
||||
var music_data
|
||||
var sfx_data
|
||||
|
||||
var current_playing_music
|
||||
|
||||
var tweens = {}
|
||||
|
||||
func _spawned():
|
||||
if _triggerer:
|
||||
_triggerer.listen("any", _on_trigger)
|
||||
|
||||
music_data = _data.data.music
|
||||
sfx_data = _data.data.sfx
|
||||
|
||||
for music in music_data:
|
||||
var music_value = music_data[music]
|
||||
|
||||
if not _data.data.audio.has(music):
|
||||
_error("Could not find file for music %s" % [music])
|
||||
continue
|
||||
|
||||
music_value.track = _data.data.audio[music]
|
||||
|
||||
var music_object = AudioStreamPlayer.new()
|
||||
music_object.name = "Music - %s" % [music_value.name]
|
||||
music_object.stream = music_value.track
|
||||
add_child(music_object)
|
||||
music_value.object = music_object
|
||||
|
||||
_info("Loaded music %s" % [music])
|
||||
|
||||
for sfx in sfx_data:
|
||||
var sfx_value = sfx_data[sfx]
|
||||
|
||||
if not _data.data.audio.has(sfx):
|
||||
_error("Could not find file for sfx %s" % [sfx])
|
||||
continue
|
||||
|
||||
sfx_value.track = _data.data.audio[sfx]
|
||||
|
||||
var sfx_object = AudioStreamPlayer.new()
|
||||
sfx_object.name = "SFX - %s" % [sfx_value.name]
|
||||
sfx_object.stream = sfx_value.track
|
||||
add_child(sfx_object)
|
||||
sfx_value.object = sfx_object
|
||||
|
||||
_info("Loaded sfx %s" % [sfx])
|
||||
|
||||
|
||||
func _on_trigger(data: Dictionary) -> void:
|
||||
var trigger = data.trigger
|
||||
|
||||
if not trigger.begins_with("audio_"):
|
||||
return
|
||||
|
||||
var audio_name = trigger.split("_", false, 1)[1]
|
||||
|
||||
for music in music_data:
|
||||
var music_value = music_data[music]
|
||||
|
||||
if not music == audio_name:
|
||||
continue
|
||||
|
||||
if not music_value.has("track"):
|
||||
continue
|
||||
|
||||
if current_playing_music:
|
||||
if tweens.has(current_playing_music):
|
||||
tweens[current_playing_music].kill()
|
||||
|
||||
tweens[current_playing_music] = create_tween()
|
||||
tweens[current_playing_music].tween_property(music_data[current_playing_music].object, "volume_db", -30, 1)
|
||||
tweens[current_playing_music].tween_callback(func():
|
||||
music_data[current_playing_music].object.stop()
|
||||
)
|
||||
|
||||
if tweens.has(music):
|
||||
tweens[music].kill()
|
||||
|
||||
if data.has("keep_position") and data.keep_position:
|
||||
music_value.object.play(music_data[current_playing_music].object.get_playback_position())
|
||||
else:
|
||||
music_value.object.play()
|
||||
|
||||
tweens[music] = create_tween()
|
||||
tweens[music].tween_property(music_data[music].object, "volume_db", 0, 1)
|
||||
|
||||
current_playing_music = music
|
||||
|
||||
return
|
||||
|
||||
for sfx in sfx_data:
|
||||
if not sfx == audio_name:
|
||||
continue
|
||||
|
||||
pass
|
6
components/Audio/information.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
name: Audio
|
||||
short: ???
|
||||
description: ???
|
||||
accent: #32ad61
|
||||
log_category: AUD
|
||||
icon: res://components/Audio/music.svg
|
1
components/Audio/music.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-music"><path d="M9 18V5l12-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/></svg>
|
After Width: | Height: | Size: 296 B |
37
components/Audio/music.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bnrlsuxullf0v"
|
||||
path="res://.godot/imported/music.svg-641a4ffd0c5780599b93a42e5f43eb33.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Audio/music.svg"
|
||||
dest_files=["res://.godot/imported/music.svg-641a4ffd0c5780599b93a42e5f43eb33.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
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
90
components/Base/base.gd
Normal file
|
@ -0,0 +1,90 @@
|
|||
class_name Base
|
||||
extends Node
|
||||
## A base addon
|
||||
##
|
||||
## A base addon for shared functionality between all other addons
|
||||
|
||||
var _logger
|
||||
var _data
|
||||
var _persister
|
||||
var _triggerer
|
||||
var _information = {
|
||||
"log_category": "???",
|
||||
"accent": "#000000",
|
||||
"icon": "res://components/Cursor/mouse-pointer-2.svg"
|
||||
}
|
||||
|
||||
var CORE_NODES = {
|
||||
"Logger": {
|
||||
"property": "_logger"
|
||||
},
|
||||
"Data": {
|
||||
"property": "_data"
|
||||
},
|
||||
"Triggerer": {
|
||||
"property": "_triggerer",
|
||||
},
|
||||
"Persister": {
|
||||
"property": "_persister",
|
||||
"connections": {"data_persisted": "_on_data_persisted"}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func _ready():
|
||||
for node in CORE_NODES:
|
||||
# Prevent circular references
|
||||
if name == node:
|
||||
break
|
||||
|
||||
# Connect up core nodes
|
||||
var node_value = CORE_NODES[node]
|
||||
|
||||
if get_tree().root.has_node(node):
|
||||
set(node_value.property, get_tree().root.get_node(node))
|
||||
var property = get(node_value.property)
|
||||
|
||||
if node_value.has("connections"):
|
||||
var connections = node_value.connections
|
||||
|
||||
for connection in connections:
|
||||
var connection_callback = connections[connection]
|
||||
|
||||
property.get(connection).connect(get(connection_callback))
|
||||
|
||||
if _data and _data.components.has(name):
|
||||
_information = _data.components[name].information
|
||||
|
||||
if _information.has("triggers"):
|
||||
for trigger in _information.triggers:
|
||||
_triggerer.listen(trigger, Callable(self, _information.triggers[trigger]))
|
||||
|
||||
if has_method("_prespawned"):
|
||||
call("_prespawned")
|
||||
|
||||
_info("%s is active" % [name])
|
||||
|
||||
if has_method("_spawned"):
|
||||
call("_spawned")
|
||||
|
||||
_info("%s is ready" % [name])
|
||||
|
||||
|
||||
func _on_data_persisted(key: String, value, category: PersisterEnums.Scope):
|
||||
pass
|
||||
|
||||
|
||||
func _debug(message: String):
|
||||
if _logger: _logger.debug(message, { "category": _information.log_category, "image": _information.icon, "color": _information.accent })
|
||||
|
||||
|
||||
func _info(message: String):
|
||||
if _logger: _logger.info(message, { "category": _information.log_category, "image": _information.icon, "color": _information.accent })
|
||||
|
||||
|
||||
func _warn(message: String):
|
||||
if _logger: _logger.warn(message, { "category": _information.log_category, "image": _information.icon, "color": _information.accent })
|
||||
|
||||
|
||||
func _error(message: String):
|
||||
if _logger: _logger.error(message, { "category": _information.log_category, "image": _information.icon, "color": _information.accent })
|
21
components/Cursor/Cursor.tscn
Normal file
|
@ -0,0 +1,21 @@
|
|||
[gd_scene load_steps=4 format=3 uid="uid://qecwga1b4yqn"]
|
||||
|
||||
[ext_resource type="Script" path="res://components/Cursor/cursor.gd" id="1_nmkwm"]
|
||||
[ext_resource type="Texture2D" uid="uid://yg134s8wlxmi" path="res://icon.svg" id="2_yaf0k"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_4cq27"]
|
||||
|
||||
[node name="Cursor" type="CanvasLayer"]
|
||||
script = ExtResource("1_nmkwm")
|
||||
|
||||
[node name="MouseControl" type="Area2D" parent="."]
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="MouseControl"]
|
||||
shape = SubResource("RectangleShape2D_4cq27")
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="MouseControl"]
|
||||
scale = Vector2(0.15625, 0.15625)
|
||||
texture = ExtResource("2_yaf0k")
|
||||
|
||||
[connection signal="area_entered" from="MouseControl" to="." method="_on_mouse_control_area_entered"]
|
||||
[connection signal="area_exited" from="MouseControl" to="." method="_on_mouse_control_area_exited"]
|
6
components/Cursor/MouseHandler.tscn
Normal file
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://dykc1mgg5uopw"]
|
||||
|
||||
[ext_resource type="Script" path="res://components/Cursor/mouse_handler.gd" id="1_n30mb"]
|
||||
|
||||
[node name="MouseHandler" type="Area2D"]
|
||||
script = ExtResource("1_n30mb")
|
30
components/Cursor/cursor.gd
Normal file
|
@ -0,0 +1,30 @@
|
|||
@icon("res://components/Cursor/mouse-pointer-2.svg")
|
||||
extends Base
|
||||
|
||||
@onready var mouse_control = $"MouseControl"
|
||||
|
||||
|
||||
func _process(delta):
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
|
||||
mouse_control.position = mouse_control.get_global_mouse_position()
|
||||
|
||||
if Input.is_action_just_pressed("left_click"):
|
||||
var overlapping_areas = mouse_control.get_overlapping_areas()
|
||||
overlapping_areas.sort_custom(func(a, b):
|
||||
return a.z_index > b.z_index
|
||||
)
|
||||
|
||||
for area in overlapping_areas:
|
||||
if area.has_method("_on_clicked"):
|
||||
if not area._on_clicked():
|
||||
break
|
||||
|
||||
|
||||
func _on_mouse_control_area_entered(area):
|
||||
if area.has_method("_on_hovered"):
|
||||
area._on_hovered()
|
||||
|
||||
|
||||
func _on_mouse_control_area_exited(area):
|
||||
if area.has_method("_on_unhovered"):
|
||||
area._on_unhovered()
|
6
components/Cursor/information.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
name: Cursor
|
||||
short: ???
|
||||
description: ???
|
||||
accent: #35b84b
|
||||
log_category: CUR
|
||||
icon: res://components/Cursor/mouse-pointer-2.svg
|
1
components/Cursor/mouse-pointer-2.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-mouse-pointer-2"><path d="m4 4 7.07 17 2.51-7.39L21 11.07z"/></svg>
|
After Width: | Height: | Size: 262 B |
37
components/Cursor/mouse-pointer-2.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cdu6b7pclsrrg"
|
||||
path="res://.godot/imported/mouse-pointer-2.svg-528a80312e1a4aed351ba060d183df97.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Cursor/mouse-pointer-2.svg"
|
||||
dest_files=["res://.godot/imported/mouse-pointer-2.svg-528a80312e1a4aed351ba060d183df97.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
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
1
components/Cursor/mouse-pointer-click.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-mouse-pointer-click"><path d="m9 9 5 12 1.8-5.2L21 14Z"/><path d="M7.2 2.2 8 5.1"/><path d="m5.1 8-2.9-.8"/><path d="M14 4.1 12 6"/><path d="m6 12-1.9 2"/></svg>
|
After Width: | Height: | Size: 356 B |
37
components/Cursor/mouse-pointer-click.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://ddkp18the486t"
|
||||
path="res://.godot/imported/mouse-pointer-click.svg-f0b06ba161b377fd039b4f40e477ff4d.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Cursor/mouse-pointer-click.svg"
|
||||
dest_files=["res://.godot/imported/mouse-pointer-click.svg-f0b06ba161b377fd039b4f40e477ff4d.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
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
39
components/Cursor/mouse_handler.gd
Normal file
|
@ -0,0 +1,39 @@
|
|||
@icon("res://components/Cursor/mouse-pointer-click.svg")
|
||||
extends Area2D
|
||||
|
||||
signal clicked
|
||||
signal hovered
|
||||
signal unhovered
|
||||
|
||||
@export var passthrough = false
|
||||
|
||||
var _logger
|
||||
|
||||
func _ready():
|
||||
if get_tree().root.has_node("Logger"):
|
||||
_logger = get_tree().root.get_node("Logger")
|
||||
|
||||
func _on_clicked():
|
||||
clicked.emit()
|
||||
#_logger.info("Clicked mouse handler for object →%s←" % [get_parent().name], {
|
||||
#"color": "#919191",
|
||||
#"image": "res://components/Cursor/mouse-pointer-click.svg",
|
||||
#"category": "MOU"
|
||||
#})
|
||||
return passthrough
|
||||
|
||||
func _on_hovered():
|
||||
hovered.emit()
|
||||
#_logger.info("Hovered over mouse handler for object →%s←" % [get_parent().name], {
|
||||
#"color": "#919191",
|
||||
#"image": "res://components/Cursor/mouse-pointer-click.svg",
|
||||
#"category": "MOU"
|
||||
#})
|
||||
|
||||
func _on_unhovered():
|
||||
unhovered.emit()
|
||||
#_logger.info("Unhovered mouse handler for object →%s←" % [get_parent().name], {
|
||||
#"color": "#919191",
|
||||
#"image": "res://components/Cursor/mouse-pointer-click.svg",
|
||||
#"category": "MOU"
|
||||
#})
|
6
components/Data/Data.tscn
Normal file
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://b4o7cekdsf4pu"]
|
||||
|
||||
[ext_resource type="Script" path="res://components/Data/data.gd" id="1_xutp1"]
|
||||
|
||||
[node name="Data" type="Node"]
|
||||
script = ExtResource("1_xutp1")
|
1
components/Data/book-marked.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-book-marked"><path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1 0-5H20"/><polyline points="10 2 10 10 13 7 16 10 16 2"/></svg>
|
After Width: | Height: | Size: 335 B |
37
components/Data/book-marked.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://05aeafxrb5ph"
|
||||
path="res://.godot/imported/book-marked.svg-4d90597eaf7440ba51cd915ad6f20255.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Data/book-marked.svg"
|
||||
dest_files=["res://.godot/imported/book-marked.svg-4d90597eaf7440ba51cd915ad6f20255.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
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
18
components/Data/data-toolbar.gd
Normal file
|
@ -0,0 +1,18 @@
|
|||
const LOG_CATEGORY = "DATAT"
|
||||
const NAME = "Data"
|
||||
|
||||
|
||||
func send_log(parent):
|
||||
parent.tools[NAME].node.info("Test Debug!", LOG_CATEGORY)
|
||||
|
||||
|
||||
func send_debug(parent):
|
||||
parent.tools[NAME].node.debug("Test Log!", LOG_CATEGORY)
|
||||
|
||||
|
||||
func send_warning(parent):
|
||||
parent.tools[NAME].node.warn("Test Warning!", LOG_CATEGORY)
|
||||
|
||||
|
||||
func send_error(parent):
|
||||
parent.tools[NAME].node.error("Test Error!", LOG_CATEGORY)
|
241
components/Data/data.gd
Normal file
|
@ -0,0 +1,241 @@
|
|||
@icon("res://components/Data/book-marked.svg")
|
||||
class_name DataType
|
||||
extends Base
|
||||
## Data handler to read in data from files
|
||||
##
|
||||
## A data handler that will read in data from txt files and other sources for
|
||||
## use in various parts of the game. Reads both from the parts folder in the
|
||||
## main game directory and the mods folder in the user folder to allow users to
|
||||
## easily mod the game.
|
||||
|
||||
var _FILE_FUNCTIONS = {
|
||||
"*.txt": _read_txt,
|
||||
"*.png": _read_resource,
|
||||
"*.png.import": _read_png_import,
|
||||
"*.ogg": _read_resource,
|
||||
"*.mp3": _read_resource,
|
||||
"*.wav": _read_resource,
|
||||
"*.gd": _read_script_resource,
|
||||
}
|
||||
|
||||
var _FILE_LOCATION_OVERRIDES = {
|
||||
"*.gd": "scripts",
|
||||
"*.png.import": "images",
|
||||
"*.png": "images",
|
||||
"*.ogg": "audio",
|
||||
"*.wav": "audio"
|
||||
}
|
||||
|
||||
var data = {}
|
||||
var components = {}
|
||||
var location_overrides = {}
|
||||
|
||||
|
||||
func _prespawned():
|
||||
_information = {
|
||||
"accent": "#a27155",
|
||||
"log_category": "DATA",
|
||||
"icon": "res://components/Data/book-marked.svg"
|
||||
}
|
||||
|
||||
|
||||
func _spawned():
|
||||
reload_data()
|
||||
|
||||
|
||||
## Reload the data object by pulling from available sources
|
||||
func reload_data() -> void:
|
||||
data = {} # Remove all old mod data
|
||||
|
||||
# Open part folder from project (Ignore if none) and if exists set mod data to it
|
||||
var res_dir = DirAccess.open("res://")
|
||||
if res_dir.dir_exists("parts"):
|
||||
data = _read_directory("res://parts")
|
||||
data = _merge_objects(location_overrides, data)
|
||||
|
||||
if res_dir.dir_exists("components"):
|
||||
location_overrides = {}
|
||||
components = _read_directory("res://components")
|
||||
components = _merge_objects(location_overrides, components)
|
||||
|
||||
|
||||
func _merge_objects(object1, object2):
|
||||
var newObject = {}
|
||||
for key in object1:
|
||||
newObject[key] = object1[key]
|
||||
for key in object2:
|
||||
if(newObject.has(key)):
|
||||
if(typeof(newObject[key]) == TYPE_STRING):
|
||||
newObject[key] = object1[key]
|
||||
elif(typeof(newObject[key]) == TYPE_OBJECT):
|
||||
if newObject[key] is Texture:
|
||||
newObject[key] = object1[key]
|
||||
else:
|
||||
newObject[key] = _merge_objects(object1[key], object2[key])
|
||||
elif(typeof(newObject[key]) == TYPE_DICTIONARY):
|
||||
newObject[key] = _merge_objects(object1[key], object2[key])
|
||||
elif(typeof(newObject[key]) == TYPE_ARRAY):
|
||||
newObject[key] = object1[key] + object2[key]
|
||||
else:
|
||||
newObject[key] = object2[key]
|
||||
return newObject
|
||||
|
||||
|
||||
func _read_directory(path) -> Dictionary:
|
||||
var dir = DirAccess.open(path)
|
||||
var local_data = {}
|
||||
|
||||
if not dir:
|
||||
_warn("Could not read directory [%s]" % [path])
|
||||
return {}
|
||||
|
||||
dir.list_dir_begin()
|
||||
var file_name = dir.get_next()
|
||||
while file_name != "":
|
||||
if dir.current_is_dir():
|
||||
var micro_data = _read_directory("%s/%s" % [path, file_name])
|
||||
if micro_data:
|
||||
local_data[file_name] = micro_data
|
||||
else:
|
||||
var file_handling = _get_file_handling(file_name)
|
||||
|
||||
if (file_handling):
|
||||
var location_override = _get_location_override(file_name)
|
||||
|
||||
if location_override:
|
||||
var micro_data = file_handling.call("%s/%s" % [path, file_name])
|
||||
if not location_overrides.has(location_override):
|
||||
location_overrides[location_override] = {}
|
||||
location_overrides[location_override][file_name.split(".")[0]] = micro_data
|
||||
else:
|
||||
var micro_data = file_handling.call("%s/%s" % [path, file_name])
|
||||
if micro_data:
|
||||
local_data[file_name.split(".")[0]] = micro_data
|
||||
|
||||
file_name = dir.get_next()
|
||||
|
||||
_info("Read directory ♢%s♢" % [path])
|
||||
return local_data
|
||||
|
||||
|
||||
func _get_file_handling(file):
|
||||
var split_file = file.split(".", true, 1)
|
||||
|
||||
for file_function in _FILE_FUNCTIONS:
|
||||
if(file_function == file):
|
||||
return _FILE_FUNCTIONS[file_function]
|
||||
|
||||
var split_file_function = file_function.split(".", true, 1)
|
||||
|
||||
if(split_file_function[0] == "*" and split_file_function[1] == split_file[1]):
|
||||
return _FILE_FUNCTIONS[file_function]
|
||||
|
||||
return null
|
||||
|
||||
|
||||
func _read_script_resource(path):
|
||||
return load(path)
|
||||
|
||||
|
||||
func _read_resource(path):
|
||||
var song = load(path)
|
||||
return song
|
||||
|
||||
|
||||
func _read_png_import(path):
|
||||
var image = load(path.rsplit(".", true, 1)[0])
|
||||
return image
|
||||
|
||||
|
||||
func _get_location_override(file):
|
||||
var split_file = file.split(".", true, 1)
|
||||
|
||||
for location_override in _FILE_LOCATION_OVERRIDES:
|
||||
if location_override == file:
|
||||
return _FILE_LOCATION_OVERRIDES[location_override]
|
||||
|
||||
var split_file_function = location_override.split(".", true, 1)
|
||||
|
||||
if(split_file_function[0] == "*" and split_file_function[1] == split_file[1]):
|
||||
return _FILE_LOCATION_OVERRIDES[location_override]
|
||||
|
||||
|
||||
func _read_txt(path) -> Dictionary:
|
||||
# Open file for reading
|
||||
var file = FileAccess.open(path, FileAccess.READ)
|
||||
var content = file.get_as_text()
|
||||
var local_data = {}
|
||||
|
||||
# Separate into lines
|
||||
var split_content = content.split("\n", false)
|
||||
|
||||
# Indentation
|
||||
var indentation = 0
|
||||
var indentation_levels = []
|
||||
|
||||
# Iterate over everything
|
||||
for content_piece in split_content:
|
||||
# Fix Indentation to actual content level
|
||||
var actual_indentation = _count_indentation(content_piece)
|
||||
|
||||
while(actual_indentation < indentation):
|
||||
indentation -= 1
|
||||
indentation_levels.pop_back()
|
||||
|
||||
# Navigate to current indentation data
|
||||
var micro_data = local_data
|
||||
var previous_data = null
|
||||
var i = 0
|
||||
while i < indentation:
|
||||
previous_data = micro_data
|
||||
micro_data = micro_data[indentation_levels[i]]
|
||||
i += 1
|
||||
|
||||
# Reading
|
||||
if(content_piece.ends_with("[]")):
|
||||
# Array handling
|
||||
var trimmed_content = content_piece.strip_edges().trim_suffix("[]")
|
||||
|
||||
indentation += 1
|
||||
indentation_levels.append(trimmed_content)
|
||||
micro_data[trimmed_content] = {}
|
||||
else:
|
||||
var split_args = content_piece.split(":", true, 1)
|
||||
|
||||
if split_args.size() == 2:
|
||||
# Dict Handling
|
||||
var key = split_args[0].strip_edges()
|
||||
var value = split_args[1].strip_edges()
|
||||
|
||||
if value.is_valid_int():
|
||||
value = value.to_int()
|
||||
|
||||
micro_data[key] = value
|
||||
elif split_args.size() == 1:
|
||||
# Value Handling
|
||||
var value = split_args[0].strip_edges()
|
||||
|
||||
if typeof(micro_data) == TYPE_DICTIONARY:
|
||||
# TODO: FIX BELOW
|
||||
if indentation_levels.size() == 0:
|
||||
continue
|
||||
|
||||
if previous_data[indentation_levels[indentation_levels.size()-1]].keys().size() == 0:
|
||||
previous_data[indentation_levels[indentation_levels.size()-1]] = [split_args[0].strip_edges()]
|
||||
else:
|
||||
pass
|
||||
else:
|
||||
previous_data[indentation_levels[indentation_levels.size()-1]] += [split_args[0].strip_edges()]
|
||||
return local_data
|
||||
|
||||
|
||||
func _count_indentation(string: String):
|
||||
var tabs = 0
|
||||
|
||||
for character in string:
|
||||
if(character == "\t"):
|
||||
tabs += 1
|
||||
else:
|
||||
return tabs
|
||||
|
||||
return tabs
|
10
components/Data/information.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
name: Data
|
||||
short: Data handler to read in data from files
|
||||
description: |
|
||||
A data handler that will read in data from txt files and other
|
||||
sources for use in various parts of the game. Reads both from the
|
||||
parts folder in the main game directory and the mods folder in the
|
||||
user folder to allow users to easily mod the game.
|
||||
accent: #a27155
|
||||
log_category: DATA
|
||||
icon: res://components/Data/book-marked.svg
|
20
components/Data/toolbar.txt
Normal file
|
@ -0,0 +1,20 @@
|
|||
debug[]
|
||||
type: button
|
||||
name: Send Debug
|
||||
accent: #11a1a1
|
||||
function: send_debug
|
||||
log[]
|
||||
type: button
|
||||
name: Send Log
|
||||
accent: #11a11a
|
||||
function: send_log
|
||||
warning[]
|
||||
type: button
|
||||
name: Send Warning
|
||||
accent: #a1a111
|
||||
function: send_warning
|
||||
error[]
|
||||
type: button
|
||||
name: Send Error
|
||||
accent: #f13333
|
||||
function: send_error
|
100
components/Dialogue/Dialogue.tscn
Normal file
|
@ -0,0 +1,100 @@
|
|||
[gd_scene load_steps=6 format=3 uid="uid://mhltvrm84abx"]
|
||||
|
||||
[ext_resource type="Script" path="res://components/Dialogue/dialogue.gd" id="1_0g08k"]
|
||||
[ext_resource type="Script" path="res://components/Dialogue/area.gd" id="3_4w6ab"]
|
||||
[ext_resource type="Texture2D" uid="uid://camtxohytwrqd" path="res://components/Dialogue/textbox.png" id="3_o1ce5"]
|
||||
[ext_resource type="Texture2D" uid="uid://yg134s8wlxmi" path="res://icon.svg" id="5_s3ups"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_wsoph"]
|
||||
size = Vector2(480, 80)
|
||||
|
||||
[node name="Dialogue" type="CanvasLayer"]
|
||||
script = ExtResource("1_0g08k")
|
||||
|
||||
[node name="TextBox" type="Control" parent="."]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
offset_left = 80.0
|
||||
offset_top = 280.0
|
||||
offset_right = 560.0
|
||||
offset_bottom = 360.0
|
||||
pivot_offset = Vector2(240, 80)
|
||||
|
||||
[node name="MinimizeHandler" type="Area2D" parent="TextBox"]
|
||||
visible = false
|
||||
z_index = 10
|
||||
script = ExtResource("3_4w6ab")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="TextBox/MinimizeHandler"]
|
||||
position = Vector2(240, 40)
|
||||
shape = SubResource("RectangleShape2D_wsoph")
|
||||
|
||||
[node name="Graphics" type="TextureRect" parent="TextBox"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 7
|
||||
anchor_left = 0.5
|
||||
anchor_top = 1.0
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -240.0
|
||||
offset_top = -80.0
|
||||
offset_right = 240.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
texture = ExtResource("3_o1ce5")
|
||||
|
||||
[node name="TextBoxAvatar" type="TextureRect" parent="TextBox/Graphics"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 7
|
||||
anchor_left = 0.5
|
||||
anchor_top = 1.0
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -206.0
|
||||
offset_top = -104.0
|
||||
offset_right = -158.0
|
||||
offset_bottom = -40.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
texture = ExtResource("5_s3ups")
|
||||
|
||||
[node name="TextBoxText" type="RichTextLabel" parent="TextBox/Graphics"]
|
||||
modulate = Color(0.705882, 0.690196, 0.552941, 1)
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -125.0
|
||||
offset_top = -24.0
|
||||
offset_right = 226.0
|
||||
offset_bottom = 30.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_colors/font_shadow_color = Color(0, 0, 0, 1)
|
||||
theme_override_constants/shadow_offset_y = 1
|
||||
theme_override_constants/shadow_offset_x = 0
|
||||
theme_override_font_sizes/normal_font_size = 16
|
||||
text = "This is test text"
|
||||
|
||||
[node name="TextBoxName" type="RichTextLabel" parent="TextBox/Graphics"]
|
||||
modulate = Color(0.705882, 0.690196, 0.552941, 1)
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -237.0
|
||||
offset_top = 14.0
|
||||
offset_right = -125.0
|
||||
offset_bottom = 38.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_colors/font_shadow_color = Color(0, 0, 0, 1)
|
||||
theme_override_constants/shadow_offset_y = 1
|
||||
theme_override_constants/shadow_offset_x = 0
|
||||
theme_override_font_sizes/normal_font_size = 16
|
||||
bbcode_enabled = true
|
||||
text = "[center]NAME"
|
9
components/Dialogue/area.gd
Normal file
|
@ -0,0 +1,9 @@
|
|||
extends Area2D
|
||||
|
||||
signal clicked
|
||||
|
||||
@export var passthrough = false
|
||||
|
||||
func _on_clicked():
|
||||
clicked.emit()
|
||||
return passthrough
|
144
components/Dialogue/dialogue.gd
Normal file
|
@ -0,0 +1,144 @@
|
|||
extends Base
|
||||
|
||||
var used_lines = []
|
||||
var mouse_over = false
|
||||
|
||||
@onready var text_box = $"TextBox"
|
||||
@onready var text_box_text = $"TextBox/Graphics/TextBoxText"
|
||||
@onready var text_box_name = $"TextBox/Graphics/TextBoxName"
|
||||
@onready var text_box_image = $"TextBox/Graphics/TextBoxAvatar"
|
||||
@onready var minimize_handler = $"TextBox/MinimizeHandler"
|
||||
|
||||
var pop_tween
|
||||
var last_lines = {}
|
||||
|
||||
func _spawned():
|
||||
text_box.modulate = Color.TRANSPARENT
|
||||
text_box.scale = Vector2(0, 0)
|
||||
text_box.position.y = 360
|
||||
|
||||
minimize_handler.clicked.connect(_on_clicked)
|
||||
|
||||
if _triggerer:
|
||||
_triggerer.listen("any", _on_trigger)
|
||||
|
||||
|
||||
func _on_trigger(data: Dictionary) -> void:
|
||||
if has_trigger(data.trigger):
|
||||
trigger_dialogue(data.trigger)
|
||||
|
||||
|
||||
func _on_clicked():
|
||||
if pop_tween:
|
||||
pop_tween.kill()
|
||||
|
||||
pop_tween = create_tween()
|
||||
pop_tween.set_ease(Tween.EASE_IN)
|
||||
pop_tween.set_trans(Tween.TRANS_BACK)
|
||||
pop_tween.set_parallel()
|
||||
pop_tween.tween_property(text_box, "modulate", Color.TRANSPARENT, 0.5)
|
||||
pop_tween.tween_property(text_box, "scale", Vector2(0, 0), 0.5)
|
||||
pop_tween.tween_property(text_box, "position:y", 360, 0.5)
|
||||
pop_tween.chain()
|
||||
|
||||
func get_priority_from_string(string: String):
|
||||
match string:
|
||||
"low": return 1
|
||||
"medium": return 2
|
||||
"high": return 3
|
||||
|
||||
func trigger_dialogue(trigger: String):
|
||||
_info("Dialogue trigger %s triggered" % [trigger])
|
||||
var dialogue = get_dialogue(trigger)
|
||||
|
||||
if not dialogue:
|
||||
return
|
||||
|
||||
var lines = dialogue.values()
|
||||
|
||||
|
||||
|
||||
|
||||
if pop_tween:
|
||||
pop_tween.kill()
|
||||
|
||||
#var person = Data.data.people[lines[0].character]
|
||||
|
||||
text_box_text.text = lines[0].text
|
||||
#text_box_image.texture = Data.data.images[lines[0].character]
|
||||
#text_box_name.text = "[center]%s" % [person.short]
|
||||
|
||||
pop_tween = create_tween()
|
||||
pop_tween.set_ease(Tween.EASE_OUT)
|
||||
pop_tween.set_trans(Tween.TRANS_BACK)
|
||||
pop_tween.set_parallel()
|
||||
pop_tween.tween_property(text_box, "modulate", Color.WHITE, 0.5)
|
||||
pop_tween.tween_property(text_box, "scale", Vector2(1, 1), 0.5)
|
||||
pop_tween.tween_property(text_box, "position:y", 280, 0.5)
|
||||
pop_tween.chain()
|
||||
|
||||
#get_parent().move_child(self, get_parent().get_child_count() - 1)
|
||||
|
||||
|
||||
func has_trigger(trigger: String):
|
||||
var dialogue_files = Data.data.dialogue.values()
|
||||
|
||||
for file in dialogue_files:
|
||||
for key in file:
|
||||
if file[key].has("trigger"):
|
||||
if file[key].trigger == trigger:
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
|
||||
func get_dialogue(trigger: String):
|
||||
var dialogue_files = Data.data.dialogue.values()
|
||||
|
||||
var combined_object = {}
|
||||
|
||||
for file in dialogue_files:
|
||||
for key in file:
|
||||
combined_object[key] = file[key]
|
||||
combined_object[key].key = key
|
||||
|
||||
var lines = combined_object.values()
|
||||
var trigger_lines = lines.filter(func(x): return x.trigger == trigger)
|
||||
|
||||
trigger_lines.sort_custom(func(a, b):
|
||||
var apriority = a.rules.priority if a.rules.has("priority") else "medium"
|
||||
var bpriority = b.rules.priority if b.rules.has("priority") else "medium"
|
||||
|
||||
if get_priority_from_string(apriority) == get_priority_from_string(bpriority):
|
||||
return randf() < 0.5
|
||||
|
||||
return get_priority_from_string(apriority) > get_priority_from_string(bpriority)
|
||||
)
|
||||
|
||||
for line in trigger_lines:
|
||||
var invalid = false
|
||||
|
||||
if last_lines.has(line.trigger) and last_lines[line.trigger] == line.key:
|
||||
invalid = true
|
||||
|
||||
for rule in line.rules:
|
||||
if rule == "priority":
|
||||
continue
|
||||
elif rule == "unique":
|
||||
if used_lines.has(line.key):
|
||||
invalid = true
|
||||
break
|
||||
else:
|
||||
var value = Persister.get_value(rule)
|
||||
if value != line.rules[rule]:
|
||||
invalid = true
|
||||
break
|
||||
|
||||
if invalid:
|
||||
continue
|
||||
|
||||
last_lines[line.trigger] = line.key
|
||||
used_lines.push_back(line.key)
|
||||
return line.lines
|
||||
|
||||
return null
|
6
components/Dialogue/information.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
name: Dialogue
|
||||
short: ???
|
||||
description: ???
|
||||
accent: #2ec778
|
||||
log_category: DIA
|
||||
icon: res://components/Dialogue/message-square-more.svg
|
1
components/Dialogue/message-square-more.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-message-square-more"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/><path d="M8 10h.01"/><path d="M12 10h.01"/><path d="M16 10h.01"/></svg>
|
After Width: | Height: | Size: 360 B |
37
components/Dialogue/message-square-more.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bwghow6a1p84w"
|
||||
path="res://.godot/imported/message-square-more.svg-c15333f4fba2c19064690b510c5f7565.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Dialogue/message-square-more.svg"
|
||||
dest_files=["res://.godot/imported/message-square-more.svg-c15333f4fba2c19064690b510c5f7565.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
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
BIN
components/Dialogue/textbox.aseprite
Normal file
BIN
components/Dialogue/textbox.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
34
components/Dialogue/textbox.png.import
Normal file
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://camtxohytwrqd"
|
||||
path="res://.godot/imported/textbox.png-a3656dca7d0232cc5645bc8f60474933.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Dialogue/textbox.png"
|
||||
dest_files=["res://.godot/imported/textbox.png-a3656dca7d0232cc5645bc8f60474933.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
|
6
components/Leaderboard/Leaderboard.tscn
Normal file
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://dvjtjq2j522co"]
|
||||
|
||||
[ext_resource type="Script" path="res://components/Leaderboard/leaderboard.gd" id="1_gvlwy"]
|
||||
|
||||
[node name="Leaderboard" type="Node"]
|
||||
script = ExtResource("1_gvlwy")
|
6
components/Leaderboard/information.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
name: Leaderboard
|
||||
short: ???
|
||||
description: ???
|
||||
accent: #2e4fc7
|
||||
log_category: LEA
|
||||
icon: res://components/Leaderboard/trophy.svg
|
2
components/Leaderboard/leaderboard.gd
Normal file
|
@ -0,0 +1,2 @@
|
|||
@icon("res://components/Leaderboard/trophy.svg")
|
||||
extends Base
|
1
components/Leaderboard/trophy.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-trophy"><path d="M6 9H4.5a2.5 2.5 0 0 1 0-5H6"/><path d="M18 9h1.5a2.5 2.5 0 0 0 0-5H18"/><path d="M4 22h16"/><path d="M10 14.66V17c0 .55-.47.98-.97 1.21C7.85 18.75 7 20.24 7 22"/><path d="M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20.24 17 22"/><path d="M18 2H6v7a6 6 0 0 0 12 0V2Z"/></svg>
|
After Width: | Height: | Size: 491 B |
37
components/Leaderboard/trophy.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://for54f1or3ir"
|
||||
path="res://.godot/imported/trophy.svg-50b272fe3a1d033c20559dd811d9f235.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Leaderboard/trophy.svg"
|
||||
dest_files=["res://.godot/imported/trophy.svg-50b272fe3a1d033c20559dd811d9f235.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
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
6
components/Logger/Logger.tscn
Normal file
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://7p8ecy62n2h8"]
|
||||
|
||||
[ext_resource type="Script" path="res://components/Logger/logger.gd" id="1_gse6q"]
|
||||
|
||||
[node name="Logger" type="Node"]
|
||||
script = ExtResource("1_gse6q")
|
2
components/Logger/commands.gd
Normal file
|
@ -0,0 +1,2 @@
|
|||
func send_log():
|
||||
pass
|
9
components/Logger/information.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
name: Logger
|
||||
short: A logger to log data to relevant locations
|
||||
description: A logger that logs various forms of data at different log levels to
|
||||
both built in locations in Godot as well as other components that listen to
|
||||
the provided log created signal.
|
||||
accent: #71a255
|
||||
log_category: LOG
|
||||
icon: res://components/Logger/scroll-text.svg
|
||||
version: v1.0.0
|
34
components/Logger/logger-toolbar.gd
Normal file
|
@ -0,0 +1,34 @@
|
|||
const LOG_CATEGORY = "TOOLT"
|
||||
const NAME = "Logger"
|
||||
|
||||
|
||||
func send_log(parent):
|
||||
parent.info("Test Log!", {
|
||||
"image": "res://components/Toolbar/hammer.svg",
|
||||
"color": "#818181",
|
||||
"category": "TST"
|
||||
})
|
||||
|
||||
|
||||
func send_debug(parent):
|
||||
parent.debug("Test Debug!", {
|
||||
"image": "res://components/Toolbar/hammer.svg",
|
||||
"color": "#818181",
|
||||
"category": "TST"
|
||||
})
|
||||
|
||||
|
||||
func send_warning(parent):
|
||||
parent.warn("Test Warn!", {
|
||||
"image": "res://components/Toolbar/hammer.svg",
|
||||
"color": "#818181",
|
||||
"category": "TST"
|
||||
})
|
||||
|
||||
|
||||
func send_error(parent):
|
||||
parent.error("Test Error!", {
|
||||
"image": "res://components/Toolbar/hammer.svg",
|
||||
"color": "#818181",
|
||||
"category": "TST"
|
||||
})
|
133
components/Logger/logger.gd
Normal file
|
@ -0,0 +1,133 @@
|
|||
@icon("res://components/Logger/scroll-text.svg")
|
||||
extends Node
|
||||
## A logger to log data to relevant locations
|
||||
##
|
||||
## A logger that logs various forms of data at different log levels to both
|
||||
## built in locations in Godot as well as other components that listen to the
|
||||
## provided log created signal.
|
||||
|
||||
signal log_created(message: String, level: LogLevel)
|
||||
|
||||
enum LogLevel {
|
||||
DEBUG,
|
||||
INFO,
|
||||
WARN,
|
||||
ERROR
|
||||
}
|
||||
|
||||
## The log level that should be outputted as a minimum.
|
||||
@export var log_level: LogLevel
|
||||
|
||||
|
||||
## Log a message at log level debug (meant for troubleshooting).
|
||||
func debug(message: String, arguments: Dictionary = {}) -> void:
|
||||
_log(message, LogLevel.DEBUG, arguments)
|
||||
|
||||
|
||||
## Log a message at log level info (log to indicate something happened).
|
||||
func info(message: String, arguments: Dictionary = {}) -> void:
|
||||
_log(message, LogLevel.INFO, arguments)
|
||||
|
||||
|
||||
## Log a warning at log level warning (something unexpected happened but it can
|
||||
## continue).
|
||||
func warn(message: String, arguments: Dictionary = {}) -> void:
|
||||
_log(message, LogLevel.WARN, arguments)
|
||||
|
||||
|
||||
## Log an error at log level error (an issue that prevents something from
|
||||
## functioning).
|
||||
func error(message: String, arguments: Dictionary = {}) -> void:
|
||||
_log(message, LogLevel.ERROR, arguments)
|
||||
|
||||
|
||||
func _log(message: String, level: LogLevel, arguments: Dictionary = {}) -> void:
|
||||
var category = arguments.category if arguments.has("category") and arguments.category else "???"
|
||||
var color = arguments.color if arguments.has("color") else "olive"
|
||||
var image = arguments.image if arguments.has("image") and arguments.image else "res://components/Logger/scroll-text.svg"
|
||||
|
||||
var adjusted_message = _clean_message(message)
|
||||
|
||||
var constructed_message = "[color=%s][%s][/color] [img= width=12 height=12 valign=center]%s[/img] %s" % [color, category, image, adjusted_message]
|
||||
print_rich(constructed_message)
|
||||
log_created.emit(constructed_message, level)
|
||||
|
||||
|
||||
func _clean_message(message: String) -> String:
|
||||
var cleans = [
|
||||
{
|
||||
"type": "button",
|
||||
"regex": "μ(.*)μ",
|
||||
"color": Color.html("#a4bf37")
|
||||
},
|
||||
{
|
||||
"type": "key",
|
||||
"regex": "<(.*)>",
|
||||
"color": Color.html("#42ad24")
|
||||
},
|
||||
{
|
||||
"type": "tool",
|
||||
"regex": "λ(.*)λ",
|
||||
"color": Color.html("#bf9d37")
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"regex": "→(.*)←",
|
||||
"color": Color.html("#854322")
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"regex": "♢(.*)♢",
|
||||
"color": Color.html("#22852e")
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"regex": "∨(.*)∨",
|
||||
"color": Color.html("#ad2452")
|
||||
},
|
||||
{
|
||||
"type": "trigger",
|
||||
"regex": "∧(.*)∧",
|
||||
"color": Color.html("#ad2d24")
|
||||
},
|
||||
{
|
||||
"type": "category",
|
||||
"regex": "\\{(.*)\\}",
|
||||
"color": Color.html("#ad9b24")
|
||||
},
|
||||
{
|
||||
"type": "value",
|
||||
"regex": "\\|(.*)\\|",
|
||||
"color": Color.TEAL
|
||||
}
|
||||
]
|
||||
|
||||
var adjusted_message = message
|
||||
|
||||
for clean in cleans:
|
||||
adjusted_message = _replace_regex_color(adjusted_message, clean.regex, clean.color)
|
||||
|
||||
return adjusted_message
|
||||
|
||||
|
||||
func _replace_regex_color(message: String, regex_string: String, color: Color) -> String:
|
||||
return _replace_regex(message, regex_string, "[color=" + color.to_html() + "]%s[/color]")
|
||||
|
||||
|
||||
func _replace_regex(message: String, regex_string: String, new_content: String) -> String:
|
||||
var adjusted_message = message
|
||||
var stripped_message = message
|
||||
|
||||
var regex = RegEx.new()
|
||||
regex.compile(regex_string)
|
||||
var result = regex.search(adjusted_message)
|
||||
|
||||
while result:
|
||||
var before_content = adjusted_message.substr(0, result.get_start())
|
||||
var after_content = adjusted_message.substr(result.get_end(), adjusted_message.length())
|
||||
var template_string = "%s" + new_content + "%s"
|
||||
adjusted_message = template_string % [before_content, result.get_string(1), after_content]
|
||||
|
||||
result = regex.search(adjusted_message)
|
||||
|
||||
return adjusted_message
|
1
components/Logger/scroll-text.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-scroll-text"><path d="M15 12h-5"/><path d="M15 8h-5"/><path d="M19 17V5a2 2 0 0 0-2-2H4"/><path d="M8 21h12a2 2 0 0 0 2-2v-1a1 1 0 0 0-1-1H11a1 1 0 0 0-1 1v1a2 2 0 1 1-4 0V5a2 2 0 1 0-4 0v2a1 1 0 0 0 1 1h3"/></svg>
|
After Width: | Height: | Size: 409 B |
37
components/Logger/scroll-text.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bt1irjjewldcq"
|
||||
path="res://.godot/imported/scroll-text.svg-3edd1135d80784e9e14ee4871d671a9a.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Logger/scroll-text.svg"
|
||||
dest_files=["res://.godot/imported/scroll-text.svg-3edd1135d80784e9e14ee4871d671a9a.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
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
11
components/Logger/settings.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
log_level[]
|
||||
name: Log Level
|
||||
description: The level of info you want as a minimum to be logged to
|
||||
relevant locations.
|
||||
category: misc
|
||||
default: LogLevel.WARN
|
||||
values[]
|
||||
LogLevel.DEBUG
|
||||
LogLevel.INFO
|
||||
LogLevel.WARN
|
||||
LogLevel.ERROR
|
24
components/Logger/toolbar.txt
Normal file
|
@ -0,0 +1,24 @@
|
|||
debug[]
|
||||
type: button
|
||||
name: Send Debug
|
||||
accent: #11a1a1
|
||||
function: send_debug
|
||||
test[]
|
||||
type: label
|
||||
name: Testing Label
|
||||
accent: #11a1cc
|
||||
log[]
|
||||
type: button
|
||||
name: Send Log
|
||||
accent: #11a11a
|
||||
function: send_log
|
||||
warning[]
|
||||
type: button
|
||||
name: Send Warning
|
||||
accent: #a1a111
|
||||
function: send_warning
|
||||
error[]
|
||||
type: button
|
||||
name: Send Error
|
||||
accent: #f13333
|
||||
function: send_error
|
691
components/Menu/Menu.tscn
Normal file
|
@ -0,0 +1,691 @@
|
|||
[gd_scene load_steps=14 format=3 uid="uid://dcu7jrwg24hg1"]
|
||||
|
||||
[ext_resource type="Script" path="res://components/Menu/menu.gd" id="1_f186y"]
|
||||
[ext_resource type="Theme" uid="uid://ck7603ob4gflc" path="res://Fonts/Theme.tres" id="1_fowhs"]
|
||||
[ext_resource type="Shader" path="res://components/Menu/god_rays.gdshader" id="1_n8upd"]
|
||||
[ext_resource type="Script" path="res://components/Menu/populate_from_metadata.gd" id="3_727p5"]
|
||||
[ext_resource type="PackedScene" uid="uid://cmyjaeahyipq4" path="res://components/Menu/MenuButton.tscn" id="5_goj86"]
|
||||
[ext_resource type="Script" path="res://components/Menu/credits.gd" id="6_b724h"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_ygqow"]
|
||||
shader = ExtResource("1_n8upd")
|
||||
shader_parameter/angle = 0.525
|
||||
shader_parameter/position = 0.27
|
||||
shader_parameter/spread = 0.595
|
||||
shader_parameter/cutoff = 0.0710001
|
||||
shader_parameter/falloff = 0.845
|
||||
shader_parameter/edge_fade = 0.34
|
||||
shader_parameter/speed = 1.0
|
||||
shader_parameter/ray1_density = 8.0
|
||||
shader_parameter/ray2_density = 30.0
|
||||
shader_parameter/ray2_intensity = 0.169
|
||||
shader_parameter/color = Vector4(1, 0.9, 0.65, 0.1)
|
||||
shader_parameter/hdr = false
|
||||
shader_parameter/seed = 5.0
|
||||
|
||||
[sub_resource type="Animation" id="Animation_5jiy0"]
|
||||
resource_name = "show_main"
|
||||
length = 5.0
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("CanvasLayer/MainMenu/GameInfo/GameTitle:position")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(135, 168), Vector2(185.297, 168), Vector2(226.423, 168), Vector2(259.221, 168), Vector2(284.538, 168), Vector2(303.219, 168), Vector2(316.109, 168), Vector2(324.053, 168), Vector2(327.897, 168), Vector2(328.486, 168), Vector2(326.665, 168), Vector2(323.28, 168), Vector2(319.175, 168), Vector2(315.197, 168), Vector2(312.19, 168), Vector2(311, 168)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("CanvasLayer/MainMenu/GameInfo/GameUnderline:position")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(650, 194), Vector2(582.556, 194), Vector2(527.41, 194), Vector2(483.431, 194), Vector2(449.483, 194), Vector2(424.434, 194), Vector2(407.15, 194), Vector2(396.497, 194), Vector2(391.343, 194), Vector2(390.553, 194), Vector2(392.995, 194), Vector2(397.534, 194), Vector2(403.038, 194), Vector2(408.372, 194), Vector2(412.404, 194), Vector2(414, 194)]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("CanvasLayer/MainMenu/GameInfo/Author:position")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(648, 199), Vector2(561.123, 199), Vector2(490.088, 199), Vector2(433.436, 199), Vector2(389.707, 199), Vector2(357.44, 199), Vector2(335.176, 199), Vector2(321.454, 199), Vector2(314.814, 199), Vector2(313.797, 199), Vector2(316.942, 199), Vector2(322.79, 199), Vector2(329.879, 199), Vector2(336.751, 199), Vector2(341.944, 199), Vector2(344, 199)]
|
||||
}
|
||||
tracks/3/type = "value"
|
||||
tracks/3/imported = false
|
||||
tracks/3/enabled = true
|
||||
tracks/3/path = NodePath("CanvasLayer/MainMenu/Rays:position")
|
||||
tracks/3/interp = 1
|
||||
tracks/3/loop_wrap = true
|
||||
tracks/3/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(0, 0), Vector2(32.0074, 0), Vector2(58.1781, 0), Vector2(79.0498, 0), Vector2(95.1607, 0), Vector2(107.048, 0), Vector2(115.251, 0), Vector2(120.307, 0), Vector2(122.753, 0), Vector2(123.127, 0), Vector2(121.969, 0), Vector2(119.814, 0), Vector2(117.202, 0), Vector2(114.671, 0), Vector2(112.757, 0), Vector2(112, 0)]
|
||||
}
|
||||
tracks/4/type = "value"
|
||||
tracks/4/imported = false
|
||||
tracks/4/enabled = true
|
||||
tracks/4/path = NodePath("CanvasLayer/MainMenu/MenuButtons/PlayButton:position")
|
||||
tracks/4/interp = 1
|
||||
tracks/4/loop_wrap = true
|
||||
tracks/4/keys = {
|
||||
"times": PackedFloat32Array(0.9, 0.933333, 0.966667, 1, 1.03333, 1.06667, 1.1, 1.13333, 1.16667, 1.2),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(-110, 128), Vector2(-39.3658, 128), Vector2(9.80145, 128), Vector2(41.0148, 128), Vector2(57.7873, 128), Vector2(63.6323, 128), Vector2(62.0629, 128), Vector2(56.5923, 128), Vector2(50.7336, 128), Vector2(48, 128)]
|
||||
}
|
||||
tracks/5/type = "value"
|
||||
tracks/5/imported = false
|
||||
tracks/5/enabled = true
|
||||
tracks/5/path = NodePath("CanvasLayer/MainMenu/MenuButtons/OptionsButton:position")
|
||||
tracks/5/interp = 1
|
||||
tracks/5/loop_wrap = true
|
||||
tracks/5/keys = {
|
||||
"times": PackedFloat32Array(1.15, 1.18333, 1.21667, 1.25, 1.28333, 1.31667, 1.35, 1.38333, 1.41667, 1.45),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(-110, 160), Vector2(-32.2129, 160), Vector2(21.9332, 160), Vector2(56.3074, 160), Vector2(74.7784, 160), Vector2(81.2154, 160), Vector2(79.487, 160), Vector2(73.4624, 160), Vector2(67.0104, 160), Vector2(64, 160)]
|
||||
}
|
||||
tracks/6/type = "value"
|
||||
tracks/6/imported = false
|
||||
tracks/6/enabled = true
|
||||
tracks/6/path = NodePath("CanvasLayer/MainMenu/MenuButtons/CreditsButton:position")
|
||||
tracks/6/interp = 1
|
||||
tracks/6/loop_wrap = true
|
||||
tracks/6/keys = {
|
||||
"times": PackedFloat32Array(1.4, 1.43333, 1.46667, 1.5, 1.53333, 1.56667, 1.6, 1.63333, 1.66667, 1.7),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(-110, 192), Vector2(-25.0601, 192), Vector2(34.065, 192), Vector2(71.6, 192), Vector2(91.7696, 192), Vector2(98.7984, 192), Vector2(96.9111, 192), Vector2(90.3325, 192), Vector2(83.2872, 192), Vector2(80, 192)]
|
||||
}
|
||||
tracks/7/type = "value"
|
||||
tracks/7/imported = false
|
||||
tracks/7/enabled = true
|
||||
tracks/7/path = NodePath("CanvasLayer/MainMenu/MenuButtons/QuitButton:position")
|
||||
tracks/7/interp = 1
|
||||
tracks/7/loop_wrap = true
|
||||
tracks/7/keys = {
|
||||
"times": PackedFloat32Array(1.65, 1.68333, 1.71667, 1.75, 1.78333, 1.81667, 1.85, 1.88333, 1.91667, 1.95),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(-110, 224), Vector2(-17.9072, 224), Vector2(46.1968, 224), Vector2(86.8927, 224), Vector2(108.761, 224), Vector2(116.381, 224), Vector2(114.335, 224), Vector2(107.203, 224), Vector2(99.5641, 224), Vector2(96, 224)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_u1e5j"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("CanvasLayer/MainMenu/GameInfo/GameTitle:position")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector2(135, 168)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("CanvasLayer/MainMenu/GameInfo/GameUnderline:position")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector2(650, 194)]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("CanvasLayer/MainMenu/GameInfo/Author:position")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector2(648, 199)]
|
||||
}
|
||||
tracks/3/type = "value"
|
||||
tracks/3/imported = false
|
||||
tracks/3/enabled = true
|
||||
tracks/3/path = NodePath("CanvasLayer/MainMenu/Rays:position")
|
||||
tracks/3/interp = 1
|
||||
tracks/3/loop_wrap = true
|
||||
tracks/3/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector2(0, 0)]
|
||||
}
|
||||
tracks/4/type = "value"
|
||||
tracks/4/imported = false
|
||||
tracks/4/enabled = true
|
||||
tracks/4/path = NodePath("CanvasLayer/MainMenu/MenuButtons/PlayButton:position")
|
||||
tracks/4/interp = 1
|
||||
tracks/4/loop_wrap = true
|
||||
tracks/4/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector2(-110, 128)]
|
||||
}
|
||||
tracks/5/type = "value"
|
||||
tracks/5/imported = false
|
||||
tracks/5/enabled = true
|
||||
tracks/5/path = NodePath("CanvasLayer/MainMenu/MenuButtons/OptionsButton:position")
|
||||
tracks/5/interp = 1
|
||||
tracks/5/loop_wrap = true
|
||||
tracks/5/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector2(-110, 160)]
|
||||
}
|
||||
tracks/6/type = "value"
|
||||
tracks/6/imported = false
|
||||
tracks/6/enabled = true
|
||||
tracks/6/path = NodePath("CanvasLayer/MainMenu/MenuButtons/CreditsButton:position")
|
||||
tracks/6/interp = 1
|
||||
tracks/6/loop_wrap = true
|
||||
tracks/6/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector2(-110, 192)]
|
||||
}
|
||||
tracks/7/type = "value"
|
||||
tracks/7/imported = false
|
||||
tracks/7/enabled = true
|
||||
tracks/7/path = NodePath("CanvasLayer/MainMenu/MenuButtons/QuitButton:position")
|
||||
tracks/7/interp = 1
|
||||
tracks/7/loop_wrap = true
|
||||
tracks/7/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector2(-110, 224)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_ob40t"]
|
||||
resource_name = "hide_main"
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("CanvasLayer/MainMenu/MenuButtons/PlayButton:position")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(48, 128), Vector2(27.6356, 128), Vector2(8.67555, 128), Vector2(-8.88, 128), Vector2(-25.0311, 128), Vector2(-39.7778, 128), Vector2(-53.12, 128), Vector2(-65.0578, 128), Vector2(-75.5911, 128), Vector2(-84.72, 128), Vector2(-92.4444, 128), Vector2(-98.7645, 128), Vector2(-103.68, 128), Vector2(-107.191, 128), Vector2(-109.298, 128), Vector2(-110, 128)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("CanvasLayer/MainMenu/MenuButtons/OptionsButton:position")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(64, 160), Vector2(41.5733, 160), Vector2(20.6933, 160), Vector2(1.36, 160), Vector2(-16.4267, 160), Vector2(-32.6667, 160), Vector2(-47.36, 160), Vector2(-60.5067, 160), Vector2(-72.1067, 160), Vector2(-82.16, 160), Vector2(-90.6667, 160), Vector2(-97.6267, 160), Vector2(-103.04, 160), Vector2(-106.907, 160), Vector2(-109.227, 160), Vector2(-110, 160)]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("CanvasLayer/MainMenu/MenuButtons/CreditsButton:position")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(80, 192), Vector2(55.5111, 192), Vector2(32.7111, 192), Vector2(11.6, 192), Vector2(-7.82223, 192), Vector2(-25.5556, 192), Vector2(-41.6, 192), Vector2(-55.9556, 192), Vector2(-68.6222, 192), Vector2(-79.6, 192), Vector2(-88.8889, 192), Vector2(-96.4889, 192), Vector2(-102.4, 192), Vector2(-106.622, 192), Vector2(-109.156, 192), Vector2(-110, 192)]
|
||||
}
|
||||
tracks/3/type = "value"
|
||||
tracks/3/imported = false
|
||||
tracks/3/enabled = true
|
||||
tracks/3/path = NodePath("CanvasLayer/MainMenu/MenuButtons/QuitButton:position")
|
||||
tracks/3/interp = 1
|
||||
tracks/3/loop_wrap = true
|
||||
tracks/3/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(96, 224), Vector2(69.4489, 224), Vector2(44.7289, 224), Vector2(21.84, 224), Vector2(0.782219, 224), Vector2(-18.4445, 224), Vector2(-35.84, 224), Vector2(-51.4044, 224), Vector2(-65.1378, 224), Vector2(-77.04, 224), Vector2(-87.1111, 224), Vector2(-95.3511, 224), Vector2(-101.76, 224), Vector2(-106.338, 224), Vector2(-109.084, 224), Vector2(-110, 224)]
|
||||
}
|
||||
tracks/4/type = "value"
|
||||
tracks/4/imported = false
|
||||
tracks/4/enabled = true
|
||||
tracks/4/path = NodePath("CanvasLayer/MainMenu/GameInfo/GameTitle:position")
|
||||
tracks/4/interp = 1
|
||||
tracks/4/loop_wrap = true
|
||||
tracks/4/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(311, 168), Vector2(288.316, 168), Vector2(267.196, 168), Vector2(247.64, 168), Vector2(229.649, 168), Vector2(213.222, 168), Vector2(198.36, 168), Vector2(185.062, 168), Vector2(173.329, 168), Vector2(163.16, 168), Vector2(154.556, 168), Vector2(147.516, 168), Vector2(142.04, 168), Vector2(138.129, 168), Vector2(135.782, 168), Vector2(135, 168)]
|
||||
}
|
||||
tracks/5/type = "value"
|
||||
tracks/5/imported = false
|
||||
tracks/5/enabled = true
|
||||
tracks/5/path = NodePath("CanvasLayer/MainMenu/GameInfo/GameUnderline:position")
|
||||
tracks/5/interp = 1
|
||||
tracks/5/loop_wrap = true
|
||||
tracks/5/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(414, 194), Vector2(458.84, 194), Vector2(498.96, 194), Vector2(534.36, 194), Vector2(565.04, 194), Vector2(591, 194), Vector2(612.24, 194), Vector2(628.76, 194), Vector2(640.56, 194), Vector2(647.64, 194), Vector2(650, 194)]
|
||||
}
|
||||
tracks/6/type = "value"
|
||||
tracks/6/imported = false
|
||||
tracks/6/enabled = true
|
||||
tracks/6/path = NodePath("CanvasLayer/MainMenu/GameInfo/Author:position")
|
||||
tracks/6/interp = 1
|
||||
tracks/6/loop_wrap = true
|
||||
tracks/6/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(344, 199), Vector2(383.182, 199), Vector2(419.662, 199), Vector2(453.44, 199), Vector2(484.516, 199), Vector2(512.889, 199), Vector2(538.56, 199), Vector2(561.529, 199), Vector2(581.796, 199), Vector2(599.36, 199), Vector2(614.222, 199), Vector2(626.382, 199), Vector2(635.84, 199), Vector2(642.596, 199), Vector2(646.649, 199), Vector2(648, 199)]
|
||||
}
|
||||
tracks/7/type = "value"
|
||||
tracks/7/imported = false
|
||||
tracks/7/enabled = true
|
||||
tracks/7/path = NodePath("CanvasLayer/MainMenu/Rays:position")
|
||||
tracks/7/interp = 1
|
||||
tracks/7/loop_wrap = true
|
||||
tracks/7/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(112, 0), Vector2(97.5644, 0), Vector2(84.1244, 0), Vector2(71.68, 0), Vector2(60.2311, 0), Vector2(49.7778, 0), Vector2(40.32, 0), Vector2(31.8578, 0), Vector2(24.3911, 0), Vector2(17.92, 0), Vector2(12.4445, 0), Vector2(7.96444, 0), Vector2(4.48, 0), Vector2(1.99111, 0), Vector2(0.49778, 0), Vector2(0, 0)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_2xxnd"]
|
||||
resource_name = "show_credits"
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("CanvasLayer/MainMenu/MenuButtons/PlayButton:position")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(48, 128), Vector2(27.6356, 128), Vector2(8.67555, 128), Vector2(-8.88, 128), Vector2(-25.0311, 128), Vector2(-39.7778, 128), Vector2(-53.12, 128), Vector2(-65.0578, 128), Vector2(-75.5911, 128), Vector2(-84.72, 128), Vector2(-92.4444, 128), Vector2(-98.7645, 128), Vector2(-103.68, 128), Vector2(-107.191, 128), Vector2(-109.298, 128), Vector2(-110, 128)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("CanvasLayer/MainMenu/MenuButtons/OptionsButton:position")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(64, 160), Vector2(41.5733, 160), Vector2(20.6933, 160), Vector2(1.36, 160), Vector2(-16.4267, 160), Vector2(-32.6667, 160), Vector2(-47.36, 160), Vector2(-60.5067, 160), Vector2(-72.1067, 160), Vector2(-82.16, 160), Vector2(-90.6667, 160), Vector2(-97.6267, 160), Vector2(-103.04, 160), Vector2(-106.907, 160), Vector2(-109.227, 160), Vector2(-110, 160)]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("CanvasLayer/MainMenu/MenuButtons/CreditsButton:position")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(80, 192), Vector2(55.5111, 192), Vector2(32.7111, 192), Vector2(11.6, 192), Vector2(-7.82223, 192), Vector2(-25.5556, 192), Vector2(-41.6, 192), Vector2(-55.9556, 192), Vector2(-68.6222, 192), Vector2(-79.6, 192), Vector2(-88.8889, 192), Vector2(-96.4889, 192), Vector2(-102.4, 192), Vector2(-106.622, 192), Vector2(-109.156, 192), Vector2(-110, 192)]
|
||||
}
|
||||
tracks/3/type = "value"
|
||||
tracks/3/imported = false
|
||||
tracks/3/enabled = true
|
||||
tracks/3/path = NodePath("CanvasLayer/MainMenu/MenuButtons/QuitButton:position")
|
||||
tracks/3/interp = 1
|
||||
tracks/3/loop_wrap = true
|
||||
tracks/3/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(96, 224), Vector2(69.4489, 224), Vector2(44.7289, 224), Vector2(21.84, 224), Vector2(0.782219, 224), Vector2(-18.4445, 224), Vector2(-35.84, 224), Vector2(-51.4044, 224), Vector2(-65.1378, 224), Vector2(-77.04, 224), Vector2(-87.1111, 224), Vector2(-95.3511, 224), Vector2(-101.76, 224), Vector2(-106.338, 224), Vector2(-109.084, 224), Vector2(-110, 224)]
|
||||
}
|
||||
tracks/4/type = "value"
|
||||
tracks/4/imported = false
|
||||
tracks/4/enabled = true
|
||||
tracks/4/path = NodePath("CanvasLayer/MainMenu/GameInfo/GameTitle:position")
|
||||
tracks/4/interp = 1
|
||||
tracks/4/loop_wrap = true
|
||||
tracks/4/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(311, 168), Vector2(354.049, 168), Vector2(394.129, 168), Vector2(431.24, 168), Vector2(465.382, 168), Vector2(496.556, 168), Vector2(524.76, 168), Vector2(549.996, 168), Vector2(572.262, 168), Vector2(591.56, 168), Vector2(607.889, 168), Vector2(621.249, 168), Vector2(631.64, 168), Vector2(639.062, 168), Vector2(643.516, 168), Vector2(645, 168)]
|
||||
}
|
||||
tracks/5/type = "value"
|
||||
tracks/5/imported = false
|
||||
tracks/5/enabled = true
|
||||
tracks/5/path = NodePath("CanvasLayer/MainMenu/GameInfo/GameUnderline:position")
|
||||
tracks/5/interp = 1
|
||||
tracks/5/loop_wrap = true
|
||||
tracks/5/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(414, 194), Vector2(458.84, 194), Vector2(498.96, 194), Vector2(534.36, 194), Vector2(565.04, 194), Vector2(591, 194), Vector2(612.24, 194), Vector2(628.76, 194), Vector2(640.56, 194), Vector2(647.64, 194), Vector2(650, 194)]
|
||||
}
|
||||
tracks/6/type = "value"
|
||||
tracks/6/imported = false
|
||||
tracks/6/enabled = true
|
||||
tracks/6/path = NodePath("CanvasLayer/MainMenu/GameInfo/Author:position")
|
||||
tracks/6/interp = 1
|
||||
tracks/6/loop_wrap = true
|
||||
tracks/6/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(344, 199), Vector2(383.182, 199), Vector2(419.662, 199), Vector2(453.44, 199), Vector2(484.516, 199), Vector2(512.889, 199), Vector2(538.56, 199), Vector2(561.529, 199), Vector2(581.796, 199), Vector2(599.36, 199), Vector2(614.222, 199), Vector2(626.382, 199), Vector2(635.84, 199), Vector2(642.596, 199), Vector2(646.649, 199), Vector2(648, 199)]
|
||||
}
|
||||
tracks/7/type = "value"
|
||||
tracks/7/imported = false
|
||||
tracks/7/enabled = true
|
||||
tracks/7/path = NodePath("CanvasLayer/MainMenu/Rays:position")
|
||||
tracks/7/interp = 1
|
||||
tracks/7/loop_wrap = true
|
||||
tracks/7/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(112, 0), Vector2(97.5644, 0), Vector2(84.1244, 0), Vector2(71.68, 0), Vector2(60.2311, 0), Vector2(49.7778, 0), Vector2(40.32, 0), Vector2(31.8578, 0), Vector2(24.3911, 0), Vector2(17.92, 0), Vector2(12.4445, 0), Vector2(7.96444, 0), Vector2(4.48, 0), Vector2(1.99111, 0), Vector2(0.49778, 0), Vector2(0, 0)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_awvye"]
|
||||
resource_name = "hide_credits"
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("CanvasLayer/MainMenu/MenuButtons/PlayButton:position")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(-110, 128), Vector2(-89.6356, 128), Vector2(-70.6756, 128), Vector2(-53.12, 128), Vector2(-36.9689, 128), Vector2(-22.2222, 128), Vector2(-8.87999, 128), Vector2(3.05778, 128), Vector2(13.5911, 128), Vector2(22.72, 128), Vector2(30.4444, 128), Vector2(36.7645, 128), Vector2(41.68, 128), Vector2(45.1911, 128), Vector2(47.2978, 128), Vector2(48, 128)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("CanvasLayer/MainMenu/MenuButtons/OptionsButton:position")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(-110, 160), Vector2(-87.5733, 160), Vector2(-66.6933, 160), Vector2(-47.36, 160), Vector2(-29.5733, 160), Vector2(-13.3333, 160), Vector2(1.36001, 160), Vector2(14.5067, 160), Vector2(26.1067, 160), Vector2(36.16, 160), Vector2(44.6667, 160), Vector2(51.6267, 160), Vector2(57.04, 160), Vector2(60.9067, 160), Vector2(63.2267, 160), Vector2(64, 160)]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("CanvasLayer/MainMenu/MenuButtons/CreditsButton:position")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(-110, 192), Vector2(-85.5111, 192), Vector2(-62.7111, 192), Vector2(-41.6, 192), Vector2(-22.1778, 192), Vector2(-4.44444, 192), Vector2(11.6, 192), Vector2(25.9556, 192), Vector2(38.6222, 192), Vector2(49.6, 192), Vector2(58.8889, 192), Vector2(66.4889, 192), Vector2(72.4, 192), Vector2(76.6222, 192), Vector2(79.1555, 192), Vector2(80, 192)]
|
||||
}
|
||||
tracks/3/type = "value"
|
||||
tracks/3/imported = false
|
||||
tracks/3/enabled = true
|
||||
tracks/3/path = NodePath("CanvasLayer/MainMenu/MenuButtons/QuitButton:position")
|
||||
tracks/3/interp = 1
|
||||
tracks/3/loop_wrap = true
|
||||
tracks/3/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(-110, 224), Vector2(-83.4489, 224), Vector2(-58.7289, 224), Vector2(-35.84, 224), Vector2(-14.7822, 224), Vector2(4.44445, 224), Vector2(21.84, 224), Vector2(37.4044, 224), Vector2(51.1378, 224), Vector2(63.04, 224), Vector2(73.1111, 224), Vector2(81.3511, 224), Vector2(87.76, 224), Vector2(92.3378, 224), Vector2(95.0844, 224), Vector2(96, 224)]
|
||||
}
|
||||
tracks/4/type = "value"
|
||||
tracks/4/imported = false
|
||||
tracks/4/enabled = true
|
||||
tracks/4/path = NodePath("CanvasLayer/MainMenu/GameInfo/GameTitle:position")
|
||||
tracks/4/interp = 1
|
||||
tracks/4/loop_wrap = true
|
||||
tracks/4/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(645, 168), Vector2(601.951, 168), Vector2(561.871, 168), Vector2(524.76, 168), Vector2(490.618, 168), Vector2(459.444, 168), Vector2(431.24, 168), Vector2(406.004, 168), Vector2(383.738, 168), Vector2(364.44, 168), Vector2(348.111, 168), Vector2(334.751, 168), Vector2(324.36, 168), Vector2(316.938, 168), Vector2(312.484, 168), Vector2(311, 168)]
|
||||
}
|
||||
tracks/5/type = "value"
|
||||
tracks/5/imported = false
|
||||
tracks/5/enabled = true
|
||||
tracks/5/path = NodePath("CanvasLayer/MainMenu/GameInfo/GameUnderline:position")
|
||||
tracks/5/interp = 1
|
||||
tracks/5/loop_wrap = true
|
||||
tracks/5/keys = {
|
||||
"times": PackedFloat32Array(0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(650, 194), Vector2(615.089, 194), Vector2(582.97, 194), Vector2(553.645, 194), Vector2(527.112, 194), Vector2(503.373, 194), Vector2(482.426, 194), Vector2(464.272, 194), Vector2(448.911, 194), Vector2(436.343, 194), Vector2(426.568, 194), Vector2(419.586, 194), Vector2(415.396, 194), Vector2(414, 194)]
|
||||
}
|
||||
tracks/6/type = "value"
|
||||
tracks/6/imported = false
|
||||
tracks/6/enabled = true
|
||||
tracks/6/path = NodePath("CanvasLayer/MainMenu/GameInfo/Author:position")
|
||||
tracks/6/interp = 1
|
||||
tracks/6/loop_wrap = true
|
||||
tracks/6/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(648, 199), Vector2(608.818, 199), Vector2(572.338, 199), Vector2(538.56, 199), Vector2(507.484, 199), Vector2(479.111, 199), Vector2(453.44, 199), Vector2(430.471, 199), Vector2(410.204, 199), Vector2(392.64, 199), Vector2(377.778, 199), Vector2(365.618, 199), Vector2(356.16, 199), Vector2(349.404, 199), Vector2(345.351, 199), Vector2(344, 199)]
|
||||
}
|
||||
tracks/7/type = "value"
|
||||
tracks/7/imported = false
|
||||
tracks/7/enabled = true
|
||||
tracks/7/path = NodePath("CanvasLayer/MainMenu/Rays:position")
|
||||
tracks/7/interp = 1
|
||||
tracks/7/loop_wrap = true
|
||||
tracks/7/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0333333, 0.0666667, 0.1, 0.133333, 0.166667, 0.2, 0.233333, 0.266667, 0.3, 0.333333, 0.366667, 0.4, 0.433333, 0.466667, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(0, 0), Vector2(14.4356, 0), Vector2(27.8756, 0), Vector2(40.32, 0), Vector2(51.7689, 0), Vector2(62.2222, 0), Vector2(71.68, 0), Vector2(80.1422, 0), Vector2(87.6089, 0), Vector2(94.08, 0), Vector2(99.5555, 0), Vector2(104.036, 0), Vector2(107.52, 0), Vector2(110.009, 0), Vector2(111.502, 0), Vector2(112, 0)]
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_twm3r"]
|
||||
_data = {
|
||||
"RESET": SubResource("Animation_u1e5j"),
|
||||
"hide_credits": SubResource("Animation_awvye"),
|
||||
"hide_main": SubResource("Animation_ob40t"),
|
||||
"show_credits": SubResource("Animation_2xxnd"),
|
||||
"show_main": SubResource("Animation_5jiy0")
|
||||
}
|
||||
|
||||
[node name="Menu" type="Node"]
|
||||
script = ExtResource("1_f186y")
|
||||
|
||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||
|
||||
[node name="MainMenu" type="Control" parent="CanvasLayer"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme = ExtResource("1_fowhs")
|
||||
|
||||
[node name="Rays" type="ColorRect" parent="CanvasLayer/MainMenu"]
|
||||
z_index = 100
|
||||
material = SubResource("ShaderMaterial_ygqow")
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="CanvasLayer/MainMenu"]
|
||||
root_node = NodePath("../../..")
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_twm3r")
|
||||
}
|
||||
|
||||
[node name="GameInfo" type="Control" parent="CanvasLayer/MainMenu"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="GameTitle" type="RichTextLabel" parent="CanvasLayer/MainMenu/GameInfo"]
|
||||
z_index = 200
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -185.0
|
||||
offset_top = -12.0
|
||||
offset_right = 183.0
|
||||
offset_bottom = 28.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_font_sizes/normal_font_size = 24
|
||||
bbcode_enabled = true
|
||||
text = "[center]Game Title"
|
||||
script = ExtResource("3_727p5")
|
||||
key = "name"
|
||||
|
||||
[node name="GameUnderline" type="ColorRect" parent="CanvasLayer/MainMenu/GameInfo"]
|
||||
z_index = 200
|
||||
layout_mode = 1
|
||||
anchors_preset = 6
|
||||
anchor_left = 1.0
|
||||
anchor_top = 0.5
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 0.5
|
||||
offset_left = 10.0
|
||||
offset_top = 14.0
|
||||
offset_right = 330.525
|
||||
offset_bottom = 16.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Author" type="RichTextLabel" parent="CanvasLayer/MainMenu/GameInfo"]
|
||||
z_index = 200
|
||||
layout_mode = 1
|
||||
anchors_preset = 6
|
||||
anchor_left = 1.0
|
||||
anchor_top = 0.5
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 0.5
|
||||
offset_left = 8.0
|
||||
offset_top = 19.0
|
||||
offset_right = 296.0
|
||||
offset_bottom = 59.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 2
|
||||
bbcode_enabled = true
|
||||
text = "[right]by Team Auboreal"
|
||||
script = ExtResource("3_727p5")
|
||||
key = "author"
|
||||
alignment = "right"
|
||||
|
||||
[node name="MenuButtons" type="Control" parent="CanvasLayer/MainMenu"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="PlayButton" parent="CanvasLayer/MainMenu/MenuButtons" instance=ExtResource("5_goj86")]
|
||||
layout_mode = 0
|
||||
anchors_preset = 0
|
||||
anchor_top = 0.0
|
||||
anchor_bottom = 0.0
|
||||
offset_left = -110.0
|
||||
offset_top = 128.0
|
||||
offset_right = -19.13
|
||||
offset_bottom = 152.515
|
||||
grow_vertical = 1
|
||||
|
||||
[node name="OptionsButton" parent="CanvasLayer/MainMenu/MenuButtons" instance=ExtResource("5_goj86")]
|
||||
layout_mode = 0
|
||||
anchors_preset = 0
|
||||
anchor_top = 0.0
|
||||
anchor_bottom = 0.0
|
||||
offset_left = -110.0
|
||||
offset_top = 160.0
|
||||
offset_right = -19.13
|
||||
offset_bottom = 184.515
|
||||
grow_vertical = 1
|
||||
text = "Options"
|
||||
|
||||
[node name="CreditsButton" parent="CanvasLayer/MainMenu/MenuButtons" instance=ExtResource("5_goj86")]
|
||||
layout_mode = 0
|
||||
anchors_preset = 0
|
||||
anchor_top = 0.0
|
||||
anchor_bottom = 0.0
|
||||
offset_left = -110.0
|
||||
offset_top = 192.0
|
||||
offset_right = -19.13
|
||||
offset_bottom = 216.515
|
||||
grow_vertical = 1
|
||||
text = "Credits"
|
||||
|
||||
[node name="QuitButton" parent="CanvasLayer/MainMenu/MenuButtons" instance=ExtResource("5_goj86")]
|
||||
layout_mode = 0
|
||||
anchors_preset = 0
|
||||
anchor_top = 0.0
|
||||
anchor_bottom = 0.0
|
||||
offset_left = -110.0
|
||||
offset_top = 224.0
|
||||
offset_right = -19.13
|
||||
offset_bottom = 248.515
|
||||
grow_vertical = 1
|
||||
text = "Quit"
|
||||
|
||||
[node name="Credits" type="Control" parent="CanvasLayer/MainMenu"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("6_b724h")
|
||||
|
||||
[connection signal="clicked" from="CanvasLayer/MainMenu/MenuButtons/PlayButton" to="." method="_on_play_button_clicked"]
|
||||
[connection signal="clicked" from="CanvasLayer/MainMenu/MenuButtons/OptionsButton" to="." method="_on_options_button_clicked"]
|
||||
[connection signal="clicked" from="CanvasLayer/MainMenu/MenuButtons/CreditsButton" to="." method="_on_credits_button_clicked"]
|
||||
[connection signal="clicked" from="CanvasLayer/MainMenu/MenuButtons/QuitButton" to="." method="_on_quit_button_clicked"]
|
45
components/Menu/MenuButton.tscn
Normal file
|
@ -0,0 +1,45 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://cmyjaeahyipq4"]
|
||||
|
||||
[ext_resource type="Script" path="res://components/Menu/menu_button.gd" id="1_kxfx8"]
|
||||
[ext_resource type="PackedScene" uid="uid://dykc1mgg5uopw" path="res://components/Cursor/MouseHandler.tscn" id="2_g6apf"]
|
||||
[ext_resource type="Script" path="res://components/Menu/background_highlight.gd" id="3_cxaw3"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_oahx4"]
|
||||
size = Vector2(147, 22)
|
||||
|
||||
[node name="MenuButton" type="RichTextLabel"]
|
||||
clip_contents = false
|
||||
anchors_preset = 4
|
||||
anchor_top = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = 48.0
|
||||
offset_top = -52.0
|
||||
offset_right = 138.87
|
||||
offset_bottom = -27.485
|
||||
grow_vertical = 2
|
||||
theme_override_font_sizes/normal_font_size = 16
|
||||
bbcode_enabled = true
|
||||
text = "Play"
|
||||
script = ExtResource("1_kxfx8")
|
||||
|
||||
[node name="MouseHandler" parent="." instance=ExtResource("2_g6apf")]
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="MouseHandler"]
|
||||
position = Vector2(36.5, 7)
|
||||
shape = SubResource("RectangleShape2D_oahx4")
|
||||
|
||||
[node name="BackgroundHighlight" type="ColorRect" parent="."]
|
||||
show_behind_parent = true
|
||||
layout_mode = 0
|
||||
offset_left = -420.0
|
||||
offset_top = -8.0
|
||||
offset_right = -142.0
|
||||
offset_bottom = 22.0
|
||||
color = Color(0, 0, 0, 1)
|
||||
script = ExtResource("3_cxaw3")
|
||||
|
||||
[connection signal="clicked" from="MouseHandler" to="." method="_on_play_mouse_handler_clicked"]
|
||||
[connection signal="hovered" from="MouseHandler" to="." method="_on_mouse_handler_hovered"]
|
||||
[connection signal="hovered" from="MouseHandler" to="BackgroundHighlight" method="_on_mouse_handler_hovered"]
|
||||
[connection signal="unhovered" from="MouseHandler" to="." method="_on_mouse_handler_unhovered"]
|
||||
[connection signal="unhovered" from="MouseHandler" to="BackgroundHighlight" method="_on_mouse_handler_unhovered"]
|
35
components/Menu/background_highlight.gd
Normal file
|
@ -0,0 +1,35 @@
|
|||
extends ColorRect
|
||||
|
||||
var tween
|
||||
|
||||
func _on_mouse_handler_hovered() -> void:
|
||||
if tween:
|
||||
tween.kill()
|
||||
|
||||
tween = create_tween()
|
||||
tween.set_ease(Tween.EASE_OUT)
|
||||
tween.set_trans(Tween.TRANS_BACK)
|
||||
tween.tween_property(self, "position:x", -136, 0.5)
|
||||
tween.set_ease(Tween.EASE_IN_OUT)
|
||||
tween.set_trans(Tween.TRANS_QUAD)
|
||||
tween.tween_property(self, "position:x", -128, 0.25)
|
||||
tween.set_ease(Tween.EASE_IN_OUT)
|
||||
tween.tween_property(self, "position:x", -132, 0.25)
|
||||
tween.tween_callback(func():
|
||||
tween = create_tween()
|
||||
tween.set_loops()
|
||||
tween.set_ease(Tween.EASE_IN_OUT)
|
||||
tween.set_trans(Tween.TRANS_QUAD)
|
||||
tween.tween_property(self, "position:x", -136, 1)
|
||||
tween.tween_property(self, "position:x", -132, 1)
|
||||
)
|
||||
|
||||
|
||||
func _on_mouse_handler_unhovered() -> void:
|
||||
if tween:
|
||||
tween.kill()
|
||||
|
||||
tween = create_tween()
|
||||
tween.set_ease(Tween.EASE_OUT)
|
||||
tween.set_trans(Tween.TRANS_BACK)
|
||||
tween.tween_property(self, "position:x", -420, 0.5)
|
69
components/Menu/credits.gd
Normal file
|
@ -0,0 +1,69 @@
|
|||
extends Control
|
||||
|
||||
var _data
|
||||
|
||||
const TEXT_PADDING = 30
|
||||
|
||||
var items = []
|
||||
var tween
|
||||
|
||||
func _ready() -> void:
|
||||
if get_tree().root.has_node("Data"):
|
||||
_data = get_tree().root.get_node("Data")
|
||||
|
||||
if _data.data.has("metadata") and _data.data.metadata.has("credits"):
|
||||
var credits = _data.data.metadata.credits
|
||||
var sections = credits.keys()
|
||||
var y = 50
|
||||
|
||||
for section in sections:
|
||||
var section_text = RichTextLabel.new()
|
||||
section_text.position = Vector2(-120, y)
|
||||
section_text.size = Vector2(40, TEXT_PADDING)
|
||||
section_text.bbcode_enabled = true
|
||||
section_text.text = "[center]%s" % [section]
|
||||
add_child(section_text)
|
||||
items.push_back(section_text)
|
||||
y += TEXT_PADDING
|
||||
var people = credits[section].keys()
|
||||
|
||||
for person in people:
|
||||
var person_text = RichTextLabel.new()
|
||||
person_text.position = Vector2(-120, y)
|
||||
person_text.size = Vector2(40, TEXT_PADDING)
|
||||
person_text.bbcode_enabled = true
|
||||
person_text.text = "[center]%s" % [person]
|
||||
add_child(person_text)
|
||||
items.push_back(person_text)
|
||||
y += TEXT_PADDING
|
||||
|
||||
var links = credits[section][person].keys()
|
||||
|
||||
for link in links:
|
||||
var url = credits[section][person][link]
|
||||
|
||||
y += TEXT_PADDING
|
||||
|
||||
|
||||
func show_credits():
|
||||
if tween:
|
||||
tween.kill()
|
||||
|
||||
tween = create_tween()
|
||||
tween.set_ease(Tween.EASE_OUT)
|
||||
tween.set_trans(Tween.TRANS_BACK)
|
||||
|
||||
for item in items:
|
||||
tween.tween_property(item, "position:x", 320, 0.25)
|
||||
|
||||
func hide_credits():
|
||||
if tween:
|
||||
tween.kill()
|
||||
|
||||
tween = create_tween()
|
||||
tween.set_parallel()
|
||||
tween.set_ease(Tween.EASE_OUT)
|
||||
tween.set_trans(Tween.TRANS_QUAD)
|
||||
|
||||
for item in items:
|
||||
tween.tween_property(item, "position:x", -120, 0.25)
|
109
components/Menu/god_rays.gdshader
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
Shader from Godot Shaders - the free shader library.
|
||||
godotshaders.com/shader/god-rays
|
||||
|
||||
Feel free to use, improve and change this shader according to your needs
|
||||
and consider sharing the modified result on godotshaders.com.
|
||||
*/
|
||||
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform float angle = -0.3;
|
||||
uniform float position = -0.2;
|
||||
uniform float spread : hint_range(0.0, 1.0) = 0.5;
|
||||
uniform float cutoff : hint_range(-1.0, 1.0) = 0.1;
|
||||
uniform float falloff : hint_range(0.0, 1.0) = 0.2;
|
||||
uniform float edge_fade : hint_range(0.0, 1.0) = 0.15;
|
||||
|
||||
uniform float speed = 1.0;
|
||||
uniform float ray1_density = 8.0;
|
||||
uniform float ray2_density = 30.0;
|
||||
uniform float ray2_intensity : hint_range(0.0, 1.0) = 0.3;
|
||||
|
||||
uniform vec4 color = vec4(1.0, 0.9, 0.65, 0.8);
|
||||
|
||||
uniform bool hdr = false;
|
||||
uniform float seed = 5.0;
|
||||
|
||||
uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
|
||||
|
||||
// Random and noise functions from Book of Shader's chapter on Noise.
|
||||
float random(vec2 _uv) {
|
||||
return fract(sin(dot(_uv.xy,
|
||||
vec2(12.9898, 78.233))) *
|
||||
43758.5453123);
|
||||
}
|
||||
|
||||
float noise (in vec2 uv) {
|
||||
vec2 i = floor(uv);
|
||||
vec2 f = fract(uv);
|
||||
|
||||
// Four corners in 2D of a tile
|
||||
float a = random(i);
|
||||
float b = random(i + vec2(1.0, 0.0));
|
||||
float c = random(i + vec2(0.0, 1.0));
|
||||
float d = random(i + vec2(1.0, 1.0));
|
||||
|
||||
|
||||
// Smooth Interpolation
|
||||
|
||||
// Cubic Hermine Curve. Same as SmoothStep()
|
||||
vec2 u = f * f * (3.0-2.0 * f);
|
||||
|
||||
// Mix 4 coorners percentages
|
||||
return mix(a, b, u.x) +
|
||||
(c - a)* u.y * (1.0 - u.x) +
|
||||
(d - b) * u.x * u.y;
|
||||
}
|
||||
|
||||
mat2 rotate(float _angle){
|
||||
return mat2(vec2(cos(_angle), -sin(_angle)),
|
||||
vec2(sin(_angle), cos(_angle)));
|
||||
}
|
||||
|
||||
vec4 screen(vec4 base, vec4 blend){
|
||||
return 1.0 - (1.0 - base) * (1.0 - blend);
|
||||
}
|
||||
|
||||
void fragment()
|
||||
{
|
||||
|
||||
// Rotate, skew and move the UVs
|
||||
vec2 transformed_uv = ( rotate(angle) * (UV - position) ) / ( (UV.y + spread) - (UV.y * spread) );
|
||||
|
||||
// Animate the ray according the the new transformed UVs
|
||||
vec2 ray1 = vec2(transformed_uv.x * ray1_density + sin(TIME * 0.1 * speed) * (ray1_density * 0.2) + seed, 1.0);
|
||||
vec2 ray2 = vec2(transformed_uv.x * ray2_density + sin(TIME * 0.2 * speed) * (ray1_density * 0.2) + seed, 1.0);
|
||||
|
||||
// Cut off the ray's edges
|
||||
float cut = step(cutoff, transformed_uv.x) * step(cutoff, 1.0 - transformed_uv.x);
|
||||
ray1 *= cut;
|
||||
ray2 *= cut;
|
||||
|
||||
// Apply the noise pattern (i.e. create the rays)
|
||||
float rays;
|
||||
|
||||
if (hdr){
|
||||
// This is not really HDR, but check this to not clamp the two merged rays making
|
||||
// their values go over 1.0. Can make for some nice effect
|
||||
rays = noise(ray1) + (noise(ray2) * ray2_intensity);
|
||||
}
|
||||
else{
|
||||
rays = clamp(noise(ray1) + (noise(ray2) * ray2_intensity), 0., 1.);
|
||||
}
|
||||
|
||||
// Fade out edges
|
||||
rays *= smoothstep(0.0, falloff, (1.0 - UV.y)); // Bottom
|
||||
rays *= smoothstep(0.0 + cutoff, edge_fade + cutoff, transformed_uv.x); // Left
|
||||
rays *= smoothstep(0.0 + cutoff, edge_fade + cutoff, 1.0 - transformed_uv.x); // Right
|
||||
|
||||
// Color to the rays
|
||||
vec3 shine = vec3(rays) * color.rgb;
|
||||
|
||||
// Try different blending modes for a nicer effect. "Screen" is included in the code,
|
||||
// but take a look at https://godotshaders.com/snippet/blending-modes/ for more.
|
||||
// With "Screen" blend mode:
|
||||
shine = screen(texture(SCREEN_TEXTURE, SCREEN_UV), vec4(color)).rgb;
|
||||
|
||||
COLOR = vec4(shine, rays * color.a);
|
||||
}
|
41
components/Menu/menu.gd
Normal file
|
@ -0,0 +1,41 @@
|
|||
extends Base
|
||||
|
||||
@onready var animation_player: AnimationPlayer = $CanvasLayer/MainMenu/AnimationPlayer
|
||||
@onready var credits: Control = $CanvasLayer/MainMenu/Credits
|
||||
|
||||
var menu_state = "start"
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if menu_state == "start" and Input.is_action_just_pressed("left_click"):
|
||||
menu_state = "main"
|
||||
animation_player.play("show_main")
|
||||
if Input.is_action_just_pressed("escape"):
|
||||
match menu_state:
|
||||
"main":
|
||||
menu_state = "start"
|
||||
animation_player.play("hide_main")
|
||||
"credits":
|
||||
menu_state = "main"
|
||||
animation_player.play("hide_credits")
|
||||
credits.hide_credits()
|
||||
|
||||
|
||||
func _on_play_button_clicked() -> void:
|
||||
if _data:
|
||||
get_tree().change_scene_to_packed(load(_data.data.metadata.start_scene))
|
||||
else:
|
||||
_error("No start scene defined")
|
||||
|
||||
|
||||
func _on_options_button_clicked() -> void:
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
func _on_credits_button_clicked() -> void:
|
||||
menu_state = "credits"
|
||||
animation_player.play("show_credits")
|
||||
credits.show_credits()
|
||||
|
||||
|
||||
func _on_quit_button_clicked() -> void:
|
||||
get_tree().quit()
|
24
components/Menu/menu_button.gd
Normal file
|
@ -0,0 +1,24 @@
|
|||
extends RichTextLabel
|
||||
|
||||
signal clicked
|
||||
|
||||
var color_tween
|
||||
|
||||
func _on_play_mouse_handler_clicked() -> void:
|
||||
clicked.emit()
|
||||
|
||||
|
||||
func _on_mouse_handler_hovered() -> void:
|
||||
if color_tween:
|
||||
color_tween.kill()
|
||||
|
||||
color_tween = create_tween()
|
||||
color_tween.tween_property(self, "self_modulate", Color.GOLD, 0.25)
|
||||
|
||||
|
||||
func _on_mouse_handler_unhovered() -> void:
|
||||
if color_tween:
|
||||
color_tween.kill()
|
||||
|
||||
color_tween = create_tween()
|
||||
color_tween.tween_property(self, "self_modulate", Color.WHITE, 0.25)
|
13
components/Menu/populate_from_metadata.gd
Normal file
|
@ -0,0 +1,13 @@
|
|||
extends RichTextLabel
|
||||
|
||||
@export var key := ""
|
||||
@export var alignment := "center"
|
||||
|
||||
var _data
|
||||
|
||||
func _ready() -> void:
|
||||
if get_tree().root.has_node("Data"):
|
||||
_data = get_tree().root.get_node("Data")
|
||||
|
||||
if _data.data.has("metadata"):
|
||||
text = "[%s]%s" % [alignment, _data.data.metadata[key]]
|
1
components/Menu/square-menu.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-square-menu"><rect width="18" height="18" x="3" y="3" rx="2"/><path d="M7 8h10"/><path d="M7 12h10"/><path d="M7 16h10"/></svg>
|
After Width: | Height: | Size: 329 B |
37
components/Menu/square-menu.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cp8tbups5d6p7"
|
||||
path="res://.godot/imported/square-menu.svg-7299523024a845ac9eafa86412b4d5c3.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Menu/square-menu.svg"
|
||||
dest_files=["res://.godot/imported/square-menu.svg-7299523024a845ac9eafa86412b4d5c3.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
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
12
components/Persister/Persister.tscn
Normal file
|
@ -0,0 +1,12 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://pht0rn54n3t8"]
|
||||
|
||||
[ext_resource type="Script" path="res://components/Persister/persister.gd" id="1_taxaa"]
|
||||
|
||||
[node name="Persister" type="Node"]
|
||||
script = ExtResource("1_taxaa")
|
||||
|
||||
[node name="Timer" type="Timer" parent="."]
|
||||
wait_time = 20.0
|
||||
autostart = true
|
||||
|
||||
[connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"]
|
11
components/Persister/data_scope.gd
Normal file
|
@ -0,0 +1,11 @@
|
|||
class_name PersisterEnums
|
||||
|
||||
enum Scope {
|
||||
PERMANENT, # Stays forever
|
||||
SAVE, # Persists through a save
|
||||
GAME, # Persists through runs
|
||||
RUN, # Persists through an entire run of the game
|
||||
ROUND, # Persists through a round (if applicable, e.g. between ifa round is 2 mins between shops)
|
||||
ROOM, # Persists within a game room (if applicable)
|
||||
UNKNOWN
|
||||
}
|
1
components/Persister/hard-drive.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-hard-drive"><line x1="22" x2="2" y1="12" y2="12"/><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/><line x1="6" x2="6.01" y1="16" y2="16"/><line x1="10" x2="10.01" y1="16" y2="16"/></svg>
|
After Width: | Height: | Size: 451 B |
37
components/Persister/hard-drive.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bru35jf108ajj"
|
||||
path="res://.godot/imported/hard-drive.svg-f9677d2ad3a8226891a78779d376d996.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Persister/hard-drive.svg"
|
||||
dest_files=["res://.godot/imported/hard-drive.svg-f9677d2ad3a8226891a78779d376d996.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
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
10
components/Persister/information.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
name: Persister
|
||||
short: Data persister to persist data through locations
|
||||
description: A data persister that is used to persist data through the game,
|
||||
run, round, or room. A function is called to set data with a key in one
|
||||
of the categories and then other functions can be called to clear
|
||||
the data for a key or all data in a category.
|
||||
accent: #a1a166
|
||||
log_category: PER
|
||||
icon: res://components/Persister/hard-drive.svg
|
||||
version: v1.0.0
|
5
components/Persister/persister-toolbar.gd
Normal file
|
@ -0,0 +1,5 @@
|
|||
func save_one(parent):
|
||||
parent.change_save(1)
|
||||
|
||||
func save_two(parent):
|
||||
parent.change_save(2)
|
334
components/Persister/persister.gd
Normal file
|
@ -0,0 +1,334 @@
|
|||
@icon("res://components/Persister/hard-drive.svg")
|
||||
extends Base
|
||||
## Data persister to persist data through locations
|
||||
##
|
||||
## A data persister that is used to persist data through the game, run, round,
|
||||
## or room. A function is called to set data with a key in one of the categories
|
||||
## and then other functions can be called to clear the data for a key or all
|
||||
## data in a category.
|
||||
|
||||
signal data_persisted(key: String, value, category: PersisterEnums.Scope)
|
||||
|
||||
var _persisted = {}
|
||||
|
||||
|
||||
func _spawned():
|
||||
if _triggerer:
|
||||
_info("Connecting to data scope triggers")
|
||||
_triggerer.listen("game", _on_game_triggered)
|
||||
_triggerer.listen("run", _on_run_triggered)
|
||||
_triggerer.listen("round", _on_round_triggered)
|
||||
_triggerer.listen("room", _on_room_triggered)
|
||||
_load()
|
||||
|
||||
|
||||
## Store data in a category
|
||||
func persist_data(key: String, value, category := PersisterEnums.Scope.RUN) -> void:
|
||||
# Only allow ints, bools or strings to be persisted and as Strings
|
||||
if value is int:
|
||||
value = str(value)
|
||||
|
||||
if value is bool:
|
||||
value = str(value)
|
||||
|
||||
if not value is String:
|
||||
_warn("Attempted to persist data for key <%s> with an invalid data type |%s|" % [key, type_string(typeof(value))])
|
||||
return
|
||||
|
||||
# Create category if does not exist
|
||||
if not _persisted.has(category):
|
||||
_info("Created new persister category {%s}" % [_get_category_name(category)])
|
||||
_persisted[category] = {}
|
||||
|
||||
# If key is already set to value exit early
|
||||
if _persisted[category].has(key) and _persisted[category][key] == value:
|
||||
return
|
||||
|
||||
_info("Set key <%s> in category {%s} to value |%s|" % [key, _get_category_name(category), value])
|
||||
_persisted[category][key] = value
|
||||
|
||||
_emit_change(key, value, category)
|
||||
|
||||
|
||||
## Get the value associated with a key in the highest priority or specified category
|
||||
func get_value(key: String, category: PersisterEnums.Scope = PersisterEnums.Scope.UNKNOWN):
|
||||
if category == PersisterEnums.Scope.UNKNOWN:
|
||||
category = _get_key_category(key)
|
||||
|
||||
if category == PersisterEnums.Scope.UNKNOWN:
|
||||
return null
|
||||
|
||||
if _persisted[category][key].is_valid_int():
|
||||
return int(_persisted[category][key])
|
||||
|
||||
if _persisted[category][key] == "true" || _persisted[category][key] == "false":
|
||||
return _persisted[category][key] == "true"
|
||||
|
||||
return _persisted[category][key]
|
||||
|
||||
|
||||
## Delete data associated with a key from a certain category
|
||||
func clear_data(key: String, category := PersisterEnums.Scope.RUN) -> void:
|
||||
if not _persisted.has(category):
|
||||
_info("Attempted to clear key <%s> in category {%s} but the category did not exist" % [key, _get_category_name(category)])
|
||||
return
|
||||
|
||||
if not _persisted[category].has(key):
|
||||
_info("Attempted to clear key <%s> in category {%s} but it did not exist" % [key, _get_category_name(category)])
|
||||
return
|
||||
|
||||
_info("Cleared key <%s> in category {%s}" % [key, _get_category_name(category)])
|
||||
_persisted[category].erase(key)
|
||||
|
||||
_emit_removal(key, category)
|
||||
|
||||
|
||||
## Delete a category including all data within it
|
||||
func clear_category(category := PersisterEnums.Scope.RUN) -> void:
|
||||
if not _persisted.has(category):
|
||||
_error("Attempted to clear category {%s} but it did not exist" % [_get_category_name(category)])
|
||||
return
|
||||
|
||||
var keys = _persisted[category].keys()
|
||||
|
||||
_info("Cleared category {%s}" % [_get_category_name(category)])
|
||||
_persisted.erase(category)
|
||||
|
||||
for key in keys:
|
||||
_emit_removal(key, category)
|
||||
|
||||
|
||||
## Add a number to a number value with the given key from a certain category
|
||||
func change_value(key: String, value: int, category := PersisterEnums.Scope.RUN) -> void:
|
||||
if not _persisted.has(category):
|
||||
_persisted[category] = {}
|
||||
|
||||
if not _persisted[category].has(key):
|
||||
persist_data(key, value, category)
|
||||
return
|
||||
|
||||
if is_nan(int(_persisted[category][key])):
|
||||
_error("Attempted to add number |%d| to key <%s> in category {%s} that is not a number (value: |%s|)" % [value, key, category, _persisted[category][key]])
|
||||
return
|
||||
|
||||
var old_value = int(_persisted[category][key])
|
||||
_info("Added number |%d| to key <%s> in category {%s} (old: |%d|) (new: |%d|)" % [value, key, _get_category_name(category), old_value, old_value + value])
|
||||
persist_data(key, value + old_value, category)
|
||||
|
||||
|
||||
func change_save(index: int):
|
||||
_save()
|
||||
persist_data("save", index)
|
||||
_load()
|
||||
|
||||
|
||||
func save():
|
||||
_save()
|
||||
|
||||
|
||||
func _emit_change(key: String, value: String, category: PersisterEnums.Scope) -> void:
|
||||
var key_category = _get_key_category(key)
|
||||
|
||||
# Only emit change if the category set has the highest priority
|
||||
if key_category == category:
|
||||
if is_nan(int(value)):
|
||||
data_persisted.emit(key, value, category)
|
||||
else:
|
||||
data_persisted.emit(key, int(value), category)
|
||||
|
||||
|
||||
func _emit_removal(key: String, category: PersisterEnums.Scope) -> void:
|
||||
var key_category = _get_key_category(key)
|
||||
|
||||
if key_category == PersisterEnums.Scope.UNKNOWN:
|
||||
return
|
||||
|
||||
var category_priority = _get_category_priority(category)
|
||||
var key_category_priority = _get_category_priority(key_category)
|
||||
|
||||
if category_priority > key_category_priority:
|
||||
var value = _persister[key_category][key]
|
||||
|
||||
if is_nan(int(value)):
|
||||
data_persisted.emit(key, value, key_category)
|
||||
else:
|
||||
data_persisted.emit(key, int(value), key_category)
|
||||
|
||||
|
||||
func _get_category_name(category: PersisterEnums.Scope) -> String:
|
||||
match category:
|
||||
PersisterEnums.Scope.PERMANENT:
|
||||
return "permanent"
|
||||
PersisterEnums.Scope.SAVE:
|
||||
return "save"
|
||||
PersisterEnums.Scope.GAME:
|
||||
return "game"
|
||||
PersisterEnums.Scope.RUN:
|
||||
return "run"
|
||||
PersisterEnums.Scope.ROUND:
|
||||
return "round"
|
||||
PersisterEnums.Scope.ROOM:
|
||||
return "room"
|
||||
_:
|
||||
return "unknown"
|
||||
|
||||
|
||||
func _get_category_priority(category: PersisterEnums.Scope) -> int:
|
||||
match category:
|
||||
PersisterEnums.Scope.PERMANENT:
|
||||
return 1
|
||||
PersisterEnums.Scope.SAVE:
|
||||
return 2
|
||||
PersisterEnums.Scope.GAME:
|
||||
return 3
|
||||
PersisterEnums.Scope.RUN:
|
||||
return 4
|
||||
PersisterEnums.Scope.ROUND:
|
||||
return 5
|
||||
PersisterEnums.Scope.ROOM:
|
||||
return 6
|
||||
_:
|
||||
return 0
|
||||
|
||||
|
||||
func _get_key_category(key: String) -> PersisterEnums.Scope:
|
||||
var category_order = []
|
||||
|
||||
for category in PersisterEnums.Scope:
|
||||
var category_value = PersisterEnums.Scope[category]
|
||||
|
||||
category_order.push_back(
|
||||
{
|
||||
"priority": _get_category_priority(category_value),
|
||||
"category": category_value
|
||||
}
|
||||
)
|
||||
|
||||
category_order.sort_custom(func(a, b):
|
||||
return a.priority > b.priority
|
||||
)
|
||||
|
||||
for value in category_order:
|
||||
var category = value.category
|
||||
|
||||
if _persisted.has(category):
|
||||
if _persisted[category].has(key):
|
||||
return category
|
||||
|
||||
return PersisterEnums.Scope.UNKNOWN
|
||||
|
||||
|
||||
func _get_all_category_data(category: PersisterEnums.Scope) -> Dictionary:
|
||||
if not _persisted.has(category):
|
||||
return {}
|
||||
|
||||
return _persisted[category]
|
||||
|
||||
|
||||
func _on_game_triggered(data: Dictionary) -> void:
|
||||
clear_category(PersisterEnums.Scope.GAME)
|
||||
|
||||
|
||||
func _on_run_triggered(data: Dictionary) -> void:
|
||||
clear_category(PersisterEnums.Scope.RUN)
|
||||
|
||||
|
||||
func _on_round_triggered(data: Dictionary) -> void:
|
||||
clear_category(PersisterEnums.Scope.ROUND)
|
||||
|
||||
|
||||
func _on_room_triggered(data: Dictionary) -> void:
|
||||
clear_category(PersisterEnums.Scope.ROOM)
|
||||
|
||||
|
||||
func _save():
|
||||
_info("Saving")
|
||||
_save_permanent_data()
|
||||
_save_save_data()
|
||||
|
||||
|
||||
func _load():
|
||||
_info("Loading")
|
||||
_load_permanent_data()
|
||||
|
||||
if not get_value("save"):
|
||||
_info("Creating starting save")
|
||||
persist_data("save", 1, PersisterEnums.Scope.PERMANENT)
|
||||
|
||||
clear_category(PersisterEnums.Scope.SAVE)
|
||||
_load_save_data()
|
||||
|
||||
|
||||
func _save_permanent_data():
|
||||
var save_file = FileAccess.open("user://data.json", FileAccess.WRITE)
|
||||
|
||||
var data = _get_all_category_data(PersisterEnums.Scope.PERMANENT)
|
||||
var data_string = JSON.stringify(data)
|
||||
|
||||
_info("Saving permanent save data")
|
||||
|
||||
save_file.store_line(data_string)
|
||||
|
||||
|
||||
func _save_save_data():
|
||||
if not FileAccess.file_exists("user://saves"):
|
||||
DirAccess.make_dir_absolute("user://saves")
|
||||
|
||||
var save = get_value("save")
|
||||
var save_file = FileAccess.open("user://saves/save-%d.json" % [save], FileAccess.WRITE)
|
||||
|
||||
var data = _get_all_category_data(PersisterEnums.Scope.SAVE)
|
||||
var data_string = JSON.stringify(data)
|
||||
|
||||
_info("Saving save save data")
|
||||
|
||||
save_file.store_line(data_string)
|
||||
|
||||
|
||||
func _load_permanent_data():
|
||||
var save_file = FileAccess.open("user://data.json", FileAccess.READ)
|
||||
|
||||
if not save_file:
|
||||
return
|
||||
|
||||
_info("Loading permanent save data")
|
||||
var json_string = ""
|
||||
|
||||
while save_file.get_position() < save_file.get_length():
|
||||
json_string += save_file.get_line()
|
||||
|
||||
var json = JSON.new()
|
||||
|
||||
var result = json.parse(json_string)
|
||||
var data = json.get_data()
|
||||
|
||||
for key in data:
|
||||
Persister.persist_data(key, data[key], PersisterEnums.Scope.PERMANENT)
|
||||
|
||||
|
||||
func _load_save_data():
|
||||
var save = get_value("save")
|
||||
var save_file = FileAccess.open("user://saves/save-%s.json" % [save], FileAccess.READ)
|
||||
|
||||
if not save_file:
|
||||
return
|
||||
|
||||
_info("Loading save save data")
|
||||
var json_string = ""
|
||||
|
||||
while save_file.get_position() < save_file.get_length():
|
||||
json_string += save_file.get_line()
|
||||
|
||||
var json = JSON.new()
|
||||
|
||||
var result = json.parse(json_string)
|
||||
var data = json.get_data()
|
||||
|
||||
Persister.clear_category(PersisterEnums.Scope.SAVE)
|
||||
|
||||
for key in data:
|
||||
Persister.persist_data(key, data[key], PersisterEnums.Scope.SAVE)
|
||||
|
||||
|
||||
func _on_timer_timeout():
|
||||
_save()
|
10
components/Persister/toolbar.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
save[]
|
||||
type: button
|
||||
name: Swap Save 1
|
||||
accent: #11a1a1
|
||||
function: save_one
|
||||
save2[]
|
||||
type: button
|
||||
name: Swap Save 2
|
||||
accent: #11a1a1
|
||||
function: save_two
|
6
components/Settings/Settings.tscn
Normal file
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://d3uc4ryq5tqby"]
|
||||
|
||||
[ext_resource type="Script" path="res://components/Settings/settings.gd" id="1_wmbcp"]
|
||||
|
||||
[node name="Settings" type="Node"]
|
||||
script = ExtResource("1_wmbcp")
|
0
components/Settings/information.txt
Normal file
16
components/Settings/settings.gd
Normal file
|
@ -0,0 +1,16 @@
|
|||
@icon("res://components/Audio/music.svg")
|
||||
extends Base
|
||||
|
||||
|
||||
func _ready():
|
||||
#_log_category = "AUD"
|
||||
#_log_icon = "res://components/Audio/music.svg"
|
||||
#_log_color = "#32ad61"
|
||||
super()
|
||||
_info("Audio is active")
|
||||
if _triggerer:
|
||||
_triggerer.listen("any", _on_trigger)
|
||||
|
||||
|
||||
func _on_trigger(data: Dictionary) -> void:
|
||||
pass
|
1
components/Settings/settings.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-settings"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg>
|
After Width: | Height: | Size: 826 B |
37
components/Settings/settings.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c1toq8e1yg4he"
|
||||
path="res://.godot/imported/settings.svg-0c63f5959ea52eb948e9c6dfb59e2f91.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Settings/settings.svg"
|
||||
dest_files=["res://.godot/imported/settings.svg-0c63f5959ea52eb948e9c6dfb59e2f91.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
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
6
components/Triggerer/TriggerReceiver.tscn
Normal file
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://cgivlj3yp8nsy"]
|
||||
|
||||
[ext_resource type="Script" path="res://components/Triggerer/trigger_receiver.gd" id="1_rb2wc"]
|
||||
|
||||
[node name="TriggerReceiver" type="Node"]
|
||||
script = ExtResource("1_rb2wc")
|
6
components/Triggerer/Triggerer.tscn
Normal file
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://rjec7f6cseh"]
|
||||
|
||||
[ext_resource type="Script" path="res://components/Triggerer/triggerer.gd" id="1_e3bhf"]
|
||||
|
||||
[node name="Triggerer" type="Node"]
|
||||
script = ExtResource("1_e3bhf")
|
1
components/Triggerer/antenna.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-antenna"><path d="M2 12 7 2"/><path d="m7 12 5-10"/><path d="m12 12 5-10"/><path d="m17 12 5-10"/><path d="M4.5 7h15"/><path d="M12 16v6"/></svg>
|
After Width: | Height: | Size: 340 B |
37
components/Triggerer/antenna.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://hnqq5c8erlns"
|
||||
path="res://.godot/imported/antenna.svg-9e84cc3637193460d89c85029a059bef.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/Triggerer/antenna.svg"
|
||||
dest_files=["res://.godot/imported/antenna.svg-9e84cc3637193460d89c85029a059bef.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
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|