Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ func _ready() -> void:
interact_area.interaction_ended.connect(_on_interaction_ended)
animated_sprite_2d.connect("frame_changed", _on_frame_changed)

GameState.global.item_collected.connect(_update_dialogue_title)
GameState.global.item_consumed.connect(_update_dialogue_title)
if GameState.quest:
GameState.quest.inventory.item_collected.connect(_update_dialogue_title)
GameState.quest.inventory.item_consumed.connect(_update_dialogue_title)
_update_dialogue_title()


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class_name CollectibleItem
extends SceneLink

## Overworld collectible that can be interacted with. When a player interacts
## with it, an [InventoryItem] is added to the [Inventory]
## with it, an [InventoryItem] is added to the [InventoryState].

## Wether the collectible can be seen or collected. This allows the collectible
## to be placed in the scene even when some condition has to be met for it to
Expand Down Expand Up @@ -93,7 +93,7 @@ func _on_interacted(player: Player, _from_right: bool) -> void:
animation_player.play("collected")
await animation_player.animation_finished

GameState.global.add_collected_item(item)
GameState.quest.inventory.add_collected_item(item)

if collected_dialogue:
DialogueManager.show_dialogue_balloon(collected_dialogue, dialogue_title, [self, player])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func show_retelling_dialogue() -> void:


func _has_magical_thread_of_type(type: InventoryItem.ItemType) -> bool:
for item: InventoryItem in GameState.global.inventory:
for item: InventoryItem in GameState.quest.inventory.items:
if item.type == type:
return true
return false
Expand Down Expand Up @@ -91,7 +91,7 @@ func give_spirit_upgrade() -> void:
func on_offering_succeeded() -> void:
loom_offering_animation_player.play(&"loom_offering")
await loom_offering_animation_player.animation_finished
GameState.global.clear_inventory()
GameState.quest.inventory.clear_inventory()

var elder: Elder = _find_elder(GameState.quest.quest)
if elder:
Expand All @@ -108,8 +108,10 @@ func has_retelling() -> bool:


func is_item_offering_possible() -> bool:
return (
GameState.quest
and GameState.quest.quest.threads_to_collect > 0
and GameState.global.inventory.size() >= GameState.quest.quest.threads_to_collect
)
if not GameState.quest:
return false

if GameState.quest.quest.threads_to_collect <= 0:
return false

return GameState.quest.inventory.items.size() >= GameState.quest.quest.threads_to_collect
8 changes: 2 additions & 6 deletions scenes/globals/game_state/game_state.gd
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,10 @@ func _ready() -> void:
return


## Sets [member quest], sets up a new [PlayerState] if necessary, and clears the
## inventory. Note that this does not actually switch to the first scene of [param
## Sets [member quest], setting up a new [PlayerState] if necessary.
## Note that this does not actually switch to the first scene of [param
## new_quest].
func start_quest(new_quest: Quest) -> void:
# TODO: this suggests that the inventory should be part of QuestState
global.clear_inventory()

var quest_player_state: PlayerState
if new_quest is LoreQuest:
# Duplicate the current global player state. If the quest is completed,
Expand Down Expand Up @@ -157,7 +154,6 @@ func mark_quest_completed() -> void:
## Abandon the current [member quest] without marking it as completed.
func abandon_quest() -> void:
quest = null
global.clear_inventory()


## Clear the persisted state.
Expand Down
46 changes: 1 addition & 45 deletions scenes/globals/game_state/global_state.gd
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,12 @@
class_name GlobalState
extends Resource

## Emitted when a new item is collected.
signal item_collected(item: InventoryItem)

## Emitted when a item is consumed, causing it to be removed from the
## [member inventory].
signal item_consumed(item: InventoryItem)

## Emitted when a quest is added or removed from [member completed_quests].
signal completed_quests_changed

## Emitted when the [member helper] changes.
signal helper_changed

## Inventory of collected threads. Modify with [member add_collected_item] and
## [member clear_inventory].
@export var inventory: Array[InventoryItem]

## Types of items in [member inventory], for storage. Use [member inventory]
## in game code.
@export_storage var inventory_item_types: Array[String]:
get():
var types: Array[String]
for item: InventoryItem in inventory:
types.append(InventoryItem.ItemType.keys()[item.type])
return types
set(new_value):
var items: Array[InventoryItem]
for type_name: String in new_value:
if InventoryItem.ItemType.has(type_name):
items.append(InventoryItem.with_type(InventoryItem.ItemType[type_name]))
else:
push_warning("Ignoring unknown inventory item type: %s" % type_name)
inventory = items
emit_changed()

## [Quest]s which the player has previously completed. Modify this with
## [method set_quest_completed_state].
@export var completed_quests: Array[Quest]
Expand Down Expand Up @@ -74,25 +45,10 @@ signal helper_changed

func _validate_property(property: Dictionary) -> void:
match property.name:
"completed_quests", "inventory":
"completed_quests":
property.usage &= ~PROPERTY_USAGE_STORAGE


## Add the [InventoryItem] to the [member inventory].
func add_collected_item(item: InventoryItem) -> void:
inventory.append(item)
item_collected.emit(item)
emit_changed()


## Remove all [InventoryItem]s from the [member inventory].
func clear_inventory() -> void:
for item: InventoryItem in inventory.duplicate():
inventory.erase(item)
item_consumed.emit(item)
emit_changed()


## Updates [member completed_quests] to include [param quest] if [param
## is_completed] is true, or remove [param quest] if [param is_completed] is
## false.
Expand Down
54 changes: 54 additions & 0 deletions scenes/globals/game_state/inventory_state.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# SPDX-FileCopyrightText: The Threadbare Authors
# SPDX-License-Identifier: MPL-2.0
@tool
class_name InventoryState
extends Resource

## Emitted when a new item is collected and added to [member items].
signal item_collected(item: InventoryItem)

## Emitted when a item is consumed, causing it to be removed from
## [member items].
signal item_consumed(item: InventoryItem)

## Collected threads. Modify with [member add_collected_item] and
## [member clear_inventory].
@export var items: Array[InventoryItem]

## Types of items in [member inventory], for storage. Use [member inventory]
## in game code.
@export_storage var item_types: Array[String]:
get():
var types: Array[String]
for item: InventoryItem in items:
types.append(InventoryItem.ItemType.keys()[item.type])
return types
set(new_value):
items = []
for type_name: String in new_value:
if InventoryItem.ItemType.has(type_name):
items.append(InventoryItem.with_type(InventoryItem.ItemType[type_name]))
else:
push_warning("Ignoring unknown inventory item type: %s" % type_name)
emit_changed()


## Add the [InventoryItem] to [member items].
func add_collected_item(item: InventoryItem) -> void:
items.append(item)
item_collected.emit(item)
emit_changed()


## Remove all [InventoryItem]s from [member items].
func clear_inventory() -> void:
for item: InventoryItem in items.duplicate():
items.erase(item)
item_consumed.emit(item)
emit_changed()


func _validate_property(property: Dictionary) -> void:
match property.name:
"inventory":
property.usage &= ~PROPERTY_USAGE_STORAGE
1 change: 1 addition & 0 deletions scenes/globals/game_state/inventory_state.gd.uid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uid://bv4qgda3w0f0t
3 changes: 3 additions & 0 deletions scenes/globals/game_state/quest_state.gd
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ extends Resource
## quest is abandoned.
@export var abandon_spawn_point: NodePath

## Inventory of collected threads.
@export var inventory := InventoryState.new()


func _init(q: Quest = null, p: PlayerState = null) -> void:
quest = q
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ do animation_player.play("retreat")
do animation_player.animation_finished
Flaxfred: Stranger, you have helped us more than you know!
Flaxfred: It feels like LinenVille’s spirit has come back to us. Here: take this thread as a parting gift.
do GameState.global.add_collected_item(InventoryItem.with_type(InventoryItem.ItemType.SPIRIT))
do GameState.quest.inventory.add_collected_item(InventoryItem.with_type(InventoryItem.ItemType.SPIRIT))
do animation_player.play("leave")
do wait(1.0)
=> END
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: The Threadbare Authors
# SPDX-License-Identifier: MPL-2.0
~ start
do GameState.global.add_collected_item(InventoryItem.with_type(InventoryItem.ItemType.SPIRIT))
do GameState.quest.inventory.add_collected_item(InventoryItem.with_type(InventoryItem.ItemType.SPIRIT))
Jeremy, envuelto en polvo y con la ropa rota, mira salir el deslumbrante sol.
Por primera vez en su vida , no se siente apurado ni ansioso por lo que venga después.
Está disfrutando del silencio, el aire y la luz. El Ojo Revelador mostró su alma. le permitió
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ func _ready() -> void:

# On ready, the HUD is populated with the items that were collected so
# far in the quest.
var items_collected := GameState.global.inventory
var items_collected := GameState.quest.inventory.items
for i: int in min(items_collected.size(), n):
items_container.get_child(i).start_as_filled(items_collected[i])

# Then, when each new item is collected, it is added to the progress UI
GameState.global.item_collected.connect(self._on_item_collected)
GameState.global.item_consumed.connect(self._on_item_consumed)
GameState.quest.inventory.item_collected.connect(self._on_item_collected)
GameState.quest.inventory.item_consumed.connect(self._on_item_consumed)


func _on_helper_state_changed() -> void:
Expand Down
2 changes: 1 addition & 1 deletion scenes/world_map/components/frays_end.dialogue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: MPL-2.0
~ hotel_california
# TODO: Uh oh, no ngettext() support in Dialogue Manager...
match GameState.global.inventory.size():
match GameState.quest.inventory.items.size():
when 1:
{{player_name}}: I’d better take this thread to the Eternal Loom first.
else:
Expand Down
5 changes: 3 additions & 2 deletions scenes/world_map/components/frays_end.gd
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ extends Node2D

func _ready() -> void:
_update_story_quest_progress_visibility()
GameState.global.item_collected.connect(_update_story_quest_progress_visibility)
GameState.global.item_consumed.connect(_update_story_quest_progress_visibility)
if GameState.quest:
GameState.quest.inventory.item_collected.connect(_update_story_quest_progress_visibility)
GameState.quest.inventory.item_consumed.connect(_update_story_quest_progress_visibility)


func _update_story_quest_progress_visibility(_item: InventoryItem = null) -> void:
Expand Down