Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -308,3 +308,8 @@ locale/translations_pot_files=PackedStringArray("res://scenes/menus/title/compon
textures/canvas_textures/default_texture_filter=0
renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"

[threadbare]

debugging/skip_sokobans=true
debugging/skip_splash=true
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# SPDX-FileCopyrightText: The Threadbare Authors
# SPDX-License-Identifier: MPL-2.0
~ start
Do you want some help?
- Yes => help_accepted
- No => help_denied

~ help_accepted
# TODO: do something that helps the player here. Like:
# do fix_bridge()
Bye!
do GameState.clear_upgrade()
=> END

~ help_denied
OK, bye!
=> 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://c667fv6ngpc7s"
path="res://.godot/imported/default_helper.dialogue-2d2de185b0afee791b6bd97e2398a0de.tres"

[deps]

source_file="res://scenes/game_elements/characters/npcs/components/default_helper.dialogue"
dest_files=["res://.godot/imported/default_helper.dialogue-2d2de185b0afee791b6bd97e2398a0de.tres"]

[params]

defaults=true
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# SPDX-FileCopyrightText: The Threadbare Authors
# SPDX-License-Identifier: MPL-2.0
extends Node

@export var target_upgrade: InventoryItem.ItemType = InventoryItem.ItemType.MEMORY
@onready var character: CharacterRandomizer = get_parent()


func _ready() -> void:
GameState.upgrade_changed.connect(_on_upgrade_changed)
_on_upgrade_changed()


func _on_upgrade_changed() -> void:
var is_enabled := (
target_upgrade == GameState.upgrade_type and bool(GameState.upgrade_character_seed)
)
character.visible = is_enabled
character.process_mode = Node.PROCESS_MODE_INHERIT if is_enabled else Node.PROCESS_MODE_DISABLED
if is_enabled:
character.character_seed = GameState.upgrade_character_seed
character.apply_character_randomizations()
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uid://diskln3jup064
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
class_name EternalLoom
extends Node2D

signal retelling_started
signal retelling_finished
signal give_retelling_upgrade(type: InventoryItem.ItemType)

const ETERNAL_LOOM_INTERACTION: DialogueResource = preload("uid://yafw7bf362gh")

## Scenes that are the first of three Sokoban puzzles. A random one will be used
Expand All @@ -24,7 +28,7 @@ var _have_threads := is_item_offering_possible()

func _ready() -> void:
talk_behavior.dialogue = ETERNAL_LOOM_INTERACTION
talk_behavior.title = "have_threads" if _have_threads else "no_threads"
talk_behavior.before_dialogue = _before_dialogue
interact_area.interaction_ended.connect(self._on_interaction_ended)

if GameState.incorporating_threads:
Expand All @@ -46,6 +50,16 @@ func _ready() -> void:
GameState.mark_quest_completed()


func _before_dialogue() -> void:
if _have_threads:
if GameState.current_quest and GameState.current_quest.retelling:
talk_behavior.title = "start_retelling"
else:
talk_behavior.title = "have_threads"
else:
talk_behavior.title = "no_threads"


func _find_elder(quest: Quest) -> Elder:
for elder in elders:
if quest.resource_path.begins_with(elder.quest_directory):
Expand All @@ -56,6 +70,16 @@ func _find_elder(quest: Quest) -> Elder:

func _on_interaction_ended() -> void:
if _have_threads:
if GameState.current_quest and GameState.current_quest.retelling:
# Hide interact label during retelling
interact_area.disabled = true
DialogueManager.show_dialogue_balloon(GameState.current_quest.retelling, "", [self])
retelling_started.emit()
await DialogueManager.dialogue_ended
await on_offering_succeeded()
interact_area.disabled = false
retelling_finished.emit()

if not ProjectSettings.get_setting(ThreadbareProjectSettings.SKIP_SOKOBANS):
# Hide interact label during scene transition
interact_area.disabled = true
Expand All @@ -65,6 +89,60 @@ func _on_interaction_ended() -> void:
GameState.mark_quest_completed()


func _has_magical_thread_of_type(type: InventoryItem.ItemType) -> bool:
for item in GameState.items_collected():
if item.type == type:
return true
return false


func has_memory() -> bool:
return _has_magical_thread_of_type(InventoryItem.ItemType.MEMORY)


func has_imagination() -> bool:
return _has_magical_thread_of_type(InventoryItem.ItemType.IMAGINATION)


func has_spirit() -> bool:
return _has_magical_thread_of_type(InventoryItem.ItemType.SPIRIT)


func memory_text() -> String:
var has_it := _has_magical_thread_of_type(InventoryItem.ItemType.MEMORY)
return "(Memory available!)" if has_it else ""


func imagination_text() -> String:
var has_it := _has_magical_thread_of_type(InventoryItem.ItemType.IMAGINATION)
return "(Imagination available!)" if has_it else ""


func spirit_text() -> String:
var has_it := _has_magical_thread_of_type(InventoryItem.ItemType.SPIRIT)
return "(Spirit available!)" if has_it else ""


func _give_upgrade(type: InventoryItem.ItemType) -> void:
var has_it := _has_magical_thread_of_type(type)
if not has_it:
push_warning("Trying to give an upgrade for missing item type", type)
return
give_retelling_upgrade.emit(type)


func give_memory_upgrade() -> void:
_give_upgrade(InventoryItem.ItemType.MEMORY)


func give_imagination_upgrade() -> void:
_give_upgrade(InventoryItem.ItemType.IMAGINATION)


func give_spirit_upgrade() -> void:
_give_upgrade(InventoryItem.ItemType.SPIRIT)


func on_offering_succeeded() -> void:
loom_offering_animation_player.play(&"loom_offering")
await loom_offering_animation_player.animation_finished
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ It seems you are lacking the threads of Memory, Imagination, and Spirit... try c
The Memory, Imagination, and Spirit threads are ready to be incorporated into the loom!
do on_offering_succeeded()
=> END

~ start_retelling
Tell us a story about your last adventure!
=> END
35 changes: 35 additions & 0 deletions scenes/globals/game_state/game_state.gd
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ signal completed_quests_changed
## Emitted when lore or StoryQuest player abilities change.
signal abilities_changed

signal upgrade_changed

const GAME_STATE_PATH := "user://game_state.cfg"
const INVENTORY_SECTION := "inventory"
const INVENTORY_ITEMS_KEY := "items_collected"
Expand All @@ -38,6 +40,8 @@ const QUEST_CHALLENGE_START_KEY := "challenge_start_scene"
const QUEST_PLAYER_ABILITIES_KEY := "quest_player_abilities"
const GLOBAL_SECTION := "global"
const GLOBAL_INCORPORATING_THREADS_KEY := "incorporating_threads"
const GLOBAL_UPGRADE_TYPE_KEY := "upgrade_type"
const GLOBAL_UPGRADE_CHARACTER_SEED_KEY := "upgrade_character_seed"
const COMPLETED_QUESTS_KEY := "completed_quests"
const CURRENTSCENE_KEY := "current_scene"
const SPAWNPOINT_KEY := "current_spawn_point"
Expand Down Expand Up @@ -87,6 +91,9 @@ var current_lives: int = MAX_LIVES
## Current state of artificial lights.
var lights_on: bool

var upgrade_type: InventoryItem.ItemType = InventoryItem.ItemType.NONE
var upgrade_character_seed: int = 0

## Set when the loom transports the player to a trio of Sokoban puzzles, so that
## when the player returns to Fray's End the loom can trigger a brief cutscene.
var incorporating_threads: bool = false
Expand Down Expand Up @@ -148,6 +155,28 @@ func _ready() -> void:
prints("[LIVES DEBUG] GameState initialized with", current_lives, "lives")


func set_upgrade(new_upgrade_type: InventoryItem.ItemType, new_upgrade_character_seed: int) -> void:
upgrade_type = new_upgrade_type
upgrade_character_seed = new_upgrade_character_seed
upgrade_changed.emit()

_state.set_value(GLOBAL_SECTION, GLOBAL_UPGRADE_TYPE_KEY, upgrade_type)
_state.set_value(GLOBAL_SECTION, GLOBAL_UPGRADE_CHARACTER_SEED_KEY, upgrade_character_seed)
_save()


func clear_upgrade() -> void:
upgrade_type = InventoryItem.ItemType.NONE
upgrade_character_seed = 0
upgrade_changed.emit()

if _state.has_section_key(GLOBAL_SECTION, GLOBAL_UPGRADE_TYPE_KEY):
_state.erase_section_key(GLOBAL_SECTION, GLOBAL_UPGRADE_TYPE_KEY)
if _state.has_section_key(GLOBAL_SECTION, GLOBAL_UPGRADE_CHARACTER_SEED_KEY):
_state.erase_section_key(GLOBAL_SECTION, GLOBAL_UPGRADE_CHARACTER_SEED_KEY)
_save()


## Set the [member incorporating_threads] flag.
func set_incorporating_threads(new_incorporating_threads: bool) -> void:
incorporating_threads = new_incorporating_threads
Expand Down Expand Up @@ -484,6 +513,12 @@ func restore() -> Dictionary:

var scene_path: String = _state.get_value(GLOBAL_SECTION, CURRENTSCENE_KEY, "")
current_spawn_point = _state.get_value(GLOBAL_SECTION, SPAWNPOINT_KEY, ^"")
if _state.has_section_key(GLOBAL_SECTION, GLOBAL_UPGRADE_TYPE_KEY):
upgrade_type = _state.get_value(GLOBAL_SECTION, GLOBAL_UPGRADE_TYPE_KEY)
if _state.has_section_key(GLOBAL_SECTION, GLOBAL_UPGRADE_CHARACTER_SEED_KEY):
upgrade_character_seed = _state.get_value(
GLOBAL_SECTION, GLOBAL_UPGRADE_CHARACTER_SEED_KEY, 0
)
incorporating_threads = _state.get_value(
GLOBAL_SECTION, GLOBAL_INCORPORATING_THREADS_KEY, false
)
Expand Down
1 change: 1 addition & 0 deletions scenes/globals/game_state/inventory/inventory_item.gd
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ enum ItemType {
MEMORY,
IMAGINATION,
SPIRIT,
NONE,
}

const HUD_TEXTURES: Dictionary[ItemType, Texture2D] = {
Expand Down
4 changes: 4 additions & 0 deletions scenes/menus/storybook/components/quest.gd
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ const FILENAME := "quest.tres"
## Whether this is a lore quest (part of the main storyline).
@export var is_lore_quest: bool = false

## Optional dialogue to retell the adventures that occurred in the quest,
## when returning the magical threads to the loom.
@export var retelling: DialogueResource

@export_group("Animation")

## An optional sprite frame library to show in the storybook page for this quest.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# SPDX-FileCopyrightText: The Threadbare Authors
# SPDX-License-Identifier: MPL-2.0
~ start
My town has been unraveled.
Do you want to hear my story?
- Yes => help_accepted
- No => help_denied

~ help_accepted
Lore lore lore.
Bye!
do GameState.clear_upgrade()
=> END

~ help_denied
OK, bye!
=> 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://jf1tng8jxd3o"
path="res://.godot/imported/music_lore_helper.dialogue-e07faa651568cb20c63b23c6b4902663.tres"

[deps]

source_file="res://scenes/quests/lore_quests/quest_001/1_music_puzzle/components/dialogues/music_lore_helper.dialogue"
dest_files=["res://.godot/imported/music_lore_helper.dialogue-e07faa651568cb20c63b23c6b4902663.tres"]

[params]

defaults=true
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,19 @@
[ext_resource type="AudioStream" uid="uid://c7om8kdork2rx" path="res://assets/third_party/sounds/characters/enemies/guard/Torch.ogg" id="31_ink4c"]
[ext_resource type="SpriteFrames" uid="uid://cefk7kf0bpm3q" path="res://scenes/quests/lore_quests/quest_001/1_music_puzzle/components/bonfire_sign/bonfire_sign_backward.tres" id="32_0wfv2"]
[ext_resource type="AudioStream" uid="uid://xuqj6b5qqs3w" path="res://assets/third_party/sounds/ambient/459405__pfannkuchn__small-river-1-fast-semi-close.ogg" id="35_l8fgn"]
[ext_resource type="PackedScene" uid="uid://dgrrudegturnw" path="res://scenes/game_elements/characters/npcs/townie.tscn" id="42_ps6xw"]
[ext_resource type="Script" uid="uid://edcifob4jc4s" path="res://scenes/game_logic/talk_behavior.gd" id="43_icnj0"]
[ext_resource type="Resource" uid="uid://jf1tng8jxd3o" path="res://scenes/quests/lore_quests/quest_001/1_music_puzzle/components/dialogues/music_lore_helper.dialogue" id="44_pgedt"]
[ext_resource type="Script" uid="uid://du8wfijr35r35" path="res://scenes/game_elements/props/interact_area/interact_area.gd" id="45_6y4lh"]
[ext_resource type="Script" uid="uid://diskln3jup064" path="res://scenes/game_elements/characters/npcs/components/helper_character.gd" id="46_jaqfj"]

[sub_resource type="Resource" id="Resource_dp3eg"]
script = ExtResource("15_rxyid")
metadata/_custom_type_script = "uid://bgmwplmj3bfls"

[sub_resource type="RectangleShape2D" id="RectangleShape2D_vigmf"]
size = Vector2(52, 61)

[sub_resource type="Curve2D" id="Curve2D_306df"]
_data = {
"points": PackedVector2Array(0, 0, 0, 0, 64, 2088, 15, 121, -15, -121, 56, 1640, 3, 148, -3, -148, -64, 1088, -99.22, 89.54, 99.22, -89.54, 8, 592, -164.56, 1.21, 164.56, -1.21, 544, 408, -84.7, -82.28, 84.7, 82.28, 1152, 552, 44.77, -128.26, -44.77, 128.26, 1168, 1528, 35.09, -88.33, -35.09, 88.33, 968, 1704, 0, 0, 0, 0, 960, 2080)
Expand Down Expand Up @@ -1476,6 +1484,34 @@ item = SubResource("Resource_dp3eg")
collected_dialogue = ExtResource("6_l4i5r")
dialogue_title = &"well_done"

[node name="Helper" parent="OnTheGround" unique_id=1098678013 instance=ExtResource("42_ps6xw")]
position = Vector2(675, 1714)
scale = Vector2(-1, 1)
look_at_side = 1

[node name="TalkBehavior" type="Node" parent="OnTheGround/Helper" unique_id=1704084092 node_paths=PackedStringArray("interact_area")]
script = ExtResource("43_icnj0")
dialogue = ExtResource("44_pgedt")
interact_area = NodePath("../InteractArea")
metadata/_custom_type_script = "uid://edcifob4jc4s"

[node name="InteractArea" type="Area2D" parent="OnTheGround/Helper" unique_id=1857849502]
visible = false
collision_layer = 32
collision_mask = 0
script = ExtResource("45_6y4lh")
interact_label_position = Vector2(0, -100)
action = "Want a story?"
metadata/_custom_type_script = "uid://du8wfijr35r35"

[node name="CollisionShape2D" type="CollisionShape2D" parent="OnTheGround/Helper/InteractArea" unique_id=317299534]
position = Vector2(0, -23.5)
shape = SubResource("RectangleShape2D_vigmf")
debug_color = Color(0.600391, 0.54335, 0, 0.42)

[node name="HelperCharacter" type="Node" parent="OnTheGround/Helper" unique_id=2049853056]
script = ExtResource("46_jaqfj")

[node name="ScreenOverlay" type="CanvasLayer" parent="." unique_id=1333274951]

[node name="HUD" parent="." unique_id=1648131045 instance=ExtResource("16_ytxvq")]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# SPDX-FileCopyrightText: The Threadbare Authors
# SPDX-License-Identifier: MPL-2.0
~ start
if FillBarrel.has_barrel_to_fill()
That jar is hard to reach!
May I fill it for you?
- Yes => help_accepted
- No => help_denied
else
You did it! => END

~ help_accepted
do FillBarrel.fill_barrel()
Bye!
do GameState.clear_upgrade()
=> END

~ help_denied
OK, bye!
=> END
Loading
Loading