188 lines
6.1 KiB
GDScript
188 lines
6.1 KiB
GDScript
@icon("res://addons/popochiu/icons/room.png")
|
|
class_name PopochiuRoomData
|
|
extends Resource
|
|
## This class is used to store information when saving and loading the game. It also ensures that
|
|
## the data remains throughout the game's execution.
|
|
##
|
|
## It also has data of the [PopochiuProp]s, [PopochiuHotspot]s, [PopochiuWalkableArea]s,
|
|
## [PopochiuRegion]s, and [PopochiuCharacter]s in a [PopochiuRoom].
|
|
|
|
## The identifier of the object used in scripts.
|
|
@export var script_name := ""
|
|
## The path to the scene file to be used when adding the character to the game during runtime.
|
|
@export_file("*.tscn") var scene := ""
|
|
## Whether the room was already visited by the player.
|
|
@export var visited := false
|
|
## Whether this is the first time the player visits the room.
|
|
@export var visited_first_time := false
|
|
## The number of times the player has visited this room.
|
|
@export var visited_times := 0
|
|
|
|
## Stores data about the [PopochiuProp]s in the room.
|
|
var props := {}
|
|
## Stores data about the [PopochiuHotspot]s in the room.
|
|
var hotspots := {}
|
|
## Stores data about the [PopochiuWalkableArea]s in the room.
|
|
var walkable_areas := {}
|
|
## Stores data about the [PopochiuRegion]s in the room.
|
|
var regions := {}
|
|
## Stores data about the [PopochiuCharacter]s in the room. To see the stored data by default, check
|
|
## [method save_characters].
|
|
var characters := {}
|
|
|
|
|
|
#region Virtual ####################################################################################
|
|
## Called when the game is saved.
|
|
## [i]Virtual[/i].
|
|
func _on_save() -> Dictionary:
|
|
return {}
|
|
|
|
|
|
## Called when the game is loaded. The structure of [param data] is the same returned by
|
|
## [method _on_save].
|
|
## [i]Virtual[/i].
|
|
func _on_load(_data: Dictionary) -> void:
|
|
pass
|
|
|
|
|
|
#endregion
|
|
|
|
#region Public #####################################################################################
|
|
## Use this to store custom data when saving the game. The returned [Dictionary] must contain only
|
|
## JSON supported types: [bool], [int], [float], [String].
|
|
func on_save() -> Dictionary:
|
|
return _on_save()
|
|
|
|
|
|
## Called when the game is loaded. [param data] will have the same structure you defined for the
|
|
## returned [Dictionary] by [method _on_save].
|
|
func on_load(data: Dictionary) -> void:
|
|
_on_load(data)
|
|
|
|
|
|
## Stores the data of each of the children inside [b]$WalkableAreas[/b], [b]$Props[/b],
|
|
## [b]$Hotspots[/b], [b]$Regions[/b], and [b]$Characters[/b].
|
|
func save_children_states() -> void:
|
|
if PopochiuUtils.r.current and PopochiuUtils.r.current.state == self:
|
|
for t in PopochiuResources.ROOM_CHILDREN:
|
|
for node in PopochiuUtils.r.current.call("get_" + t):
|
|
if node is PopochiuProp and not node.clickable: continue
|
|
|
|
_save_object_state(
|
|
node,
|
|
PopochiuResources["%s_IGNORE" % (t as String).to_upper()],
|
|
get(t)
|
|
)
|
|
|
|
# Save the state of characters
|
|
save_characters()
|
|
|
|
return
|
|
|
|
var base_dir := resource_path.get_base_dir()
|
|
var dependencies_paths: Array = Array(ResourceLoader.get_dependencies(
|
|
resource_path.replace(".tres", ".tscn")
|
|
)).map(
|
|
func (dependency: String) -> String:
|
|
return dependency.get_slice("::", 2)
|
|
)
|
|
|
|
for t in PopochiuResources.ROOM_CHILDREN:
|
|
if (get(t) as Dictionary).is_empty():
|
|
var category := (t as String).replace(" ", "")
|
|
var objs_path := "%s/%s" % [base_dir, category]
|
|
|
|
var dir := DirAccess.open(objs_path)
|
|
|
|
if not dir: continue
|
|
|
|
dir.include_hidden = false
|
|
dir.include_navigational = false
|
|
|
|
dir.list_dir_begin()
|
|
|
|
var folder_name := dir.get_next()
|
|
|
|
while folder_name != "":
|
|
if dir.current_is_dir():
|
|
# ---- Fix #320 ----------------------------------------------------------------
|
|
# Ignore objects that are not part of the dependencies of the room. This is the
|
|
# scenario where an object from the room was removed from the tree but not from
|
|
# the file system
|
|
var scene_path := "%s/%s/%s_%s.tscn" % [
|
|
objs_path,
|
|
folder_name,
|
|
category.trim_suffix("s"),
|
|
folder_name,
|
|
]
|
|
if not scene_path in dependencies_paths:
|
|
folder_name = dir.get_next()
|
|
continue
|
|
# ---------------------------------------------------------------- Fix #320 ----
|
|
|
|
var script_path := scene_path.replace("tscn", "gd")
|
|
if not FileAccess.file_exists(script_path):
|
|
folder_name = dir.get_next()
|
|
continue
|
|
|
|
var node: Node2D = load(script_path).new()
|
|
node.script_name = folder_name.to_pascal_case()
|
|
|
|
_save_object_state(
|
|
node,
|
|
PopochiuResources["%s_IGNORE" % (t as String).to_upper()],
|
|
get(t)
|
|
)
|
|
|
|
node.free()
|
|
|
|
folder_name = dir.get_next()
|
|
|
|
|
|
## Save room data related to the characters in the room. The stored data contains:
|
|
## [codeblock]{
|
|
## x = PopochiuCharacter.position.x
|
|
## y = PopochiuCharacter.position.y
|
|
## facing = PopochiuCharacter._looking_dir
|
|
## visible = PopochiuCharacter.visible
|
|
## modulate = PopochiuCharacter.modulate
|
|
## self_modulate = PopochiuCharacter.self_modulate
|
|
## light_mask = PopochiuCharacter.light_mask
|
|
## }[/codeblock]
|
|
func save_characters() -> void:
|
|
for character: PopochiuCharacter in PopochiuUtils.r.current.get_characters():
|
|
characters[character.script_name] = {
|
|
x = character.position.x,
|
|
y = character.position.y,
|
|
facing = character._looking_dir,
|
|
visible = character.visible,
|
|
modulate = character.modulate.to_html(),
|
|
self_modulate = character.self_modulate.to_html(),
|
|
light_mask = character.light_mask,
|
|
baseline = character.baseline,
|
|
# Store this values using built-in types
|
|
walk_to_point = {
|
|
x = character.walk_to_point.x,
|
|
y = character.walk_to_point.y,
|
|
},
|
|
look_at_point = {
|
|
x = character.look_at_point.x,
|
|
y = character.look_at_point.y,
|
|
},
|
|
# TODO: Store the state of the current animation (and more data if
|
|
# necessary)
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
#region Private ####################################################################################
|
|
func _save_object_state(node: Node2D, ignore: Array, target: Dictionary) -> void:
|
|
var state := {}
|
|
PopochiuResources.store_properties(state, node, ignore)
|
|
|
|
# Add the PopochiuProp state to the room's props
|
|
target[node.script_name] = state
|
|
|
|
|
|
#endregion
|