maxgame/addons/popochiu/migration/migrations/popochiu_migration_2.gd
2025-07-17 01:49:18 -04:00

671 lines
28 KiB
GDScript

@tool
class_name PopochiuMigration2
extends PopochiuMigration
## Migrates projects from Beta to Release.
const VERSION = 2
const DESCRIPTION = "Make changes from beta-x to 2.0.0 release"
const STEPS = [
"Update external scenes and assign scripts that didn't exist before. (pre [i]release[/i])",
"Add a [b]ScalingPolygon[/b] node to each [b]PopochiuCharacter[/b]. (pre [i]beta 1[/i])",
"Move popochiu_settings.tres to ProjectSettings. (pre [i]beta 3[/i])",
#"Update the DialogMenu GUI component. (pre [i]beta 3[/i])",
#"(Optional) Update SettingsBar in 2-click Context-sensitive GUI template. (pre [i]beta 3[/i])",
"Remove [b]BaselineHelper[/b] and [b]WalkToHelper[/b] nodes in [b]PopochiuClickable[/b]s." \
+ " Also remove [b]DialogPos[/b] node in [b]PopochiuCharacter[/b]s. (pre [i]release[/i])",
"Update uses of deprecated properties and methods. (pre [i]release[/i])",
"Update rooms sizes",
]
const RESET_CHILDREN_OWNER = "reset_children_owner"
const GAME_INVENTORY_BAR_PATH =\
"res://game/gui/components/inventory_bar/inventory_bar.tscn"
const GAME_SETTINGS_BAR_PATH =\
"res://game/gui/components/settings_bar/settings_bar.tscn"
const GAME_DIALOG_MENU_PATH = "res://game/gui/components/dialog_menu/dialog_menu.tscn"
const GAME_DIALOG_MENU_OPTION_PATH =\
"res://game/gui/components/dialog_menu/dialog_menu_option/"
const ADDON_DIALOG_MENU_PATH =\
"res://addons/popochiu/engine/objects/gui/components/dialog_menu/dialog_menu.tscn"
const TextSpeedOption = preload(
PopochiuResources.GUI_ADDON_FOLDER + "components/settings_bar/resources/text_speed_option.gd"
)
var _gui_templates_helper := preload(
"res://addons/popochiu/editor/helpers/popochiu_gui_templates_helper.gd"
)
#region Virtual ####################################################################################
## This is code specific for this migration. This should return [code]true[/code] if the migration
## is successful. This is called from [method do_migration] which checks to make sure the migration
## should be done before calling this.
func _do_migration() -> bool:
return await PopochiuMigrationHelper.execute_migration_steps(
self,
[
_update_objects_in_rooms,
_add_scaling_polygon_to_characters,
_move_settings_to_project_settings,
#_update_dialog_menu,
#_update_simple_click_settings_bar,
_remove_helper_nodes,
_replace_deprecated,
_update_rooms_sizes,
]
)
#endregion
#region Private ####################################################################################
## Update external prop scenes and assign missing scripts for each prop, hotspot, region, and
## walkable area that didn't exist prior [i]beta 1[/i].
func _update_objects_in_rooms() -> Completion:
var any_room_updated := PopochiuUtils.any_exhaustive(
PopochiuEditorHelper.get_rooms(), _update_room
)
_reload_needed = any_room_updated
return Completion.DONE if any_room_updated else Completion.IGNORED
## Update the children of the different groups in [param popochiu_room] so the use instances of the
## new objects: [PopochiuProp], [PopochiuHotspot], [PopochiuRegion], and [PopochiuWalkableArea].
func _update_room(popochiu_room: PopochiuRoom) -> bool:
var room_objects_to_add := []
var room_objects_to_check := []
PopochiuUtils.any_exhaustive([
PopochiuPropFactory.new(),
PopochiuHotspotFactory.new(),
PopochiuRegionFactory.new(),
PopochiuWalkableAreaFactory.new(),
PopochiuMarkerFactory.new(),
], _create_new_room_objects.bind(popochiu_room, room_objects_to_add, room_objects_to_check))
for group: Dictionary in room_objects_to_add:
group.objects.all(
func (new_obj) -> bool:
# Set the owner of the new object and do the same for its children (those that
# were marked as PopochiuRoomObjFactory.CHILD_VISIBLE_IN_ROOM_META)
new_obj.owner = popochiu_room
for child: Node in new_obj.get_meta(RESET_CHILDREN_OWNER):
child.owner = popochiu_room
new_obj.remove_meta(RESET_CHILDREN_OWNER)
return true
)
if PopochiuEditorHelper.pack_scene(popochiu_room) != OK:
PopochiuUtils.print_error(
"Migration 2: Couldn't update [b]%s[/b] after adding new nodes." %
popochiu_room.script_name
)
var room_object_updated := false
for obj: Node2D in room_objects_to_check:
# Check if the node's scene has all the expected nodes based on its base scene
var added_nodes := _add_lacking_nodes(obj)
if added_nodes and not room_object_updated:
room_object_updated = added_nodes
if room_object_updated and PopochiuEditorHelper.pack_scene(popochiu_room) != OK:
PopochiuUtils.print_error(
"Migration 2: Couldn't update [b]%s[/b] after adding lacking nodes." %
popochiu_room.script_name
)
return !room_objects_to_add.is_empty() or room_object_updated
## Create a new scene of the [param factory] type. The scene will be placed in its corresponding
## folder inside the [param popochiu_room] folder. Created [Node]s will be stored in
## [param room_objects_to_add] so they are added to the room later.
func _create_new_room_objects(
factory: PopochiuRoomObjFactory,
popochiu_room: PopochiuRoom,
room_objects_to_add := [],
room_objects_to_check := []
) -> bool:
var created_objects := []
for obj in _get_room_objects(
popochiu_room.get_node(factory.get_group()),
[],
factory.get_type_method()
):
# Copy the points of the polygons that were previously a node visible in the Room tree, but
# now are only properties
if (
(obj is PopochiuProp or obj is PopochiuHotspot or obj is PopochiuRegion)
and (obj.has_node("InteractionPolygon") or obj.has_node("InteractionPolygon2"))
):
var interaction_polygon: CollisionPolygon2D = obj.get_node("InteractionPolygon")
if obj.has_node("InteractionPolygon2"):
interaction_polygon = obj.get_node("InteractionPolygon2")
if interaction_polygon.owner == popochiu_room:
# Store the polygon vectors into the new @export variable
obj.interaction_polygon = interaction_polygon.polygon
obj.interaction_polygon_position = interaction_polygon.position
# Delete the CollisionPolygon2D node that in previous versions was attached to the
# room
interaction_polygon.owner = null
interaction_polygon.free()
elif (
obj is PopochiuWalkableArea
and (obj.has_node("Perimeter") or obj.has_node("Perimeter2"))
):
var perimeter: NavigationRegion2D = obj.get_node("Perimeter")
if obj.has_node("Perimeter2"):
perimeter = obj.get_node("Perimeter2")
if perimeter.owner == popochiu_room:
# Store the navigation polygon vectors into the new @export variable
obj.map_navigation_polygon(perimeter)
# Delete the NavigationRegion2D node that in previous versions was attached to the
# room
perimeter.owner = null
perimeter.free()
# If the object already has its own scene and a script that is not inside Popochiu's folder,
# then just check if there are lacking nodes inside its scene
if (
not obj.scene_file_path.is_empty()
and not "addons" in obj.scene_file_path
and not "addons" in obj.get_script().resource_path
):
room_objects_to_check.append(obj)
continue
# Create the new scene (and script if needed) of the [obj]
var obj_factory: PopochiuRoomObjFactory = factory.get_new_instance()
if obj_factory.create_from(obj, popochiu_room) != ResultCodes.SUCCESS:
continue
# Map the properties of the [obj] to its new instance
created_objects.append(_create_new_room_obj(obj_factory, obj, popochiu_room))
if created_objects.is_empty():
return false
room_objects_to_add.append({
factory = factory,
objects = created_objects
})
return true
## Recursively search for nodes of a specific type in the [param parent] and its children. The nodes
## found are added to the [param objects] array. The [param type_method] is used to determine if a
## node is the desired type.
func _get_room_objects(parent: Node, objects: Array, type_method: Callable) -> Array:
for child: Node in parent.get_children():
if type_method.call(child):
objects.append(child)
else:
# If the child is a Node containing other nodes, go deeper in the tree looking for room
# object nodes
_get_room_objects(child, objects, type_method)
return objects
## Maps the properties (and nodes if needed) of [param source] to a new instance of itself created
## from [param obj_factory]. This assures that objects coming from versions prior to [i]beta 1[/i]
## will have the corresponding structure of new Popochiu versions.
func _create_new_room_obj(
obj_factory: PopochiuRoomObjFactory, source: Node, room: PopochiuRoom
) -> Node:
var new_obj: Node = (ResourceLoader.load(
obj_factory.get_scene_path()
) as PackedScene).instantiate(PackedScene.GEN_EDIT_STATE_INSTANCE)
new_obj.set_meta(RESET_CHILDREN_OWNER, [])
source.name += "_"
source.get_parent().add_child(new_obj)
source.get_parent().move_child(new_obj, source.get_index())
# Check if the original object has a script attached (different from the default one)
if (
source.get_script()
and not "addons" in source.get_script().resource_path
and source.get_script().resource_path != new_obj.get_script().resource_path
):
# Change the default script by the one attached to the original object
new_obj.set_script(load(source.get_script().resource_path))
# Copy its extra properties (those declared as vars in the script) to the new instance
PopochiuResources.copy_popochiu_object_properties(
new_obj, source, PopochiuResources[
"%s_IGNORE" % obj_factory.get_group().to_snake_case().to_upper()
]
)
new_obj.position = source.position
new_obj.scale = source.scale
new_obj.z_index = source.z_index
if new_obj is PopochiuProp or new_obj is PopochiuHotspot:
new_obj.baseline = source.baseline
new_obj.walk_to_point = source.walk_to_point
if new_obj is PopochiuProp:
new_obj.texture = source.texture
new_obj.frames = source.frames
new_obj.v_frames = source.v_frames
new_obj.link_to_item = source.link_to_item
new_obj.interaction_polygon = source.interaction_polygon
new_obj.interaction_polygon_position = source.interaction_polygon_position
if obj_factory.get_snake_name() in ["bg", "background"]:
new_obj.z_index = -1
if new_obj is PopochiuRegion:
new_obj.interaction_polygon = source.interaction_polygon
new_obj.interaction_polygon_position = source.interaction_polygon_position
if new_obj is PopochiuWalkableArea:
new_obj.interaction_polygon = source.interaction_polygon
new_obj.interaction_polygon_position = source.interaction_polygon_position
# Remove the old [source] node from the room
source.free()
return new_obj
## Checks the [code].tscn[/code] file of [param source] for lacking nodes based on its type. If
## there are any, then it will add them so the structure of the scene matches the one of the object
## it inherits from.
func _add_lacking_nodes(source: Node) -> bool:
var obj_scene: Node2D = ResourceLoader.load(source.scene_file_path).instantiate()
var was_updated := false
if (
PopochiuEditorHelper.is_prop(obj_scene)
or PopochiuEditorHelper.is_hotspot(obj_scene)
or PopochiuEditorHelper.is_region(obj_scene)
) and not obj_scene.has_node("InteractionPolygon"):
var interaction_polygon := CollisionPolygon2D.new()
interaction_polygon.name = "InteractionPolygon"
interaction_polygon.polygon = PackedVector2Array([
Vector2(-10, -10), Vector2(10, -10), Vector2(10, 10), Vector2(-10, 10)
])
obj_scene.add_child(interaction_polygon)
obj_scene.move_child(interaction_polygon, 0)
interaction_polygon.owner = obj_scene
was_updated = true
elif PopochiuEditorHelper.is_walkable_area(obj_scene) and not obj_scene.has_node("Perimeter"):
var perimeter := NavigationRegion2D.new()
perimeter.name = "Perimeter"
var polygon := NavigationPolygon.new()
polygon.agent_radius = 0.0
perimeter.navigation_polygon = polygon
obj_scene.add_child(perimeter)
perimeter.owner = obj_scene
obj_scene.interaction_polygon = source.interaction_polygon
obj_scene.clear_and_bake(perimeter.navigation_polygon)
was_updated = true
if PopochiuEditorHelper.is_prop(obj_scene) and not obj_scene.has_node("AnimationPlayer"):
var animation_player := AnimationPlayer.new()
obj_scene.add_child(animation_player)
animation_player.owner = obj_scene
was_updated = true
if was_updated:
PopochiuEditorHelper.pack_scene(obj_scene)
return was_updated
## Add a [CollisionPolygon2D] node named "ScalingPolygon" to each [PopochiuCharacter] that doesn't
## have it. Returns [code]Completion.DONE[/code] if any character is updated,
## [code]Completion.IGNORED[/code] otherwise.
func _add_scaling_polygon_to_characters() -> Completion:
# Get the characters' .tscn files
var file_paths := PopochiuMigrationHelper.get_absolute_file_paths_for_file_extensions(
PopochiuResources.CHARACTERS_PATH,
["tscn"]
)
var any_character_updated := PopochiuUtils.any_exhaustive(file_paths, _add_scaling_polygon_to)
return Completion.DONE if any_character_updated else Completion.IGNORED
## Loads the [PopochiuCharacter] in [param scene_path] and add a [CollisionPolygon2D] node if it
## doesn't has a [code]ScalingPolygon[/code] child.
func _add_scaling_polygon_to(scene_path: String) -> bool:
var popochiu_character: PopochiuCharacter = (load(scene_path) as PackedScene).instantiate()
var was_scene_updated := false
# ---- Add the ScalingPolygon node if needed ---------------------------------------------------
if not popochiu_character.has_node("ScalingPolygon"):
was_scene_updated = true
var scaling_polygon := CollisionPolygon2D.new()
scaling_polygon.name = "ScalingPolygon"
scaling_polygon.polygon = PackedVector2Array([
Vector2(-5, -5), Vector2(5, -5), Vector2(5, 5), Vector2(-5, 5)
])
popochiu_character.add_child(scaling_polygon)
popochiu_character.move_child(scaling_polygon, 1)
scaling_polygon.owner = popochiu_character
if was_scene_updated and PopochiuEditorHelper.pack_scene(popochiu_character) != OK:
PopochiuUtils.print_error(
"Couldn't update [b]%s[/b] with new voices array." % popochiu_character.script_name
)
return was_scene_updated
## Move the values from the old [code]popochiu_settings.tres[/code] file to the new
## [code]Project Settings > Popochiu[/code] section. Returns [constant Completion.DONE] if the values
## are moved, [constant Completion.IGNORED] if the file doesn't exist, [constant Completion.FAILED]
## otherwise.
func _move_settings_to_project_settings() -> Completion:
var old_settings_file := PopochiuMigrationHelper.old_settings_file
if not FileAccess.file_exists(old_settings_file):
return Completion.IGNORED
# Move custom defined values in the old [popochiu_settings.tres] file to Project Settings
var old_settings: PopochiuSettings = load(old_settings_file)
var settings_map := {
# ---- GUI ---------------------------------------------------------------------------------
"SCALE_GUI": "",
"FADE_COLOR": "",
"SKIP_CUTSCENE_TIME": "",
# ---- Dialogs -----------------------------------------------------------------------------
"TEXT_SPEED": old_settings.text_speeds[old_settings.default_text_speed],
"AUTO_CONTINUE_TEXT": "",
"USE_TRANSLATIONS": "",
# ---- Inventory ---------------------------------------------------------------------------
"INVENTORY_LIMIT": "",
# ---- Pixel game --------------------------------------------------------------------------
"PIXEL_ART_TEXTURES": "is_pixel_art_game",
"PIXEL_PERFECT": "is_pixel_perfect",
}
for key: String in settings_map:
PopochiuConfig.set_project_setting(
key,
old_settings[key.to_lower()] if key.is_empty() else settings_map[key]
)
for item_name: StringName in old_settings.items_on_start:
var items_on_start := PopochiuConfig.get_inventory_items_on_start()
items_on_start.append(str(item_name))
PopochiuConfig.set_inventory_items_on_start(items_on_start)
# Move custom defined values in the old [popochiu_settings.tres] to their corresponding GUI
# components
if FileAccess.file_exists(GAME_INVENTORY_BAR_PATH):
var inventory_bar: Control = load(GAME_INVENTORY_BAR_PATH).instantiate()
inventory_bar.always_visible = old_settings.inventory_always_visible
PopochiuEditorHelper.pack_scene(inventory_bar)
if FileAccess.file_exists(GAME_SETTINGS_BAR_PATH):
var settings_bar: PanelContainer = load(GAME_SETTINGS_BAR_PATH).instantiate()
settings_bar.always_visible = old_settings.toolbar_always_visible
PopochiuEditorHelper.pack_scene(settings_bar)
# Remove the old [popochiu_settings.tres]
if DirAccess.remove_absolute(old_settings_file) != OK:
PopochiuUtils.print_error("Couldn't delete [code]%s[/code]." % old_settings_file)
return Completion.FAILED
return Completion.DONE
## Update the [code]DialogMenu[/code] GUI component to use the new [code]DialogMenuOption[/code].
## Returns [constant Completion.DONE] if the component is updated, [constant Completion.IGNORED] if
## the game's GUI is not using the [code]DialogMenu[/code] component or is already using the new
## version, [constant Completion.FAILED] otherwise.
func _update_dialog_menu() -> Completion:
if (
not FileAccess.file_exists(GAME_DIALOG_MENU_PATH)
or DirAccess.dir_exists_absolute(GAME_DIALOG_MENU_OPTION_PATH)
):
# The game's GUI is not using the DialogMenu GUI component or is already using its beta-3
# version
return Completion.IGNORED
# Copy the new [PopochiuDialogMenuOption] component to the game's GUI components folder
await _gui_templates_helper.copy_components(ADDON_DIALOG_MENU_PATH)
# Store the scene of the new [PopochiuDialogMenuOption] in the game's graphic interface folder
var game_dialog_menu_option: PackedScene = load(PopochiuResources.GUI_GAME_FOLDER.path_join(
"components/dialog_menu/dialog_menu_option/dialog_menu_option.tscn"
))
# Assign the new [PopochiuDialogMenuOption] to the game's GUI dialog menu component and delete
# any option inside its DialogOptionsContainer child
var game_dialog_menu: PopochiuDialogMenu = load(GAME_DIALOG_MENU_PATH).instantiate()
game_dialog_menu.option_scene = game_dialog_menu_option
for opt in game_dialog_menu.get_node("ScrollContainer/DialogOptionsContainer").get_children():
opt.owner = null
opt.free()
var done := PopochiuEditorHelper.pack_scene(game_dialog_menu)
if done != OK:
PopochiuUtils.print_error(
"Couldn't update PopochiuDialogMenuOption reference in PopochiuDialogMenu"
)
return Completion.FAILED
# Update the dependency to [PopochiuDialogMenuOption] in the game's graphic interface scene
var game_gui: PopochiuGraphicInterface = load(PopochiuResources.GUI_GAME_SCENE).instantiate()
game_gui.get_node("DialogMenu").option_scene = game_dialog_menu_option
done = PopochiuEditorHelper.pack_scene(game_gui)
if done != OK:
PopochiuUtils.print_error(
"Couldn't update PopochiuDialogMenuOption reference in PopochiuGraphicInterface"
)
return Completion.FAILED
# Delete the old [dialog_menu_option.tscn] file
done = DirAccess.remove_absolute(
"res://game/gui/components/dialog_menu/dialog_menu_option.tscn"
)
if done != OK:
PopochiuUtils.print_error(
"Couldn't update PopochiuDialogMenuOption reference in PopochiuDialogMenu"
)
return Completion.FAILED
return Completion.DONE
## Update the [code]SettingsBar[/code] GUI component in the 2-click Context-sensitive GUI template.
## Returns [constant Completion.DONE] if the component is updated, [constant Completion.IGNORED] if
## the game's GUI does not use the [code]SettingsBar[/code] GUI component or is already using the
## new version, [constant Completion.FAILED] otherwise.
func _update_simple_click_settings_bar() -> Completion:
if not FileAccess.file_exists(GAME_SETTINGS_BAR_PATH):
# The game's GUI does not use the SettingsBar GUI component
return Completion.IGNORED
var game_settings_bar: PanelContainer = load(GAME_SETTINGS_BAR_PATH).instantiate()
var dialog_speed_button: TextureButton = game_settings_bar.get_node("Box/BtnDialogSpeed")
if not dialog_speed_button.speed_options.is_empty():
# The component is up to date with the beta-3 version
return Completion.IGNORED
var addons_settings_bar: PanelContainer = load(PopochiuResources.GUI_TEMPLATES_FOLDER.path_join(
"simple_click/components/settings_bar/settings_bar.tscn"
)).instantiate()
# Store the speed options defined in the original component
var speed_options := []
for opt: TextSpeedOption in addons_settings_bar.get_node("Box/BtnDialogSpeed").speed_options:
var option := TextSpeedOption.new()
option.resource_name = opt.resource_name
option.speed = opt.speed
option.description = opt.description
option.icon = load(opt.icon.resource_path.replace(
PopochiuResources.GUI_TEMPLATES_FOLDER.path_join(
"simple_click/components/settings_bar/sprites/"
),
"res://game/gui/components/settings_bar/sprites/"
))
speed_options.append(option)
# Assign the options to the component in the game's graphic interface component and save the
# SettingsBat scene
dialog_speed_button.speed_options = speed_options
var scene_updated := PopochiuEditorHelper.pack_scene(game_settings_bar)
return Completion.DONE if scene_updated == OK else Completion.FAILED
## Remove visual helper nodes in all [PopochiuProp]s, [PopochiuHotspot]s, and [PopochiuCharacter]s.
func _remove_helper_nodes() -> Completion:
var characters_paths := PopochiuMigrationHelper.get_absolute_file_paths_for_file_extensions(
PopochiuResources.CHARACTERS_PATH,
["tscn"]
)
var props_and_hotspots_paths :=\
PopochiuMigrationHelper.get_absolute_file_paths_for_file_extensions(
PopochiuResources.ROOMS_PATH,
["tscn"],
["markers", "regions", "walkable_areas"]
).filter(
func (file_path: String) -> bool:
return not "room_" in file_path
)
var popochiu_clickables := characters_paths + props_and_hotspots_paths
var any_updated := PopochiuUtils.any_exhaustive(popochiu_clickables, _remove_helper_nodes_in)
return Completion.DONE if any_updated else Completion.IGNORED
## Remove the [code]BaselineHelper[/code] and [code]WalkToHelper[/code] nodes in [param scene_path].
## Also remove the [code]DialogPos[/code] node if it is a [PopochiuCharacter]. Returns
## [constant Completion.DONE] if any node is removed, [constant Completion.IGNORED] otherwise.
func _remove_helper_nodes_in(scene_path: String) -> bool:
# Load the scene ignoring cache so changes made in previous steps are taken into account
var popochiu_clickable: PopochiuClickable = (
ResourceLoader.load(scene_path, "", ResourceLoader.CACHE_MODE_IGNORE) as PackedScene
).instantiate(PackedScene.GEN_EDIT_STATE_MAIN)
var was_scene_updated := false
# ---- Remove the BaselineHelper and WalkToHelper nodes ----------------------------------------
if _remove_node(popochiu_clickable, "BaselineHelper"):
was_scene_updated = true
if _remove_node(popochiu_clickable, "WalkToHelper"):
was_scene_updated = true
# ---- Remove the DialogPos node ---------------------------------------------------------------
# TODO: Uncomment this once PR #241 is merged
if popochiu_clickable is PopochiuCharacter and popochiu_clickable.has_node("DialogPos"):
popochiu_clickable.dialog_pos = popochiu_clickable.get_node("DialogPos").position
_remove_node(popochiu_clickable, "DialogPos")
was_scene_updated = true
if was_scene_updated and PopochiuEditorHelper.pack_scene(popochiu_clickable, scene_path) != OK:
PopochiuUtils.print_error(
"Couldn't remove helper nodes in [b]%s[/b]." % popochiu_clickable.script_name
)
return was_scene_updated
## Remove the node in [param parent] with the path [param node_path]. Returns [code]true[/code] if
## the node is removed, [code]false[/code] otherwise.
func _remove_node(parent: Node, node_path: NodePath) -> bool:
if parent.has_node(node_path):
var child: Node = parent.get_node(node_path)
child.owner = null
child.free()
return true
return false
## Replace calls to deprecated properties and methods:
## - [code]E.current_room[/code] by [code]R.current[/code].
## - [code]E.goto_room()[/code] by [code]R.goto_room()[/code].
## - [code]E.queue_camera_offset()[/code] by [code]E.camera.queue_change_offset()[/code].
## - [code]E.camera_offset()[/code] by [code]E.camera.change_offset()[/code].
## - [code]E.queue_camera_shake()[/code] by [code]E.camera.queue_shake()[/code].
## - [code]E.camera_shake()[/code] by [code]E.camera.shake()[/code].
## - [code]E.queue_camera_shake_bg()[/code] by [code]E.camera.queue_shake_bg()[/code].
## - [code]E.camera_shake_bg()[/code] by [code]E.camera.shake_bg()[/code].
## - [code]E.queue_camera_zoom()[/code] by [code]E.camera.queue_change_zoom()[/code].
## - [code]E.camera_zoom()[/code] by [code]E.camera.change_zoom()[/code].
## - [code]E.stop_camera_shake()[/code] by [code]E.camera.stop_shake()[/code].
## - [code]return super.get_runtime_room()[/code] by [code]return get_runtime_room()[/code].
## - [code]return super.get_runtime_character()[/code] by [code]return get_runtime_character()[/code].
## - [code]return super.get_item_instance()[/code] by [code]return get_item_instance()[/code].
## - [code]return E.get_dialog()[/code] by [code]return get_instance()[/code].
## Returns [constant Completion.DONE] if any replacement is done, [constant Completion.IGNORED]
## otherwise.
func _replace_deprecated() -> Completion:
return Completion.DONE if PopochiuMigrationHelper.replace_in_scripts([
{from = "E.current_room", to = "R.current"},
{from = "E.goto_room(", to = "R.goto_room("},
{from = "E.queue_camera_offset(", to = "E.camera.queue_change_offset("},
{from = "E.camera_offset(", to = "E.camera.change_offset("},
{from = "E.queue_camera_shake(", to = "E.camera.queue_shake("},
{from = "E.camera_shake(", to = "E.camera.shake("},
{from = "E.queue_camera_shake_bg(", to = "E.camera.queue_shake_bg("},
{from = "E.camera_shake_bg(", to = "E.camera.shake_bg("},
{from = "E.queue_camera_zoom(", to = "E.camera.queue_change_zoom("},
{from = "E.camera_zoom(", to = "E.camera.change_zoom("},
{from = "E.stop_camera_shake()", to = "E.camera.stop_shake()"},
# autoloads
{from = "return super.get_runtime_room(", to = "return get_runtime_room("},
{from = "return super.get_runtime_character(", to = "return get_runtime_character("},
{from = "return super.get_item_instance(", to = "return get_item_instance("},
{from = "return E.get_dialog(", to = "return get_instance("},
]) else Completion.IGNORED
## Update camera limit calculations for each room to utilize the new [member PopochiuRoom.width]
## and [member PopochiuRoom.height] properties.
func _update_rooms_sizes() -> Completion:
var any_room_updated := PopochiuUtils.any_exhaustive(
PopochiuEditorHelper.get_rooms(), _update_room_size
)
_reload_needed = any_room_updated
return Completion.DONE if any_room_updated else Completion.IGNORED
## Updates the values of [member PopochiuRoom.width] and [member PopochiuRoom.height] in
## [param popochiu_room] based on the values of the deprecated camera limits properties.
func _update_room_size(popochiu_room: PopochiuRoom) -> bool:
var viewport_width := ProjectSettings.get_setting(PopochiuResources.DISPLAY_WIDTH)
var viewport_height := ProjectSettings.get_setting(PopochiuResources.DISPLAY_HEIGHT)
# Calculate the width based on the camera limits
var left := 0.0 if is_inf(popochiu_room.limit_left) else popochiu_room.limit_left
var right := 0.0 if is_inf(popochiu_room.limit_right) else popochiu_room.limit_right
var width: int = viewport_width - int(left)
width += int(right) - viewport_width
popochiu_room.width = maxi(width, viewport_width)
# Calculate the height based on the camera limits
var top := 0.0 if is_inf(popochiu_room.limit_top) else popochiu_room.limit_top
var bottom := 0.0 if is_inf(popochiu_room.limit_bottom) else popochiu_room.limit_bottom
var height: int = viewport_height - int(top)
height += int(bottom) - viewport_height
popochiu_room.height = maxi(height, viewport_height)
if PopochiuEditorHelper.pack_scene(popochiu_room) != OK:
PopochiuUtils.print_error(
"Migration 2: Couldn't update the [code]width[/code] and [code]height[/code] of" +\
" [b]%s[/b] room." % popochiu_room.script_name
)
return false
return true
#endregion