46 Commits
Author SHA1 Message Date
Altaezio 981965d8c7 plant-builder working 2026-02-24 14:28:24 +01:00
Altaezio d28e734806 branch rotated + optimization 2026-02-22 00:05:35 +01:00
Altaezio 4ca102966b plant tester + shado assets 2026-02-21 18:40:00 +01:00
Altaezio 35004684f4 working with new sprites 2026-02-20 14:22:13 +01:00
zacharie fb8a2da4ff ajout du détecteur et liaison entre les scènes 2026-02-20 01:00:55 +01:00
zacharie dc1a6686bc modification de la scène de cockpit et ajout de lien entre les scènes 2026-02-19 22:15:38 +01:00
Altaezio fadf0cb769 tools separated in inv 2026-02-15 19:32:21 +01:00
Altaezio f1acb6e3e9 rename to plant_texture_builder 2026-02-15 16:32:29 +01:00
Altaezio 6a1a663020 Merge branch 'plant-builder' 2026-02-15 16:02:17 +01:00
Altaezio e305e3213d texture_builder + growing sprites 2026-02-13 16:49:14 +01:00
Altaezio e6d34a50a5 branches and one texture 2026-02-13 11:18:34 +01:00
zacharie c992950789 Ajout de la cinématique de début et refonte du système audio
Et toujours un peu de correction de bug par ci par là
2026-02-11 21:11:32 +01:00
Altaezio ab5089ad6c plant builder 2026-02-10 20:09:34 +01:00
zacharie 4b8e59ee56 suppression des print de debug et ajout du code des timeline dans l'audio manager 2026-02-07 17:05:48 +01:00
zacharie 9570fd96c2 modification de l'UI en 3D et renommage des particules 2026-02-07 16:41:39 +01:00
zacharie 3a82e8b3c1 réparation de audio manager 2026-02-07 15:02:04 +01:00
Nilouandzacharie 3146198725 remixage des morceaux #107 2026-02-07 00:24:58 +01:00
Nilouandzacharie 8d3b0768fa finition du morceau de phase 1 et ajout du morceau de phase 2 #107 2026-02-07 00:24:58 +01:00
Nilouandzacharie 27b236b27c correction du dialogue post-tuto #130 2026-02-07 00:24:57 +01:00
Nilouandzacharie 6a751eaf7d amélioration du dialogue post-tuto #130 2026-02-07 00:24:57 +01:00
Nilouandzacharie f2aa04e5e9 corrections du dialogue d'outro et d'échec #125 #128 2026-02-07 00:24:57 +01:00
Nilouandzacharie 00742de387 écriture du dialogue post-tuto #130 2026-02-07 00:24:57 +01:00
Nilouandzacharie 6632c2f533 création du dialogue intermédiaire et ajout du morceau et ambiance du vaisseau #127 2026-02-07 00:24:57 +01:00
Nilouandzacharie 4457b4ff84 dialogue d'outro révisé (manque juste la correction) #125 2026-02-07 00:24:56 +01:00
Nilouandzacharie 32f0867d1e modification du morceau de phase 1 #107 2026-02-07 00:24:28 +01:00
Nilouandzacharie eb009d6f41 dialogue d'échec (manque l'ambiance sonore) #128 2026-02-07 00:24:27 +01:00
Nilouandzacharie 71f36fb430 ajout du sfx de téléphone #126 2026-02-07 00:24:27 +01:00
Nilouandzacharie 42bbef60d5 correction du dialogue d'outro #125 2026-02-07 00:24:27 +01:00
Nilouandzacharie 7d81023331 nouvelle version du dialague d'outro #125 2026-02-07 00:24:26 +01:00
Nilouandzacharie d835de1d66 suppression des espaces et accents #125 2026-02-07 00:24:26 +01:00
Nilouandzacharie 605b5a16cf dialogue d'outro complet (manque la piste d'ambiance) #125 2026-02-07 00:24:26 +01:00
Nilouandzacharie 1922864343 overhaul du dialogue d'intro (vitesse, pauses, couleurs, sons) et création du dialogue d'outro #125 #119 2026-02-07 00:24:25 +01:00
Nilouandzacharie 3f4f024070 remastering du morceau de phase 1 #7 2026-02-07 00:24:23 +01:00
Nilouandzacharie 96e20b7ff0 modifications et corrections du dialogue d'introduction #119 2026-02-07 00:24:23 +01:00
Nilouandzacharie 99a0522e9e sfx de minage fonctionnels #109 2026-02-07 00:24:23 +01:00
Nilouandzacharie 9dbc3ffb49 creation du node de sfx pickaxe #109 2026-02-07 00:24:22 +01:00
Nilouandzacharie 109c9c3b84 suppression de la reverb sur les sfx de pioche #109 2026-02-07 00:24:04 +01:00
Nilouandzacharie c54d072bcb passage d'ambiance liée au score à playlist #77 2026-02-07 00:24:04 +01:00
Nilouandzacharie 307b7418f4 ajout de l'ambiance de dialogue avec Demeter #82 2026-02-07 00:23:36 +01:00
zacharie 3fa84994cd ajout d'une gui en 3d, d'un tuto et correction de bug à la pelletée 2026-02-07 00:22:12 +01:00
zacharie 5722fbb437 sauvegarde des contrôles 2026-02-06 10:53:34 +01:00
zacharie 96d1a4f4dd nettoyage de repo 2026-02-06 10:29:32 +01:00
zacharie cc421a951f système de sauvegarde, scène 3D de test sur la base astra et passage en forward+ 2026-02-06 10:28:36 +01:00
zacharie 83d462f2f4 changement du scene manager, amélioration du cockpit et autres
* refonte du scene manager
* refonte du audio manager
* premier rework des plantes
* nettoyage des dossiers/fichiers
* renommage de planète en region
* fix des run
2026-01-23 18:06:27 +01:00
zacharie 62b34473b6 ajout de la scène du cockpit 2026-01-17 11:15:53 +01:00
zacharie ff4feacea3 ajout d'une animation de recharge et réparation du crash au chargement de chunk 2026-01-16 12:28:36 +01:00
605 changed files with 13638 additions and 4470 deletions
+3
View File
@@ -19,3 +19,6 @@ mono_crash.*.json
.vscode
.export/
stw_demo_save.tres
stw_settings.tres
@@ -3,20 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://cl03vrbj5wsjk"
path="res://.godot/imported/expand-icon.svg-26099b197ab0f314e2253848fcc22962.ctex"
path.s3tc="res://.godot/imported/expand-icon.svg-26099b197ab0f314e2253848fcc22962.s3tc.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://addons/dialogic/Editor/Images/Pieces/expand-icon.svg"
dest_files=["res://.godot/imported/expand-icon.svg-26099b197ab0f314e2253848fcc22962.ctex"]
dest_files=["res://.godot/imported/expand-icon.svg-26099b197ab0f314e2253848fcc22962.s3tc.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -24,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -38,7 +39,7 @@ 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
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
@@ -3,20 +3,21 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://qx5bntelnslj"
path="res://.godot/imported/update_portrait.svg-b90fa6163d3720d34df8578ce2aa35e1.ctex"
path.s3tc="res://.godot/imported/update_portrait.svg-b90fa6163d3720d34df8578ce2aa35e1.s3tc.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://addons/dialogic/Modules/Character/update_portrait.svg"
dest_files=["res://.godot/imported/update_portrait.svg-b90fa6163d3720d34df8578ce2aa35e1.ctex"]
dest_files=["res://.godot/imported/update_portrait.svg-b90fa6163d3720d34df8578ce2aa35e1.s3tc.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -24,7 +25,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -38,7 +39,7 @@ 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
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+326 -326
View File
@@ -24,18 +24,18 @@ var portrait := ""
## Used to set the character resource from the unique name identifier and vice versa
var character_identifier: String:
get:
if character and not "{" in character_identifier:
var identifier := character.get_identifier()
if not identifier.is_empty():
return identifier
return character_identifier
set(value):
character_identifier = value
character = DialogicResourceUtil.get_character_resource(value)
if Engine.is_editor_hint() and ((not character) or (character and not character.portraits.has(portrait))):
portrait = ""
ui_update_needed.emit()
get:
if character and not "{" in character_identifier:
var identifier := character.get_identifier()
if not identifier.is_empty():
return identifier
return character_identifier
set(value):
character_identifier = value
character = DialogicResourceUtil.get_character_resource(value)
if Engine.is_editor_hint() and ((not character) or (character and not character.portraits.has(portrait))):
portrait = ""
ui_update_needed.emit()
var regex := RegEx.create_from_string(r'\s*((")?(?<name>(?(2)[^"\n]*|[^(: \n]*))(?(2)"|)(\W*(?<portrait>\(.*\)))?\s*(?<!\\):)?(?<text>(.|\n)*)')
var split_regex := RegEx.create_from_string(r"((\[n\]|\[n\+\])?((?!(\[n\]|\[n\+\]))(.|\n))+)")
@@ -49,225 +49,225 @@ signal advance
################################################################################
func _clear_state() -> void:
dialogic.current_state_info.erase('text_sub_idx')
_disconnect_signals()
dialogic.current_state_info.erase('text_sub_idx')
_disconnect_signals()
func _execute() -> void:
if text.is_empty():
finish()
return
if text.is_empty():
finish()
return
## If the speaker is provided as an expression, parse it now.
if "{" in character_identifier:
character = null
var character_name: String = dialogic.Expressions.execute_string(character_identifier)
get_or_create_character(character_name)
## If the speaker is provided as an expression, parse it now.
if "{" in character_identifier:
character = null
var character_name: String = dialogic.Expressions.execute_string(character_identifier)
get_or_create_character(character_name)
## Change Portrait and Active Speaker
if dialogic.has_subsystem("Portraits"):
if character:
## Change Portrait and Active Speaker
if dialogic.has_subsystem("Portraits"):
if character:
dialogic.Portraits.change_speaker(character, portrait)
dialogic.Portraits.change_speaker(character, portrait)
if portrait and dialogic.Portraits.is_character_joined(character):
dialogic.Portraits.change_character_portrait(character, portrait)
if portrait and dialogic.Portraits.is_character_joined(character):
dialogic.Portraits.change_character_portrait(character, portrait)
else:
dialogic.Portraits.change_speaker(null)
else:
dialogic.Portraits.change_speaker(null)
## Change and Type Sound Mood
if character:
dialogic.Text.update_name_label(character)
## Change and Type Sound Mood
if character:
dialogic.Text.update_name_label(character)
var current_portrait: String = portrait
if portrait.is_empty():
current_portrait = dialogic.current_state_info["portraits"].get(character.get_identifier(), {}).get("portrait", "")
var current_portrait: String = portrait
if portrait.is_empty():
current_portrait = dialogic.current_state_info["portraits"].get(character.get_identifier(), {}).get("portrait", "")
var current_portrait_sound_mood: String = character.portraits.get(current_portrait, {}).get("sound_mood", "")
dialogic.Text.update_typing_sound_mood_from_character(character, current_portrait_sound_mood)
var current_portrait_sound_mood: String = character.portraits.get(current_portrait, {}).get("sound_mood", "")
dialogic.Text.update_typing_sound_mood_from_character(character, current_portrait_sound_mood)
else:
dialogic.Text.update_name_label(null)
dialogic.Text.update_typing_sound_mood()
else:
dialogic.Text.update_name_label(null)
dialogic.Text.update_typing_sound_mood()
## Handle style changes
if dialogic.has_subsystem("Styles"):
var current_base_style: String = dialogic.current_state_info.get("base_style")
var current_style: String = dialogic.current_state_info.get("style", "")
var character_style: String = "" if not character else character.custom_info.get("style", "")
## Handle style changes
if dialogic.has_subsystem("Styles"):
var current_base_style: String = dialogic.current_state_info.get("base_style")
var current_style: String = dialogic.current_state_info.get("style", "")
var character_style: String = "" if not character else character.custom_info.get("style", "")
## Change back to base style, if another characters style is currently used
if (not character or character_style.is_empty()) and (current_base_style != current_style):
dialogic.Styles.change_style(dialogic.current_state_info.get("base_style", "Default"))
await dialogic.get_tree().process_frame
## Change back to base style, if another characters style is currently used
if (not character or character_style.is_empty()) and (current_base_style != current_style):
dialogic.Styles.change_style(dialogic.current_state_info.get("base_style", "Default"))
await dialogic.get_tree().process_frame
## Change to the characters style if this character has one
elif character and not character_style.is_empty():
dialogic.Styles.change_style(character_style, false)
await dialogic.get_tree().process_frame
## Change to the characters style if this character has one
elif character and not character_style.is_empty():
dialogic.Styles.change_style(character_style, false)
await dialogic.get_tree().process_frame
_connect_signals()
_connect_signals()
var character_name_text := dialogic.Text.get_character_name_parsed(character)
var final_text: String = get_property_translated('text')
if ProjectSettings.get_setting('dialogic/text/split_at_new_lines', false):
match ProjectSettings.get_setting('dialogic/text/split_at_new_lines_as', 0):
0:
final_text = final_text.replace('\n', '[n]')
1:
final_text = final_text.replace('\n', '[n+][br]')
var character_name_text := dialogic.Text.get_character_name_parsed(character)
var final_text: String = get_property_translated('text')
if ProjectSettings.get_setting('dialogic/text/split_at_new_lines', false):
match ProjectSettings.get_setting('dialogic/text/split_at_new_lines_as', 0):
0:
final_text = final_text.replace('\n', '[n]')
1:
final_text = final_text.replace('\n', '[n+][br]')
var split_text := []
for i in split_regex.search_all(final_text):
split_text.append([i.get_string().trim_prefix('[n]').trim_prefix('[n+]')])
split_text[-1].append(i.get_string().begins_with('[n+]'))
var split_text := []
for i in split_regex.search_all(final_text):
split_text.append([i.get_string().trim_prefix('[n]').trim_prefix('[n+]')])
split_text[-1].append(i.get_string().begins_with('[n+]'))
dialogic.current_state_info['text_sub_idx'] = dialogic.current_state_info.get('text_sub_idx', -1)
dialogic.current_state_info['text_sub_idx'] = dialogic.current_state_info.get('text_sub_idx', -1)
var reveal_next_segment: bool = dialogic.current_state_info['text_sub_idx'] == -1
var reveal_next_segment: bool = dialogic.current_state_info['text_sub_idx'] == -1
for section_idx in range(min(max(0, dialogic.current_state_info['text_sub_idx']), len(split_text)-1), len(split_text)):
dialogic.Inputs.block_input(ProjectSettings.get_setting('dialogic/text/text_reveal_skip_delay', 0.1))
for section_idx in range(min(max(0, dialogic.current_state_info['text_sub_idx']), len(split_text)-1), len(split_text)):
dialogic.Inputs.block_input(ProjectSettings.get_setting('dialogic/text/text_reveal_skip_delay', 0.1))
if reveal_next_segment:
dialogic.Text.hide_next_indicators()
if reveal_next_segment:
dialogic.Text.hide_next_indicators()
dialogic.current_state_info['text_sub_idx'] = section_idx
dialogic.current_state_info['text_sub_idx'] = section_idx
var segment: String = dialogic.Text.parse_text(split_text[section_idx][0], 0)
var is_append: bool = split_text[section_idx][1]
var segment: String = dialogic.Text.parse_text(split_text[section_idx][0], 0)
var is_append: bool = split_text[section_idx][1]
final_text = ProjectSettings.get_setting("dialogic/text/dialog_text_prefix", "")+segment
dialogic.Text.about_to_show_text.emit({'text':final_text, 'character':character, 'portrait':portrait, 'append': is_append})
final_text = ProjectSettings.get_setting("dialogic/text/dialog_text_prefix", "")+segment
dialogic.Text.about_to_show_text.emit({'text':final_text, 'character':character, 'portrait':portrait, 'append': is_append})
await dialogic.Text.update_textbox(final_text, false)
await dialogic.Text.update_textbox(final_text, false)
state = States.REVEALING
_try_play_current_line_voice()
final_text = dialogic.Text.update_dialog_text(final_text, false, is_append)
state = States.REVEALING
_try_play_current_line_voice()
final_text = dialogic.Text.update_dialog_text(final_text, false, is_append)
dialogic.Text.text_started.emit({'text':final_text, 'character':character, 'portrait':portrait, 'append': is_append})
dialogic.Text.text_started.emit({'text':final_text, 'character':character, 'portrait':portrait, 'append': is_append})
_mark_as_read(character_name_text, final_text)
_mark_as_read(character_name_text, final_text)
# We must skip text animation before we potentially return when there
# is a Choice event.
if dialogic.Inputs.auto_skip.enabled:
dialogic.Text.skip_text_reveal()
else:
await dialogic.Text.text_finished
# We must skip text animation before we potentially return when there
# is a Choice event.
if dialogic.Inputs.auto_skip.enabled:
dialogic.Text.skip_text_reveal()
else:
await dialogic.Text.text_finished
state = States.IDLE
else:
reveal_next_segment = true
state = States.IDLE
else:
reveal_next_segment = true
# Handling potential Choice Events.
if section_idx == len(split_text)-1 and dialogic.has_subsystem('Choices') and dialogic.Choices.is_question(dialogic.current_event_idx):
dialogic.Text.show_next_indicators(true)
# Handling potential Choice Events.
if section_idx == len(split_text)-1 and dialogic.has_subsystem('Choices') and dialogic.Choices.is_question(dialogic.current_event_idx):
dialogic.Text.show_next_indicators(true)
finish()
return
finish()
return
elif dialogic.Inputs.auto_advance.is_enabled():
dialogic.Text.show_next_indicators(false, true)
dialogic.Inputs.auto_advance.start()
else:
dialogic.Text.show_next_indicators()
elif dialogic.Inputs.auto_advance.is_enabled():
dialogic.Text.show_next_indicators(false, true)
dialogic.Inputs.auto_advance.start()
else:
dialogic.Text.show_next_indicators()
if section_idx == len(split_text)-1:
state = States.DONE
if section_idx == len(split_text)-1:
state = States.DONE
# If Auto-Skip is enabled and there are multiple parts of this text
# we need to skip the text after the defined time per event.
if dialogic.Inputs.auto_skip.enabled:
await dialogic.Inputs.start_autoskip_timer()
# If Auto-Skip is enabled and there are multiple parts of this text
# we need to skip the text after the defined time per event.
if dialogic.Inputs.auto_skip.enabled:
await dialogic.Inputs.start_autoskip_timer()
# Check if Auto-Skip is still enabled.
if not dialogic.Inputs.auto_skip.enabled:
await advance
# Check if Auto-Skip is still enabled.
if not dialogic.Inputs.auto_skip.enabled:
await advance
else:
await advance
else:
await advance
finish()
finish()
func _mark_as_read(character_name_text: String, final_text: String) -> void:
if dialogic.has_subsystem('History'):
if character:
dialogic.History.store_simple_history_entry(final_text, event_name, {'character':character_name_text, 'character_color':character.color})
else:
dialogic.History.store_simple_history_entry(final_text, event_name)
dialogic.History.mark_event_as_visited()
if dialogic.has_subsystem('History'):
if character:
dialogic.History.store_simple_history_entry(final_text, event_name, {'character':character_name_text, 'character_color':character.color})
else:
dialogic.History.store_simple_history_entry(final_text, event_name)
dialogic.History.mark_event_as_visited()
func _connect_signals() -> void:
if not dialogic.Inputs.dialogic_action.is_connected(_on_dialogic_input_action):
dialogic.Inputs.dialogic_action.connect(_on_dialogic_input_action)
if not dialogic.Inputs.dialogic_action.is_connected(_on_dialogic_input_action):
dialogic.Inputs.dialogic_action.connect(_on_dialogic_input_action)
dialogic.Inputs.auto_skip.toggled.connect(_on_auto_skip_enable)
dialogic.Inputs.auto_skip.toggled.connect(_on_auto_skip_enable)
if not dialogic.Inputs.auto_advance.autoadvance.is_connected(_on_dialogic_input_autoadvance):
dialogic.Inputs.auto_advance.autoadvance.connect(_on_dialogic_input_autoadvance)
if not dialogic.Inputs.auto_advance.autoadvance.is_connected(_on_dialogic_input_autoadvance):
dialogic.Inputs.auto_advance.autoadvance.connect(_on_dialogic_input_autoadvance)
## If the event is done, this method can clean-up signal connections.
func _disconnect_signals() -> void:
if dialogic.Inputs.dialogic_action.is_connected(_on_dialogic_input_action):
dialogic.Inputs.dialogic_action.disconnect(_on_dialogic_input_action)
if dialogic.Inputs.auto_advance.autoadvance.is_connected(_on_dialogic_input_autoadvance):
dialogic.Inputs.auto_advance.autoadvance.disconnect(_on_dialogic_input_autoadvance)
if dialogic.Inputs.auto_skip.toggled.is_connected(_on_auto_skip_enable):
dialogic.Inputs.auto_skip.toggled.disconnect(_on_auto_skip_enable)
if dialogic.Inputs.dialogic_action.is_connected(_on_dialogic_input_action):
dialogic.Inputs.dialogic_action.disconnect(_on_dialogic_input_action)
if dialogic.Inputs.auto_advance.autoadvance.is_connected(_on_dialogic_input_autoadvance):
dialogic.Inputs.auto_advance.autoadvance.disconnect(_on_dialogic_input_autoadvance)
if dialogic.Inputs.auto_skip.toggled.is_connected(_on_auto_skip_enable):
dialogic.Inputs.auto_skip.toggled.disconnect(_on_auto_skip_enable)
## Tries to play the voice clip for the current line.
func _try_play_current_line_voice() -> void:
# If Auto-Skip is enabled and we skip voice clips, we don't want to play.
if (dialogic.Inputs.auto_skip.enabled
and dialogic.Inputs.auto_skip.skip_voice):
return
# If Auto-Skip is enabled and we skip voice clips, we don't want to play.
if (dialogic.Inputs.auto_skip.enabled
and dialogic.Inputs.auto_skip.skip_voice):
return
# Plays the audio region for the current line.
if (dialogic.has_subsystem('Voice')
and dialogic.Voice.is_voiced(dialogic.current_event_idx)):
dialogic.Voice.play_voice()
# Plays the audio region for the current line.
if (dialogic.has_subsystem('Voice')
and dialogic.Voice.is_voiced(dialogic.current_event_idx)):
dialogic.Voice.play_voice()
func _on_dialogic_input_action() -> void:
match state:
States.REVEALING:
if dialogic.Text.is_text_reveal_skippable():
dialogic.Text.skip_text_reveal()
dialogic.Inputs.stop_timers()
_:
if dialogic.Inputs.manual_advance.is_enabled():
advance.emit()
dialogic.Inputs.stop_timers()
match state:
States.REVEALING:
if dialogic.Text.is_text_reveal_skippable():
dialogic.Text.skip_text_reveal()
dialogic.Inputs.stop_timers()
_:
if dialogic.Inputs.manual_advance.is_enabled():
advance.emit()
dialogic.Inputs.stop_timers()
func _on_dialogic_input_autoadvance() -> void:
if state == States.IDLE or state == States.DONE:
advance.emit()
if state == States.IDLE or state == States.DONE:
advance.emit()
func _on_auto_skip_enable(enabled: bool) -> void:
if not enabled:
return
if not enabled:
return
match state:
States.DONE:
await dialogic.Inputs.start_autoskip_timer()
match state:
States.DONE:
await dialogic.Inputs.start_autoskip_timer()
# If Auto-Skip is still enabled, advance the text.
if dialogic.Inputs.auto_skip.enabled:
advance.emit()
# If Auto-Skip is still enabled, advance the text.
if dialogic.Inputs.auto_skip.enabled:
advance.emit()
States.REVEALING:
dialogic.Text.skip_text_reveal()
States.REVEALING:
dialogic.Text.skip_text_reveal()
#endregion
@@ -276,12 +276,12 @@ func _on_auto_skip_enable(enabled: bool) -> void:
################################################################################
func _init() -> void:
event_name = "Text"
set_default_color('Color1')
event_category = "Main"
event_sorting_index = 0
expand_by_default = true
help_page_path = "https://docs.dialogic.pro/writing-texts.html"
event_name = "Text"
set_default_color('Color1')
event_category = "Main"
event_sorting_index = 0
expand_by_default = true
help_page_path = "https://docs.dialogic.pro/writing-texts.html"
@@ -289,92 +289,92 @@ func _init() -> void:
################################################################################
func to_text() -> String:
var result := text.replace('\n', '\\\n').strip_edges(false).trim_suffix("\\")
result = result.replace(':', '\\:')
if result.is_empty():
result = "<Empty Text Event>"
var result := text.replace('\n', '\\\n').strip_edges(false).trim_suffix("\\")
result = result.replace(':', '\\:')
if result.is_empty():
result = "<Empty Text Event>"
if character or character_identifier:
var name := character_identifier
if character:
name = character.get_identifier()
if name.count(" ") > 0:
name = '"' + name + '"'
if not portrait.is_empty():
result = name+" ("+portrait+"): "+result
else:
result = name+": "+result
for event in DialogicResourceUtil.get_event_cache():
if not event is DialogicTextEvent and event.is_valid_event(result):
result = '\\'+result
break
if character or character_identifier:
var name := character_identifier
if character:
name = character.get_identifier()
if name.count(" ") > 0:
name = '"' + name + '"'
if not portrait.is_empty():
result = name+" ("+portrait+"): "+result
else:
result = name+": "+result
for event in DialogicResourceUtil.get_event_cache():
if not event is DialogicTextEvent and event.is_valid_event(result):
result = '\\'+result
break
return result
return result
func from_text(string:String) -> void:
# Load default character
# This is only of relevance if the default has been overriden (usually not)
character = DialogicResourceUtil.get_character_resource(character_identifier)
# Load default character
# This is only of relevance if the default has been overriden (usually not)
character = DialogicResourceUtil.get_character_resource(character_identifier)
var result := regex.search(string.trim_prefix('\\'))
var result := regex.search(string.trim_prefix('\\'))
if result.get_string('portrait'):
portrait = result.get_string('portrait').strip_edges().trim_prefix('(').trim_suffix(')')
if result.get_string('portrait'):
portrait = result.get_string('portrait').strip_edges().trim_prefix('(').trim_suffix(')')
if result and not result.get_string('name').is_empty():
var name := result.get_string('name').strip_edges()
if result and not result.get_string('name').is_empty():
var name := result.get_string('name').strip_edges()
if name == '_':
character = null
elif "{" in name:
## If it's an expression, we load the character in _execute.
character_identifier = name
character = null
else:
get_or_create_character(name)
if name == '_':
character = null
elif "{" in name:
## If it's an expression, we load the character in _execute.
character_identifier = name
character = null
else:
get_or_create_character(name)
if not result:
return
if not result:
return
text = result.get_string('text').replace("\\\n", "\n").replace('\\:', ':').strip_edges().trim_prefix('\\')
if text == '<Empty Text Event>':
text = ""
text = result.get_string('text').replace("\\\n", "\n").replace('\\:', ':').strip_edges().trim_prefix('\\')
if text == '<Empty Text Event>':
text = ""
func get_or_create_character(name:String) -> void:
character = DialogicResourceUtil.get_character_resource(name)
character = DialogicResourceUtil.get_character_resource(name)
if character == null:
if Engine.is_editor_hint() == false:
character = DialogicCharacter.new()
character.display_name = name
character.set_identifier(name)
if portrait:
if "{" in portrait:
character.color = Color(dialogic.Expressions.execute_string(portrait))
else:
character.color = Color(portrait)
else:
character_identifier = name
if character == null:
if Engine.is_editor_hint() == false:
character = DialogicCharacter.new()
character.display_name = name
character.set_identifier(name)
if portrait:
if "{" in portrait:
character.color = Color(dialogic.Expressions.execute_string(portrait))
else:
character.color = Color(portrait)
else:
character_identifier = name
func is_valid_event(_string:String) -> bool:
return true
return true
func is_string_full_event(string:String) -> bool:
return !string.ends_with('\\')
return !string.ends_with('\\')
# this is only here to provide a list of default values
# this way the module manager can add custom default overrides to this event.
func get_shortcode_parameters() -> Dictionary:
return {
#param_name : property_info
"character" : {"property": "character_identifier", "default": "", "ext_file":true},
"portrait" : {"property": "portrait", "default": ""},
}
return {
#param_name : property_info
"character" : {"property": "character_identifier", "default": "", "ext_file":true},
"portrait" : {"property": "portrait", "default": ""},
}
#endregion
@@ -382,14 +382,14 @@ func get_shortcode_parameters() -> Dictionary:
################################################################################
func _get_translatable_properties() -> Array:
return ['text']
return ['text']
func _get_property_original_translation(property:String) -> String:
match property:
'text':
return text
return ''
match property:
'text':
return text
return ''
#endregion
@@ -399,44 +399,44 @@ func _get_property_original_translation(property:String) -> String:
################################################################################
func _enter_visual_editor(editor:DialogicEditor):
editor.opened.connect(func(): ui_update_needed.emit())
editor.opened.connect(func(): ui_update_needed.emit())
func build_event_editor() -> void:
add_header_edit('character_identifier', ValueType.DYNAMIC_OPTIONS,
{'file_extension' : '.dch',
'mode' : 2,
'suggestions_func' : get_character_suggestions,
'placeholder' : '(No one)',
'icon' : load("res://addons/dialogic/Editor/Images/Resources/character.svg")}, 'do_any_characters_exist()')
add_header_edit('portrait', ValueType.DYNAMIC_OPTIONS,
{'suggestions_func' : get_portrait_suggestions,
'placeholder' : "(Don't change)",
'icon' : load("res://addons/dialogic/Editor/Images/Resources/portrait.svg"),
'collapse_when_empty': true,},
'should_show_portrait_selector()')
add_body_edit('text', ValueType.MULTILINE_TEXT, {'autofocus':true})
add_header_edit('character_identifier', ValueType.DYNAMIC_OPTIONS,
{'file_extension' : '.dch',
'mode' : 2,
'suggestions_func' : get_character_suggestions,
'placeholder' : '(No one)',
'icon' : load("res://addons/dialogic/Editor/Images/Resources/character.svg")}, 'do_any_characters_exist()')
add_header_edit('portrait', ValueType.DYNAMIC_OPTIONS,
{'suggestions_func' : get_portrait_suggestions,
'placeholder' : "(Don't change)",
'icon' : load("res://addons/dialogic/Editor/Images/Resources/portrait.svg"),
'collapse_when_empty': true,},
'should_show_portrait_selector()')
add_body_edit('text', ValueType.MULTILINE_TEXT, {'autofocus':true})
func should_show_portrait_selector() -> bool:
return character and not character.portraits.is_empty() and not character.portraits.size() == 1
return character and not character.portraits.is_empty() and not character.portraits.size() == 1
func do_any_characters_exist() -> bool:
return not DialogicResourceUtil.get_character_directory().is_empty()
return not DialogicResourceUtil.get_character_directory().is_empty()
func get_character_suggestions(search_text:String) -> Dictionary:
var suggestions := DialogicUtil.get_character_suggestions(search_text, character, true, false, editor_node)
if search_text and not search_text in suggestions:
suggestions[search_text] = {
"value":search_text,
"tooltip": "A temporary character, created on the spot.",
"editor_icon":["GuiEllipsis", "EditorIcons"]}
return suggestions
var suggestions := DialogicUtil.get_character_suggestions(search_text, character, true, false, editor_node)
if search_text and not search_text in suggestions:
suggestions[search_text] = {
"value":search_text,
"tooltip": "A temporary character, created on the spot.",
"editor_icon":["GuiEllipsis", "EditorIcons"]}
return suggestions
func get_portrait_suggestions(search_text:String) -> Dictionary:
return DialogicUtil.get_portrait_suggestions(search_text, character, true, "Don't change")
return DialogicUtil.get_portrait_suggestions(search_text, character, true, "Don't change")
#endregion
@@ -447,45 +447,45 @@ func get_portrait_suggestions(search_text:String) -> Dictionary:
var completion_text_character_getter_regex := RegEx.new()
var completion_text_effects := {}
func _get_code_completion(CodeCompletionHelper:Node, TextNode:TextEdit, line:String, _word:String, symbol:String) -> void:
if completion_text_character_getter_regex.get_pattern().is_empty():
completion_text_character_getter_regex.compile("(\"[^\"]*\"|[^\\s:]*)")
if completion_text_character_getter_regex.get_pattern().is_empty():
completion_text_character_getter_regex.compile("(\"[^\"]*\"|[^\\s:]*)")
if completion_text_effects.is_empty():
for idx in DialogicUtil.get_indexers():
for effect in idx._get_text_effects():
completion_text_effects[effect['command']] = effect
if completion_text_effects.is_empty():
for idx in DialogicUtil.get_indexers():
for effect in idx._get_text_effects():
completion_text_effects[effect['command']] = effect
if not ':' in line.substr(0, TextNode.get_caret_column()) and symbol == '(':
var completion_character := completion_text_character_getter_regex.search(line).get_string().trim_prefix('"').trim_suffix('"')
CodeCompletionHelper.suggest_portraits(TextNode, completion_character)
if not ':' in line.substr(0, TextNode.get_caret_column()) and symbol == '(':
var completion_character := completion_text_character_getter_regex.search(line).get_string().trim_prefix('"').trim_suffix('"')
CodeCompletionHelper.suggest_portraits(TextNode, completion_character)
if symbol == '[':
suggest_bbcode(TextNode)
for effect in completion_text_effects.values():
if effect.get('arg', false):
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, effect.command, effect.command+'=', TextNode.syntax_highlighter.normal_color, TextNode.get_theme_icon("RichTextEffect", "EditorIcons"))
else:
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, effect.command, effect.command, TextNode.syntax_highlighter.normal_color, TextNode.get_theme_icon("RichTextEffect", "EditorIcons"), ']')
if symbol == '[':
suggest_bbcode(TextNode)
for effect in completion_text_effects.values():
if effect.get('arg', false):
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, effect.command, effect.command+'=', TextNode.syntax_highlighter.normal_color, TextNode.get_theme_icon("RichTextEffect", "EditorIcons"))
else:
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, effect.command, effect.command, TextNode.syntax_highlighter.normal_color, TextNode.get_theme_icon("RichTextEffect", "EditorIcons"), ']')
if symbol == '{':
CodeCompletionHelper.suggest_variables(TextNode)
if symbol == '{':
CodeCompletionHelper.suggest_variables(TextNode)
if symbol == '=':
if CodeCompletionHelper.get_line_untill_caret(line).ends_with('[portrait='):
var completion_character := completion_text_character_getter_regex.search(line).get_string('name')
CodeCompletionHelper.suggest_portraits(TextNode, completion_character, ']')
if symbol == '=':
if CodeCompletionHelper.get_line_untill_caret(line).ends_with('[portrait='):
var completion_character := completion_text_character_getter_regex.search(line).get_string('name')
CodeCompletionHelper.suggest_portraits(TextNode, completion_character, ']')
func _get_start_code_completion(CodeCompletionHelper:Node, TextNode:TextEdit) -> void:
CodeCompletionHelper.suggest_characters(TextNode, CodeEdit.KIND_CLASS, self)
CodeCompletionHelper.suggest_characters(TextNode, CodeEdit.KIND_CLASS, self)
func suggest_bbcode(TextNode:CodeEdit):
for i in [['b (bold)', 'b'], ['i (italics)', 'i'], ['color', 'color='], ['font size','font_size=']]:
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, i[0], i[1], TextNode.syntax_highlighter.normal_color, TextNode.get_theme_icon("RichTextEffect", "EditorIcons"),)
TextNode.add_code_completion_option(CodeEdit.KIND_CLASS, 'end '+i[0], '/'+i[1], TextNode.syntax_highlighter.normal_color, TextNode.get_theme_icon("RichTextEffect", "EditorIcons"), ']')
for i in [['new event', 'n'],['new event (same box)', 'n+']]:
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, i[0], i[1], TextNode.syntax_highlighter.normal_color, TextNode.get_theme_icon("ArrowRight", "EditorIcons"),)
for i in [['b (bold)', 'b'], ['i (italics)', 'i'], ['color', 'color='], ['font size','font_size=']]:
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, i[0], i[1], TextNode.syntax_highlighter.normal_color, TextNode.get_theme_icon("RichTextEffect", "EditorIcons"),)
TextNode.add_code_completion_option(CodeEdit.KIND_CLASS, 'end '+i[0], '/'+i[1], TextNode.syntax_highlighter.normal_color, TextNode.get_theme_icon("RichTextEffect", "EditorIcons"), ']')
for i in [['new event', 'n'],['new event (same box)', 'n+']]:
TextNode.add_code_completion_option(CodeEdit.KIND_MEMBER, i[0], i[1], TextNode.syntax_highlighter.normal_color, TextNode.get_theme_icon("ArrowRight", "EditorIcons"),)
#endregion
@@ -496,56 +496,56 @@ func suggest_bbcode(TextNode:CodeEdit):
var text_effects := ""
var text_effects_regex := RegEx.new()
func load_text_effects() -> void:
if text_effects.is_empty():
for idx in DialogicUtil.get_indexers():
for effect in idx._get_text_effects():
text_effects+= effect['command']+'|'
text_effects += "b|i|u|s|code|p|center|left|right|fill|n\\+|n|indent|url|img|font|font_size|opentype_features|color|bg_color|fg_color|outline_size|outline_color|table|cell|ul|ol|lb|rb|br"
if text_effects_regex.get_pattern().is_empty():
text_effects_regex.compile("(?<!\\\\)\\[\\s*/?(?<command>"+text_effects+")\\s*(=\\s*(?<value>.+?)\\s*)?\\]")
if text_effects.is_empty():
for idx in DialogicUtil.get_indexers():
for effect in idx._get_text_effects():
text_effects+= effect['command']+'|'
text_effects += "b|i|u|s|code|p|center|left|right|fill|n\\+|n|indent|url|img|font|font_size|opentype_features|color|bg_color|fg_color|outline_size|outline_color|table|cell|ul|ol|lb|rb|br"
if text_effects_regex.get_pattern().is_empty():
text_effects_regex.compile("(?<!\\\\)\\[\\s*/?(?<command>"+text_effects+")\\s*(=\\s*(?<value>.+?)\\s*)?\\]")
var text_random_word_regex := RegEx.new()
var text_effect_color := Color('#898276')
func _get_syntax_highlighting(Highlighter:SyntaxHighlighter, dict:Dictionary, line:String) -> Dictionary:
load_text_effects()
if text_random_word_regex.get_pattern().is_empty():
text_random_word_regex.compile(r"(?<!\\)\<[^\>]+(\/[^\>]*)\>")
load_text_effects()
if text_random_word_regex.get_pattern().is_empty():
text_random_word_regex.compile(r"(?<!\\)\<[^\>]+(\/[^\>]*)\>")
var result := regex.search(line)
if not result:
return dict
if Highlighter.mode == Highlighter.Modes.FULL_HIGHLIGHTING:
if result.get_string('name'):
dict[result.get_start('name')] = {"color":Highlighter.character_name_color}
dict[result.get_end('name')] = {"color":Highlighter.normal_color}
if result.get_string('portrait'):
dict[result.get_start('portrait')] = {"color":Highlighter.character_portrait_color}
dict[result.get_end('portrait')] = {"color":Highlighter.normal_color}
if result.get_string('text'):
var result := regex.search(line)
if not result:
return dict
if Highlighter.mode == Highlighter.Modes.FULL_HIGHLIGHTING:
if result.get_string('name'):
dict[result.get_start('name')] = {"color":Highlighter.character_name_color}
dict[result.get_end('name')] = {"color":Highlighter.normal_color}
if result.get_string('portrait'):
dict[result.get_start('portrait')] = {"color":Highlighter.character_portrait_color}
dict[result.get_end('portrait')] = {"color":Highlighter.normal_color}
if result.get_string('text'):
## Color the random selection modifier
for replace_mod_match in text_random_word_regex.search_all(result.get_string('text')):
var color: Color = Highlighter.string_color
color = color.lerp(Highlighter.normal_color, 0.4)
dict[replace_mod_match.get_start()+result.get_start('text')] = {'color':Highlighter.string_color}
var offset := 1
for b:RegExMatch in RegEx.create_from_string(r"(\[[^\]]*\]|[^\/]|\/\/)+").search_all(replace_mod_match.get_string().trim_prefix("<").trim_suffix(">")):
color.h = wrap(color.h+0.2, 0, 1)
dict[replace_mod_match.get_start()+result.get_start('text')+offset] = {'color':color}
offset += len(b.get_string())
dict[replace_mod_match.get_start()+result.get_start('text')+offset] = {'color':Highlighter.string_color}
offset += 1
dict[replace_mod_match.get_end()+result.get_start('text')] = {'color':Highlighter.normal_color}
## Color the random selection modifier
for replace_mod_match in text_random_word_regex.search_all(result.get_string('text')):
var color: Color = Highlighter.string_color
color = color.lerp(Highlighter.normal_color, 0.4)
dict[replace_mod_match.get_start()+result.get_start('text')] = {'color':Highlighter.string_color}
var offset := 1
for b:RegExMatch in RegEx.create_from_string(r"(\[[^\]]*\]|[^\/]|\/\/)+").search_all(replace_mod_match.get_string().trim_prefix("<").trim_suffix(">")):
color.h = wrap(color.h+0.2, 0, 1)
dict[replace_mod_match.get_start()+result.get_start('text')+offset] = {'color':color}
offset += len(b.get_string())
dict[replace_mod_match.get_start()+result.get_start('text')+offset] = {'color':Highlighter.string_color}
offset += 1
dict[replace_mod_match.get_end()+result.get_start('text')] = {'color':Highlighter.normal_color}
## Color bbcode and text effects
var effects_result := text_effects_regex.search_all(line)
for eff in effects_result:
var prev_color: Color = Highlighter.dict_get_color_at_column(dict, eff.get_start())
dict[eff.get_start()] = {"color":text_effect_color.lerp(prev_color, 0.4)}
dict[eff.get_end()] = {"color":prev_color}
dict = Highlighter.color_region(dict, Highlighter.variable_color, line, '{', '}', result.get_start('text'))
## Color bbcode and text effects
var effects_result := text_effects_regex.search_all(line)
for eff in effects_result:
var prev_color: Color = Highlighter.dict_get_color_at_column(dict, eff.get_start())
dict[eff.get_start()] = {"color":text_effect_color.lerp(prev_color, 0.4)}
dict[eff.get_end()] = {"color":prev_color}
dict = Highlighter.color_region(dict, Highlighter.variable_color, line, '{', '}', result.get_start('text'))
return dict
return dict
#endregion
+13
View File
@@ -0,0 +1,13 @@
[gd_resource type="StandardMaterial3D" format=3 uid="uid://dvvi1k5c5iowc"]
[ext_resource type="Texture2D" uid="uid://dlsx1mofjccib" path="res://common/assets/textures/3d_texture.png" id="1_cc1ni"]
[resource]
diffuse_mode = 3
specular_mode = 2
albedo_texture = ExtResource("1_cc1ni")
roughness = 0.0
rim_tint = 0.48
stencil_flags = 2
stencil_reference = 5
stencil_outline_thickness = 0.626
+9
View File
@@ -0,0 +1,9 @@
[gd_resource type="StandardMaterial3D" format=3 uid="uid://b5vlcdry8vtgi"]
[ext_resource type="Texture2D" uid="uid://dlsx1mofjccib" path="res://common/assets/textures/3d_texture.png" id="1_buts1"]
[resource]
transparency = 1
depth_draw_mode = 1
albedo_color = Color(1, 1, 1, 0.79607844)
albedo_texture = ExtResource("1_buts1")
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -0,0 +1,41 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dlsx1mofjccib"
path.s3tc="res://.godot/imported/3d_texture.png-5d7cb2d23d37985e4dc0c0bd241d8e43.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://common/assets/textures/3d_texture.png"
dest_files=["res://.godot/imported/3d_texture.png-5d7cb2d23d37985e4dc0c0bd241d8e43.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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=0
Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

@@ -0,0 +1,41 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dc8gajse5ti5t"
path.s3tc="res://.godot/imported/dither_texture.jpg-29df728b3fc6c30c4db6300481aaf214.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://common/assets/textures/dither_texture.jpg"
dest_files=["res://.godot/imported/dither_texture.jpg-29df728b3fc6c30c4db6300481aaf214.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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=0
@@ -12,7 +12,7 @@ dest_files=["res://.godot/imported/ambiance_Demeter.ogg-ee9f7eeda2d23a3915bf6592
[params]
loop=false
loop=true
loop_offset=0
bpm=0
beat_count=0
@@ -0,0 +1,19 @@
[remap]
importer="oggvorbisstr"
type="AudioStreamOggVorbis"
uid="uid://d3jou8c7c536c"
path="res://.godot/imported/ship_ambience.ogg-e3739ef3659489a38bbb2970034a7b9a.oggvorbisstr"
[deps]
source_file="res://common/audio_manager/assets/ambiance/vaisseau/ship_ambience.ogg"
dest_files=["res://.godot/imported/ship_ambience.ogg-e3739ef3659489a38bbb2970034a7b9a.oggvorbisstr"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4
@@ -2,7 +2,7 @@
importer="oggvorbisstr"
type="AudioStreamOggVorbis"
uid="uid://brtjlgjqnrvcb"
uid="uid://dadg6o6dl2k6t"
path="res://.godot/imported/truck_music.ogg-71e4f19f9a59a19e62e72df06380f7df.oggvorbisstr"
[deps]
@@ -12,8 +12,8 @@ dest_files=["res://.godot/imported/truck_music.ogg-71e4f19f9a59a19e62e72df06380f
[params]
loop=true
loop_offset=0.0
bpm=0.0
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4
@@ -0,0 +1,19 @@
[remap]
importer="oggvorbisstr"
type="AudioStreamOggVorbis"
uid="uid://b1hut6lc1jevh"
path="res://.godot/imported/mines_phase_2.ogg-3c0a31b97007a40bd6aa91f1f208f9d3.oggvorbisstr"
[deps]
source_file="res://common/audio_manager/assets/morceaux/niveau_v2/mines_phase_2.ogg"
dest_files=["res://.godot/imported/mines_phase_2.ogg-3c0a31b97007a40bd6aa91f1f208f9d3.oggvorbisstr"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4
@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://dsrft8ing7qwj"
path="res://.godot/imported/closing_transmission.wav-2a60c34966d2ae692c46d5740f5d3f94.sample"
[deps]
source_file="res://common/audio_manager/assets/sfx/dialogs/sfx/closing_transmission.wav"
dest_files=["res://.godot/imported/closing_transmission.wav-2a60c34966d2ae692c46d5740f5d3f94.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=2
@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://c8cwobmqg80dw"
path="res://.godot/imported/deactivation.wav-f941c93b81a553c4a9b003d564a3ce38.sample"
[deps]
source_file="res://common/audio_manager/assets/sfx/dialogs/sfx/deactivation.wav"
dest_files=["res://.godot/imported/deactivation.wav-f941c93b81a553c4a9b003d564a3ce38.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=2
@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://dk87b7iet1sae"
path="res://.godot/imported/incoming_transmission.wav-636f576bb9d1fcafc6fd9813344a7a1f.sample"
[deps]
source_file="res://common/audio_manager/assets/sfx/dialogs/sfx/incoming_transmission.wav"
dest_files=["res://.godot/imported/incoming_transmission.wav-636f576bb9d1fcafc6fd9813344a7a1f.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=2
@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://ocm1dkkhv7ls"
path="res://.godot/imported/phone_ringing.wav-a6cb60c7f7d9ed8d10532f5bd69157cf.sample"
[deps]
source_file="res://common/audio_manager/assets/sfx/phone/phone_ringing.wav"
dest_files=["res://.godot/imported/phone_ringing.wav-a6cb60c7f7d9ed8d10532f5bd69157cf.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=2
edit/loop_begin=0
edit/loop_end=-1
compress/mode=2
Binary file not shown.
@@ -0,0 +1,19 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://c5y70k3codtn"
path="res://.godot/imported/signal.mp3-2f41c9334233d52845bfe384d47f2a96.mp3str"
[deps]
source_file="res://common/audio_manager/assets/sfx/signal/signal.mp3"
dest_files=["res://.godot/imported/signal.mp3-2f41c9334233d52845bfe384d47f2a96.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4
+32 -34
View File
@@ -1,18 +1,18 @@
[gd_scene load_steps=30 format=3 uid="uid://b6hscxcrj065q"]
[gd_scene format=3 uid="uid://b6hscxcrj065q"]
[ext_resource type="Script" uid="uid://2p5d6vogtn82" path="res://common/audio_manager/scripts/audio_manager.gd" id="1_0tvca"]
[ext_resource type="AudioStream" uid="uid://dipnmlprwfo12" path="res://common/audio_manager/assets/ambiance/niveau/ambiance_phase_1.ogg" id="2_a4u5m"]
[ext_resource type="AudioStream" uid="uid://bm0tdi6bd2e65" path="res://common/audio_manager/assets/ambiance/niveau/ambiance_phase_2.ogg" id="3_8nsyr"]
[ext_resource type="AudioStream" uid="uid://dftxjfdqgsbd3" path="res://common/audio_manager/assets/ambiance/niveau/ambiance_phase_3.ogg" id="4_athui"]
[ext_resource type="AudioStream" uid="uid://dipnmlprwfo12" path="res://common/audio_manager/assets/ambiance/niveau/ambiance_phase_1.ogg" id="2_tuvql"]
[ext_resource type="AudioStream" uid="uid://dcbuhtc085q2x" path="res://common/audio_manager/assets/morceaux/niveau_v2/mines_phase_1.ogg" id="5_ajci6"]
[ext_resource type="AudioStream" uid="uid://bqwiaek5b5q00" path="res://common/audio_manager/assets/morceaux/niveau/forest_phase_2.ogg" id="6_ldyhq"]
[ext_resource type="AudioStream" uid="uid://d4lqhgf0lhgge" path="res://common/audio_manager/assets/morceaux/niveau/forest_phase_3.ogg" id="7_ol34x"]
[ext_resource type="AudioStream" uid="uid://brtjlgjqnrvcb" path="res://common/audio_manager/assets/morceaux/autres/truck_music.ogg" id="8_0e5ja"]
[ext_resource type="AudioStream" uid="uid://bpf6witukorka" path="res://common/audio_manager/assets/morceaux/autres/main_menu.ogg" id="7_tuvql"]
[ext_resource type="AudioStream" uid="uid://dadg6o6dl2k6t" path="res://common/audio_manager/assets/morceaux/autres/truck_music.ogg" id="8_0e5ja"]
[ext_resource type="AudioStream" uid="uid://bnxsnege8qq6e" path="res://common/audio_manager/assets/morceaux/niveau/forest_phase_4.ogg" id="8_ajci6"]
[ext_resource type="AudioStream" uid="uid://dfrp66a4isnt6" path="res://common/audio_manager/assets/sfx/dig/dig_1.wav" id="9_gv65y"]
[ext_resource type="AudioStream" uid="uid://bdxkvaciw4mb3" path="res://common/audio_manager/assets/sfx/dig/dig_2.wav" id="10_n7o7n"]
[ext_resource type="AudioStream" uid="uid://llxrlwfccywb" path="res://common/audio_manager/assets/sfx/dig/dig_3.wav" id="11_wtvls"]
[ext_resource type="AudioStream" uid="uid://b8inedx4yjslw" path="res://common/audio_manager/assets/sfx/drop/drop_1.wav" id="12_4hp8f"]
[ext_resource type="AudioStream" uid="uid://c5y70k3codtn" path="res://common/audio_manager/assets/sfx/signal/signal.mp3" id="12_ajci6"]
[ext_resource type="AudioStream" uid="uid://8nmr5vifkt1f" path="res://common/audio_manager/assets/sfx/harvest/harvest_1.wav" id="13_xoaox"]
[ext_resource type="AudioStream" uid="uid://dgkdcq4j6fe3o" path="res://common/audio_manager/assets/sfx/harvest/harvest_2.wav" id="14_b5bgj"]
[ext_resource type="AudioStream" uid="uid://eh3dbuxu5qtw" path="res://common/audio_manager/assets/sfx/harvest/harvest_3.wav" id="15_ynvb4"]
@@ -24,15 +24,6 @@
[ext_resource type="AudioStream" uid="uid://d1cpi438ep0ys" path="res://common/audio_manager/assets/sfx/announce/annnounce.wav" id="22_btfwx"]
[ext_resource type="AudioStream" uid="uid://ccq04ahrwr3bv" path="res://common/audio_manager/assets/sfx/alarm/alarm.wav" id="23_fwu3w"]
[sub_resource type="AudioStreamSynchronized" id="AudioStreamSynchronized_i5lxw"]
stream_count = 3
stream_0/stream = ExtResource("2_a4u5m")
stream_0/volume = 0.0
stream_1/stream = ExtResource("3_8nsyr")
stream_1/volume = -60.0
stream_2/stream = ExtResource("4_athui")
stream_2/volume = -60.0
[sub_resource type="AudioStreamPlaylist" id="AudioStreamPlaylist_ajci6"]
stream_count = 4
stream_0 = ExtResource("5_ajci6")
@@ -46,6 +37,11 @@ stream_0/stream = ExtResource("9_gv65y")
stream_1/stream = ExtResource("10_n7o7n")
stream_2/stream = ExtResource("11_wtvls")
[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_8204s"]
random_pitch = 1.0594631
streams_count = 1
stream_0/stream = ExtResource("12_ajci6")
[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_1w04j"]
random_pitch = 1.2
streams_count = 1
@@ -66,53 +62,55 @@ streams_count = 2
stream_0/stream = ExtResource("20_pu6t4")
stream_1/stream = ExtResource("21_dk5s6")
[node name="AudioManager" type="Node" node_paths=PackedStringArray("playing_soundtracks")]
[node name="AudioManager" type="Node" unique_id=1871137180]
process_mode = 3
script = ExtResource("1_0tvca")
default_fade_time = 2.0
garden_phases_scores = Array[int]([0, 10, 30])
playing_soundtracks = [NodePath("Ambiance/Default")]
[node name="Ambiance" type="Node" parent="."]
[node name="Ambiance" type="Node" parent="." unique_id=1989991562]
unique_name_in_owner = true
[node name="Default" type="AudioStreamPlayer" parent="Ambiance"]
[node name="Exterior" type="AudioStreamPlayer" parent="Ambiance" unique_id=1405716780]
unique_name_in_owner = true
stream = SubResource("AudioStreamSynchronized_i5lxw")
autoplay = true
stream = ExtResource("2_tuvql")
[node name="Musics" type="Node" parent="."]
[node name="Musics" type="Node" parent="." unique_id=1450527710]
unique_name_in_owner = true
[node name="Planet" type="AudioStreamPlayer" parent="Musics"]
[node name="Region" type="AudioStreamPlayer" parent="Musics" unique_id=1029114070]
unique_name_in_owner = true
stream = SubResource("AudioStreamPlaylist_ajci6")
autoplay = true
[node name="Truck" type="AudioStreamPlayer" parent="Musics"]
[node name="Title" type="AudioStreamPlayer" parent="Musics" unique_id=2105759422]
unique_name_in_owner = true
stream = ExtResource("7_tuvql")
bus = &"Music"
[node name="Truck" type="AudioStreamPlayer" parent="Musics" unique_id=1165150318]
unique_name_in_owner = true
stream = ExtResource("8_0e5ja")
autoplay = true
[node name="Sfx" type="Node" parent="."]
[node name="Sfx" type="Node" parent="." unique_id=2023641207]
unique_name_in_owner = true
[node name="Dig" type="AudioStreamPlayer" parent="Sfx"]
[node name="Dig" type="AudioStreamPlayer" parent="Sfx" unique_id=486042600]
stream = SubResource("AudioStreamRandomizer_kfbah")
[node name="Drop" type="AudioStreamPlayer" parent="Sfx"]
[node name="Signal" type="AudioStreamPlayer" parent="Sfx" unique_id=641246368]
stream = SubResource("AudioStreamRandomizer_8204s")
[node name="Drop" type="AudioStreamPlayer" parent="Sfx" unique_id=1391500830]
stream = SubResource("AudioStreamRandomizer_1w04j")
[node name="Harvest" type="AudioStreamPlayer" parent="Sfx"]
[node name="Harvest" type="AudioStreamPlayer" parent="Sfx" unique_id=345539331]
stream = SubResource("AudioStreamRandomizer_i4m0x")
[node name="PickUp" type="AudioStreamPlayer" parent="Sfx"]
[node name="PickUp" type="AudioStreamPlayer" parent="Sfx" unique_id=176915166]
stream = SubResource("AudioStreamRandomizer_jjdv2")
volume_db = -10.0
[node name="Announce" type="AudioStreamPlayer" parent="Sfx"]
[node name="Announce" type="AudioStreamPlayer" parent="Sfx" unique_id=876644323]
stream = ExtResource("22_btfwx")
volume_db = 8.627
[node name="Alarm" type="AudioStreamPlayer" parent="Sfx"]
[node name="Alarm" type="AudioStreamPlayer" parent="Sfx" unique_id=689347925]
stream = ExtResource("23_fwu3w")
+180 -114
View File
@@ -3,136 +3,202 @@ extends Node
const MIN_VOLUME = -60.
const MAX_VOLUME = 24.
@onready var settings : SettingsData = GameInfo.game_data.settings
const DEFAULT_FADE_TIME : float = 0.5
@export var default_fade_time = 1.0
@onready var settings : SettingsData = GameInfo.settings_data
@export var garden_phase = 0
@export var garden_phases_scores : Array[int]
@export var playing_soundtracks : Array[AudioStreamPlayer] = []
var music_action : AudioAction
var ambiance_action : AudioAction
var playing_music : AudioStreamPlayer = null
var playing_ambiance : AudioStreamPlayer = null
var default_volumes := {}
func _ready():
GameInfo.game_data.current_planet_data_updated.connect(_on_current_planet_data_updated)
fetch_default_volumes()
setup_volume()
settings.sound_changed.connect(
func(_s) : setup_volume()
)
for player in get_all_soundtrack_players():
player.play()
for player in get_all_players():
player.stop()
fetch_default_volumes()
# setup_players_bus()
settings.sound_changed.connect(
func(_s) : setup_players_bus()
)
SceneManager.scene_loaded.connect(_on_change_scene)
Dialogic.timeline_started.connect(_on_timeline_started)
Dialogic.timeline_ended.connect(_on_timeline_ended)
func _process(_d):
if music_action:
playing_music = process_audio_action(
music_action,
%Musics,
playing_music
)
music_action = null
if ambiance_action:
playing_ambiance = process_audio_action(
ambiance_action,
%Ambiance,
playing_ambiance
)
ambiance_action = null
func process_audio_action(
audio_action : AudioAction,
player_search_node: Node,
current_player: AudioStreamPlayer = null
) -> AudioStreamPlayer:
if audio_action is AudioLaunch:
return process_audio_launch(audio_action, player_search_node, current_player)
elif audio_action is AudioStop and current_player and current_player.playing:
stop_player(current_player)
return null
func process_audio_launch(
audio_launch : AudioLaunch,
player_search_node: Node,
current_player: AudioStreamPlayer = null,
) -> AudioStreamPlayer:
var player = player_search_node.find_child(audio_launch.player_name)
if not player:
printerr("Player %s not found in category %s" % [audio_launch.player_name, player_search_node.name])
return null
if current_player and current_player.playing and current_player.name == audio_launch.player_name:
return current_player
elif current_player:
stop_player(current_player)
start_player(player, audio_launch.from_random_time, audio_launch.fade_time)
return player
func _on_change_scene(scene : Scene):
stop_ambiance()
match scene.scene_id:
"TITLE":
play_music("Title", false, 0.0)
"REGION":
play_music("Region", true)
play_ambiance("Exterior", true)
"COCKPIT":
play_music("Truck", true)
func _on_timeline_started():
var timeline_name = Dialogic.current_timeline.resource_path.split("/")[-1].trim_suffix(".dtl")
# Timeline name et le nom du fichier de timeline, par exemple demeter_intro
# Amuse toi Nilou ;)
func _on_timeline_ended():
_on_change_scene(SceneManager.actual_scene)
func play_music(player_name : String = "", from_random_time := false, fade_time := DEFAULT_FADE_TIME):
music_action = AudioLaunch.new(
player_name,
from_random_time,
fade_time
)
func stop_music():
music_action = AudioStop.new()
func play_ambiance(player_name : String = "", from_random_time := false, fade_time := DEFAULT_FADE_TIME):
ambiance_action = AudioLaunch.new(
player_name,
from_random_time,
fade_time
)
func stop_ambiance():
ambiance_action = AudioStop.new()
func fetch_default_volumes():
var all_players := get_all_soundtrack_players()
all_players.append_array(get_all_sfx_players())
var all_players := get_all_players()
for player in all_players:
default_volumes[player] = player.volume_db
for player in all_players:
default_volumes[player] = player.volume_db
func setup_volume():
for player in get_all_soundtrack_players():
player.volume_db = get_volume_from_parent(player) if (
playing_soundtracks.find(player) != -1
) else MIN_VOLUME
setup_phase(player)
for player in get_all_sfx_players():
player.volume_db = get_volume_from_parent(player)
func setup_players_bus():
for player in get_all_players():
if player.get_parent() == %Musics:
player.bus = (AudioServer.get_bus_name(SettingsData.MUSIC_BUS_ID))
elif player.get_parent() == %Sfx:
player.bus = (AudioServer.get_bus_name(SettingsData.SFX_BUS_ID))
elif player.get_parent() == %Ambiance:
player.bus = (AudioServer.get_bus_name(SettingsData.AMBIANCE_BUS_ID))
func get_volume_from_parent(player : AudioStreamPlayer) -> float:
var settings_volume = 0.5
func get_volume(player : AudioStreamPlayer) -> float:
return default_volumes[player]
if player.get_parent() == %Ambiance:
settings_volume = settings.ambiance_volume
elif player.get_parent() == %Sfx:
settings_volume = settings.sfx_volume
elif player.get_parent() == %Musics:
settings_volume = settings.music_volume
func get_all_players() -> Array[AudioStreamPlayer]:
var players : Array[AudioStreamPlayer] = []
players.append_array(get_players_from_node(%Musics))
players.append_array(get_players_from_node(%Ambiance))
players.append_array(get_players_from_node(%Sfx))
return default_volumes[player] + lerp(MIN_VOLUME, MAX_VOLUME, settings_volume)
func update_phase():
for player in get_all_soundtrack_players():
var playing : bool = player.volume_db != MIN_VOLUME
if playing:
await set_volume(player, MIN_VOLUME).finished
setup_phase(player)
if playing:
set_volume(player, get_volume_from_parent(player))
func get_all_soundtrack_players() -> Array[AudioStreamPlayer]:
var players : Array[AudioStreamPlayer] = []
players.append_array(get_players_from_node(%Musics))
players.append_array(get_players_from_node(%Ambiance))
return players
func get_all_sfx_players() -> Array[AudioStreamPlayer]:
return get_players_from_node(%Sfx)
return players
func get_players_from_node(node : Node) -> Array[AudioStreamPlayer]:
var streams : Array[AudioStreamPlayer] = []
var streams : Array[AudioStreamPlayer] = []
for c in node.get_children():
if c is AudioStreamPlayer:
streams.append(c)
return streams
for c in node.get_children():
if c is AudioStreamPlayer:
streams.append(c)
return streams
func set_volume(player : AudioStreamPlayer, to : float, fade_time := 0.0) -> Tween:
var fade_tween : Tween = get_tree().create_tween()
fade_tween.tween_property(player, "volume_db", to, fade_time)
return fade_tween
func start_player(player: AudioStreamPlayer, from_random_time = false, fade_time = DEFAULT_FADE_TIME):
if player and not player.playing:
player.play(
0.0 if not from_random_time
else randf_range(0.0, player.stream.get_length())
)
if fade_time > 0.0:
player.volume_db = MIN_VOLUME
await set_volume(player, get_volume(player), fade_time).finished
func stop_player(player : AudioStreamPlayer, fade_time = DEFAULT_FADE_TIME):
if player and player.playing:
if fade_time > 0.0:
await set_volume(player, MIN_VOLUME, fade_time).finished
player.stop()
player.volume_db = get_volume(player)
func reset_volume(player : AudioStreamPlayer):
player.volume_db = get_volume(player)
func play_sfx(sfx_name : String):
var player := %Sfx.find_child(sfx_name) as AudioStreamPlayer
if player:
player.play()
else:
printerr("Sfx %s not found" % sfx_name)
class AudioAction:
pass
class AudioLaunch extends AudioAction:
var player_name : String
var from_random_time : bool
var fade_time : float
func _init(
_player_name : String,
_from_random_time := false,
_fade_time := DEFAULT_FADE_TIME,
):
player_name = _player_name
from_random_time = _from_random_time
fade_time = _fade_time
func _on_current_planet_data_updated(planet_data : PlanetData):
if planet_data:
update_garden_phase(planet_data)
planet_data.updated.connect(update_garden_phase)
func update_garden_phase(planet_data : PlanetData):
var phase : int = garden_phase
for i in range(len(garden_phases_scores)):
if planet_data.garden_score >= garden_phases_scores[i] and i > garden_phase:
phase = i
if garden_phase != phase:
update_phase()
garden_phase = phase
func enter_planet():
play_music(%Planet, true)
stop_music(%Truck, true)
func enter_truck():
play_music(%Truck, true)
stop_music(%Planet, true)
func stop_music(music : AudioStreamPlayer, with_fade = false):
if playing_soundtracks.find(music) != -1:
playing_soundtracks.remove_at(playing_soundtracks.find(music))
set_volume(music, MIN_VOLUME, with_fade)
func play_music(player : AudioStreamPlayer, with_fade = false):
playing_soundtracks.append(player)
set_volume(player, get_volume_from_parent(player), with_fade)
func setup_phase(music : AudioStreamPlayer):
if music.stream is AudioStreamSynchronized:
var sync_stream = music.stream as AudioStreamSynchronized
var phase_stream_id = min(garden_phase, sync_stream.stream_count - 1)
for i in range(sync_stream.stream_count):
sync_stream.set_sync_stream_volume(
i,
0. if i == phase_stream_id else MIN_VOLUME
)
func set_volume(music : AudioStreamPlayer, to : float, fade_time = default_fade_time) -> Tween:
var fade_tween : Tween = get_tree().create_tween()
fade_tween.tween_property(music, "volume_db", to, fade_time)
return fade_tween
func play_sfx(name : String):
var player := %Sfx.find_child(name) as AudioStreamPlayer
if player:
player.play()
else:
printerr("Sfx %s not found" % name)
class AudioStop extends AudioAction:
pass
+39 -81
View File
@@ -1,100 +1,58 @@
extends Resource
class_name GameData
signal current_planet_data_updated(p : PlanetData)
signal current_region_data_updated(p : RegionData)
func _init():
set_default_unlocked()
@export var current_run : RunData = null
@export var tutorial_done = false
@export var settings : SettingsData = SettingsData.new()
@export var current_run : RunData = RunData.new()
@export var current_planet_data : PlanetData : get = get_current_planet_data
@export var current_region_data : RegionData = null
@export var player_data : PlayerData = PlayerData.new()
@export var unlocked_plant_types : Array[PlantType] = []
@export var unlocked_plant_mutations : Array[PlantMutation] = []
@export var unlocked_machines : Array[MachineType] = []
@export var max_mutations_by_plant : int = 2
@export var truck_data : TruckData = TruckData.new()
@export var last_game_scene : Scene = null
func _ready():
current_run.run_point_changed.connect(
func(): current_planet_data_updated.emit(get_current_planet_data)
)
@export var ship_in_space = false
func set_default_unlocked():
unlocked_plant_types = all_plant_types()
unlocked_plant_mutations = all_plant_mutations()
unlocked_machines = all_machines()
@export var tutorial_done = false
func reset_run():
current_run = RunData.new()
current_planet_data_updated.emit()
@export var incubator_used = []
@export var dialogs_done : Array[String] = [] #Chemin des dialogues démarrés
func start_run():
player_data.inventory.clear_items()
current_run = RunData.new()
current_run.current_run_point_changed.connect(
func(rp : RunPoint):
start_region(rp.region_parameter)
)
func reset_player():
player_data = PlayerData.new()
func reset_truck():
truck_data = TruckData.new()
player_data = PlayerData.new()
func reset_all():
reset_run()
reset_player()
reset_truck()
start_run()
reset_player()
unlocked_plant_types = []
func start_region(region_param : RegionParameter):
current_region_data = RegionData.new(region_param)
current_region_data_updated.emit(current_region_data)
GameInfo.save_game_data()
func unlock_plant_type(new_plant_type : PlantType):
if not is_plant_type_unlocked(new_plant_type):
unlocked_plant_types.append(new_plant_type.duplicate_deep())
func give_up():
current_region_data = null
current_run = null
func get_locked_plant_types() -> Array[PlantType]:
var locked_plant_type : Array[PlantType] = []
for pt in GameInfo.game_data.all_plant_types():
if not is_plant_type_unlocked(pt):
locked_plant_type.append(pt)
return locked_plant_type
func get_current_planet_data():
return current_run.get_current_planet_data()
func is_plant_type_unlocked(new_plant_type : PlantType):
return unlocked_plant_types.find_custom(
func (upt : PlantType): return new_plant_type.name == upt.name
) != -1
func all_plant_types() -> Array[PlantType]:
return [
preload("res://entities/plants/resources/plant_types/champ.tres"),
preload("res://entities/plants/resources/plant_types/chardi.tres"),
preload("res://entities/plants/resources/plant_types/ferno.tres"),
preload("res://entities/plants/resources/plant_types/maias.tres"),
preload("res://entities/plants/resources/plant_types/philea.tres"),
preload("res://entities/plants/resources/plant_types/pili.tres"),
preload("res://entities/plants/resources/plant_types/solita.tres"),
]
func all_machines() -> Array[MachineType]:
return [
preload("res://entities/interactables/machines/solar_pannel/solar_pannel.tres"),
]
func all_plant_mutations() -> Array[PlantMutation]:
return [
preload("res://entities/plants/resources/plant_mutations/ancient_mutation.tres"),
preload("res://entities/plants/resources/plant_mutations/elitist_mutation.tres"),
preload("res://entities/plants/resources/plant_mutations/ermit_mutation.tres"),
preload("res://entities/plants/resources/plant_mutations/precocious_mutation.tres"),
preload("res://entities/plants/resources/plant_mutations/quality_mutation.tres"),
preload("res://entities/plants/resources/plant_mutations/quick_mutation.tres"),
preload("res://entities/plants/resources/plant_mutations/sociable_mutation.tres"),
preload("res://entities/plants/resources/plant_mutations/strong_mutation.tres"),
]
func start_tutorial():
current_region_data = RegionData.new(
RegionParameter.new(
10,
3,
tr("TUTORIAL"),
true,
0,
randi()
)
)
+42 -32
View File
@@ -1,22 +1,27 @@
extends Resource
class_name RunData
const RUN_POINT_POSITION_DERIVATION = 70
const DIFFICULTY_INCREASE_BY_LEVEL = 1
const RUN_POINTS_NEXT_NUMBER :Array[int] = [2,3]
const RUN_POINT_MAX_LEVEL = 10
enum State {STARTED, IN_PROGRESS, FINISHED}
signal run_point_changed
const RUN_POINT_POSITION_DERIVATION = 100
const DIFFICULTY_INCREASE_BY_LEVEL = 1
const RUN_POINTS_NEXT_NUMBER :Array[int] = [2]
const RUN_POINT_MAX_LEVEL = 6
signal current_run_point_changed
var run_seed = randi()
@export var next_run_points : Array[RunPoint] = [generate_first_run_point()]
@export var current_run_point : RunPoint = null
@export var current_run_point : RunPoint = null :
set(v):
current_run_point = v
current_run_point_changed.emit(v)
@export var visited_run_points : Array[RunPoint] = []
#region ------------------ Generation ------------------
func generate_first_run_point() -> RunPoint:
return RunPoint.new(0, PlanetParameter.new())
return RunPoint.new(0, RegionParameter.new())
func generate_next_run_points(run_point : RunPoint) -> Array[RunPoint]:
var nb_next_run_points = RUN_POINTS_NEXT_NUMBER.pick_random()
@@ -38,18 +43,18 @@ func generate_next_run_points(run_point : RunPoint) -> Array[RunPoint]:
func generate_next_run_point(run_point : RunPoint) -> RunPoint:
return RunPoint.new(
run_point.level + 1,
generate_difficulty_increased_planet_parameter(run_point.planet_parameter, DIFFICULTY_INCREASE_BY_LEVEL),
generate_difficulty_increased_region_parameter(run_point.region_parameter, DIFFICULTY_INCREASE_BY_LEVEL),
(run_point.position + randi_range(-RUN_POINT_POSITION_DERIVATION, RUN_POINT_POSITION_DERIVATION)) % 360
)
func generate_difficulty_increased_planet_parameter(
planet_parameter : PlanetParameter,
func generate_difficulty_increased_region_parameter(
region_parameter : RegionParameter,
difficulty : int = 1
) -> PlanetParameter:
) -> RegionParameter:
var i_diff := difficulty
var new_planet_parameter = PlanetParameter.new(
planet_parameter.charges,
planet_parameter.objective
var new_region_parameter = RegionParameter.new(
region_parameter.charges,
region_parameter.objective
)
while i_diff > 0:
@@ -58,51 +63,56 @@ func generate_difficulty_increased_planet_parameter(
DifficultyIncreaseObjective.new()
].filter(
func (mod : DifficultyModifier):
return mod.get_difficulty_cost() <= i_diff and mod.can_modifiy(new_planet_parameter)
return mod.get_difficulty_cost() <= i_diff and mod.can_modifiy(new_region_parameter)
)
var selected_difficulty_modifier = available_difficulty_modifier.pick_random()
selected_difficulty_modifier.modify(new_planet_parameter)
selected_difficulty_modifier.modify(new_region_parameter)
i_diff -= max(1,selected_difficulty_modifier.get_difficulty_cost())
return new_planet_parameter
return new_region_parameter
#endregion
func get_next_run_points() -> Array[RunPoint]:
return next_run_points
func get_state() -> State:
if not current_run_point:
return State.STARTED
elif current_run_point.level == RUN_POINT_MAX_LEVEL:
return State.FINISHED
else :
return State.IN_PROGRESS
func get_current_planet_data() -> PlanetData:
if current_run_point:
return current_run_point.planet_data
else:
return null
func get_next_run_points() -> Array[RunPoint]:
if current_run_point and current_run_point.level == RUN_POINT_MAX_LEVEL:
return []
return next_run_points
func choose_next_run_point(run_point : RunPoint) -> RunPoint:
if current_run_point:
visited_run_points.append(current_run_point)
current_run_point = run_point
GameInfo.game_data.start_region(run_point.region_parameter)
next_run_points = generate_next_run_points(current_run_point)
return current_run_point
class DifficultyModifier:
func modify(_planet_parameter : PlanetParameter):
func modify(_region_parameter : RegionParameter):
pass
func can_modifiy(_planet_parameter : PlanetParameter) -> bool:
func can_modifiy(_region_parameter : RegionParameter) -> bool:
return true
func get_difficulty_cost() -> int:
return 1
class DifficultyIncreaseObjective extends DifficultyModifier:
func modify(planet_parameter : PlanetParameter):
planet_parameter.objective += 1
func modify(region_parameter : RegionParameter):
region_parameter.objective += 1
class DifficultyDecreaseCharge extends DifficultyModifier:
func modify(planet_parameter : PlanetParameter):
planet_parameter.charges -= 1
func modify(region_parameter : RegionParameter):
region_parameter.charges -= 1
func can_modifiy(planet_parameter : PlanetParameter) -> bool:
return planet_parameter.charges >= 3
func can_modifiy(region_parameter : RegionParameter) -> bool:
return region_parameter.charges >= 3
+8 -30
View File
@@ -8,53 +8,31 @@ const OBJECTIVE_ICON = preload("res://common/icons/dna.svg")
const CHARGE_ICON = preload("res://common/icons/bolt.svg")
@export var level : int = 0 # X pos along the planet, and difficulty
@export var planet_parameter : PlanetParameter = PlanetParameter.new() :
@export var region_parameter : RegionParameter = RegionParameter.new() :
set(v):
planet_parameter = v
planet_data = PlanetData.new(planet_parameter)
@export var region_name : String = generate_region_name()
region_parameter = v
@export var position : int = 0 # Y pos along the planet, 0 to 360
var planet_data : PlanetData
func _init(
_level : int = 0,
_planet_parameter : PlanetParameter = PlanetParameter.new(),
_region_parameter : RegionParameter = RegionParameter.new(),
_position : int = randi_range(0,360),
_region_name : String = generate_region_name()
):
level = _level
planet_parameter = _planet_parameter
region_parameter = _region_parameter
region_parameter.level = level
position = _position
region_name = _region_name
planet_data = PlanetData.new(planet_parameter)
func card_info() -> CardInfo:
var info = CardInfo.new(region_name)
var info = CardInfo.new(region_parameter.name)
info.important_stat_icon = DANGER_ICON
info.important_stat_text = "%d" % level
info.type_icon = TYPE_ICON
info.stats.append_array([
CardStatInfo.new(tr("%d_GARDEN_POINTS") % planet_parameter.objective, OBJECTIVE_ICON),
CardStatInfo.new(tr("%d_CHARGES_AVAILABLE") % planet_parameter.charges, CHARGE_ICON),
CardStatInfo.new(str(region_parameter.objective), OBJECTIVE_ICON),
CardStatInfo.new(str(region_parameter.charges), CHARGE_ICON),
])
return info
func generate_region_name() -> String:
var vowel = ["a","e","i","o","u","y"]
var consonants = ["b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "z", "'"]
var word_len = randf_range(4,8)
var word = ''
var last_letter_is_vowel = false
for i in range(word_len):
if last_letter_is_vowel:
word += consonants.pick_random()
else:
word += vowel.pick_random()
last_letter_is_vowel = not last_letter_is_vowel
return word.capitalize()
@@ -1,6 +1,10 @@
extends Resource
class_name SettingsData
const MUSIC_BUS_ID = 1
const SFX_BUS_ID = 2
const AMBIANCE_BUS_ID = 3
signal language_changed(settings : SettingsData)
signal sound_changed(settings : SettingsData)
signal video_changed(settings : SettingsData)
@@ -44,3 +48,8 @@ const AVAILABLE_LANGUAGES_LABEL = [
set(v):
full_screen = v
video_changed.emit(self)
#region ------------------ Controls ------------------
@export var action_remapped : Array[String] = []
@export var input_remapped : Array[InputEvent] = []
+71 -18
View File
@@ -1,34 +1,87 @@
extends Node
const SAVE_GAME_LOCATION = "user://stw_demo_save.tres"
const SAVE_SETTINGS_LOCATION = "user://stw_settings.tres"
var game_loaded = false
signal game_data_updated(g : GameData)
var game_data : GameData :
set(v):
game_data = v
game_data_updated.emit(v)
set(v):
game_data = v
game_data_updated.emit(v)
var settings_data : SettingsData
func load_game_data() -> GameData:
if ResourceLoader.exists(SAVE_GAME_LOCATION):
game_loaded = true
game_data = ResourceLoader.load(SAVE_GAME_LOCATION).duplicate_deep()
else :
game_data = GameData.new()
save_game_data()
return game_data
func save_game_data():
if game_data:
ResourceSaver.save(game_data, SAVE_GAME_LOCATION)
func load_settings_data() -> SettingsData:
if ResourceLoader.exists(SAVE_SETTINGS_LOCATION):
settings_data = ResourceLoader.load(SAVE_SETTINGS_LOCATION).duplicate_deep()
else :
settings_data = SettingsData.new()
save_settings()
return settings_data
func save_settings():
if settings_data:
ResourceSaver.save(settings_data, SAVE_SETTINGS_LOCATION)
func restart_game_data():
game_data = GameData.new()
save_game_data()
func _init():
if not game_data:
game_data = GameData.new()
update_language_settings(game_data.settings)
update_video_settings(game_data.settings)
game_data.settings.language_changed.connect(_on_settings_language_changed)
game_data.settings.video_changed.connect(_on_settings_video_changed)
load_game_data()
load_settings_data()
update_language_settings()
update_video_settings()
settings_data.language_changed.connect(_on_settings_language_changed)
settings_data.video_changed.connect(_on_settings_video_changed)
settings_data.sound_changed.connect(_on_settings_sound_changed)
func _ready():
Dialogic.timeline_started.connect(_on_timeline_started)
func _on_settings_video_changed(s : SettingsData):
update_video_settings(s)
update_video_settings(s)
func _on_settings_language_changed(s : SettingsData):
update_language_settings(s)
update_language_settings(s)
func update_language_settings(s : SettingsData):
TranslationServer.set_locale(s.language)
func _on_settings_sound_changed(s : SettingsData):
AudioServer.set_bus_volume_db(SettingsData.MUSIC_BUS_ID, linear_to_db(s.music_volume))
AudioServer.set_bus_volume_db(SettingsData.SFX_BUS_ID, linear_to_db(s.sfx_volume))
AudioServer.set_bus_volume_db(SettingsData.AMBIANCE_BUS_ID, linear_to_db(s.ambiance_volume))
func update_video_settings(s : SettingsData):
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN if s.full_screen else DisplayServer.WINDOW_MODE_WINDOWED)
func _on_timeline_started():
var dialog_path = Dialogic.current_timeline.resource_path
if not dialog_path in game_data.dialogs_done:
game_data.dialogs_done.append(dialog_path)
save_game_data()
func update_input(action : String, old_event : InputEvent, event : InputEvent):
InputMap.action_erase_event(action, old_event)
InputMap.action_add_event(action, event)
func update_language_settings(s : SettingsData = settings_data):
TranslationServer.set_locale(s.language)
func update_video_settings(s : SettingsData = settings_data):
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN if s.full_screen else DisplayServer.WINDOW_MODE_WINDOWED)
func update_inputs(s : SettingsData = settings_data):
for i in range(len(s.input_remapped)):
InputMap.action_erase_events(s.action_remapped[i])
InputMap.action_add_event(s.action_remapped[i], s.input_remapped[i])
+7 -6
View File
@@ -3,19 +3,20 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://eug5icp6t1h3"
path="res://.godot/imported/arrow-narrow-up.svg-3e96282c2af955cf23507b48c4348810.ctex"
path.s3tc="res://.godot/imported/arrow-narrow-up.svg-3e96282c2af955cf23507b48c4348810.s3tc.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://common/icons/arrow-narrow-up.svg"
dest_files=["res://.godot/imported/arrow-narrow-up.svg-3e96282c2af955cf23507b48c4348810.ctex"]
dest_files=["res://.godot/imported/arrow-narrow-up.svg-3e96282c2af955cf23507b48c4348810.s3tc.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +24,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +38,7 @@ 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
detect_3d/compress_to=0
svg/scale=2.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

@@ -2,16 +2,16 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://d2p7h0aga85tn"
path="res://.godot/imported/truck_interior.png-ff9bd2d0107d83f7c4209d959ee69f15.ctex"
uid="uid://dw80a4c5iekir"
path="res://.godot/imported/bar.png-623df5fbea38f9d862a997485a02d36c.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://stages/terrain/truck/assets/sprite/truck_interior.png"
dest_files=["res://.godot/imported/truck_interior.png-ff9bd2d0107d83f7c4209d959ee69f15.ctex"]
source_file="res://common/icons/bar.png"
dest_files=["res://.godot/imported/bar.png-623df5fbea38f9d862a997485a02d36c.ctex"]
[params]
+7 -6
View File
@@ -3,19 +3,20 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://dcgnamu7sb3ov"
path="res://.godot/imported/bolt.svg-a559d5e701996c7d105fc68102331434.ctex"
path.s3tc="res://.godot/imported/bolt.svg-a559d5e701996c7d105fc68102331434.s3tc.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://common/icons/bolt.svg"
dest_files=["res://.godot/imported/bolt.svg-a559d5e701996c7d105fc68102331434.ctex"]
dest_files=["res://.godot/imported/bolt.svg-a559d5e701996c7d105fc68102331434.s3tc.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +24,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +38,7 @@ 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
detect_3d/compress_to=0
svg/scale=2.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-brand-instagram"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 8a4 4 0 0 1 4 -4h8a4 4 0 0 1 4 4v8a4 4 0 0 1 -4 4h-8a4 4 0 0 1 -4 -4l0 -8" /><path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0" /><path d="M16.5 7.5v.01" /></svg>

After

Width:  |  Height:  |  Size: 469 B

+43
View File
@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dh1jaup4y1f6q"
path="res://.godot/imported/brand-instagram.svg-93b67e1c651e77c13169000f3fa1764f.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://common/icons/brand-instagram.svg"
dest_files=["res://.godot/imported/brand-instagram.svg-93b67e1c651e77c13169000f3fa1764f.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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=2.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-brand-steam"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M16.5 5a4.5 4.5 0 1 1 -.653 8.953l-4.347 3.009l0 .038a3 3 0 0 1 -2.824 3l-.176 0a3 3 0 0 1 -2.94 -2.402l-2.56 -1.098v-3.5l3.51 1.755a2.989 2.989 0 0 1 2.834 -.635l2.727 -3.818a4.5 4.5 0 0 1 4.429 -5.302" /><path d="M15.5 9.5a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" fill="#ffffff" /></svg>

After

Width:  |  Height:  |  Size: 584 B

+43
View File
@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cpkye7t28ragp"
path="res://.godot/imported/brand-steam.svg-9dbbdc409ded6b7066179206cac90cca.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://common/icons/brand-steam.svg"
dest_files=["res://.godot/imported/brand-steam.svg-9dbbdc409ded6b7066179206cac90cca.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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=2.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-broadcast"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M18.364 19.364a9 9 0 1 0 -12.728 0" /><path d="M15.536 16.536a5 5 0 1 0 -7.072 0" /><path d="M11 13a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /></svg>

After

Width:  |  Height:  |  Size: 442 B

+43
View File
@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://qshtr3peinak"
path="res://.godot/imported/broadcast.svg-d7376e52ecc5b74fcdaea71ccbe04a97.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://common/icons/broadcast.svg"
dest_files=["res://.godot/imported/broadcast.svg-d7376e52ecc5b74fcdaea71ccbe04a97.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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=2.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#ffffff" class="icon icon-tabler icons-tabler-filled icon-tabler-coin"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M17 3.34a10 10 0 1 1 -15 8.66l.005 -.324a10 10 0 0 1 14.995 -8.336zm-5 2.66a1 1 0 0 0 -1 1a3 3 0 1 0 0 6v2a1.024 1.024 0 0 1 -.866 -.398l-.068 -.101a1 1 0 0 0 -1.732 .998a3 3 0 0 0 2.505 1.5h.161a1 1 0 0 0 .883 .994l.117 .007a1 1 0 0 0 1 -1l.176 -.005a3 3 0 0 0 -.176 -5.995v-2c.358 -.012 .671 .14 .866 .398l.068 .101a1 1 0 0 0 1.732 -.998a3 3 0 0 0 -2.505 -1.501h-.161a1 1 0 0 0 -1 -1zm1 7a1 1 0 0 1 0 2v-2zm-2 -4v2a1 1 0 0 1 0 -2z" /></svg>

After

Width:  |  Height:  |  Size: 662 B

@@ -2,16 +2,16 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://cqqlkm14lawpa"
path="res://.godot/imported/panneau_solaire_1.png-b9a4049f295152380ed394a82c03b8e2.ctex"
uid="uid://cs5jk1312wauu"
path="res://.godot/imported/coin.svg-08623932cd6c1ab8a19bb6ae049240d0.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://entities/interactables/machines/solar_pannel/assets/sprites/panneau_solaire_1.png"
dest_files=["res://.godot/imported/panneau_solaire_1.png-b9a4049f295152380ed394a82c03b8e2.ctex"]
source_file="res://common/icons/coin.svg"
dest_files=["res://.godot/imported/coin.svg-08623932cd6c1ab8a19bb6ae049240d0.ctex"]
[params]
@@ -38,3 +38,6 @@ process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+7 -6
View File
@@ -3,19 +3,20 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://baaujfw8piywi"
path="res://.godot/imported/dna.svg-0d37cb06a607035637eb8d87826b10a6.ctex"
path.s3tc="res://.godot/imported/dna.svg-0d37cb06a607035637eb8d87826b10a6.s3tc.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://common/icons/dna.svg"
dest_files=["res://.godot/imported/dna.svg-0d37cb06a607035637eb8d87826b10a6.ctex"]
dest_files=["res://.godot/imported/dna.svg-0d37cb06a607035637eb8d87826b10a6.s3tc.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +24,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +38,7 @@ 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
detect_3d/compress_to=0
svg/scale=2.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-focus"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M11.5 12a.5 .5 0 1 0 1 0a.5 .5 0 1 0 -1 0" fill="#ffffff" /><path d="M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" /></svg>

After

Width:  |  Height:  |  Size: 415 B

+43
View File
@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ba8vh5h3r6pr2"
path="res://.godot/imported/focus.svg-cc30e969e976522254107343300a103b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://common/icons/focus.svg"
dest_files=["res://.godot/imported/focus.svg-cc30e969e976522254107343300a103b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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=2.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-hand-stop"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M8 13v-7.5a1.5 1.5 0 0 1 3 0v6.5" /><path d="M11 5.5v-2a1.5 1.5 0 1 1 3 0v8.5" /><path d="M14 5.5a1.5 1.5 0 0 1 3 0v6.5" /><path d="M17 7.5a1.5 1.5 0 0 1 3 0v8.5a6 6 0 0 1 -6 6h-2h.208a6 6 0 0 1 -5.012 -2.7a69.74 69.74 0 0 1 -.196 -.3c-.312 -.479 -1.407 -2.388 -3.286 -5.728a1.5 1.5 0 0 1 .536 -2.022a1.867 1.867 0 0 1 2.28 .28l1.47 1.47" /></svg>

After

Width:  |  Height:  |  Size: 651 B

+43
View File
@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://3slhocr5wy3w"
path="res://.godot/imported/hand-stop.svg-bc0d0e986bcb4b50bdd5686b5bff814b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://common/icons/hand-stop.svg"
dest_files=["res://.godot/imported/hand-stop.svg-bc0d0e986bcb4b50bdd5686b5bff814b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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=2.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+7 -6
View File
@@ -3,19 +3,20 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://dex283rx00fjb"
path="res://.godot/imported/logout.svg-15891d2f0d875a13ef182339fdbc6039.ctex"
path.s3tc="res://.godot/imported/logout.svg-15891d2f0d875a13ef182339fdbc6039.s3tc.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://common/icons/logout.svg"
dest_files=["res://.godot/imported/logout.svg-15891d2f0d875a13ef182339fdbc6039.ctex"]
dest_files=["res://.godot/imported/logout.svg-15891d2f0d875a13ef182339fdbc6039.s3tc.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +24,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +38,7 @@ 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
detect_3d/compress_to=0
svg/scale=2.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#ffffff" class="icon icon-tabler icons-tabler-filled icon-tabler-phone"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 3a1 1 0 0 1 .877 .519l.051 .11l2 5a1 1 0 0 1 -.313 1.16l-.1 .068l-1.674 1.004l.063 .103a10 10 0 0 0 3.132 3.132l.102 .062l1.005 -1.672a1 1 0 0 1 1.113 -.453l.115 .039l5 2a1 1 0 0 1 .622 .807l.007 .121v4c0 1.657 -1.343 3 -3.06 2.998c-8.579 -.521 -15.418 -7.36 -15.94 -15.998a3 3 0 0 1 2.824 -2.995l.176 -.005h4z" /></svg>

After

Width:  |  Height:  |  Size: 544 B

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dks6cugwif2em"
path.s3tc="res://.godot/imported/phone.svg-8966bc13014a00a59fa575f3ae370ef6.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://common/icons/phone.svg"
dest_files=["res://.godot/imported/phone.svg-8966bc13014a00a59fa575f3ae370ef6.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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=0
svg/scale=2.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+7 -6
View File
@@ -3,19 +3,20 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://b43thuq8piv18"
path="res://.godot/imported/skull.svg-1f3a01497295060c28293df722ed0ddd.ctex"
path.s3tc="res://.godot/imported/skull.svg-1f3a01497295060c28293df722ed0ddd.s3tc.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://common/icons/skull.svg"
dest_files=["res://.godot/imported/skull.svg-1f3a01497295060c28293df722ed0ddd.ctex"]
dest_files=["res://.godot/imported/skull.svg-1f3a01497295060c28293df722ed0ddd.s3tc.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +24,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +38,7 @@ 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
detect_3d/compress_to=0
svg/scale=2.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
@@ -3,19 +3,20 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://b6dwhn0uotdgu"
path="res://.godot/imported/square-rounded-nofill.svg-3b394b5967765acc26d391129de152eb.ctex"
path.s3tc="res://.godot/imported/square-rounded-nofill.svg-3b394b5967765acc26d391129de152eb.s3tc.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://common/icons/square-rounded-nofill.svg"
dest_files=["res://.godot/imported/square-rounded-nofill.svg-3b394b5967765acc26d391129de152eb.ctex"]
dest_files=["res://.godot/imported/square-rounded-nofill.svg-3b394b5967765acc26d391129de152eb.s3tc.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +24,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +38,7 @@ 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
detect_3d/compress_to=0
svg/scale=2.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+7 -6
View File
@@ -3,19 +3,20 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://rdrhi3r11ey6"
path="res://.godot/imported/square-rounded.svg-4eece25055f2b80264664150c832a797.ctex"
path.s3tc="res://.godot/imported/square-rounded.svg-4eece25055f2b80264664150c832a797.s3tc.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://common/icons/square-rounded.svg"
dest_files=["res://.godot/imported/square-rounded.svg-4eece25055f2b80264664150c832a797.ctex"]
dest_files=["res://.godot/imported/square-rounded.svg-4eece25055f2b80264664150c832a797.s3tc.ctex"]
[params]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
@@ -23,7 +24,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -37,7 +38,7 @@ 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
detect_3d/compress_to=0
svg/scale=2.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
@@ -0,0 +1,113 @@
[gd_scene format=3 uid="uid://b8gqdgabrjaml"]
[ext_resource type="Script" uid="uid://dt2ip3pw2cboy" path="res://entities/plants/scripts/texture_builder/plant_texture_builder.gd" id="1_s8rsj"]
[ext_resource type="Script" uid="uid://b3jwglylqdqtw" path="res://entities/plants/scripts/texture_builder/plant_part.gd" id="2_cfiqo"]
[ext_resource type="Resource" uid="uid://bfyafiewcrjln" path="res://entities/plants/resources/plant_parts/Base1.tres" id="3_15wue"]
[ext_resource type="Resource" uid="uid://7hrdkl6bf3o4" path="res://entities/plants/resources/plant_parts/Branch1.tres" id="4_ggud5"]
[ext_resource type="Resource" uid="uid://bgh8a4xwc5stw" path="res://entities/plants/resources/plant_parts/Base2.tres" id="5_21cjy"]
[ext_resource type="Resource" uid="uid://ceisi5yyie7to" path="res://entities/plants/resources/plant_parts/Branch2.tres" id="5_ufbqh"]
[ext_resource type="Resource" uid="uid://cxiu8frk04b5i" path="res://entities/plants/resources/plant_parts/Branch3.tres" id="6_jbu3q"]
[ext_resource type="Resource" uid="uid://53p5g07e3pb4" path="res://entities/plants/resources/plant_parts/Branch4.tres" id="7_21cjy"]
[ext_resource type="Resource" uid="uid://cyfyodtfxne1w" path="res://entities/plants/resources/plant_parts/Branch5.tres" id="8_qm7aw"]
[ext_resource type="Resource" uid="uid://cuvtf4y1dspcp" path="res://entities/plants/resources/plant_parts/Branch6.tres" id="9_3e4c1"]
[ext_resource type="Resource" uid="uid://wgmxpk52rg7x" path="res://entities/plants/resources/plant_parts/LeafA1.tres" id="11_fc4k8"]
[ext_resource type="Resource" uid="uid://d2y7o2hc6ffei" path="res://entities/plants/resources/plant_parts/Branch11.tres" id="11_hvwgo"]
[ext_resource type="Resource" uid="uid://cbejb0uvdke7k" path="res://entities/plants/resources/plant_parts/LeafA2.tres" id="12_1b4fr"]
[ext_resource type="Resource" uid="uid://civ4gr1c2pq7g" path="res://entities/plants/resources/plant_parts/Branch12.tres" id="12_npk80"]
[ext_resource type="Resource" uid="uid://dujxttu80g0lo" path="res://entities/plants/resources/plant_parts/LeafA3.tres" id="13_ggcwy"]
[ext_resource type="Resource" uid="uid://bqfocs6f0iypo" path="res://entities/plants/resources/plant_parts/Branch13.tres" id="13_hyb2i"]
[ext_resource type="Resource" uid="uid://drml5dm8i3j3a" path="res://entities/plants/resources/plant_parts/Branch14.tres" id="14_4gk8a"]
[ext_resource type="Resource" uid="uid://bgv3nb10t6u3y" path="res://entities/plants/resources/plant_parts/LeafF1.tres" id="14_8r35x"]
[ext_resource type="Resource" uid="uid://bix3qwmsvuxs4" path="res://entities/plants/resources/plant_parts/LeafA4.tres" id="14_15wue"]
[ext_resource type="Resource" uid="uid://c31h25xdll8si" path="res://entities/plants/resources/plant_parts/FlowerD1.tres" id="15_3ti7v"]
[ext_resource type="Resource" uid="uid://be17y7clvf88e" path="res://entities/plants/resources/plant_parts/LeafE1.tres" id="15_p2blu"]
[ext_resource type="Resource" uid="uid://bkgw3wmoam10n" path="res://entities/plants/resources/plant_parts/LeafF2.tres" id="15_rbd7l"]
[ext_resource type="Script" uid="uid://cfjd8jelpm8dt" path="res://entities/plants/scripts/texture_builder/part_mutation_association.gd" id="16_c3tk3"]
[ext_resource type="Resource" uid="uid://r5mspvasrq6y" path="res://entities/plants/resources/plant_parts/FlowerD2.tres" id="16_cpf4r"]
[ext_resource type="Resource" uid="uid://m8j2gfumw11w" path="res://entities/plants/resources/plant_parts/LeafF3.tres" id="16_nfxo0"]
[ext_resource type="Resource" uid="uid://dw7wdihxxy0uf" path="res://entities/plants/resources/plant_parts/LeafE2.tres" id="16_xt8tm"]
[ext_resource type="Resource" uid="uid://dth4dp88vs3gh" path="res://entities/plants/resources/plant_parts/LeafF4.tres" id="17_i8j71"]
[ext_resource type="Resource" uid="uid://br80voioh4jxu" path="res://entities/plants/resources/plant_parts/FlowerD3.tres" id="17_p2blu"]
[ext_resource type="Resource" uid="uid://3yi8hk73s5mm" path="res://entities/plants/resources/plant_parts/LeafE3.tres" id="17_qm7aw"]
[ext_resource type="Resource" uid="uid://cka6sihumbjpw" path="res://entities/plants/resources/plant_parts/LeafF5.tres" id="18_l2vrg"]
[ext_resource type="Resource" uid="uid://dq5dwqherb6ac" path="res://entities/plants/resources/plant_parts/LeafF6.tres" id="19_14c4k"]
[ext_resource type="Resource" uid="uid://ckef0dno4j5mn" path="res://entities/plants/resources/plant_parts/FlowerF1.tres" id="20_lggh7"]
[ext_resource type="Resource" uid="uid://dhhyh56shnure" path="res://entities/plants/resources/plant_parts/FlowerF2.tres" id="21_8r35x"]
[ext_resource type="Resource" uid="uid://banfc3pgm6a0m" path="res://entities/plants/resources/plant_parts/FlowerC1.tres" id="21_alra6"]
[ext_resource type="Resource" uid="uid://dmdyj7t4g48p" path="res://entities/plants/resources/plant_parts/FlowerC2.tres" id="22_lggh7"]
[ext_resource type="Resource" uid="uid://bhj7j78tokt25" path="res://entities/plants/resources/plant_parts/FlowerC3.tres" id="23_8r35x"]
[ext_resource type="Resource" uid="uid://bkgrwffi7m2i4" path="res://entities/plants/resources/plant_parts/FlowerC4.tres" id="24_rbd7l"]
[ext_resource type="Resource" uid="uid://bchwhdmxsaqic" path="res://entities/plants/resources/plant_parts/LeafA5.tres" id="29_nfxo0"]
[ext_resource type="Resource" uid="uid://cvr81iqokda6x" path="res://entities/plants/resources/plant_parts/LeafA6.tres" id="30_i8j71"]
[ext_resource type="Resource" uid="uid://cwskfwdasvv0g" path="res://entities/plants/resources/plant_parts/FlowerF3.tres" id="38_rbd7l"]
[ext_resource type="Resource" uid="uid://e0u1baixvaxn" path="res://entities/plants/resources/plant_parts/LeafE4.tres" id="42_14c4k"]
[ext_resource type="Resource" uid="uid://dgivyissl512e" path="res://entities/plants/resources/plant_parts/LeafG1.tres" id="43_y02ao"]
[ext_resource type="Resource" uid="uid://u6dwq3eowpcb" path="res://entities/plants/resources/plant_parts/LeafG2.tres" id="44_s8rsj"]
[ext_resource type="Resource" uid="uid://c4artcndro0r5" path="res://entities/plants/resources/plant_parts/FlowerB1.tres" id="45_coupj"]
[ext_resource type="Resource" uid="uid://b3dfua388ub4k" path="res://entities/plants/resources/plant_parts/FlowerB2.tres" id="46_ggud5"]
[ext_resource type="Resource" uid="uid://bnn0tcoab4plv" path="res://entities/plants/resources/plant_parts/FlowerB3.tres" id="47_ufbqh"]
[sub_resource type="Resource" id="Resource_rt6tw"]
script = ExtResource("16_c3tk3")
parts = Array[ExtResource("2_cfiqo")]([ExtResource("11_fc4k8"), ExtResource("12_1b4fr"), ExtResource("13_ggcwy"), ExtResource("14_15wue"), ExtResource("29_nfxo0"), ExtResource("30_i8j71")])
part_amount = 4
metadata/_custom_type_script = "uid://cfjd8jelpm8dt"
[sub_resource type="Resource" id="Resource_y02ao"]
script = ExtResource("16_c3tk3")
parts = Array[ExtResource("2_cfiqo")]([ExtResource("15_3ti7v"), ExtResource("16_cpf4r"), ExtResource("17_p2blu")])
part_amount = 5
metadata/_custom_type_script = "uid://cfjd8jelpm8dt"
[sub_resource type="Resource" id="Resource_nfxo0"]
script = ExtResource("16_c3tk3")
parts = Array[ExtResource("2_cfiqo")]([ExtResource("20_lggh7"), ExtResource("21_8r35x"), ExtResource("38_rbd7l")])
part_amount = 5
metadata/_custom_type_script = "uid://cfjd8jelpm8dt"
[sub_resource type="Resource" id="Resource_s8rsj"]
script = ExtResource("16_c3tk3")
parts = Array[ExtResource("2_cfiqo")]([ExtResource("15_p2blu"), ExtResource("16_xt8tm"), ExtResource("17_qm7aw"), ExtResource("42_14c4k")])
part_amount = 5
metadata/_custom_type_script = "uid://cfjd8jelpm8dt"
[sub_resource type="Resource" id="Resource_14c4k"]
script = ExtResource("16_c3tk3")
parts = Array[ExtResource("2_cfiqo")]([ExtResource("21_alra6"), ExtResource("22_lggh7"), ExtResource("23_8r35x"), ExtResource("24_rbd7l")])
part_amount = 4
metadata/_custom_type_script = "uid://cfjd8jelpm8dt"
[sub_resource type="Resource" id="Resource_cfiqo"]
script = ExtResource("16_c3tk3")
parts = Array[ExtResource("2_cfiqo")]([ExtResource("43_y02ao"), ExtResource("44_s8rsj")])
part_amount = 3
metadata/_custom_type_script = "uid://cfjd8jelpm8dt"
[sub_resource type="Resource" id="Resource_jbu3q"]
script = ExtResource("16_c3tk3")
parts = Array[ExtResource("2_cfiqo")]([ExtResource("45_coupj"), ExtResource("46_ggud5"), ExtResource("47_ufbqh")])
part_amount = 5
metadata/_custom_type_script = "uid://cfjd8jelpm8dt"
[node name="TextureBuilder" type="Node" unique_id=79184097]
script = ExtResource("1_s8rsj")
bases = Array[ExtResource("2_cfiqo")]([ExtResource("3_15wue")])
baby_bases = Array[ExtResource("2_cfiqo")]([ExtResource("5_21cjy")])
branches = Array[ExtResource("2_cfiqo")]([ExtResource("4_ggud5"), ExtResource("5_ufbqh"), ExtResource("6_jbu3q"), ExtResource("7_21cjy"), ExtResource("8_qm7aw"), ExtResource("9_3e4c1"), ExtResource("11_hvwgo"), ExtResource("12_npk80"), ExtResource("13_hyb2i"), ExtResource("14_4gk8a")])
n_branches = 5
base_leaves = Array[ExtResource("2_cfiqo")]([ExtResource("14_8r35x"), ExtResource("15_rbd7l"), ExtResource("16_nfxo0"), ExtResource("17_i8j71"), ExtResource("18_l2vrg"), ExtResource("19_14c4k")])
parts_mutation_associations = Dictionary[String, ExtResource("16_c3tk3")]({
"ANCIENT": SubResource("Resource_rt6tw"),
"EPHEMERAL": SubResource("Resource_y02ao"),
"FERTILE": SubResource("Resource_nfxo0"),
"PURIFICATION": SubResource("Resource_s8rsj"),
"QUICK": SubResource("Resource_14c4k"),
"SOCIAL": SubResource("Resource_cfiqo"),
"TOUGH": SubResource("Resource_jbu3q")
})
chance_to_have_part = 0.9
origin_weights_base = Dictionary[int, int]({
0: 20,
1: 10,
2: 5
})
+15
View File
@@ -0,0 +1,15 @@
[gd_scene format=3 uid="uid://dac5wte80dwj0"]
[ext_resource type="Script" uid="uid://bb44144ckt2w7" path="res://common/scene_manager/scripts/scene_manager.gd" id="1_1c0qu"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="2_c1lr7"]
[ext_resource type="Resource" uid="uid://bvksiaiocwob5" path="res://common/scene_manager/scenes/cockpit.tres" id="3_e28ni"]
[ext_resource type="Resource" uid="uid://bvgdq43fpl1xs" path="res://common/scene_manager/scenes/intro.tres" id="4_msho1"]
[ext_resource type="Resource" uid="uid://boqgwjyxyb45r" path="res://common/scene_manager/scenes/region.tres" id="5_ytog4"]
[ext_resource type="Resource" uid="uid://c27wenetitwm" path="res://common/scene_manager/scenes/region_selection.tres" id="6_chs32"]
[ext_resource type="Resource" uid="uid://diro74w272onp" path="res://common/scene_manager/scenes/title.tres" id="7_ol3d5"]
[ext_resource type="Resource" uid="uid://jegdqnd2sqi2" path="res://common/scene_manager/scenes/astra.tres" id="8_e28ni"]
[ext_resource type="Resource" uid="uid://b3ebbo88ptrrc" path="res://common/scene_manager/scenes/garage.tres" id="9_msho1"]
[node name="SceneManager" type="Node" unique_id=1630600782]
script = ExtResource("1_1c0qu")
scenes = Array[ExtResource("2_c1lr7")]([ExtResource("3_e28ni"), ExtResource("4_msho1"), ExtResource("5_ytog4"), ExtResource("6_chs32"), ExtResource("7_ol3d5"), ExtResource("8_e28ni"), ExtResource("9_msho1")])
+10
View File
@@ -0,0 +1,10 @@
[gd_resource type="Resource" script_class="Scene" format=3 uid="uid://jegdqnd2sqi2"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="1_114vb"]
[resource]
script = ExtResource("1_114vb")
scene_id = "ASTRA"
scene_path = "res://stages/3d_scenes/astra_base/astra_base.tscn"
mouse_captured = true
metadata/_custom_type_script = "uid://1ejbvr3431ac"
+10
View File
@@ -0,0 +1,10 @@
[gd_resource type="Resource" script_class="Scene" format=3 uid="uid://bvksiaiocwob5"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="1_tkiq8"]
[resource]
script = ExtResource("1_tkiq8")
scene_id = "COCKPIT"
scene_path = "res://stages/3d_scenes/cockpit_scene/cockpit_scene.tscn"
mouse_captured = true
metadata/_custom_type_script = "uid://1ejbvr3431ac"
+10
View File
@@ -0,0 +1,10 @@
[gd_resource type="Resource" script_class="Scene" format=3 uid="uid://b3ebbo88ptrrc"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="1_v8prw"]
[resource]
script = ExtResource("1_v8prw")
scene_id = "GARAGE"
scene_path = "res://stages/3d_scenes/ship_garage/ship_garage.tscn"
mouse_captured = true
metadata/_custom_type_script = "uid://1ejbvr3431ac"
+9
View File
@@ -0,0 +1,9 @@
[gd_resource type="Resource" script_class="Scene" load_steps=2 format=3 uid="uid://bvgdq43fpl1xs"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="1_6ws88"]
[resource]
script = ExtResource("1_6ws88")
scene_id = "INTRO"
scene_path = "res://stages/intro/intro.tscn"
metadata/_custom_type_script = "uid://1ejbvr3431ac"
+10
View File
@@ -0,0 +1,10 @@
[gd_resource type="Resource" script_class="Scene" load_steps=2 format=3 uid="uid://boqgwjyxyb45r"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="1_10qbh"]
[resource]
script = ExtResource("1_10qbh")
scene_id = "REGION"
scene_path = "res://stages/terrain/region/region.tscn"
need_terrain_generated = true
metadata/_custom_type_script = "uid://1ejbvr3431ac"
@@ -0,0 +1,9 @@
[gd_resource type="Resource" script_class="Scene" load_steps=2 format=3 uid="uid://c27wenetitwm"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="1_smjh0"]
[resource]
script = ExtResource("1_smjh0")
scene_id = "REGION_SELECTION"
scene_path = "res://stages/region_selection/region_selection.tscn"
metadata/_custom_type_script = "uid://1ejbvr3431ac"
+10
View File
@@ -0,0 +1,10 @@
[gd_resource type="Resource" script_class="Scene" format=3 uid="uid://diro74w272onp"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="1_48g2j"]
[resource]
script = ExtResource("1_48g2j")
scene_id = "TITLE"
scene_path = "res://stages/title_screen/title_screen.tscn"
need_to_be_saved = false
metadata/_custom_type_script = "uid://1ejbvr3431ac"
+8
View File
@@ -0,0 +1,8 @@
extends Resource
class_name Scene
@export var scene_id : String
@export_file_path() var scene_path : String
@export var mouse_captured := false
@export var need_terrain_generated := false
@export var need_to_be_saved = true
@@ -0,0 +1 @@
uid://1ejbvr3431ac
@@ -1,24 +1,44 @@
extends Node
const TITLE_SCREEN = "res://stages/title_screen/title_screen.tscn"
const PLANET_SCENE = "res://stages/terrain/planet/planet.tscn"
const TRUCK_SCENE = "res://stages/terrain/truck/truck.tscn"
const INTRO_SCENE = "res://stages/intro/intro.tscn"
const REGION_SELECTION_SCREEN = "res://stages/region_selection/region_selection.tscn"
@export var scenes : Array[Scene]
signal scene_loaded
signal scene_node_ready
signal scene_loaded(scene : Scene)
signal scene_node_ready(scene : Scene)
var actual_scene = null
var loading_scene = false
var generating_node = false
var scene_to_load := ""
var next_scene_node : Node
@onready var current_scene_node : Node = get_tree().root.get_children().back()
func change_scene(scene_path : String, with_loading = true):
func search_scenes(scene_id : String) -> Scene:
var scene_pos : int = scenes.find_custom(
func (s : Scene):
return s.scene_id == scene_id
)
if scene_pos == -1:
return null
else :
return scenes[scene_pos]
func change_to_scene_id(scene_id : String, with_loading = true):
var scene = search_scenes(scene_id)
if not scene:
printerr("Scene %s not found" % scene_id)
return
change_to_scene(scene, with_loading)
func change_to_scene(scene : Scene, with_loading = true):
if loading_scene or generating_node:
await scene_node_ready
actual_scene = scene
loading_scene = true
scene_to_load = scene_path
ResourceLoader.load_threaded_request(scene_to_load)
var scene_path_to_load = scene.scene_path
ResourceLoader.load_threaded_request(scene_path_to_load)
LoadingScreen.loading_text = "LOADING_SCENE"
var scene_to_hide = current_scene_node
if with_loading:
@@ -30,16 +50,16 @@ func change_scene(scene_path : String, with_loading = true):
if loading_scene:
await scene_loaded
next_scene_node = ResourceLoader.load_threaded_get(scene_to_load).instantiate()
next_scene_node = ResourceLoader.load_threaded_get(scene_path_to_load).instantiate()
if next_scene_node.has_method("hide"):
next_scene_node.hide()
get_tree().root.add_child(next_scene_node)
generating_node = true
if next_scene_node is Planet:
if scene.need_terrain_generated:
LoadingScreen.loading_text = "GENERATING_TERRAIN"
if generating_node:
await scene_node_ready
await scene_node_ready
if current_scene_node:
current_scene_node.queue_free()
@@ -47,23 +67,32 @@ func change_scene(scene_path : String, with_loading = true):
if current_scene_node.has_method("show"):
current_scene_node.show()
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED if scene.mouse_captured else Input.MOUSE_MODE_VISIBLE
GameInfo.update_inputs()
if actual_scene.need_to_be_saved:
GameInfo.game_data.last_game_scene = scene
GameInfo.save_game_data()
if with_loading:
LoadingScreen.hide_loading_screen()
func _process(_delta):
if loading_scene:
var progress = []
var load_status := ResourceLoader.load_threaded_get_status(scene_to_load, progress)
var load_status := ResourceLoader.load_threaded_get_status(actual_scene.scene_path, progress)
LoadingScreen.loading_value = progress[0]
if load_status == ResourceLoader.THREAD_LOAD_LOADED:
loading_scene = false
scene_loaded.emit()
scene_loaded.emit(actual_scene)
if load_status == ResourceLoader.THREAD_LOAD_FAILED or load_status == ResourceLoader.THREAD_LOAD_INVALID_RESOURCE:
printerr()
elif generating_node:
if next_scene_node is Planet:
if next_scene_node is Region:
LoadingScreen.loading_value = next_scene_node.generated_value
if next_scene_node.is_generated:
generating_node = false
scene_node_ready.emit()
elif next_scene_node.is_node_ready():
generating_node = false
scene_node_ready.emit()
scene_node_ready.emit(actual_scene)
+11 -11
View File
@@ -2,33 +2,33 @@ class_name Math
static func get_chunk_from_pos(coord) -> Vector2i:
return Vector2i(
floori(coord.x / (Planet.CHUNK_TILE_SIZE * Planet.TILE_SIZE)),
floori(coord.y / (Planet.CHUNK_TILE_SIZE * Planet.TILE_SIZE))
floori(coord.x / (Region.CHUNK_TILE_SIZE * Region.TILE_SIZE)),
floori(coord.y / (Region.CHUNK_TILE_SIZE * Region.TILE_SIZE))
)
static func get_tile_from_pos(coord) -> Vector2i:
return Vector2i(
floori(coord.x / (Planet.TILE_SIZE)),
floori(coord.y / (Planet.TILE_SIZE)),
floori(coord.x / (Region.TILE_SIZE)),
floori(coord.y / (Region.TILE_SIZE)),
)
static func get_tiles_in_circle(center: Vector2, radius : float) -> Array[Vector2i]:
var tiles : Array[Vector2i] = []
for x in range(
floori((center.x - radius/2.) / Planet.TILE_SIZE),
ceili((center.x + radius/2.) / Planet.TILE_SIZE),
floori((center.x - radius/2.) / Region.TILE_SIZE),
ceili((center.x + radius/2.) / Region.TILE_SIZE),
):
for y in range(
floori((center.y - radius/2.) / Planet.TILE_SIZE),
ceili((center.y + radius/2.) / Planet.TILE_SIZE),
floori((center.y - radius/2.) / Region.TILE_SIZE),
ceili((center.y + radius/2.) / Region.TILE_SIZE),
):
if is_tile_on_circle(Vector2i(x,y), center, radius):
tiles.append(Vector2i(x,y))
return tiles
static func is_tile_on_circle(tile_coord : Vector2i, circle_center: Vector2, circle_radius : float) -> bool:
var absolute_tile_pos : Vector2 = tile_coord * Planet.TILE_SIZE
var absolute_tile_pos : Vector2 = tile_coord * Region.TILE_SIZE
# Loop over tile corners to know if the area collide
var corners : Array[Vector2] = []
@@ -36,8 +36,8 @@ static func is_tile_on_circle(tile_coord : Vector2i, circle_center: Vector2, cir
for y in [0,1]:
corners.append(
absolute_tile_pos
+ Vector2.RIGHT * x * Planet.TILE_SIZE
+ Vector2.DOWN * y * Planet.TILE_SIZE
+ Vector2.RIGHT * x * Region.TILE_SIZE
+ Vector2.DOWN * y * Region.TILE_SIZE
)
# Check if segment touch area
+59
View File
@@ -0,0 +1,59 @@
class_name Random
const MIN_WORD_LEN = 4
const MAX_WORD_LEN = 8
const VOWEL = ["a","e","i","o","u","y"]
const CONSONANTS = ["b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "z"]
static func generate_random_word(_random_seed = randi()) -> String:
var word_len = randf_range(4,8)
var word = ''
var last_letter_is_vowel = false
for i in range(word_len):
if last_letter_is_vowel:
word += CONSONANTS.pick_random()
else:
word += VOWEL.pick_random()
last_letter_is_vowel = not last_letter_is_vowel
return word.capitalize()
static func mutate_word(word : String) -> String:
var rand_int = randi()
if len(word) > MIN_WORD_LEN and rand_int % 3 == 0:
return shorten_word(word)
elif len(word) < MAX_WORD_LEN and rand_int % 3 == 1:
return elongate_word(word)
return replace_character(word)
static func shorten_word(word : String):
if randi()%2 == 0:
return word.left(len(word) - 1).capitalize()
else :
return word.right(len(word) - 1).capitalize()
static func elongate_word(word : String):
if randi()%2 == 0:
var letter = CONSONANTS.pick_random() if word.left(1) in VOWEL else VOWEL.pick_random()
return (letter + word).capitalize()
else :
var letter = CONSONANTS.pick_random() if word.right(1) in VOWEL else VOWEL.pick_random()
return (word + letter).capitalize()
static func replace_character(word : String):
var character_id = randi_range(0, len(word))
var character = word[character_id]
if character in VOWEL:
character = VOWEL.pick_random()
else:
character = CONSONANTS.pick_random()
word[character_id] = character
return word
+1
View File
@@ -0,0 +1 @@
uid://ukeanrcup7of
@@ -0,0 +1,85 @@
shader_type spatial;
render_mode unshaded, depth_draw_opaque, depth_prepass_alpha;
// Inspired by https://godotshaders.com/shader/3d-pixel-art-outline-highlight-post-processing-shader/
uniform sampler2D DEPTH_TEXTURE : hint_depth_texture, filter_linear_mipmap;
uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
uniform sampler2D NORMAL_TEXTURE : hint_normal_roughness_texture, filter_nearest;
uniform vec3 shadow_color : source_color = vec3(0.0);
uniform float shadow_thickness = 2.0;
vec2 getDepth(vec2 screen_uv, sampler2D depth_texture, mat4 inv_projection_matrix){
float raw_depth = texture(depth_texture, screen_uv)[0];
vec3 normalized_device_coordinates = vec3(screen_uv * 2.0 - 1.0, raw_depth);
vec4 view_space = inv_projection_matrix * vec4(normalized_device_coordinates, 1.0);
view_space.xyz /= view_space.w;
return vec2(-view_space.z, raw_depth);
}
void fragment() {
vec2 e = vec2(1./VIEWPORT_SIZE.xy)*1.0;
float depth_diff = 0.0;
float neg_depth_diff = .5;
vec2 depth_data = getDepth(SCREEN_UV, DEPTH_TEXTURE, INV_PROJECTION_MATRIX);
float depth = depth_data.x;
vec3 color = texture(SCREEN_TEXTURE, SCREEN_UV).rgb;
vec3 c = vec3(0.0);
vec2 min_depth_data = depth_data;
float min_depth = 9999999.9;
vec3 normal = texture(NORMAL_TEXTURE, SCREEN_UV).rgb * 2.0 - 1.0;
for (float x = -shadow_thickness; x <= shadow_thickness;x += 1.0){
for (float y = -shadow_thickness; y <= shadow_thickness; y += 1.0){
if ((x == 0.0 && y == 0.0) || (shadow_thickness*shadow_thickness < (x*x + y*y))){
continue;
}
vec2 du_data = getDepth(SCREEN_UV+1.0*vec2(x, y)*e, DEPTH_TEXTURE, INV_PROJECTION_MATRIX);
vec2 dd_data = getDepth(SCREEN_UV+0.5*vec2(x, y)*e, DEPTH_TEXTURE, INV_PROJECTION_MATRIX);
float du = du_data.x;
float dd = dd_data.x;
float dd_diff = clamp(abs((depth - dd) - (dd - du)), 0.0, 1.0);
float val = clamp(abs(depth - du), 0., 1.)/(x*x + y*y)*dd_diff*dd_diff*5000.0;
val = clamp(val, 0.0, 1.0);
depth_diff += val;
if (du < min_depth){
min_depth = du;
min_depth_data = du_data;
c = texture(SCREEN_TEXTURE, SCREEN_UV+vec2(x, y)*e).rgb;
c *= clamp(0.5+ 0.5*dot(normalize(vec2(x, y)), (vec2(0.0, 1.0))), 0.0, 1.0);
}
vec3 nu = texture(NORMAL_TEXTURE, SCREEN_UV+vec2(x, y)*e).rgb * 2.0 - 1.0;
depth_diff += (1.0-abs(dot(nu, normal)))/max(min(dd, depth), 2.0);
}
}
depth_diff = smoothstep(0.2, 0.3, depth_diff);
vec3 final = c*shadow_color;
ALBEDO = final;
float alpha_mask = depth_diff;
DEPTH = min_depth_data.y*alpha_mask + depth_data.y*(1.0-alpha_mask);
ALPHA = clamp((alpha_mask) * 5., 0., 1.);
}
@@ -0,0 +1 @@
uid://b14e5ju3o3bvs
@@ -0,0 +1,56 @@
shader_type spatial;
render_mode blend_premul_alpha, unshaded, ambient_light_disabled;
uniform sampler2D depth_texture : hint_depth_texture;
uniform int step_count : hint_range(3, 15, 2) = 3; // 2 samples per step
uniform float thickness : hint_range(1.0, 16.0, 0.1) = 3.0;
uniform vec3 edge_color : source_color = vec3(0.);
uniform float fade_start : hint_range(1.0, 1000.0, 0.1) = 100.0;
uniform float fade_length : hint_range(1.0, 1000.0, 0.1) = 200.0;
void fragment() {
// Setup step parameters
vec2 step_length = 1.0 / VIEWPORT_SIZE * thickness;
float step_angle = TAU / float(step_count);
// Per-pixel jitter to reduce patterning
float start_angle = fract(sin(dot(SCREEN_UV, vec2(12.9898, 78.233))) * 43758.5453) * TAU;
vec2 dir = vec2(cos(start_angle), sin(start_angle));
// step rotation matrix
mat2 rot = mat2(
vec2(cos(step_angle), -sin(step_angle)),
vec2(sin(step_angle), cos(step_angle)));
vec3 avg_dx = vec3(0.0);
vec3 avg_dy = vec3(0.0);
// save closest pixel to uniformly fade line.
float min_z = 1e6;
// Sample and average derivatives for all pairs
for (int i = 0; i < step_count; i++) {
vec2 uv1 = SCREEN_UV + dir * step_length;
vec2 uv2 = SCREEN_UV - dir * step_length;
float d1 = texture(depth_texture, uv1).r;
float d2 = texture(depth_texture, uv2).r;
vec4 up1 = INV_PROJECTION_MATRIX * vec4(uv1 * 2.0 - 1.0, d1, 1.0);
vec4 up2 = INV_PROJECTION_MATRIX * vec4(uv2 * 2.0 - 1.0, d2, 1.0);
vec3 p1 = up1.xyz / up1.w;
vec3 p2 = up2.xyz / up2.w;
min_z = min(min_z, min(-p1.z, -p2.z));
vec3 diff = p1 - p2;
avg_dx += diff * dir.x;
avg_dy += diff * dir.y;
dir = rot * dir; // rotate direction for next step
}
// fade outline width with distance
float distance_fade = 1e-4 + smoothstep(fade_start + fade_length, fade_start, min_z);
// Edge mask
float edge = 1.0 - smoothstep(0.1, 0.15, dot(normalize(cross(avg_dy, avg_dx)), VIEW));
// Small vignette at screen edges
edge *= smoothstep(0.00, 0.015 * thickness,
1.0 - max(abs(SCREEN_UV.x - 0.5), abs(SCREEN_UV.y - 0.5)) * 2.0);
// blend_premul_alpha avoids need to sample screentexture.
ALBEDO = edge_color * edge;
ALPHA = edge * distance_fade;
}
@@ -0,0 +1 @@
uid://n6r7u234l2iy
@@ -0,0 +1,50 @@
// Luan Ha Trong 2025 //
shader_type canvas_item;
uniform sampler2D SCREEN_TEXTURE: hint_screen_texture,repeat_disable, filter_nearest;
uniform float hue_shift_deg : hint_range(-360.0, 360.0) = 0.0;
uniform float saturation : hint_range(0.0, 2.0) = 1.0;
uniform float value : hint_range(0.0, 2.0) = 1.0;
uniform float alpha : hint_range(0.0, 1.0) = 1.0;
vec3 rgb2hsv(vec3 c) {
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
vec4 p = mix(vec4(c.bg, K.wz),
vec4(c.gb, K.xy),
step(c.b, c.g));
vec4 q = mix(vec4(p.xyw, c.r),
vec4(c.r, p.yzx),
step(p.x, c.r));
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)),
d / (q.x + e),
q.x);
}
vec3 hsv2rgb(vec3 c) {
vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0, 4.0, 2.0),
6.0) - 3.0) - 1.0,
0.0,
1.0);
return c.z * mix(vec3(1.0), rgb, c.y);
}
void fragment() {
vec4 col = texture(SCREEN_TEXTURE, SCREEN_UV);
vec3 hsv = rgb2hsv(col.rgb);
float hue_shift = hue_shift_deg / 360.0;
hsv.x = mod(hsv.x + hue_shift, 1.0);
hsv.y *= saturation;
hsv.z *= value;
col.rgb = hsv2rgb(hsv);
col.a *= alpha;
COLOR = col;
}
@@ -0,0 +1 @@
uid://cs6exg41r28t4
@@ -1,62 +0,0 @@
shader_type canvas_item;
uniform vec4 color : source_color = vec4(1.0);
uniform float width : hint_range(0, 10) = 1.0;
uniform int pattern : hint_range(0, 2) = 0; // diamond, circle, square
uniform bool inside = false;
uniform bool add_margins = true; // only useful when inside is false
void vertex() {
if (add_margins) {
VERTEX += (UV * 2.0 - 1.0) * width;
}
}
bool hasContraryNeighbour(vec2 uv, vec2 texture_pixel_size, sampler2D texture) {
for (float i = -ceil(width); i <= ceil(width); i++) {
float x = abs(i) > width ? width * sign(i) : i;
float offset;
if (pattern == 0) {
offset = width - abs(x);
} else if (pattern == 1) {
offset = floor(sqrt(pow(width + 0.5, 2) - x * x));
} else if (pattern == 2) {
offset = width;
}
for (float j = -ceil(offset); j <= ceil(offset); j++) {
float y = abs(j) > offset ? offset * sign(j) : j;
vec2 xy = uv + texture_pixel_size * vec2(x, y);
if ((xy != clamp(xy, vec2(0.0), vec2(1.0)) || texture(texture, xy).a <= 0.0) == inside) {
return true;
}
}
}
return false;
}
void fragment() {
vec2 uv = UV;
if (add_margins) {
vec2 texture_pixel_size = vec2(1.0) / (vec2(1.0) / TEXTURE_PIXEL_SIZE + vec2(width * 2.0));
uv = (uv - texture_pixel_size * width) * TEXTURE_PIXEL_SIZE / texture_pixel_size;
if (uv != clamp(uv, vec2(0.0), vec2(1.0))) {
COLOR.a = 0.0;
} else {
COLOR = texture(TEXTURE, uv);
}
} else {
COLOR = texture(TEXTURE, uv);
}
if ((COLOR.a > 0.0) == inside && hasContraryNeighbour(uv, TEXTURE_PIXEL_SIZE, TEXTURE)) {
COLOR.rgb = inside ? mix(COLOR.rgb, color.rgb, color.a) : color.rgb;
COLOR.a += (1.0 - COLOR.a) * color.a;
}
}
@@ -1 +0,0 @@
uid://bt4t4qrug135
@@ -1,7 +1,7 @@
[gd_scene load_steps=6 format=3 uid="uid://bg7jmrwdgdqg4"]
[gd_scene format=3 uid="uid://bg7jmrwdgdqg4"]
[ext_resource type="Texture2D" uid="uid://baaujfw8piywi" path="res://common/icons/dna.svg" id="1_88fy1"]
[ext_resource type="Script" uid="uid://bddlpqlfrydn8" path="res://common/vfx/particles/scripts/particles.gd" id="1_faap1"]
[ext_resource type="Texture2D" uid="uid://baaujfw8piywi" path="res://common/icons/dna.svg" id="1_d4jao"]
[ext_resource type="Script" uid="uid://bddlpqlfrydn8" path="res://common/vfx/particles/scripts/effect_particles.gd" id="2_u4sse"]
[sub_resource type="Curve" id="Curve_xmi7c"]
_limits = [-200.0, 200.0, 0.0, 1.0]
@@ -16,9 +16,9 @@ point_count = 2
offsets = PackedFloat32Array(0, 0.80172414, 1)
colors = PackedColorArray(1, 1, 1, 0.65882355, 1, 1, 1, 0.72156864, 1, 1, 1, 0)
[node name="Particles" type="CPUParticles2D"]
[node name="Particles" type="CPUParticles2D" unique_id=222001900]
amount = 1
texture = ExtResource("1_88fy1")
texture = ExtResource("1_d4jao")
randomness = 0.3
emission_shape = 1
emission_sphere_radius = 30.0
@@ -30,4 +30,4 @@ scale_amount_min = 0.4
scale_amount_max = 0.6
scale_amount_curve = SubResource("Curve_22a4c")
color_ramp = SubResource("Gradient_li6gc")
script = ExtResource("1_faap1")
script = ExtResource("2_u4sse")
@@ -0,0 +1,12 @@
[gd_scene format=3 uid="uid://drf23tyb65cpc"]
[ext_resource type="Texture2D" uid="uid://rdrhi3r11ey6" path="res://common/icons/square-rounded.svg" id="1_60vma"]
[node name="ExplosionParticles" type="CPUParticles2D" unique_id=1558673457]
emitting = false
texture = ExtResource("1_60vma")
one_shot = true
direction = Vector2(0, -10)
spread = 60.41
initial_velocity_min = 156.29
initial_velocity_max = 252.19
@@ -1,5 +1,5 @@
extends CPUParticles2D
class_name Particles
class_name EffectParticles
func setup_particles(param : Parameters):
texture = param.texture
+21
View File
@@ -0,0 +1,21 @@
[gd_resource type="AudioBusLayout" format=3 uid="uid://b4cpfxfs74sb8"]
[resource]
bus/1/name = &"Music"
bus/1/solo = false
bus/1/mute = false
bus/1/bypass_fx = false
bus/1/volume_db = 0.0
bus/1/send = &"Master"
bus/2/name = &"Sfx"
bus/2/solo = false
bus/2/mute = false
bus/2/bypass_fx = false
bus/2/volume_db = 0.0
bus/2/send = &"Master"
bus/3/name = &"Ambiance"
bus/3/solo = false
bus/3/mute = false
bus/3/bypass_fx = false
bus/3/volume_db = 0.0
bus/3/send = &"Master"
+31
View File
@@ -0,0 +1,31 @@
{
"@path": "res://addons/dialogic/Resources/character.gd",
"@subpath": NodePath(""),
&"_translation_id": "",
&"color": Color(0, 0.60784316, 1, 1),
&"custom_info": {
"prefix": "",
"sound_mood_default": "",
"sound_moods": {},
"style": "",
"suffix": ""
},
&"default_portrait": "demeter",
&"description": "",
&"display_name": "Demeter",
&"mirror": false,
&"nicknames": [""],
&"offset": Vector2(0, 0),
&"portraits": {
"demeter": {
"export_overrides": {
"image": "\"res://dialogs/characters/portraits/mysterious_demeter.png\""
},
"mirror": false,
"offset": Vector2(0, 0),
"scale": 1,
"scene": ""
}
},
&"scale": 1.0
}
+1
View File
@@ -0,0 +1 @@
uid://c1qjc2ykaypj2
Binary file not shown.
@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://lajbj05iuxut"
path="res://.godot/imported/baguera.wav-a0e2179506d9f51c2a553ff65014308b.sample"
[deps]
source_file="res://dialogs/characters/typing_sounds/baguera.wav"
dest_files=["res://.godot/imported/baguera.wav-a0e2179506d9f51c2a553ff65014308b.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=2
@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://xkiwnglpsqi0"
path="res://.godot/imported/sigourney_weaver.wav-045b3fe21e9c1474adb4b65507740115.sample"
[deps]
source_file="res://dialogs/characters/typing_sounds/sigourney_weaver.wav"
dest_files=["res://.godot/imported/sigourney_weaver.wav-045b3fe21e9c1474adb4b65507740115.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=2
+2 -2
View File
@@ -1,4 +1,4 @@
[gd_resource type="Resource" script_class="DialogicStyle" load_steps=21 format=3 uid="uid://cujoao6hdwng6"]
[gd_resource type="Resource" script_class="DialogicStyle" format=3 uid="uid://cujoao6hdwng6"]
[ext_resource type="PackedScene" uid="uid://cqpb3ie51rwl5" path="res://addons/dialogic/Modules/DefaultLayoutParts/Base_Default/default_layout_base.tscn" id="1_bc2c1"]
[ext_resource type="Script" uid="uid://bwg6yncmh2cml" path="res://addons/dialogic/Resources/dialogic_style_layer.gd" id="2_gjyq6"]
@@ -77,4 +77,4 @@ layer_info = {
"16": SubResource("Resource_cw4cs"),
"17": SubResource("Resource_wofh5")
}
metadata/_latest_layer = "13"
metadata/_latest_layer = ""
@@ -0,0 +1,22 @@
audio "res://common/audio_manager/assets/sfx/dialogs/sfx/incoming_transmission.wav"
[wait time="1.5"]
join demeter center [animation="Bounce In" length="1.0"]
demeter: Hello again !
demeter: It seems that you ran out of energy...
- I'm sorry...
- That's really hard !
- I'm just doing my best !
demeter: It's ok [color=#FFA617]Orchid[/color] ! I spent years waiting for this moment, I can wait more !
demeter: I found you a new body, and a new ship is waiting you outside, but I'm afraid I couldn't get your seeds... I hope you find new ones !
demeter: Do you need some advices ?
- No I'm ok !
- Can I have back some explanations on how all of this works ?
demeter: When you emerge from this building, you'll arrive in a little yellow zone. Its a [b]fertile zone[/b], created by the return of the Talion. This is in this zone and only there were you can plant.
demeter: Then you'll have to get seeds. For that, nothing more simple, you take your shovel tool, and you smash some stones ! Preferably those with yellow cristals on it, it's the [b]Talion veins[/b] .
demeter: Each time you use a tool or plant a seed, you'll spend an [b]energy[/b]. When your out of it, you can just go recharge on the [b]recharge station[/b] you'll find near the entrance. Each time you recharge, time will pass. One day in fact (yes, you don't have a good battery), and the plants will grow !
demeter: You have to obtain enough [b]plant points[/b]. Each plant give one or more [b]plant points[/b] when mature.
demeter: And yes, I almost forgot ! Some plants gain [b]mutations[/b] that can affect their points or behavior. You can get these mutations on new seeds by harvesting, and gain better ones ! But you'll have to wait the plants to die, or smashing them with your shovel when mature.
demeter: Hope I helped !
demeter: I send you the elevator, see you soon !
audio "res://common/audio_manager/assets/sfx/dialogs/sfx/closing_transmission.wav"
[wait time="2.0"]
@@ -0,0 +1 @@
uid://clq4utdtxf01d

Some files were not shown because too many files have changed in this diff Show More