-
Notifications
You must be signed in to change notification settings - Fork 403
Primer PR de StoryQuest "El Hilo Que No Teji" #2428
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
671bf8e
81497ca
fb8de0c
a7d3a1c
b03e6ff
ee7d779
f98b939
f6ee385
91a7cd8
0820759
88e1a91
6583e64
9759e94
9c803f7
3a90f0e
2c82899
c60b49c
621f322
f8986eb
767c9bf
df31f03
ed947e4
09890d5
4212fbf
ab8c10a
97e12f1
f473b01
388b8f5
c433efc
b7a2331
7ef8800
fbda393
60dfc25
cb80b4e
7f1d649
199a1fd
d634231
6ee58f2
047c21c
1cb5c14
0edbd3c
16edf11
4759603
a5bcd74
aa42604
d1c24ea
473b1ff
d06c9c7
d35a167
11f466f
6750078
c240d77
f998e12
d7575eb
fb10f5e
2e03482
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # SPDX-FileCopyrightText: The Threadbare Authors | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| extends CanvasLayer | ||
|
|
||
|
|
||
| # Called when the node enters the scene tree for the first time. | ||
| func _ready() -> void: | ||
| pass # Replace with function body. | ||
|
|
||
|
|
||
| # Called every frame. 'delta' is the elapsed time since the previous frame. | ||
| func _process(delta: float) -> void: | ||
| pass |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| uid://drhc8bfctccyi |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| [gd_scene format=3 uid="uid://3jye8tk0fbof"] | ||
|
|
||
| [ext_resource type="Script" uid="uid://drhc8bfctccyi" path="res://scenes/quests/story_quests/el_hilo_que_no_teji/0_intro/intro_components/FlashOverlay.gd" id="1_db7qw"] | ||
|
|
||
| [node name="FlashOverlay" type="CanvasLayer" unique_id=64455848] | ||
| script = ExtResource("1_db7qw") | ||
|
|
||
| [node name="ColorRect" type="ColorRect" parent="." unique_id=1298434957] | ||
| offset_right = 40.0 | ||
| offset_bottom = 40.0 | ||
| color = Color(0, 0, 0, 0) |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,80 @@ | ||||||||||||
| # SPDX-FileCopyrightText: The Threadbare Authors | ||||||||||||
| # SPDX-License-Identifier: MPL-2.0 | ||||||||||||
| extends Node | ||||||||||||
| signal intro_finished | ||||||||||||
|
|
||||||||||||
| @onready var camera: Camera2D = $"../Camera2D" | ||||||||||||
| @onready var flash_layer: CanvasLayer = $"../FlashOverlay" | ||||||||||||
| @onready var flash_rect: ColorRect = $"../FlashOverlay/ColorRect" | ||||||||||||
|
|
||||||||||||
| @onready var lino_animation: AnimationPlayer = $"../OnTheGround/AnimationPlayer" | ||||||||||||
| @onready var tilemap_walls: TileMapLayer = $"../CabanaParedes" | ||||||||||||
| @onready var tilemap_furnitures: TileMapLayer = $"../Furnitures" | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| func _ready() -> void: | ||||||||||||
| intro_finished.connect(_on_intro_finished) | ||||||||||||
|
|
||||||||||||
| start_intro() | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| func start_intro() -> void: | ||||||||||||
| print("INTRO DIRECTOR FUNCIONA EN PLANO FIJO") | ||||||||||||
| camera.make_current() | ||||||||||||
| flash_rect.modulate.a = 0.0 | ||||||||||||
|
|
||||||||||||
| if lino_animation: | ||||||||||||
| lino_animation.stop() | ||||||||||||
|
|
||||||||||||
| await get_tree().process_frame | ||||||||||||
| await _run_sequence() | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| func _run_sequence() -> void: | ||||||||||||
| # ========================================================================= | ||||||||||||
| # FASE 1: REPRODUCCIÓN DE LA CINEMÁTICA PRINCIPAL | ||||||||||||
| # ========================================================================= | ||||||||||||
| if lino_animation: | ||||||||||||
| lino_animation.play("intro_cinematic") | ||||||||||||
|
|
||||||||||||
| await lino_animation.animation_finished | ||||||||||||
| else: | ||||||||||||
| print("ERROR: No se encontró el AnimationPlayer en la ruta especificada.") | ||||||||||||
|
|
||||||||||||
| # ========================================================================= | ||||||||||||
| # FASE 2: AJUSTES FINALES DEL ENTORNO (Puerta abierta / Perro) | ||||||||||||
| # ========================================================================= | ||||||||||||
| await _flash_in() | ||||||||||||
|
|
||||||||||||
| if tilemap_walls: | ||||||||||||
| tilemap_walls.set_cell(Vector2i(14, 5), -1) | ||||||||||||
|
|
||||||||||||
| if tilemap_furnitures: | ||||||||||||
| tilemap_furnitures.set_cell(Vector2i(14, 6), -1) | ||||||||||||
|
|
||||||||||||
| await get_tree().create_timer(1.0).timeout | ||||||||||||
|
|
||||||||||||
| print("INTRO SECUENCIA TERMINADA") | ||||||||||||
|
|
||||||||||||
| intro_finished.emit() | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| func _flash_in() -> void: | ||||||||||||
| flash_rect.modulate.a = 1.0 | ||||||||||||
| var tween := create_tween() | ||||||||||||
| tween.tween_property(flash_rect, "modulate:a", 0.0, 0.4) | ||||||||||||
| await tween.finished | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| # ========================================================================= | ||||||||||||
| # CAMBIO DE ESCENA AUTOMÁTICO | ||||||||||||
| # ========================================================================= | ||||||||||||
| func _on_intro_finished() -> void: | ||||||||||||
| print("CAMBIANDO AL NIVEL DE STEALTH...") | ||||||||||||
|
|
||||||||||||
| var nueva_escena_ruta: String = "res://scenes/quests/story_quests/el_hilo_que_no_teji/1_stealth/el_hilo_que_no_teji_stealth.tscn" | ||||||||||||
|
|
||||||||||||
| if ResourceLoader.exists(nueva_escena_ruta): | ||||||||||||
| get_tree().change_scene_to_file(nueva_escena_ruta) | ||||||||||||
| else: | ||||||||||||
| print("ERROR CRÍTICO: No se encontró el archivo de escena en: ", nueva_escena_ruta) | ||||||||||||
|
Comment on lines
+77
to
+80
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
If you change scene directly, the game state does not get updated, and so the current scene will be lost across save & resume. |
||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| uid://dhnyq4cxprbbv |
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This dialogue doesn't seem to be used. If that is intentional, please remove the unused file. I think it's great that your intro scene establishes the mood with just animation, without any text - it's effective! |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # SPDX-FileCopyrightText: The Threadbare Authors | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
|
|
||
| ~ start | ||
| do animation_player.play(&"walk_on") | ||
| [speed=0.25]... | ||
| [speed=0.5]Hace frío... [speed=0.5]¿La puerta... [speed=0.5]abierta? | ||
| [speed=0.5]¿Manchitas? [speed=0.85]¡Manchitas! | ||
| # (Aquí el jugador camina hacia la puerta y activa el gatillo del collar) | ||
| [speed=0.25]Si esto… [speed=0.25]es un sueño... [speed=0.2]¿por qué su collar sigue mojándome las manos? | ||
| do animation_player.play(&"walk_off") | ||
| => END |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| [remap] | ||
|
|
||
| importer="dialogue_manager" | ||
| importer_version=15 | ||
| type="Resource" | ||
| uid="uid://d2stoi0e0r3uf" | ||
| path="res://.godot/imported/el_hilo_que_no_teji_intro.dialogue-4cced3a830a4a166356e901e4247afde.tres" | ||
|
|
||
| [deps] | ||
|
|
||
| source_file="res://scenes/quests/story_quests/el_hilo_que_no_teji/0_intro/intro_components/el_hilo_que_no_teji_intro.dialogue" | ||
| dest_files=["res://.godot/imported/el_hilo_que_no_teji_intro.dialogue-4cced3a830a4a166356e901e4247afde.tres"] | ||
|
|
||
| [params] | ||
|
|
||
| defaults=true |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # SPDX-FileCopyrightText: The Threadbare Authors | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| extends Label | ||
|
|
||
| # Las variables estáticas son inmortales y sobreviven a las recargas por muerte | ||
| static var base_hilos_nivel: int = -1 | ||
| static var ultima_escena_cargada: String = "" | ||
|
|
||
| func _ready() -> void: | ||
| # Obtenemos la ruta exacta del minijuego en el que estamos ahora mismo | ||
| var escena_actual = get_tree().current_scene.scene_file_path | ||
|
|
||
| # Si la escena actual es diferente a la última registrada, significa que pasamos de nivel | ||
| if escena_actual != ultima_escena_cargada: | ||
| ultima_escena_cargada = escena_actual | ||
| # Tomamos la "foto" de los hilos globales solo al entrar por primera vez al nivel | ||
| base_hilos_nivel = ElHiloQueNoTejiState.hilos_recogidos | ||
|
|
||
| func _process(_delta: float) -> void: | ||
| var hilos_actuales = ElHiloQueNoTejiState.hilos_recogidos | ||
|
|
||
| # Restamos usando la variable estática que no se borra al morir | ||
| var fragmentos_en_este_nivel = hilos_actuales - base_hilos_nivel | ||
|
|
||
| # Blindamos los resultados por si acaso | ||
| if fragmentos_en_este_nivel <= 0: | ||
| text = "0/3" | ||
| elif fragmentos_en_este_nivel >= 3: | ||
| text = "3/3" | ||
| else: | ||
| text = str(fragmentos_en_este_nivel) + "/3" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| uid://2ipchillwtnj |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| shader_type canvas_item; | ||
|
|
||
| // Parámetros ajustables en el Inspector | ||
| uniform vec4 fog_color : source_color = vec4(0.45, 0.48, 0.52, 0.35); | ||
| // Velocidad moderada pero constante (ajustada para que no canse la vista) | ||
| uniform float speed : hint_range(0.0, 1.0) = 0.12; | ||
| uniform float detail_steps : hint_range(1.0, 6.0) = 4.0; | ||
| uniform float thread_shredding : hint_range(0.1, 3.0) = 1.8; // Más alto deshilacha más la niebla | ||
| uniform float density : hint_range(0.1, 5.0) = 0.5; // Menos densidad para que se vean las islas flotantes | ||
|
|
||
| // DIRECCIÓN ÚNICA: El viento viaja hacia la izquierda de forma infinita y fluida | ||
| uniform vec2 wind_direction = vec2(-1.0, -0.05); | ||
| // ESTIRADO EXTREMO: Convierte la niebla en filamentos largos como hilos de viento | ||
| uniform float stretch_factor : hint_range(1.0, 10.0) = 5.0; | ||
|
|
||
| varying vec2 world_position; | ||
|
|
||
| float rand(vec2 coord) { | ||
| return fract(sin(dot(coord, vec2(12.9898, 78.233))) * 43758.5453123); | ||
| } | ||
|
|
||
| float noise(vec2 coord) { | ||
| vec2 i = floor(coord); | ||
| vec2 f = fract(coord); | ||
| float a = rand(i); | ||
| float b = rand(i + vec2(1.0, 0.0)); | ||
| float c = rand(i + vec2(0.0, 1.0)); | ||
| float d = rand(i + vec2(1.0, 1.0)); | ||
| vec2 u = f * f * (3.0 - 2.0 * f); | ||
| return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; | ||
| } | ||
|
|
||
| // Movimiento fractal limpio para mantener el loop perfecto | ||
| float fbm(vec2 coord) { | ||
| float value = 0.0; | ||
| float scale = 1.0; | ||
| // Matriz fija para que el ruido no rebote ni cambie de dirección | ||
| mat2 magic_rotation = mat2(vec2(0.8, 0.6), vec2(-0.6, 0.8)); | ||
|
|
||
| for (int i = 0; i < 4; i++) { | ||
| value += noise(coord) * scale; | ||
| coord = magic_rotation * coord * 3.5; | ||
| scale *= 0.25; | ||
| } | ||
| return value; | ||
| } | ||
|
|
||
| void vertex() { | ||
| world_position = (MODEL_MATRIX * vec4(VERTEX, 0.0, 1.0)).xy; | ||
| } | ||
|
|
||
| void fragment() { | ||
| // Estiramos drásticamente el eje X para crear líneas de viento estables | ||
| vec2 stretch = vec2(stretch_factor, 1.0); | ||
| vec2 base_uv = (world_position * 0.002 * density) / stretch; | ||
|
|
||
| // Movimiento 100% lineal y en una sola dirección (sin senos ni cosenos que causen vaivén) | ||
| vec2 wind_1 = wind_direction * (TIME * speed); | ||
| vec2 wind_2 = wind_direction * (TIME * speed * 0.7) + vec2(0.2, 0.5); | ||
|
|
||
| // Mezclamos las capas de viento estirado | ||
| float layer1 = fbm(base_uv + wind_1); | ||
| float layer2 = fbm(base_uv * 1.3 + wind_2); | ||
|
|
||
| // Filtramos con un contraste alto para que queden pasillos transparentes entre las rocas filosas | ||
| float final_shredded_fog = smoothstep(0.55, 0.75, layer1 * layer2 * 1.6); | ||
|
|
||
| // Deshilachamos los bordes para que parezcan jirones de niebla rasgados por las islas | ||
| final_shredded_fog = pow(final_shredded_fog, thread_shredding); | ||
|
|
||
| float alpha_mask = final_shredded_fog * fog_color.a; | ||
|
|
||
| COLOR = vec4(fog_color.rgb, alpha_mask); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| uid://dn6w5kifgeusk |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| [gd_scene format=3 uid="uid://cahsamhamvuqc"] | ||
|
|
||
| [ext_resource type="Script" uid="uid://o54tdc374nxc" path="res://scenes/game_elements/props/sign/components/sign.gd" id="1_qdt8g"] | ||
| [ext_resource type="Texture2D" uid="uid://cq5l1xle30ch7" path="res://assets/third_party/tiny-swords/Deco/17.png" id="2_ng0n8"] | ||
| [ext_resource type="FontFile" uid="uid://b0tjcgrk504qg" path="res://assets/third_party/fonts/jersey/Jersey10-Regular.ttf" id="3_br1b7"] | ||
|
|
||
| [sub_resource type="CapsuleShape2D" id="CapsuleShape2D_cb2ey"] | ||
| radius = 12.0 | ||
| height = 50.0 | ||
|
|
||
| [sub_resource type="CircleShape2D" id="CircleShape2D_85li6"] | ||
| radius = 161.89503 | ||
|
|
||
| [node name="Sign" type="Node2D" unique_id=1579530966] | ||
| script = ExtResource("1_qdt8g") | ||
|
|
||
| [node name="Appearance" type="Sprite2D" parent="." unique_id=1364985273] | ||
| texture = ExtResource("2_ng0n8") | ||
| offset = Vector2(0, -30) | ||
|
|
||
| [node name="Collider" type="StaticBody2D" parent="." unique_id=882843758] | ||
| collision_layer = 16 | ||
| collision_mask = 0 | ||
|
|
||
| [node name="CollisionShape2D" type="CollisionShape2D" parent="Collider" unique_id=505297847] | ||
| rotation = -1.57079 | ||
| shape = SubResource("CapsuleShape2D_cb2ey") | ||
|
|
||
| [node name="LabelContainer" type="MarginContainer" parent="." unique_id=1137800349] | ||
| z_index = 1 | ||
| offset_left = -96.0 | ||
| offset_top = -176.0 | ||
| offset_right = 104.0 | ||
| offset_bottom = -76.0 | ||
| pivot_offset = Vector2(100, 50) | ||
|
|
||
| [node name="PanelContainer" type="PanelContainer" parent="LabelContainer" unique_id=1780698378] | ||
| layout_mode = 2 | ||
| size_flags_horizontal = 4 | ||
| size_flags_vertical = 8 | ||
|
|
||
| [node name="MarginContainer" type="MarginContainer" parent="LabelContainer/PanelContainer" unique_id=869205213] | ||
| layout_mode = 2 | ||
| size_flags_horizontal = 4 | ||
| size_flags_vertical = 8 | ||
| theme_override_constants/margin_left = 10 | ||
| theme_override_constants/margin_top = 5 | ||
| theme_override_constants/margin_right = 10 | ||
| theme_override_constants/margin_bottom = 5 | ||
|
|
||
| [node name="Label" type="Label" parent="LabelContainer/PanelContainer/MarginContainer" unique_id=1830143827] | ||
| unique_name_in_owner = true | ||
| layout_mode = 2 | ||
| size_flags_horizontal = 4 | ||
| theme_override_fonts/font = ExtResource("3_br1b7") | ||
| theme_override_font_sizes/font_size = 19 | ||
| horizontal_alignment = 1 | ||
| vertical_alignment = 2 | ||
|
|
||
| [node name="Area2D" type="Area2D" parent="." unique_id=1146211072] | ||
| collision_layer = 4 | ||
|
|
||
| [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D" unique_id=966380620] | ||
| shape = SubResource("CircleShape2D_85li6") | ||
|
|
||
| [connection signal="body_entered" from="Area2D" to="." method="_on_area_2d_body_entered"] | ||
| [connection signal="body_exited" from="Area2D" to="." method="_on_area_2d_body_exited"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Empty script, can be removed.