From 50262c02a282973a678556a86ad9709b100e9ed1 Mon Sep 17 00:00:00 2001 From: Levi Lindsey <4317587+levilindsey@users.noreply.github.com> Date: Thu, 18 Mar 2021 13:19:18 -0700 Subject: [PATCH] WIP: Continue restructuring framework and incorporating infrastructure from Inner-Tube Climber. --- .gitignore | 50 + LICENSE | 2 +- README.md | 482 +---- addons/scaffold/LICENSE | 21 + addons/scaffold/README.md | 11 + .../assets}/fonts/Open_Sans/LICENSE.txt | 0 .../assets}/fonts/Open_Sans/OpenSans-Bold.ttf | Bin .../fonts/Open_Sans/OpenSans-BoldItalic.ttf | Bin .../fonts/Open_Sans/OpenSans-ExtraBold.ttf | Bin .../Open_Sans/OpenSans-ExtraBoldItalic.ttf | Bin .../fonts/Open_Sans/OpenSans-Italic.ttf | Bin .../fonts/Open_Sans/OpenSans-Light.ttf | Bin .../fonts/Open_Sans/OpenSans-LightItalic.ttf | Bin .../fonts/Open_Sans/OpenSans-Regular.ttf | Bin .../fonts/Open_Sans/OpenSans-SemiBold.ttf | Bin .../Open_Sans/OpenSans-SemiBoldItalic.ttf | Bin .../assets/fonts/main_font_italic.tres | 7 + addons/scaffold/assets/fonts/main_font_l.tres | 7 + addons/scaffold/assets/fonts/main_font_m.tres | 6 + .../assets/fonts/main_font_m_bold.tres | 8 + .../assets/fonts/main_font_m_italic.tres | 8 + addons/scaffold/assets/fonts/main_font_s.tres | 7 + .../scaffold/assets/fonts/main_font_xl.tres | 7 + .../scaffold/assets}/fonts/main_font_xs.tres | 2 +- .../assets}/fonts/main_font_xs_italic.tres | 3 +- .../assets}/images/device-icons/icon-128.png | Bin .../images/device-icons/icon-128.png.import | 6 +- .../assets}/images/device-icons/icon-32.png | Bin .../images/device-icons/icon-32.png.import | 6 +- .../assets}/images/device-icons/icon-64.png | Bin .../images/device-icons/icon-64.png.import | 6 +- .../assets/images/gui/go_icon_normal.aseprite | Bin 0 -> 716 bytes .../images/gui/go_icon_normal_large.aseprite | Bin 0 -> 765 bytes .../images/gui/go_icon_normal_large.png | Bin 0 -> 409 bytes .../gui/go_icon_normal_large.png.import | 34 + .../assets/images/spinning_gear_icon.gif | Bin 0 -> 18825 bytes .../scaffold/assets}/music/on_a_quest.ogg | Bin .../assets/music/on_a_quest.ogg.import | 15 + .../scaffold/assets}/sounds/achievement.wav | Bin .../assets/sounds/achievement.wav.import | 21 + .../scaffold/assets}/sounds/cadence.wav | Bin .../assets}/sounds/cadence.wav.import | 6 +- .../scaffold/assets}/sounds/fall.wav | Bin .../scaffold/assets}/sounds/fall.wav.import | 6 +- .../scaffold/assets}/sounds/jump.wav | Bin .../scaffold/assets}/sounds/jump.wav.import | 6 +- .../scaffold/assets}/sounds/land.wav | Bin .../scaffold/assets}/sounds/land.wav.import | 6 +- .../scaffold/assets}/sounds/menu_select.wav | Bin .../assets/sounds/menu_select.wav.import | 21 + .../assets}/sounds/menu_select_fancy.wav | Bin .../sounds/menu_select_fancy.wav.import | 21 + .../assets}/sounds/single_cat_snore.wav | Bin .../assets/sounds/single_cat_snore.wav.import | 21 + .../scaffold/assets}/sounds/walk.wav | Bin .../scaffold/assets}/sounds/walk.wav.import | 6 +- addons/scaffold/scaffold_config.gd | 270 --- addons/scaffold/{ => src}/audio.gd | 36 +- .../scaffold/{ => src}/camera_controller.gd | 0 addons/scaffold/{ => src}/camera_shake.gd | 0 addons/scaffold/{ => src}/camera_shake.tscn | 3 +- addons/scaffold/{ => src}/canvas_layers.gd | 6 +- addons/scaffold/{ => src}/data/analytics.gd | 0 .../scaffold/{ => src}/data/gesture_record.gd | 0 addons/scaffold/{ => src}/data/log.gd | 0 addons/scaffold/{ => src}/data/save_state.gd | 0 .../scaffold/{ => src}/gui/accordion_panel.gd | 0 .../{ => src}/gui/accordion_panel.tscn | 3 +- .../gui/centered_in_full_screen_panel.gd | 2 +- .../gui/centered_in_full_screen_panel.tscn | 3 +- .../scaffold/{ => src}/gui/centered_panel.gd | 2 +- .../{ => src}/gui/centered_panel.tscn | 3 +- addons/scaffold/{ => src}/gui/debug_panel.gd | 0 .../scaffold/{ => src}/gui/debug_panel.tscn | 6 +- .../{ => src}/gui/full_screen_panel.gd | 2 +- .../{ => src}/gui/full_screen_panel.tscn | 3 +- .../gui/labeled_control_item_type.gd | 0 .../{ => src}/gui/labeled_control_list.gd | 0 .../{ => src}/gui/labeled_control_list.tscn | 3 +- addons/scaffold/{ => src}/gui/nav_bar.gd | 5 +- addons/scaffold/{ => src}/gui/nav_bar.tscn | 12 +- addons/scaffold/{ => src}/gui/screen.gd | 0 .../screens/confirm_data_deletion_screen.gd | 0 .../screens/confirm_data_deletion_screen.tscn | 14 +- .../{ => src}/gui/screens/credits_screen.gd | 6 + .../{ => src}/gui/screens/credits_screen.tscn | 58 +- .../gui/screens/data_agreement_screen.gd | 0 .../gui/screens/data_agreement_screen.tscn | 14 +- .../gui/screens/developer_splash_screen.gd | 0 .../gui/screens/developer_splash_screen.tscn | 5 +- .../{ => src}/gui/screens/fade_transition.gd | 0 .../gui/screens/fade_transition.tscn | 3 +- .../{ => src}/gui/screens/game_screen.gd | 5 +- .../{ => src}/gui/screens/game_screen.tscn | 3 +- .../gui/screens/godot_splash_screen.gd | 0 .../gui/screens/godot_splash_screen.tscn | 5 +- .../{ => src}/gui/screens/main_menu_screen.gd | 16 +- .../gui/screens/main_menu_screen.tscn | 40 +- .../gui/screens/notification_screen.gd | 0 .../gui/screens/notification_screen.tscn | 14 +- .../{ => src}/gui/screens/pause_screen.gd | 2 +- .../{ => src}/gui/screens/pause_screen.tscn | 13 +- .../{ => src}/gui/screens/rate_app_screen.gd | 1 - .../gui/screens/rate_app_screen.tscn | 16 +- .../{ => src}/gui/screens/settings_screen.gd | 0 .../gui/screens/settings_screen.tscn | 13 +- .../screens/third_party_licenses_screen.gd | 0 .../screens/third_party_licenses_screen.tscn | 12 +- addons/scaffold/{ => src}/gui/shiny_button.gd | 2 +- .../scaffold/{ => src}/gui/shiny_button.tscn | 7 +- addons/scaffold/{ => src}/ios_model_names.gd | 0 addons/scaffold/{ => src}/ios_resolutions.gd | 0 addons/scaffold/{ => src}/navigation.gd | 3 +- addons/scaffold/{ => src}/priority_queue.gd | 0 .../scaffold/{ => src}/scaffold_bootstrap.gd | 28 +- addons/scaffold/src/scaffold_config.gd | 281 +++ addons/scaffold/{ => src}/scaffold_level.gd | 0 .../scaffold_third_party_licenses.gd | 0 addons/scaffold/{ => src}/scaffold_utils.gd | 8 + addons/scaffold/{ => src}/stopwatch.gd | 0 addons/scaffold/{ => src}/time.gd | 0 addons/scaffold/{ => src}/todo_sign.gd | 0 addons/scaffold/{ => src}/todo_sign.tscn | 6 +- addons/surfacer/LICENSE | 21 + addons/surfacer/README.md | 475 +++++ addons/surfacer/global.gd | 36 - addons/surfacer/gui/panels/credits_panel.gd | 22 - addons/surfacer/gui/panels/credits_panel.tscn | 294 --- .../panels/third_party_licenses_panel.tscn | 473 ----- addons/surfacer/preloads.gd | 44 - .../annotation_elements/annotation_element.gd | 0 .../annotation_element_defaults.gd | 0 .../annotation_element_type.gd | 0 .../destination_surface_annotation_element.gd | 0 .../edge_annotation_element.gd | 0 .../edge_step_annotation_element.gd | 6 +- .../failed_edge_attempt_annotation_element.gd | 0 ...e_with_jump_distance_annotation_element.gd | 0 ...ithout_jump_distance_annotation_element.gd | 0 .../jump_land_positions_annotation_element.gd | 0 .../origin_surface_annotation_element.gd | 0 .../polyline_annotation_element.gd | 0 .../surface_annotation_element.gd | 0 .../{ => src}/annotators/annotator_type.gd | 0 .../{ => src}/annotators/annotators.gd | 33 +- .../{ => src}/annotators/click_annotator.gd | 2 +- .../annotators/color_params/color_params.gd | 0 .../color_params/color_params_factory.gd | 0 .../color_params/color_params_type.gd | 0 .../color_params/hsv_color_params.gd | 0 .../color_params/hsv_range_color_params.gd | 0 .../{ => src}/annotators/element_annotator.gd | 12 +- .../annotators/grid_indices_annotator.gd | 4 +- .../annotators/navigator_annotator.gd | 0 .../{ => src}/annotators/player_annotator.gd | 0 .../annotators/player_position_annotator.gd | 0 .../player_recent_movement_annotator.gd | 0 .../annotators/player_surface_annotator.gd | 0 .../annotators/player_tile_annotator.gd | 0 .../{ => src}/annotators/ruler_annotator.gd | 6 +- .../surface_preselection_annotator.gd | 2 +- .../annotators/surface_selection_annotator.gd | 0 .../surfacer/{ => src}/gui/legend/legend.gd | 0 .../surfacer/{ => src}/gui/legend/legend.tscn | 6 +- .../continuous_edge_trajectory_legend_item.gd | 0 .../legend_items/destination_legend_item.gd | 4 +- .../destination_surface_legend_item.gd | 0 .../discrete_edge_trajectory_legend_item.gd | 0 .../failed_edge_trajectory_legend_item.gd | 0 ...ll_range_with_jump_distance_legend_item.gd | 0 ...range_without_jump_distance_legend_item.gd | 0 ...ypothetical_edge_trajectory_legend_item.gd | 0 .../instruction_end_legend_item.gd | 0 .../instruction_start_legend_item.gd | 0 .../gui/legend/legend_items/legend_item.gd | 4 +- .../legend/legend_items/legend_item_type.gd | 0 .../legend/legend_items/origin_legend_item.gd | 2 +- .../origin_surface_legend_item.gd | 0 .../legend_items/polyline_legend_item.gd | 0 .../legend_items/surface_legend_item.gd | 0 .../valid_edge_trajectory_legend_item.gd | 0 .../{ => src}/gui/panels/utility_panel.gd | 52 +- .../{ => src}/gui/panels/utility_panel.tscn | 156 +- .../{ => src}/gui/panels/welcome_panel.gd | 2 +- .../{ => src}/gui/panels/welcome_panel.tscn | 9 +- .../description_item_controller.gd | 0 .../edge_attempt_item_controller.gd | 0 ...dge_calc_profiler_group_item_controller.gd | 0 ...ge_calc_result_metadata_item_controller.gd | 0 ...ep_calc_result_metadata_item_controller.gd | 0 ...result_metadata_item_controller_factory.gd | 0 ...dge_type_in_edges_group_item_controller.gd | 0 ...ed_by_result_type_group_item_controller.gd | 0 .../edges_group_item_controller.gd | 0 ...asing_jump_height_group_item_controller.gd | 0 ...ges_with_one_step_group_item_controller.gd | 0 ...asing_jump_height_group_item_controller.gd | 0 .../inspector_item_controller.gd | 6 +- .../inspector_item_type.gd | 0 .../platform_graph_item_controller.gd | 0 .../global_counts_group_item_controller.gd | 0 .../profiler_count_item_controller.gd | 0 .../profiler_group_item_controller.gd | 0 .../profiler_timing_item_controller.gd | 0 .../surface_parser_group_item_controller.gd | 0 .../ceilings_item_controller.gd | 0 .../destination_surface_item_controller.gd | 0 ..._type_in_surfaces_group_item_controller.gd | 0 .../failed_edge_item_controller.gd | 0 .../failed_edges_group_item_controller.gd | 0 .../surfaces_group/floors_item_controller.gd | 0 .../left_walls_item_controller.gd | 0 .../origin_surface_item_controller.gd | 0 .../right_walls_item_controller.gd | 0 .../surfaces_group_item_controller.gd | 0 .../surfaces_of_side_item_controller.gd | 0 .../valid_edge_item_controller.gd | 0 .../inspector_search_type.gd | 0 .../platform_graph_inspector.gd | 44 +- .../platform_graph_inspector.tscn | 6 +- .../platform_graph_inspector_selector.gd | 14 +- .../{ => src}/gui/selection_description.gd | 0 .../{ => src}/gui/selection_description.tscn | 6 +- addons/surfacer/{ => src}/input_wrapper.gd | 4 +- .../calculators/air_to_surface_calculator.gd | 0 .../climb_down_wall_to_floor_calculator.gd | 0 .../climb_over_wall_to_floor_calculator.gd | 0 .../edge/calculators/edge_calculator.gd | 0 .../calculators/fall_from_floor_calculator.gd | 0 .../calculators/fall_from_wall_calculator.gd | 0 .../jump_from_surface_to_air_calculator.gd | 0 .../jump_inter_surface_calculator.gd | 0 ...lk_to_ascend_wall_from_floor_calculator.gd | 0 .../edge/edges/air_to_air_edge.gd | 0 .../edge/edges/air_to_surface_edge.gd | 0 .../edges/climb_down_wall_to_floor_edge.gd | 0 .../edges/climb_over_wall_to_floor_edge.gd | 0 .../platform_graph/edge/edges/edge.gd | 0 .../platform_graph/edge/edges/edge_type.gd | 0 .../edge/edges/fall_from_floor_edge.gd | 0 .../edge/edges/fall_from_wall_edge.gd | 0 .../edge/edges/intra_surface_edge.gd | 0 .../edges/jump_from_surface_to_air_edge.gd | 0 .../edge/edges/jump_inter_surface_edge.gd | 0 .../walk_to_ascend_wall_from_floor_edge.gd | 0 .../models/collision_calc_result_metadata.gd | 0 .../models/collision_calculation_params.gd | 2 +- .../models/collision_tile_map_coord_result.gd | 0 .../edge/models/edge_attempt.gd | 0 .../edge/models/edge_calc_params.gd | 0 .../edge/models/edge_calc_result.gd | 0 .../edge/models/edge_calc_result_metadata.gd | 0 .../edge/models/edge_calc_result_type.gd | 0 .../edge/models/edge_instruction.gd | 0 .../edge/models/edge_instructions.gd | 0 .../platform_graph/edge/models/edge_step.gd | 0 .../edge/models/edge_step_calc_params.gd | 0 .../models/edge_step_calc_result_metadata.gd | 0 .../edge/models/edge_step_calc_result_type.gd | 0 .../edge/models/edge_trajectory.gd | 0 .../edge/models/failed_edge_attempt.gd | 0 .../edge/models/inter_surface_edges_result.gd | 0 .../edge/models/jump_land_positions.gd | 0 .../edge/models/movement_params.gd | 0 .../edge/models/surface_collision.gd | 0 .../edge/models/vertical_edge_step.gd | 0 .../platform_graph/edge/models/waypoint.gd | 0 .../edge/models/waypoint_validity.gd | 0 .../edge/utils/collision_check_utils.gd | 0 .../edge/utils/edge_instructions_utils.gd | 0 .../edge/utils/edge_step_utils.gd | 0 .../edge/utils/edge_trajectory_utils.gd | 0 .../edge/utils/fall_movement_utils.gd | 0 .../edge/utils/horizontal_movement_utils.gd | 0 .../edge/utils/jump_land_positions_utils.gd | 0 .../edge/utils/movement_utils.gd | 0 .../edge/utils/vertical_movement_utils.gd | 0 .../edge/utils/waypoint_utils.gd | 0 .../{ => src}/platform_graph/navigator.gd | 9 +- .../platform_graph/platform_graph.gd | 6 +- .../platform_graph/platform_graph_path.gd | 0 .../surface/position_along_surface.gd | 0 .../platform_graph/surface/surface.gd | 0 .../platform_graph/surface/surface_parser.gd | 0 .../platform_graph/surface/surface_side.gd | 0 .../platform_graph/surface/surface_type.gd | 0 .../action/action_handlers/air_dash_action.gd | 0 .../action_handlers/air_default_action.gd | 0 .../action/action_handlers/air_jump_action.gd | 0 .../action_handlers/all_default_action.gd | 0 .../action_handlers/cap_velocity_action.gd | 0 .../action_handlers/floor_dash_action.gd | 0 .../action_handlers/floor_default_action.gd | 0 .../floor_fall_through_action.gd | 0 .../action_handlers/floor_friction_action.gd | 0 .../action_handlers/floor_jump_action.gd | 0 .../action_handlers/floor_walk_action.gd | 0 .../match_expected_edge_trajectory_action.gd | 0 .../action_handlers/wall_climb_action.gd | 0 .../action_handlers/wall_dash_action.gd | 0 .../action_handlers/wall_default_action.gd | 0 .../action_handlers/wall_fall_action.gd | 0 .../action_handlers/wall_jump_action.gd | 0 .../action_handlers/wall_walk_action.gd | 0 .../action/instructions_action_source.gd | 0 .../player/action/instructions_playback.gd | 0 .../player/action/player_action_handler.gd | 0 .../player/action/player_action_source.gd | 0 .../player/action/player_action_state.gd | 0 .../player/action/player_action_type.gd | 0 .../player/action/user_action_source.gd | 0 .../player/animator/fake_player_animator.gd | 0 .../player/animator/player_animator.gd | 0 .../player/animator/player_animator_params.gd | 0 addons/surfacer/{ => src}/player/player.gd | 4 +- .../player/player_navigation_state.gd | 0 .../{ => src}/player/player_params.gd | 0 .../{ => src}/player/player_params_utils.gd | 4 +- .../player/player_pointer_handler.gd | 8 +- .../{ => src}/player/player_surface_state.gd | 0 .../surfacer/{ => src}/player/player_type.gd | 0 addons/surfacer/src/surfacer_bootstrap.gd | 36 + addons/surfacer/src/surfacer_config.gd | 110 ++ addons/surfacer/{ => src}/surfacer_level.gd | 56 +- .../surfacer_third_party_licenses.gd | 0 addons/surfacer/{ => src}/utils/colors.gd | 0 addons/surfacer/{ => src}/utils/draw_utils.gd | 0 addons/surfacer/{ => src}/utils/geometry.gd | 0 addons/surfacer/{ => src}/utils/profiler.gd | 18 +- .../{ => src}/utils/profiler_metric.gd | 0 addons/surfacer/surfacer_config.gd | 55 - .../test/data/integration_test_bed.gd | 16 +- assets/fonts/main_font_italic.tres | 6 - assets/fonts/main_font_l.tres | 7 - assets/fonts/main_font_normal.tres | 6 - assets/fonts/main_font_normal_bold.tres | 7 - assets/fonts/main_font_normal_italic.tres | 7 - assets/fonts/main_font_s.tres | 7 - assets/fonts/main_font_xl.tres | 7 - .../loading.gif} | Bin .../squirrel-running-loader-spritesheet.png | Bin 0 -> 3294 bytes ...rrel-running-loader-spritesheet.png.import | 34 + assets/main_theme.tres | 2 +- assets/music/on_a_quest.ogg.import | 15 - assets/sfx/squirrel_jump.wav.import | 21 - assets/sfx/squirrel_land.wav.import | 21 - assets/sfx/squirrel_yell.wav.import | 21 - assets/sounds/achievement.wav.import | 21 - assets/{sfx => sounds}/cat_jump.wav | Bin assets/{sfx => sounds}/cat_jump.wav.import | 6 +- assets/{sfx => sounds}/cat_land.wav | Bin assets/{sfx => sounds}/cat_land.wav.import | 6 +- assets/{sfx => sounds}/contact.wav | Bin assets/{sfx => sounds}/contact.wav.import | 6 +- assets/sounds/menu_select.wav.import | 21 - assets/sounds/menu_select_fancy.wav.import | 21 - assets/sounds/single_cat_snore.wav.import | 21 - assets/{sfx => sounds}/squirrel_jump.wav | Bin assets/sounds/squirrel_jump.wav.import | 21 + assets/{sfx => sounds}/squirrel_land.wav | Bin assets/sounds/squirrel_land.wav.import | 21 + assets/{sfx => sounds}/squirrel_yell.wav | Bin assets/sounds/squirrel_yell.wav.import | 21 + design/logo.aseprite | Bin 2483 -> 4406 bytes design/logo.png | Bin 0 -> 1646 bytes dist/{squirrel-running.gif => loading.gif} | Bin export_presets.cfg | 2 +- index.html | 4 +- project.godot | 519 ++--- src/{export-shell.html => export_shell.html} | 2 +- src/levels/level_1.tscn | 2 +- src/levels/level_2.tscn | 8 +- src/levels/level_3.tscn | 8 +- src/levels/level_4.tscn | 8 +- src/levels/level_5.tscn | 8 +- src/levels/level_6.tscn | 6 +- src/levels/level_7.tscn | 6 +- src/main.gd | 41 +- src/main_menu_image.tscn | 4 +- src/players/cat/cat_player.gd | 31 +- src/players/squirrel/squirrel_player.gd | 33 +- src/squirrel_away_config.gd | 167 +- src/squirrel_away_level.gd | 27 +- tier_tile_map.gd | 2 - tier_tile_map.tscn | 16 - tileset.tres | 1723 ----------------- 386 files changed, 2212 insertions(+), 4536 deletions(-) create mode 100644 addons/scaffold/LICENSE create mode 100644 addons/scaffold/README.md rename {assets => addons/scaffold/assets}/fonts/Open_Sans/LICENSE.txt (100%) rename {assets => addons/scaffold/assets}/fonts/Open_Sans/OpenSans-Bold.ttf (100%) rename {assets => addons/scaffold/assets}/fonts/Open_Sans/OpenSans-BoldItalic.ttf (100%) rename {assets => addons/scaffold/assets}/fonts/Open_Sans/OpenSans-ExtraBold.ttf (100%) rename {assets => addons/scaffold/assets}/fonts/Open_Sans/OpenSans-ExtraBoldItalic.ttf (100%) rename {assets => addons/scaffold/assets}/fonts/Open_Sans/OpenSans-Italic.ttf (100%) rename {assets => addons/scaffold/assets}/fonts/Open_Sans/OpenSans-Light.ttf (100%) rename {assets => addons/scaffold/assets}/fonts/Open_Sans/OpenSans-LightItalic.ttf (100%) rename {assets => addons/scaffold/assets}/fonts/Open_Sans/OpenSans-Regular.ttf (100%) rename {assets => addons/scaffold/assets}/fonts/Open_Sans/OpenSans-SemiBold.ttf (100%) rename {assets => addons/scaffold/assets}/fonts/Open_Sans/OpenSans-SemiBoldItalic.ttf (100%) create mode 100644 addons/scaffold/assets/fonts/main_font_italic.tres create mode 100644 addons/scaffold/assets/fonts/main_font_l.tres create mode 100644 addons/scaffold/assets/fonts/main_font_m.tres create mode 100644 addons/scaffold/assets/fonts/main_font_m_bold.tres create mode 100644 addons/scaffold/assets/fonts/main_font_m_italic.tres create mode 100644 addons/scaffold/assets/fonts/main_font_s.tres create mode 100644 addons/scaffold/assets/fonts/main_font_xl.tres rename {assets => addons/scaffold/assets}/fonts/main_font_xs.tres (57%) rename {assets => addons/scaffold/assets}/fonts/main_font_xs_italic.tres (57%) rename {assets => addons/scaffold/assets}/images/device-icons/icon-128.png (100%) rename {assets => addons/scaffold/assets}/images/device-icons/icon-128.png.import (66%) rename {assets => addons/scaffold/assets}/images/device-icons/icon-32.png (100%) rename {assets => addons/scaffold/assets}/images/device-icons/icon-32.png.import (68%) rename {assets => addons/scaffold/assets}/images/device-icons/icon-64.png (100%) rename {assets => addons/scaffold/assets}/images/device-icons/icon-64.png.import (68%) create mode 100644 addons/scaffold/assets/images/gui/go_icon_normal.aseprite create mode 100644 addons/scaffold/assets/images/gui/go_icon_normal_large.aseprite create mode 100644 addons/scaffold/assets/images/gui/go_icon_normal_large.png create mode 100644 addons/scaffold/assets/images/gui/go_icon_normal_large.png.import create mode 100644 addons/scaffold/assets/images/spinning_gear_icon.gif rename {assets => addons/scaffold/assets}/music/on_a_quest.ogg (100%) create mode 100644 addons/scaffold/assets/music/on_a_quest.ogg.import rename {assets => addons/scaffold/assets}/sounds/achievement.wav (100%) create mode 100644 addons/scaffold/assets/sounds/achievement.wav.import rename {assets => addons/scaffold/assets}/sounds/cadence.wav (100%) rename {assets => addons/scaffold/assets}/sounds/cadence.wav.import (52%) rename {assets => addons/scaffold/assets}/sounds/fall.wav (100%) rename {assets => addons/scaffold/assets}/sounds/fall.wav.import (52%) rename {assets => addons/scaffold/assets}/sounds/jump.wav (100%) rename {assets => addons/scaffold/assets}/sounds/jump.wav.import (52%) rename {assets => addons/scaffold/assets}/sounds/land.wav (100%) rename {assets => addons/scaffold/assets}/sounds/land.wav.import (52%) rename {assets => addons/scaffold/assets}/sounds/menu_select.wav (100%) create mode 100644 addons/scaffold/assets/sounds/menu_select.wav.import rename {assets => addons/scaffold/assets}/sounds/menu_select_fancy.wav (100%) create mode 100644 addons/scaffold/assets/sounds/menu_select_fancy.wav.import rename {assets => addons/scaffold/assets}/sounds/single_cat_snore.wav (100%) create mode 100644 addons/scaffold/assets/sounds/single_cat_snore.wav.import rename {assets => addons/scaffold/assets}/sounds/walk.wav (100%) rename {assets => addons/scaffold/assets}/sounds/walk.wav.import (52%) delete mode 100644 addons/scaffold/scaffold_config.gd rename addons/scaffold/{ => src}/audio.gd (86%) rename addons/scaffold/{ => src}/camera_controller.gd (100%) rename addons/scaffold/{ => src}/camera_shake.gd (100%) rename addons/scaffold/{ => src}/camera_shake.tscn (54%) rename addons/scaffold/{ => src}/canvas_layers.gd (89%) rename addons/scaffold/{ => src}/data/analytics.gd (100%) rename addons/scaffold/{ => src}/data/gesture_record.gd (100%) rename addons/scaffold/{ => src}/data/log.gd (100%) rename addons/scaffold/{ => src}/data/save_state.gd (100%) rename addons/scaffold/{ => src}/gui/accordion_panel.gd (100%) rename addons/scaffold/{ => src}/gui/accordion_panel.tscn (74%) rename addons/scaffold/{ => src}/gui/centered_in_full_screen_panel.gd (97%) rename addons/scaffold/{ => src}/gui/centered_in_full_screen_panel.tscn (83%) rename addons/scaffold/{ => src}/gui/centered_panel.gd (96%) rename addons/scaffold/{ => src}/gui/centered_panel.tscn (83%) rename addons/scaffold/{ => src}/gui/debug_panel.gd (100%) rename addons/scaffold/{ => src}/gui/debug_panel.tscn (84%) rename addons/scaffold/{ => src}/gui/full_screen_panel.gd (87%) rename addons/scaffold/{ => src}/gui/full_screen_panel.tscn (82%) rename addons/scaffold/{ => src}/gui/labeled_control_item_type.gd (100%) rename addons/scaffold/{ => src}/gui/labeled_control_list.gd (100%) rename addons/scaffold/{ => src}/gui/labeled_control_list.tscn (77%) rename addons/scaffold/{ => src}/gui/nav_bar.gd (91%) rename addons/scaffold/{ => src}/gui/nav_bar.tscn (94%) rename addons/scaffold/{ => src}/gui/screen.gd (100%) rename addons/scaffold/{ => src}/gui/screens/confirm_data_deletion_screen.gd (100%) rename addons/scaffold/{ => src}/gui/screens/confirm_data_deletion_screen.tscn (91%) rename addons/scaffold/{ => src}/gui/screens/credits_screen.gd (89%) rename addons/scaffold/{ => src}/gui/screens/credits_screen.tscn (90%) rename addons/scaffold/{ => src}/gui/screens/data_agreement_screen.gd (100%) rename addons/scaffold/{ => src}/gui/screens/data_agreement_screen.tscn (90%) rename addons/scaffold/{ => src}/gui/screens/developer_splash_screen.gd (100%) rename addons/scaffold/{ => src}/gui/screens/developer_splash_screen.tscn (81%) rename addons/scaffold/{ => src}/gui/screens/fade_transition.gd (100%) rename addons/scaffold/{ => src}/gui/screens/fade_transition.tscn (89%) rename addons/scaffold/{ => src}/gui/screens/game_screen.gd (95%) rename addons/scaffold/{ => src}/gui/screens/game_screen.tscn (89%) rename addons/scaffold/{ => src}/gui/screens/godot_splash_screen.gd (100%) rename addons/scaffold/{ => src}/gui/screens/godot_splash_screen.tscn (83%) rename addons/scaffold/{ => src}/gui/screens/main_menu_screen.gd (73%) rename addons/scaffold/{ => src}/gui/screens/main_menu_screen.tscn (80%) rename addons/scaffold/{ => src}/gui/screens/notification_screen.gd (100%) rename addons/scaffold/{ => src}/gui/screens/notification_screen.tscn (87%) rename addons/scaffold/{ => src}/gui/screens/pause_screen.gd (98%) rename addons/scaffold/{ => src}/gui/screens/pause_screen.tscn (89%) rename addons/scaffold/{ => src}/gui/screens/rate_app_screen.gd (96%) rename addons/scaffold/{ => src}/gui/screens/rate_app_screen.tscn (89%) rename addons/scaffold/{ => src}/gui/screens/settings_screen.gd (100%) rename addons/scaffold/{ => src}/gui/screens/settings_screen.tscn (86%) rename addons/scaffold/{ => src}/gui/screens/third_party_licenses_screen.gd (100%) rename addons/scaffold/{ => src}/gui/screens/third_party_licenses_screen.tscn (76%) rename addons/scaffold/{ => src}/gui/shiny_button.gd (99%) rename addons/scaffold/{ => src}/gui/shiny_button.tscn (91%) rename addons/scaffold/{ => src}/ios_model_names.gd (100%) rename addons/scaffold/{ => src}/ios_resolutions.gd (100%) rename addons/scaffold/{ => src}/navigation.gd (99%) rename addons/scaffold/{ => src}/priority_queue.gd (100%) rename addons/scaffold/{ => src}/scaffold_bootstrap.gd (59%) create mode 100644 addons/scaffold/src/scaffold_config.gd rename addons/scaffold/{ => src}/scaffold_level.gd (100%) rename addons/scaffold/{ => src}/scaffold_third_party_licenses.gd (100%) rename addons/scaffold/{ => src}/scaffold_utils.gd (98%) rename addons/scaffold/{ => src}/stopwatch.gd (100%) rename addons/scaffold/{ => src}/time.gd (100%) rename addons/scaffold/{ => src}/todo_sign.gd (100%) rename addons/scaffold/{ => src}/todo_sign.tscn (82%) create mode 100644 addons/surfacer/LICENSE create mode 100644 addons/surfacer/README.md delete mode 100644 addons/surfacer/global.gd delete mode 100644 addons/surfacer/gui/panels/credits_panel.gd delete mode 100644 addons/surfacer/gui/panels/credits_panel.tscn delete mode 100644 addons/surfacer/gui/panels/third_party_licenses_panel.tscn delete mode 100644 addons/surfacer/preloads.gd rename addons/surfacer/{ => src}/annotators/annotation_elements/annotation_element.gd (100%) rename addons/surfacer/{ => src}/annotators/annotation_elements/annotation_element_defaults.gd (100%) rename addons/surfacer/{ => src}/annotators/annotation_elements/annotation_element_type.gd (100%) rename addons/surfacer/{ => src}/annotators/annotation_elements/destination_surface_annotation_element.gd (100%) rename addons/surfacer/{ => src}/annotators/annotation_elements/edge_annotation_element.gd (100%) rename addons/surfacer/{ => src}/annotators/annotation_elements/edge_step_annotation_element.gd (98%) rename addons/surfacer/{ => src}/annotators/annotation_elements/failed_edge_attempt_annotation_element.gd (100%) rename addons/surfacer/{ => src}/annotators/annotation_elements/fall_range_with_jump_distance_annotation_element.gd (100%) rename addons/surfacer/{ => src}/annotators/annotation_elements/fall_range_without_jump_distance_annotation_element.gd (100%) rename addons/surfacer/{ => src}/annotators/annotation_elements/jump_land_positions_annotation_element.gd (100%) rename addons/surfacer/{ => src}/annotators/annotation_elements/origin_surface_annotation_element.gd (100%) rename addons/surfacer/{ => src}/annotators/annotation_elements/polyline_annotation_element.gd (100%) rename addons/surfacer/{ => src}/annotators/annotation_elements/surface_annotation_element.gd (100%) rename addons/surfacer/{ => src}/annotators/annotator_type.gd (100%) rename addons/surfacer/{ => src}/annotators/annotators.gd (86%) rename addons/surfacer/{ => src}/annotators/click_annotator.gd (97%) rename addons/surfacer/{ => src}/annotators/color_params/color_params.gd (100%) rename addons/surfacer/{ => src}/annotators/color_params/color_params_factory.gd (100%) rename addons/surfacer/{ => src}/annotators/color_params/color_params_type.gd (100%) rename addons/surfacer/{ => src}/annotators/color_params/hsv_color_params.gd (100%) rename addons/surfacer/{ => src}/annotators/color_params/hsv_range_color_params.gd (100%) rename addons/surfacer/{ => src}/annotators/element_annotator.gd (83%) rename addons/surfacer/{ => src}/annotators/grid_indices_annotator.gd (94%) rename addons/surfacer/{ => src}/annotators/navigator_annotator.gd (100%) rename addons/surfacer/{ => src}/annotators/player_annotator.gd (100%) rename addons/surfacer/{ => src}/annotators/player_position_annotator.gd (100%) rename addons/surfacer/{ => src}/annotators/player_recent_movement_annotator.gd (100%) rename addons/surfacer/{ => src}/annotators/player_surface_annotator.gd (100%) rename addons/surfacer/{ => src}/annotators/player_tile_annotator.gd (100%) rename addons/surfacer/{ => src}/annotators/ruler_annotator.gd (96%) rename addons/surfacer/{ => src}/annotators/surface_preselection_annotator.gd (99%) rename addons/surfacer/{ => src}/annotators/surface_selection_annotator.gd (100%) rename addons/surfacer/{ => src}/gui/legend/legend.gd (100%) rename addons/surfacer/{ => src}/gui/legend/legend.tscn (80%) rename addons/surfacer/{ => src}/gui/legend/legend_items/continuous_edge_trajectory_legend_item.gd (100%) rename addons/surfacer/{ => src}/gui/legend/legend_items/destination_legend_item.gd (87%) rename addons/surfacer/{ => src}/gui/legend/legend_items/destination_surface_legend_item.gd (100%) rename addons/surfacer/{ => src}/gui/legend/legend_items/discrete_edge_trajectory_legend_item.gd (100%) rename addons/surfacer/{ => src}/gui/legend/legend_items/failed_edge_trajectory_legend_item.gd (100%) rename addons/surfacer/{ => src}/gui/legend/legend_items/fall_range_with_jump_distance_legend_item.gd (100%) rename addons/surfacer/{ => src}/gui/legend/legend_items/fall_range_without_jump_distance_legend_item.gd (100%) rename addons/surfacer/{ => src}/gui/legend/legend_items/hypothetical_edge_trajectory_legend_item.gd (100%) rename addons/surfacer/{ => src}/gui/legend/legend_items/instruction_end_legend_item.gd (100%) rename addons/surfacer/{ => src}/gui/legend/legend_items/instruction_start_legend_item.gd (100%) rename addons/surfacer/{ => src}/gui/legend/legend_items/legend_item.gd (91%) rename addons/surfacer/{ => src}/gui/legend/legend_items/legend_item_type.gd (100%) rename addons/surfacer/{ => src}/gui/legend/legend_items/origin_legend_item.gd (91%) rename addons/surfacer/{ => src}/gui/legend/legend_items/origin_surface_legend_item.gd (100%) rename addons/surfacer/{ => src}/gui/legend/legend_items/polyline_legend_item.gd (100%) rename addons/surfacer/{ => src}/gui/legend/legend_items/surface_legend_item.gd (100%) rename addons/surfacer/{ => src}/gui/legend/legend_items/valid_edge_trajectory_legend_item.gd (100%) rename addons/surfacer/{ => src}/gui/panels/utility_panel.gd (74%) rename addons/surfacer/{ => src}/gui/panels/utility_panel.tscn (64%) rename addons/surfacer/{ => src}/gui/panels/welcome_panel.gd (91%) rename addons/surfacer/{ => src}/gui/panels/welcome_panel.tscn (84%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/description_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/edge_attempt_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/edge_calc_profiler_group_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/edge_calc_result_metadata_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/edge_step_calc_result_metadata_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/edge_step_calc_result_metadata_item_controller_factory.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edge_type_in_edges_group_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_filtered_by_result_type_group_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_group_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_with_increasing_jump_height_group_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_with_one_step_group_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_without_increasing_jump_height_group_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/inspector_item_controller.gd (97%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/inspector_item_type.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/platform_graph_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/global_counts_group_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_count_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_group_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_timing_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/surface_parser_group_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/ceilings_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/destination_surface_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/edge_type_in_surfaces_group_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/failed_edge_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/failed_edges_group_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/floors_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/left_walls_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/origin_surface_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/right_walls_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/surfaces_group_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/surfaces_of_side_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_item_controllers/valid_edge_item_controller.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/inspector_search_type.gd (100%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/platform_graph_inspector.gd (93%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/platform_graph_inspector.tscn (59%) rename addons/surfacer/{ => src}/gui/platform_graph_inspector/platform_graph_inspector_selector.gd (89%) rename addons/surfacer/{ => src}/gui/selection_description.gd (100%) rename addons/surfacer/{ => src}/gui/selection_description.tscn (75%) rename addons/surfacer/{ => src}/input_wrapper.gd (83%) rename addons/surfacer/{ => src}/platform_graph/edge/calculators/air_to_surface_calculator.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/calculators/climb_down_wall_to_floor_calculator.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/calculators/climb_over_wall_to_floor_calculator.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/calculators/edge_calculator.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/calculators/fall_from_floor_calculator.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/calculators/fall_from_wall_calculator.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/calculators/jump_from_surface_to_air_calculator.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/calculators/jump_inter_surface_calculator.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/calculators/walk_to_ascend_wall_from_floor_calculator.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/edges/air_to_air_edge.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/edges/air_to_surface_edge.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/edges/climb_down_wall_to_floor_edge.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/edges/climb_over_wall_to_floor_edge.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/edges/edge.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/edges/edge_type.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/edges/fall_from_floor_edge.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/edges/fall_from_wall_edge.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/edges/intra_surface_edge.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/edges/jump_from_surface_to_air_edge.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/edges/jump_inter_surface_edge.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/edges/walk_to_ascend_wall_from_floor_edge.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/collision_calc_result_metadata.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/collision_calculation_params.gd (93%) rename addons/surfacer/{ => src}/platform_graph/edge/models/collision_tile_map_coord_result.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/edge_attempt.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/edge_calc_params.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/edge_calc_result.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/edge_calc_result_metadata.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/edge_calc_result_type.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/edge_instruction.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/edge_instructions.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/edge_step.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/edge_step_calc_params.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/edge_step_calc_result_metadata.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/edge_step_calc_result_type.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/edge_trajectory.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/failed_edge_attempt.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/inter_surface_edges_result.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/jump_land_positions.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/movement_params.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/surface_collision.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/vertical_edge_step.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/waypoint.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/models/waypoint_validity.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/utils/collision_check_utils.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/utils/edge_instructions_utils.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/utils/edge_step_utils.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/utils/edge_trajectory_utils.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/utils/fall_movement_utils.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/utils/horizontal_movement_utils.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/utils/jump_land_positions_utils.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/utils/movement_utils.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/utils/vertical_movement_utils.gd (100%) rename addons/surfacer/{ => src}/platform_graph/edge/utils/waypoint_utils.gd (100%) rename addons/surfacer/{ => src}/platform_graph/navigator.gd (99%) rename addons/surfacer/{ => src}/platform_graph/platform_graph.gd (99%) rename addons/surfacer/{ => src}/platform_graph/platform_graph_path.gd (100%) rename addons/surfacer/{ => src}/platform_graph/surface/position_along_surface.gd (100%) rename addons/surfacer/{ => src}/platform_graph/surface/surface.gd (100%) rename addons/surfacer/{ => src}/platform_graph/surface/surface_parser.gd (100%) rename addons/surfacer/{ => src}/platform_graph/surface/surface_side.gd (100%) rename addons/surfacer/{ => src}/platform_graph/surface/surface_type.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/air_dash_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/air_default_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/air_jump_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/all_default_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/cap_velocity_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/floor_dash_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/floor_default_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/floor_fall_through_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/floor_friction_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/floor_jump_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/floor_walk_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/match_expected_edge_trajectory_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/wall_climb_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/wall_dash_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/wall_default_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/wall_fall_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/wall_jump_action.gd (100%) rename addons/surfacer/{ => src}/player/action/action_handlers/wall_walk_action.gd (100%) rename addons/surfacer/{ => src}/player/action/instructions_action_source.gd (100%) rename addons/surfacer/{ => src}/player/action/instructions_playback.gd (100%) rename addons/surfacer/{ => src}/player/action/player_action_handler.gd (100%) rename addons/surfacer/{ => src}/player/action/player_action_source.gd (100%) rename addons/surfacer/{ => src}/player/action/player_action_state.gd (100%) rename addons/surfacer/{ => src}/player/action/player_action_type.gd (100%) rename addons/surfacer/{ => src}/player/action/user_action_source.gd (100%) rename addons/surfacer/{ => src}/player/animator/fake_player_animator.gd (100%) rename addons/surfacer/{ => src}/player/animator/player_animator.gd (100%) rename addons/surfacer/{ => src}/player/animator/player_animator_params.gd (100%) rename addons/surfacer/{ => src}/player/player.gd (99%) rename addons/surfacer/{ => src}/player/player_navigation_state.gd (100%) rename addons/surfacer/{ => src}/player/player_params.gd (100%) rename addons/surfacer/{ => src}/player/player_params_utils.gd (98%) rename addons/surfacer/{ => src}/player/player_pointer_handler.gd (93%) rename addons/surfacer/{ => src}/player/player_surface_state.gd (100%) rename addons/surfacer/{ => src}/player/player_type.gd (100%) create mode 100644 addons/surfacer/src/surfacer_bootstrap.gd create mode 100644 addons/surfacer/src/surfacer_config.gd rename addons/surfacer/{ => src}/surfacer_level.gd (83%) rename addons/surfacer/{ => src}/surfacer_third_party_licenses.gd (100%) rename addons/surfacer/{ => src}/utils/colors.gd (100%) rename addons/surfacer/{ => src}/utils/draw_utils.gd (100%) rename addons/surfacer/{ => src}/utils/geometry.gd (100%) rename addons/surfacer/{ => src}/utils/profiler.gd (92%) rename addons/surfacer/{ => src}/utils/profiler_metric.gd (100%) delete mode 100644 addons/surfacer/surfacer_config.gd delete mode 100644 assets/fonts/main_font_italic.tres delete mode 100644 assets/fonts/main_font_l.tres delete mode 100644 assets/fonts/main_font_normal.tres delete mode 100644 assets/fonts/main_font_normal_bold.tres delete mode 100644 assets/fonts/main_font_normal_italic.tres delete mode 100644 assets/fonts/main_font_s.tres delete mode 100644 assets/fonts/main_font_xl.tres rename assets/{squirrel-running.gif => images/loading.gif} (100%) create mode 100644 assets/images/players/squirrel-running-loader-spritesheet.png create mode 100644 assets/images/players/squirrel-running-loader-spritesheet.png.import delete mode 100644 assets/music/on_a_quest.ogg.import delete mode 100644 assets/sfx/squirrel_jump.wav.import delete mode 100644 assets/sfx/squirrel_land.wav.import delete mode 100644 assets/sfx/squirrel_yell.wav.import delete mode 100644 assets/sounds/achievement.wav.import rename assets/{sfx => sounds}/cat_jump.wav (100%) rename assets/{sfx => sounds}/cat_jump.wav.import (51%) rename assets/{sfx => sounds}/cat_land.wav (100%) rename assets/{sfx => sounds}/cat_land.wav.import (51%) rename assets/{sfx => sounds}/contact.wav (100%) rename assets/{sfx => sounds}/contact.wav.import (53%) delete mode 100644 assets/sounds/menu_select.wav.import delete mode 100644 assets/sounds/menu_select_fancy.wav.import delete mode 100644 assets/sounds/single_cat_snore.wav.import rename assets/{sfx => sounds}/squirrel_jump.wav (100%) create mode 100644 assets/sounds/squirrel_jump.wav.import rename assets/{sfx => sounds}/squirrel_land.wav (100%) create mode 100644 assets/sounds/squirrel_land.wav.import rename assets/{sfx => sounds}/squirrel_yell.wav (100%) create mode 100644 assets/sounds/squirrel_yell.wav.import create mode 100644 design/logo.png rename dist/{squirrel-running.gif => loading.gif} (100%) rename src/{export-shell.html => export_shell.html} (99%) delete mode 100644 tier_tile_map.gd delete mode 100644 tier_tile_map.tscn delete mode 100644 tileset.tres diff --git a/.gitignore b/.gitignore index 5c64e6f7..c6684bd5 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,53 @@ node_modules secure-config.js .mono .import +*.kra~ +dist/ios/* + +# Built application files +android/build/*/build/ +android/build/build/ + +# Crashlytics configuations +com_crashlytics_export_strings.xml + +# Local configuration file (sdk path, etc) +local.properties + +# Gradle generated files +.gradle/ + +# Signing files +.signing/ + +# User-specific configurations +.idea/libraries/ +.idea/workspace.xml +.idea/tasks.xml +.idea/.name +.idea/compiler.xml +.idea/copyright/profiles_settings.xml +.idea/encodings.xml +.idea/misc.xml +.idea/modules.xml +.idea/scopes/scope_settings.xml +.idea/vcs.xml +*.iml +project.code-workspace + +# OS-specific files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Releases that shouldn't be included in the repo +*.apk + +# App-release secrets +secret/ +secrets/ +export_presets.cfg diff --git a/LICENSE b/LICENSE index 5e2762eb..65f2f708 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019-2020 Levi Lindsey +Copyright (c) 2019-2021 Snoring Cat LLC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index f8b07e6c..07fe4eac 100644 --- a/README.md +++ b/README.md @@ -1,478 +1,28 @@ -# Surfacer +# Squirrel Away -_**Demo: [Squirrel Away](https://levi.dev/squirrel)**._ +_**[Live demo](https://levi.dev/squirrel)**._ -_A procedural pathfinding 2D-platformer framework for [Godot](https://godotengine.org/)._ +This simple game showcases procedural pathfinding across 2D-platformer surfaces using the [Surfacer](https://github.com/snoringcatgames/surfacer/) framework. -_"Surfacer": Like a platformer, but with walking, climbing, and jumping on all surfaces!_ - --------- - -**_NOTE_: This framework is still in development.** - -_TODO: Once v1.0 of this framework is done, split this apart into two repos: one for the underlying framework, and one for the demo game ("Squirrel Away")._ - --------- - -![Surfaces and edges in a plattform graph](./docs/surfaces-and-edges.png) - -**tl;dr**: Surfacer works by **pre-parsing** a level into a **"platform graph"**. The **nodes** are represented by points along the different surfaces in the level (floors, walls, and ceilings). The **edges** are represented by possible movement trajectories between points along surfaces. There are different types of edges for different types of movement (e.g., jumping from a floor to a floor, falling from a wall, walking along a floor). At run time, **[A* search](https://en.wikipedia.org/wiki/A*_search_algorithm)** is used to calculate a path to a given destination. - -Some features include: -- Walking on floors, climbing on walls, climbing on ceilings, jumping and falling from anywhere. -- [Variable-height jump and fast-fall](https://kotaku.com/the-mechanics-behind-satisfying-2d-jumping-1761940693). -- Adjusting movement trajectories around intermediate surfaces (such as jumping over a wall or under an overhang). -- Configurable movement parameters on a per-player basis (e.g., horizontal acceleration, jump power, gravity, collision boundary shape and size, which types of edge movement are allowed). -- Level creation using Godot's standard pattern with a [TileMap in the 2D scene editor](https://docs.godotengine.org/en/3.2/tutorials/2d/using_tilemaps.html). -- Preparsing the level into a platform graph, and using A* search for efficient path-finding at runtime. -- A powerful inspector for analyzing the platform graph, in order to debug and better understand how edges were calculated. - -## Buy why? - -Because there aren't many other good tools out there for intelligent pathfinding in a platformer. - -The vast majority of platformers use pretty simple computer-player AI for movement--for example: -- Walk to edge, turn around, repeat. -- Jump continuously, moving forward. -- Move with a regular bounce or surface-following pattern. -- Move horizontally toward the human player, "floating" vertically as needed in order to move around obstacles and platforms. - -Most examples of more sophisticated AI pathfinding behavior are usually still pretty limited. One common technique uses machine-learning and is trained by hundreds to thousands of human-generated jumps on an explicit pre-fabricated level. This makes level-generation difficult and is not flexible to dynamic platform creation/movement. - -There are two key reasons why good path-finding AI isn't really used in platformers: -1. It's hard to implement right; there is a lot of math involved, and there are a lot of different edge cases to account for. -2. Dumb AI is usually plenty effective on its own to create compelling gameplay. The user often doesn't really notice or care how simple the behavior is. - -But there are use-cases for which we really benefit from an AI that can accurately immitate the same movement mechanics of the player. One example is if we want to be able to control the player by tapping on locations that they should move through the level toward. Another example is if we want to have a flexible game mode in which a computer player can swap in for a human player depending on how many humans are present. - -## Platformer AI - -### The platform graph: Pre-parsing the world - -Surfacer depends on the level being represented as a [`TileMap`](https://docs.godotengine.org/en/stable/classes/class_tilemap.html#class-tilemap). - -In order for our AI to traverse our world, we first need to parse the world into a platform graph. We do this up-front, when the level is loaded, so that we can efficiently search the graph at run time. Dynamic updates to the graph can be performed at runtime, but these could be expensive if not done with care. - -The nodes of this graph correspond to positions along distinct surfaces. Since our players can walk on floors, climb on walls, and climb on ceilings, we store floor, wall, and ceiling surfaces. - -The edges of this graph correspond to a type of movement that the player could perform in order to move from one position on a surface node to another. -- These edges are directional, since the player may be able to move from A to B but not from B to A. -- The ends of an edge could be along the same surface or on different surfaces (e.g., for climbing up a wall vs jumping from a floor). -- There could be multiple edges between a single pair of nodes, since there could be multiple types of movement that could get the player from the one to the other. -- These edges are specific to a given player type. If we need to consider a different player that has different movement parameters, then we need to calculate a separate platform graph for that player. - -![Surfaces in a plattform graph](./docs/surfaces.png) - -![Edges in a plattform graph](./docs/edges.png) - -### Nodes: Parsing a Godot `TileMap` into surfaces - -**NOTE**: The following algorithm assumes that the given `TileMap` only uses tiles with convex collision boundaries. - -#### Parse individual tiles into their constituent surfaces - -- Map each `TileMap` cell into a polyline that corresponds to the top-side/floor portion of its collision polygon. - - Calculate whether the collision polygon's vertices are specified in a clockwise order. - - Use this to determine the iteration step size. - - `step_size = 1` if clockwise; `step_size = -1` if counter-clockwise. - - Regardless of whether the vertices are specified in a clockwise order, we will iterate over them in clockwise order. - - Find both the leftmost and rightmost vertices. - - Start with the leftmost vertex. - - If there is a wall segment on the left side of the polygon, then this vertex is part of it. - - If there is no wall segment on the left side of the polygon, then this vertex must be the cusp between a preceding bottom-side/ceiling segment and a following top-side/floor segment (i.e., the previous segment is underneath the next segment). - - Even if there is no segment along one side, we store a surface for that side; this surface is only represented by a single point. - - Iterate over the following vertices until we find a non-wall segment (this could be the first segment, the one connecting to the leftmost vertex). - - Wall segments are distinguished from floor/ceiling segments according to their angle. This is configurable, but typically, a segment up to 45-degrees is a floor/ceiling and a segment steeper than 45-degrees is a wall. - - This non-wall segment must be the start of the top-side/floor polyline. - - Iterate, adding segments to the result polyline, until we find either a wall segment or the rightmost vertex. - - We then also save a mapping from a `TileMap` cell index to each of the different surfaces we've calculated as existing in that cell. -- Repeat the above process for the right-side, left-side, and bottom-side surfaces. - -#### Remove internal surfaces - -**NOTE**: This will only detect internal surface segments that are equivalent with another internal segment. But for grid-based tiling systems, this can often be enough. - -- Check for pairs of floor+ceiling segments or left-wall+right-wall segments, such that both segments share the same vertices. -- Remove both segments in these pairs. - -#### Merge any connecting surfaces - -- Iterate across each floor surface A. -- Nested iterate across each other floor surface B. - - Ideally, we should be using a spatial data structure that allows us to only consider nearby surfaces during this nested iteration (such as an R-Tree). -- Check whether A and B form a "continuous" surface. - - A and B are both polylines that only have two end points. - - Just check whether either endpoint of A equals either endpoint of B. - - Actually, our original `TileMap` parsing results in every surface polyline being stored in clockwise order, so we only need to compare the end of A with the start of B and the start of A with the end of B. -- If they do: - - Merge B into A. - - Optionally, remove any newly created redundant internal colinear points. - - Remove B from the surface collection. -- Repeat the iteration until no merges were performed. - -#### Record adjacent neighbor surfaces - -- Every surface should have both adjacent clockwise and counter-clockwise neighbor surfaces. -- Use a similar process as above for finding surfaces with matching end positions. - -### Edges: Calculating jump movement trajectories - -**tl;dr**: The Surfacer framework uses a procedural approach to calculate trajectories for movement between surfaces. The algorithms used rely heavily on the classic [one-dimensional equations of motion for constant acceleration](https://physics.info/motion-equations/). These trajectories are calculated to match to the same abilities and limitations that are exhibited by corresponding human-controlled movement. After the trajectory for an edge is calculated, it is translated into a simple instruction/input-key start/end sequence that should reproduce the calculated trajectory. - -**NOTE**: A machine-learning-based approach would probably be a good alternate way to solve this general problem. However, one perk of a procedural approach is that it's relatively easy to understand how it works and to modify it to perform better for any given edge-case (and there are a _ton_ of edge-cases). - -#### The high-level steps - -- Determine how high we need to jump in order to reach the destination. -- If the destination is out of reach (vertically or horizontally), ignore it. -- Calculate how long it will take for vertical motion to reach the destination from the origin. -- We will define the movement trajectory as a combination of two independent components: a "vertical step" and a "horizontal step". The vertical step is based primarily on on the jump duration calculated above. -- Calculate the horizontal step that would reach the destination displacement over the given duration. -- Check for any unexpected collisions along the trajectory represented by the vertical and horizontal steps. - - If there is an intermediate surface that the player would collide with, we need to try adjusting the jump trajectory to go around either side of the colliding surface. - - We call these points that movement must go through in order to avoid collisions, "waypoints". - - Recursively check whether the jump is valid to and from either side of the colliding surface. - - If we can't reach the destination when moving around the colliding surface, then try backtracking and consider whether a higher jump height from the start would get us there. - - If there is no intermediate collision, then we can calculate the ultimate edge movement instructions for playback based on the vertical and horizontal steps we've calculated. - -#### Some important aspects - -- We treat horizontal and vertical motion as independent to each other. This greatly simplifies our calculations. - - We calculate the necessary jump duration--and from that the vertical component of motion--up-front, and use this to determine times for each potential step and waypoint of the motion. Knowing these times up-front makes the horizontal min/max calculations easier. -- We have a broad-phase check to quickly eliminate possible surfaces that are obviously out of reach. - - This primarily looks at the horizontal and vertical distance from the origin to the destination. - -#### Calculating "good" jump and land positions - -Deciding which jump and land positions to base an edge calculation off of is non-trivial. We could just try calculating edges for a bunch of different jump/land positions for a given pair of surfaces. But edge calculations aren't cheap, and executing too many of them impacts performance. So it's important that we carefully choose "good" jump/land positions that have a relatively high likelihood of producing a valid and efficient edge. - -Additionally, when jumping from a floor, we need to determine what initial horizontal velocity to use for the edge calculation. This horizontal start velocity can then influence the jump/land positions. - -- Some interesting jump/land positions for a surface include the following: - - Either end of the surface. - - The closest position along the surface to either end of the other surface. - - This closest position, but with a slight offset to account for the width of the player. - - This closest position, but with an additional offset to account for horizontal or vertical displacement with minimum jump time and maximum horizontal velocity. - - This offset becomes important when considering jumps that start with max-speed horizontal velocity, which could otherwise overshoot the land position if we didn't account for the offset. - - The closest interior position along the surface to the closest interior position along the other surface. - - The position along a horizontal surface that is behind the overall connected region that the vertical land surface is a part of. - - This position is important if we need to consider movement around behind a wall that then lands on the top of the wall. -- We try to minimize the number of jump/land positions returned, since having more of these greatly increases the overall time to parse the platform graph. -- We usually consider surface-interior points before surface-end points (which usually puts shortest distances first). -- We also decide start velocity when we decide the jump/land positions. - - We only ever consider start velocities with zero or max speed. -- Additionally, we often quit early as soon as we've calculated the first valid edge for a given pair of surfaces. - - In order to decide whether to skip an edge calculation for a given jump/land position pair, we look at how far away it is from any other jump/land position pair that we already found a valid edge for, on the same surface, for the same surface pair. If it's too close, we skip it. - - This is another important performance optimization. - -Unfortunately, most jump/land position calculations are highly dependent on the types and spatial arrangement of the two surfaces. There are many possible combinations, and the most of these combinations must be considered individually. The following diagrams illustrate the many different jump/land combinations. - -![A legend for the illustrations of jump-land-position combinations](./docs/jump-land-positions-legend.png) - -![Illustrations of floor-to-floor jump-land-position combinations](./docs/jump-land-positions-floor-to-floor.png) - -![Illustrations of floor-to-wall jump-land-position combinations](./docs/jump-land-positions-floor-to-wall.png) - -![Illustrations of wall-to-floor jump-land-position combinations](./docs/jump-land-positions-wall-to-floor.png) - -![Illustrations of wall-to-opposite-facing-wall jump-land-position combinations](./docs/jump-land-positions-wall-to-opposite-wall.png) - -![Illustrations of wall-to-same-facing-wall jump-land-position combinations](./docs/jump-land-positions-wall-to-same-wall.png) - -![Illustrations of floor-to-ceiling jump-land-position combinations](./docs/jump-land-positions-floor-to-ceiling.png) - -#### Calculating the start velocity for a jump - -- In the general case, we can't know at build-time what direction along a surface the player will - be moving from when they need to start a jump. -- Unfortunately, using start velocity x values of zero for all jump edges tends to produce very - unnatural composite trajectories (similar to using perpendicular Manhatten distance routes - instead of more diagonal routes). -- So, we can assume that for surface-end jump-off positions, we'll be approaching the jump-off - point from the center of the edge. -- And for most edges we should have enough run-up distance in order to hit max horizontal speed - before reaching the jump-off point--since horizontal acceleration is relatively quick. -- Also, we only ever consider velocity-start values of zero or max horizontal speed. Since the - horizontal acceleration is quick, most jumps at run time shouldn't need some medium-speed. And - even if they did, we force the initial velocity of the jump to match expected velocity, so the - jump trajectory should proceed as expected, and any sudden change in velocity at the jump start - should be acceptably small. - -#### Calculating the total jump duration (and the vertical step for the edge) - -- At the start of each edge-calculation traversal, we calculate the minimum total time needed to reach the destination. - - If the destination is above, this might be the time needed to rise that far in the jump. - - If the destination is below, this might be the time needed to fall that far (still taking into account any initial upward jump-off velocity). - - If the destination is far away horizontally, this might be the time needed to move that far horizontally (taking into account the horizontal movement acceleration and max speed). - - The greatest of these three possibilities is the minimum required total duration of the jump. -- The minimum peak jump height can be determined from this total duration. -- All of this takes into account our variable-height jump mechanic and the difference in slow-ascent and fast-fall gravities. - - With our variable-height jump mechanic, there is a greater acceleration of gravity when the player either is moving downward or has released the jump button. - - If the player releases the jump button before reaching the maximum peak of the jump, then their current velocity will continue pushing them upward, but with the new stronger gravity. - - To determine the duration to the jump peak height in this scenario, we first construct two instances of one of the basic equations of motion--one for the former part of the ascent, with the slow-ascent gravity, and one for the latter part of the ascent, with the fast-fall gravity. We then use algebra to substitute the equations and solve for the duration. - -#### Calculating the horizontal steps in an edge - -- If we decide whether a surface could be within reach, we then check for possible collisions between the origin and destination. - - To do this, we simulate frame-by-frame motion using the same physics timestep and the same movement-update function calls that would be used when running the game normally. We then check for any collisions between each frame. -- If we detect a collision, then we define two possible "waypoints"--one for each end of the collided surface. - - In order to make it around this intermediate surface, we know the player must pass around one of the ends of this surface. - - These waypoints we calculate represent the minimum required deviation from the player's original path. -- We then recursively check whether the player could move to and from each of the waypoints. - - We keep the original vertical step and overall duration the same. - - We can use that to calculate the time and vertical state that must be used for the waypoint. - - Then we only really consider whether the horizontal movement could be valid within the the given time limit. -- If so, we concatenate and return the horizontal steps required to reach the waypoint from the original starting position and the horizontal steps required to reach the original destination from the waypoint. - -#### Backtracking to consider a higher max jump height - -- Sometimes, a waypoint may be out of reach, when we're calculating horizontal steps, given the current step's starting position and velocity. -- However, maybe the waypoint could be within reach, if we had originally jumped a little higher. -- To account for this, we backtrack to the start of the overall movement traversal and consider whether a higher jump could reach the waypoint. - - The destination waypoint is first updated to support a new jump height that would allow for a previously-out-of-reach intermediate waypoint to also be reached. - - Then all steps are re-calculated from the start of the movement, while considering the new destination state. -- If it could, we return that result instead. - -#### Waypoint calculations - -- We calculate waypoints before steps. - - We calculate a lot of state to store on them, and then depend on this state during step calculation. - - Some of this state includes: - - The time for passing through the waypoint (corresponding to the overall jump height and edge duration). - - The horizontal direction of movement through the waypoint (according to the direction of travel from the previous waypoint or according to the direction of the surface). - - The min and max possible x-velocity when the movement passes through this waypoint. - - With a higher speed through a waypoint, we could reach further for the next waypoint, or we could be stuck overshooting the next waypoint. So it's useful to calculate the range of possible horizontal velocities through a waypoint. - - The actual x-velocity for movement through the waypoint is calculated later when calculating the cooresponding movement step. - - We typically try to use an x-velocity that will minimize speed through the waypoint, while still satisfying the horizontal step displacement and the waypoint's min/max limitations. -- Here's the sequence of events for waypoint calculations: - - Start by calculating origin and destination waypoints. - - For the origin waypoint, min, max, and actual x-velocity are all zero. - - For the destination waypoint, min and max are assigned according to how acceleration can be applied during the step (e.g., at the start or at the end of the interval). - - Then, during step calculation traversal, when a new intermediate waypoint is created, its min and max x-velocity are assigned according to both the min and max x-velocity of the following waypoint and the actual displacement and duration of the step from the new waypoint to the next waypoint. - - Intermediate waypoints are calculated with pre-order tree traversal. - - This poses a small problem: - - The calculation of a waypoint depends on the accuracy of the min/max x-velocity of it's next waypoint. - - However, the min/max x-velocity of the next waypoint could need to be updated if it in turn has a new next waypoint later on. - - Additionally, a new waypoint could be created later on that would become the new next waypoint instead of the old next waypoint. - - To ameliorate this problem, everytime a new waypoint is created, we update its immediate neighbor waypoints. - - These updates do not solve all cases, since we may in turn need to update the min/max x-velocities and movement sign for all other waypoints. And these updates could then result in the addition/removal of other intermediate waypoints. But we have found that these two updates are enough for most cases. If we detect that a neigbor waypoint would be invalidated during an update, we abandon the edge calculation, which could result in a false-negative result. - - Steps are calculated with in-order tree traversal (i.e., in the same order they'd be executed when moving from origin to destination). - -#### Fake waypoints - -- When calcuting steps to navigate around a collision with a ceiling or floor surface, sometimes one of the two possible waypoints is what we call "fake". -- A fake waypoint corresponds to the left side of the floor/ceiling surface when movement from the previous waypoint is rightward (or to the right side when movement is leftward). -- In this case, movement will need to go around both the floor/ceiling as well as its adjacent wall surface. -- The final movement trajectory should not end-up moving through the fake waypoint. -- The actual waypoint that the final movement should move through, is instead the "real" waypoint that cooresponds to the far edge of this adjacent wall surface. -- So, when we find a fake waypoint, we immediately replace it with its adjacent real waypoint. -- Example scenario: - - Origin is waypoint #0, Destination is waypoint #3 - - Assume we are jumping from a low-left platform to a high-right platform, and there is an intermediate block in the way. - - Our first step attempt hits the underside of the block, so we try waypoints on either side. - - After trying the left-hand waypoint (#1), we then hit the left side of the block. So we then try a top-side waypoint (#2). - - (Bottom-side fails the surface-already-encountered check). - - After going through this new left-side (right-wall), top-side waypoint (#2), we can successfully reach the destination. - - With the resulting scenario, we shouldn't actually move through both of the intermediate waypoints (#1 and #2). We should should instead skip the first intermediate waypoint (#1) and go straight from the origin to the second intermediate waypoint (#2). - -TODO: screenshot of example scenario - -#### Collision calculation madness - -**tl;dr**: Godot's collision-detection engine is very broken. We try to make it work for our -pathfinding, but there are still false negatives and rough edges. - -Here's a direct quote from a comment in Godot's underlying collision-calculation logic: - -> give me back regular physics engine logic
-> this is madness
-> and most people using this function will think
-> what it does is simpler than using physics
-> this took about a week to get right..
-> but is it right? who knows at this point..
- -(https://github.com/godotengine/godot/blob/a7f49ac9a107820a62677ee3fb49d38982a25165/servers/physics_2d/space_2d_sw.cpp#L692) - -Some known limitations and rough edges include: -- When a [`KinematicBody2D`](https://docs.godotengine.org/en/stable/classes/class_kinematicbody2d.html) is sliding around a corner of another collidable, Godot can sometimes calculate the wrong results (oppositite direction) for `is_floor()`/`is_ceiling()`. -- Inconsistency between the behavior of the [`KinematicBody2D`](https://docs.godotengine.org/en/stable/classes/class_kinematicbody2d.html) and [`Physics2DDirectSpaceState`](https://docs.godotengine.org/en/stable/classes/class_physics2ddirectspacestate.html) collision APIs. - - We were originally using the Physics2DDirectSpaceState for most of our graph calculations. However, this API seems to be more broken than the KinematicBody2D API. Also, we're using the KinematicBody2D API at run time, so we see more consistent results by using the KinematicBody2D API at build time as well. - -### Navigator: Using the platform graph to move from A to B - -Once the platform graph has been parsed, finding and moving along a path through the graph is relatively straight-forward. The sequence of events looks like the following: - -- Given a target point to navigate towards and the player's current position. -- Find the closest point along the closest surface to the target point. -- Use A* search to find a path through the graph from the origin to the destination. - - We can use distance or duration as the edge weights. -- Execute playback of the instruction set for each edge of the path, in sequence. - -![Navigator finding a path to a destination](./docs/navigator-preselection.png) - -#### Dynamic edge optimization according to runtime approach - -At runtime, after finding a path through build-time-calculated edges, we try to optimize the jump-off points of the edges to better account for the direction that the player will be approaching the edge from. This produces more efficient and natural movement. The build-time-calculated edge state would only use surface end-points or closest points. We also take this opportunity to update start velocities to exactly match what is allowed from the ramp-up distance along the edge, rather than either the fixed zero or max-speed value used for the build-time-calculated edge state. - -#### Edge instructions playback - -When we create the edges, we represent the movement trajectories according to the sequence of instructions that would produce the trajectory. Each instruction is simply represented by an ID for the relevant input key, whether the key is being pressed or released, and the time. The player movement system can then handle these input key events in the same way as actual human-triggered input key events. - -#### Correcting for runtime vs buildtime trajectory discrepancies - -When executing edge instructions, the resulting run-time trajectory is usually slightly off from the expected trajectory that was pre-calculated when creating the edge. This variance is usually pretty minor, but, just in case, a given player can be configured to use the exact pre-calculated edge trajectory rather than the run-time version. - -Theoretically, this discrepancy shouldn't exist, and we should be able to eliminate it at some point. - -## Platform graph inspector - -As you might imagine, the calculations for these edges can get quite complicated. To make these calculations easier to understand and debug, we created a powerful platform graph inspector. This can be accessed from the utility menu (the gear icon in the top-right corner of the screen). - -![Platform graph inspector](./docs/platform-graph.png) - -The inspector is a tree-view widget with the following structure: - -``` - - Platform graph [player_name] - - Edges [#] - - [#] Edges calculated with increasing jump height - - JUMP_INTER_SURFACE_EDGEs [#] - - [(x,y), (x,y)] - - Profiler - - ... - - EDGE_VALID_WITH_INCREASING_JUMP_HEIGHT [1] - - 1: Movement is valid. - - ... - - ... - - ... - - [#] Edges calculated without increasing jump height - - ... - - [#] Edges calculated with one step - - ... - - Surfaces [#] - - FLOORs [#] - - [(x,y), (x,y)] - - _# valid outbound edges_ - - _Destination surfaces:_ - - FLOOR [(x,y), (x,y)] - - JUMP_INTER_SURFACE_EDGEs [#] - - [(x,y), (x,y)] - - Profiler - - ... - - EDGE_VALID_WITH_INCREASING_JUMP_HEIGHT [1] - - 1: Movement is valid. - - ... - - ... - - Failed edge calculations [#] - - REASON_FOR_FAILING [(x,y), (x,y)] - - Profiler - - ... - - REASON_FOR_FAILING [#] - - 1: Step result info - - 2: Step result info - - ... - - ... - - ... - - ... - - ... - - ... - - ... - - ... - - Profiler - - ... - - Global counts - - # total surfaces - - # total edges - - # JUMP_INTER_SURFACE_EDGEs - - ... -``` - -Each entry in this inspector tree is encoded with annotation information which will render debugging info over the level for the corresponding entity. Additionally, each entry contains a detailed description. These are both shown when selecting the entry. - -![Edge-step calculation debugging annotation](./docs/edge-step-calculation-debugging.png) - -## Annotators - -We include a large collection of annotators that are useful for visually debugging calculation of the platform graph. Some of these are rendered by selecting entries in the platform graph inspector and some of them can be toggled through checkboxes in the utility panel. - -## Movement parameters - -We support a large number of flags and parameters for adjusting various aspects of player/movement/platform-graph behavior. For a complete list of these params, see [movement_params.gd](./framework/platform_graph/edge/models/movement_params.gd). - -## Notable limitations - -- Our build-time graph calculations take a long time, especially for a level with lots of surfaces (such as a big level, or a level with a small cell size). -- There is slight discrepancy between discrete and continuous trajectories. The former is what we see from movement produced by the frame-by-frame application of gravity and input actions on the player. The latter is what we see from our precise numerical analysis of algebraic equations when pre-calculating the platform graph. We support a few different techniques for reconciling this: - - `MovementParams.syncs_player_velocity_to_edge_trajectory`: When this flag is enabled, the player's run-time _velocity_ will be forced to match the expected pre-calculated (continuous) velocity for the current frame in the currently executing platform graph edge. - - `MovementParams.syncs_player_position_to_edge_trajectory`: When this flag is enabled, the player's run-time _position_ will be forced to match the expected pre-calculated (continuous) velocity for the current frame in the currently executing platform graph edge. - - `MovementParams.retries_navigation_when_interrupted`: When this flag is enabled, the navigator will re-attempt navigation to the original destination from the current position whenever it detects that the player has hit an unexpected surface, which is what can happen when the run-time discrete trajectories don't match build-time continuous trajectories. -- When two surfaces face each other and are too close for thte player to fit between (plus a margin of a handful of extra pixels), our graph calculations can produce some false positives. -- Surfacer doesn't currently fully support surfaces that consist of one point. -- Our platform graph calculations produce false negatives for some types of jump edge scenarios: - - An jump edge that needs to displace the jump position in order to make it around an intermediate waypoint with enough horizontal velocity to then reach the destination. - - For example, if the player is jumping from the bottom of a set of stair-like surfaces, the jump position ideally wouldn't be as close as possible to the first rise of the first step (because they can't start accelerating horizontally until vertically clearing the top of the rise). Instead, if the player jumps from a slight offset from the rise, then they can pass over the rise with more speed, which lets them travel further during the jump. - - A single horizontal step that needs multiple different sideways-movement instructions (i.e., accelerating to both one side and then the other in the same jump): - - For example, backward acceleration in order to not overshoot the end position as well as forward acceleration to then have enough step-end x velocity in order to reach the following waypoint for the next step. -- Surfacer is opinionated. It requires that you structure your app using TileMaps, specific node groups, and by subclassing certain framework classes in order to create players. - - You need to define a set of input actions with the following names (via Project Settings > Input Map): - - jump - - move_up - - move_down - - move_left - - move_right - - dash - - zoom_in - - zoom_out - - pan_up - - pan_down - - pan_left - - pan_right - - face_left - - face_right - - grab_wall - - Your level collidable foreground tiles must be defined in a TileMap that belongs to the "surfaces" node group. - - The Surfacer framework isn't yet decoupled from the Squirrel Away demo app logic. - -## Future work - -For a list of planned future work items / TODOs, see [main.gd](./main.gd). - -Some high-level planned future features include: -- Add an option for saving/loading the platform graph instead of parsing it each time. -- Bypass the Godot collision system at runtime, and use only the pre-calculated expected edge trajectories from the platform graph. -- More intelligent squirral avoidance. -- Better game-play goal, with an event that happens when you catch the squirrel. -- Decouple the Surface framework logic from the Squirrel Away demo logic. -- Add Surfacer to the Godot Asset Library. -- Use an R-Tree for faster surface lookup. -- Support for fall-through floors and walls in the platform graph. -- Support for double jumps in the platform graph. -- Support for dashes in the platform graph. -- Support for surfaces that face each other and are too close for player to fit between. -- Support for surfaces of one point. -- Support an alternate, template-based edge calculation pattern, which should be able to offer faster build times and still have quick run times. -- Add networking. -- Procedural level generation. - -## Tests - -_**NOTE**: Sadly, the tests are not set up to automatically run on presubmit, so some of the tests are severely out-of-date and broken._ - -Surfacer uses the [Gut tool](https://github.com/bitwes/Gut) for writing and running unit tests. +In this game, the user can click anywhere in the level, and the cat character will then jump, walk, and climb across platforms in order to reach that target destination. ## Software used -- [Godot](https://godotengine.org/) was used to create the Surfacer framework and Squirrel Away game. -- [Piskel](https://www.piskelapp.com/user/5663844106502144) was used to create the squirrel images. -- [Aseprite](https://www.aseprite.org/) was used to create all other images. -- [Bfxr](https://www.bfxr.net/) was used to create the sound effects. -- [DefleMask](https://deflemask.com/) was used to create the music. +- [Surfacer](https://github.com/snoringcatgames/surfacer/): A framework that enables procedural path-finding across 2D platforms. +- [Godot Scaffold](https://github.com/snoringcatgames/godot-scaffold/): A framework that provides some general app infrastructure. +- [Godot](https://godotengine.org/): Game engine. +- [Piskel](https://www.piskelapp.com/user/5663844106502144): Pixel-art image editor. +- [Aseprite](https://www.aseprite.org/): Pixel-art image editor. +- [Bfxr](https://www.bfxr.net/): Sound effects editor. +- [DefleMask](https://deflemask.com/): Chiptune music tracker. ## Licenses -- The Surfacer framework is published under the [MIT license](LICENSE). -- All art assets (files under `assets/images/`, `assets/music/`, and `assets/sfx/`) are published under the [CC0 1.0 Universal license](https://creativecommons.org/publicdomain/zero/1.0/deed.en). -- The Surface framework depends on various pieces of third-party code that are licensed separately. Here are lists of these third-party licenses: +- All code is published under the [MIT license](LICENSE). +- All art assets (files under `assets/images/`, `assets/music/`, and `assets/sounds/`) are published under the [CC0 1.0 Universal license](https://creativecommons.org/publicdomain/zero/1.0/deed.en). +- This project depends on various pieces of third-party code that are licensed separately. Here are lists of these third-party licenses: - [addons/scaffold/scaffold_third_party_licenses.gd](./addons/scaffold/scaffold_third_party_licenses.gd) - [addons/surfacer/surfacer_third_party_licenses.gd](./addons/surfacer/surfacer_third_party_licenses.gd) - [src/squirrel_away_third_party_licenses.gd](./src/squirrel_away_third_party_licenses.gd) + +![An animated GIF showing a squirrel running](assets/images/loading.gif) diff --git a/addons/scaffold/LICENSE b/addons/scaffold/LICENSE new file mode 100644 index 00000000..36dbd644 --- /dev/null +++ b/addons/scaffold/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020-2021 Snoring Cat LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/addons/scaffold/README.md b/addons/scaffold/README.md new file mode 100644 index 00000000..a797bfe9 --- /dev/null +++ b/addons/scaffold/README.md @@ -0,0 +1,11 @@ +# Godot Scaffold + +_**[Example app](https://github.com/snoringcatgames/squirrel-away)**_ + +## Licenses + +- All code is published under the [MIT license](LICENSE). +- All art assets (files under `assets/images/`, `assets/music/`, and `assets/sounds/`) are published under the [CC0 1.0 Universal license](https://creativecommons.org/publicdomain/zero/1.0/deed.en). +- This project depends on various pieces of third-party code that are licensed separately. [Here is a list of these third-party licenses](./src/scaffold_third_party_licenses.gd). + +![An animated icon consisting of spinning gear, a game controller, and a pixelated jumping character](assets/images/spinning_gear_icon.gif) diff --git a/assets/fonts/Open_Sans/LICENSE.txt b/addons/scaffold/assets/fonts/Open_Sans/LICENSE.txt similarity index 100% rename from assets/fonts/Open_Sans/LICENSE.txt rename to addons/scaffold/assets/fonts/Open_Sans/LICENSE.txt diff --git a/assets/fonts/Open_Sans/OpenSans-Bold.ttf b/addons/scaffold/assets/fonts/Open_Sans/OpenSans-Bold.ttf similarity index 100% rename from assets/fonts/Open_Sans/OpenSans-Bold.ttf rename to addons/scaffold/assets/fonts/Open_Sans/OpenSans-Bold.ttf diff --git a/assets/fonts/Open_Sans/OpenSans-BoldItalic.ttf b/addons/scaffold/assets/fonts/Open_Sans/OpenSans-BoldItalic.ttf similarity index 100% rename from assets/fonts/Open_Sans/OpenSans-BoldItalic.ttf rename to addons/scaffold/assets/fonts/Open_Sans/OpenSans-BoldItalic.ttf diff --git a/assets/fonts/Open_Sans/OpenSans-ExtraBold.ttf b/addons/scaffold/assets/fonts/Open_Sans/OpenSans-ExtraBold.ttf similarity index 100% rename from assets/fonts/Open_Sans/OpenSans-ExtraBold.ttf rename to addons/scaffold/assets/fonts/Open_Sans/OpenSans-ExtraBold.ttf diff --git a/assets/fonts/Open_Sans/OpenSans-ExtraBoldItalic.ttf b/addons/scaffold/assets/fonts/Open_Sans/OpenSans-ExtraBoldItalic.ttf similarity index 100% rename from assets/fonts/Open_Sans/OpenSans-ExtraBoldItalic.ttf rename to addons/scaffold/assets/fonts/Open_Sans/OpenSans-ExtraBoldItalic.ttf diff --git a/assets/fonts/Open_Sans/OpenSans-Italic.ttf b/addons/scaffold/assets/fonts/Open_Sans/OpenSans-Italic.ttf similarity index 100% rename from assets/fonts/Open_Sans/OpenSans-Italic.ttf rename to addons/scaffold/assets/fonts/Open_Sans/OpenSans-Italic.ttf diff --git a/assets/fonts/Open_Sans/OpenSans-Light.ttf b/addons/scaffold/assets/fonts/Open_Sans/OpenSans-Light.ttf similarity index 100% rename from assets/fonts/Open_Sans/OpenSans-Light.ttf rename to addons/scaffold/assets/fonts/Open_Sans/OpenSans-Light.ttf diff --git a/assets/fonts/Open_Sans/OpenSans-LightItalic.ttf b/addons/scaffold/assets/fonts/Open_Sans/OpenSans-LightItalic.ttf similarity index 100% rename from assets/fonts/Open_Sans/OpenSans-LightItalic.ttf rename to addons/scaffold/assets/fonts/Open_Sans/OpenSans-LightItalic.ttf diff --git a/assets/fonts/Open_Sans/OpenSans-Regular.ttf b/addons/scaffold/assets/fonts/Open_Sans/OpenSans-Regular.ttf similarity index 100% rename from assets/fonts/Open_Sans/OpenSans-Regular.ttf rename to addons/scaffold/assets/fonts/Open_Sans/OpenSans-Regular.ttf diff --git a/assets/fonts/Open_Sans/OpenSans-SemiBold.ttf b/addons/scaffold/assets/fonts/Open_Sans/OpenSans-SemiBold.ttf similarity index 100% rename from assets/fonts/Open_Sans/OpenSans-SemiBold.ttf rename to addons/scaffold/assets/fonts/Open_Sans/OpenSans-SemiBold.ttf diff --git a/assets/fonts/Open_Sans/OpenSans-SemiBoldItalic.ttf b/addons/scaffold/assets/fonts/Open_Sans/OpenSans-SemiBoldItalic.ttf similarity index 100% rename from assets/fonts/Open_Sans/OpenSans-SemiBoldItalic.ttf rename to addons/scaffold/assets/fonts/Open_Sans/OpenSans-SemiBoldItalic.ttf diff --git a/addons/scaffold/assets/fonts/main_font_italic.tres b/addons/scaffold/assets/fonts/main_font_italic.tres new file mode 100644 index 00000000..fef1b091 --- /dev/null +++ b/addons/scaffold/assets/fonts/main_font_italic.tres @@ -0,0 +1,7 @@ +[gd_resource type="DynamicFont" load_steps=2 format=2] + +[ext_resource path="res://addons/scaffold/assets/fonts/Open_Sans/OpenSans-Italic.ttf" type="DynamicFontData" id=1] + + +[resource] +font_data = ExtResource( 1 ) diff --git a/addons/scaffold/assets/fonts/main_font_l.tres b/addons/scaffold/assets/fonts/main_font_l.tres new file mode 100644 index 00000000..c509194c --- /dev/null +++ b/addons/scaffold/assets/fonts/main_font_l.tres @@ -0,0 +1,7 @@ +[gd_resource type="DynamicFont" load_steps=2 format=2] + +[ext_resource path="res://addons/scaffold/assets/fonts/Open_Sans/OpenSans-Regular.ttf" type="DynamicFontData" id=1] + +[resource] +size = 28 +font_data = ExtResource( 1 ) diff --git a/addons/scaffold/assets/fonts/main_font_m.tres b/addons/scaffold/assets/fonts/main_font_m.tres new file mode 100644 index 00000000..7c30a2dd --- /dev/null +++ b/addons/scaffold/assets/fonts/main_font_m.tres @@ -0,0 +1,6 @@ +[gd_resource type="DynamicFont" load_steps=2 format=2] + +[ext_resource path="res://addons/scaffold/assets/fonts/Open_Sans/OpenSans-Regular.ttf" type="DynamicFontData" id=1] + +[resource] +font_data = ExtResource( 1 ) diff --git a/addons/scaffold/assets/fonts/main_font_m_bold.tres b/addons/scaffold/assets/fonts/main_font_m_bold.tres new file mode 100644 index 00000000..7fa91373 --- /dev/null +++ b/addons/scaffold/assets/fonts/main_font_m_bold.tres @@ -0,0 +1,8 @@ +[gd_resource type="DynamicFont" load_steps=2 format=2] + +[ext_resource path="res://addons/scaffold/assets/fonts/Open_Sans/OpenSans-Bold.ttf" type="DynamicFontData" id=1] + + +[resource] +size = 20 +font_data = ExtResource( 1 ) diff --git a/addons/scaffold/assets/fonts/main_font_m_italic.tres b/addons/scaffold/assets/fonts/main_font_m_italic.tres new file mode 100644 index 00000000..b6d9e608 --- /dev/null +++ b/addons/scaffold/assets/fonts/main_font_m_italic.tres @@ -0,0 +1,8 @@ +[gd_resource type="DynamicFont" load_steps=2 format=2] + +[ext_resource path="res://addons/scaffold/assets/fonts/Open_Sans/OpenSans-Italic.ttf" type="DynamicFontData" id=1] + + +[resource] +size = 20 +font_data = ExtResource( 1 ) diff --git a/addons/scaffold/assets/fonts/main_font_s.tres b/addons/scaffold/assets/fonts/main_font_s.tres new file mode 100644 index 00000000..9437ce59 --- /dev/null +++ b/addons/scaffold/assets/fonts/main_font_s.tres @@ -0,0 +1,7 @@ +[gd_resource type="DynamicFont" load_steps=2 format=2] + +[ext_resource path="res://addons/scaffold/assets/fonts/Open_Sans/OpenSans-Regular.ttf" type="DynamicFontData" id=1] + +[resource] +size = 12 +font_data = ExtResource( 1 ) diff --git a/addons/scaffold/assets/fonts/main_font_xl.tres b/addons/scaffold/assets/fonts/main_font_xl.tres new file mode 100644 index 00000000..ac9eddf0 --- /dev/null +++ b/addons/scaffold/assets/fonts/main_font_xl.tres @@ -0,0 +1,7 @@ +[gd_resource type="DynamicFont" load_steps=2 format=2] + +[ext_resource path="res://addons/scaffold/assets/fonts/Open_Sans/OpenSans-Regular.ttf" type="DynamicFontData" id=1] + +[resource] +size = 32 +font_data = ExtResource( 1 ) diff --git a/assets/fonts/main_font_xs.tres b/addons/scaffold/assets/fonts/main_font_xs.tres similarity index 57% rename from assets/fonts/main_font_xs.tres rename to addons/scaffold/assets/fonts/main_font_xs.tres index 1ddc54ce..a18728db 100644 --- a/assets/fonts/main_font_xs.tres +++ b/addons/scaffold/assets/fonts/main_font_xs.tres @@ -1,6 +1,6 @@ [gd_resource type="DynamicFont" load_steps=2 format=2] -[ext_resource path="res://assets/fonts/Open_Sans/OpenSans-Regular.ttf" type="DynamicFontData" id=1] +[ext_resource path="res://addons/scaffold/assets/fonts/Open_Sans/OpenSans-Regular.ttf" type="DynamicFontData" id=1] [resource] size = 10 diff --git a/assets/fonts/main_font_xs_italic.tres b/addons/scaffold/assets/fonts/main_font_xs_italic.tres similarity index 57% rename from assets/fonts/main_font_xs_italic.tres rename to addons/scaffold/assets/fonts/main_font_xs_italic.tres index f582b37e..25a5538a 100644 --- a/assets/fonts/main_font_xs_italic.tres +++ b/addons/scaffold/assets/fonts/main_font_xs_italic.tres @@ -1,6 +1,7 @@ [gd_resource type="DynamicFont" load_steps=2 format=2] -[ext_resource path="res://assets/fonts/Open_Sans/OpenSans-Italic.ttf" type="DynamicFontData" id=1] +[ext_resource path="res://addons/scaffold/assets/fonts/Open_Sans/OpenSans-Italic.ttf" type="DynamicFontData" id=1] + [resource] size = 10 diff --git a/assets/images/device-icons/icon-128.png b/addons/scaffold/assets/images/device-icons/icon-128.png similarity index 100% rename from assets/images/device-icons/icon-128.png rename to addons/scaffold/assets/images/device-icons/icon-128.png diff --git a/assets/images/device-icons/icon-128.png.import b/addons/scaffold/assets/images/device-icons/icon-128.png.import similarity index 66% rename from assets/images/device-icons/icon-128.png.import rename to addons/scaffold/assets/images/device-icons/icon-128.png.import index a7386a7c..4455b18c 100644 --- a/assets/images/device-icons/icon-128.png.import +++ b/addons/scaffold/assets/images/device-icons/icon-128.png.import @@ -2,15 +2,15 @@ importer="texture" type="StreamTexture" -path="res://.import/icon-128.png-83b76ec9fb0adca68462470a2d823da2.stex" +path="res://.import/icon-128.png-a16bec5b2d3b6a154ee666151c7d5397.stex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/images/device-icons/icon-128.png" -dest_files=[ "res://.import/icon-128.png-83b76ec9fb0adca68462470a2d823da2.stex" ] +source_file="res://addons/scaffold/assets/images/device-icons/icon-128.png" +dest_files=[ "res://.import/icon-128.png-a16bec5b2d3b6a154ee666151c7d5397.stex" ] [params] diff --git a/assets/images/device-icons/icon-32.png b/addons/scaffold/assets/images/device-icons/icon-32.png similarity index 100% rename from assets/images/device-icons/icon-32.png rename to addons/scaffold/assets/images/device-icons/icon-32.png diff --git a/assets/images/device-icons/icon-32.png.import b/addons/scaffold/assets/images/device-icons/icon-32.png.import similarity index 68% rename from assets/images/device-icons/icon-32.png.import rename to addons/scaffold/assets/images/device-icons/icon-32.png.import index 600a4646..5572120c 100644 --- a/assets/images/device-icons/icon-32.png.import +++ b/addons/scaffold/assets/images/device-icons/icon-32.png.import @@ -2,15 +2,15 @@ importer="texture" type="StreamTexture" -path="res://.import/icon-32.png-5fcfb806c967f4e325b8d8cb150cbff3.stex" +path="res://.import/icon-32.png-0d70db2e3280e9e70e7b2c58e5da7d72.stex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/images/device-icons/icon-32.png" -dest_files=[ "res://.import/icon-32.png-5fcfb806c967f4e325b8d8cb150cbff3.stex" ] +source_file="res://addons/scaffold/assets/images/device-icons/icon-32.png" +dest_files=[ "res://.import/icon-32.png-0d70db2e3280e9e70e7b2c58e5da7d72.stex" ] [params] diff --git a/assets/images/device-icons/icon-64.png b/addons/scaffold/assets/images/device-icons/icon-64.png similarity index 100% rename from assets/images/device-icons/icon-64.png rename to addons/scaffold/assets/images/device-icons/icon-64.png diff --git a/assets/images/device-icons/icon-64.png.import b/addons/scaffold/assets/images/device-icons/icon-64.png.import similarity index 68% rename from assets/images/device-icons/icon-64.png.import rename to addons/scaffold/assets/images/device-icons/icon-64.png.import index 668e9db3..8a609192 100644 --- a/assets/images/device-icons/icon-64.png.import +++ b/addons/scaffold/assets/images/device-icons/icon-64.png.import @@ -2,15 +2,15 @@ importer="texture" type="StreamTexture" -path="res://.import/icon-64.png-f4b64229df29080eebb50a8c28041bb7.stex" +path="res://.import/icon-64.png-cd21c3475104f2222840825ab82fef76.stex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/images/device-icons/icon-64.png" -dest_files=[ "res://.import/icon-64.png-f4b64229df29080eebb50a8c28041bb7.stex" ] +source_file="res://addons/scaffold/assets/images/device-icons/icon-64.png" +dest_files=[ "res://.import/icon-64.png-cd21c3475104f2222840825ab82fef76.stex" ] [params] diff --git a/addons/scaffold/assets/images/gui/go_icon_normal.aseprite b/addons/scaffold/assets/images/gui/go_icon_normal.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..2273fa66f1eac309052e18e337c4bb94d2501bed GIT binary patch literal 716 zcmcJN%}W$v9Dv_#T~jFRv{ERJlA0%XH&fRgR1`1y6%u}6qG2w$!iplYBDf%0X@?aR z#a+KHqD1CFMU;>g!HWgmQarRq9aIo3V(|l~=QSn&f!<-B8QwYko@Zu0-Vh=%r4tHA zn9vC!UU2?fi9#ng#T}0Su?m=fa%8xeYG8no^QLk!^4ho%Hts5kmpcj9o?P9=DJhx| zc@I=*x0<1+)CRvcCBW@TJ3L(X!qcCraOB4m=vXzuv_U7#uTO?0`S+nkwZg2d7HF#J zgq6-+SnJbZ^{4M}bLR|dEFpZeOR%fs6|8qSU`1&OY|ZI~?<^L$T~-Ufw68$V@MGB9 zD5rbpc3`*JmDRIbukHR2S(wWp*bj7Ld4?zu(SOtbbCCo##s$p_J`nOs}&9&uY>8f=P(>O z3`31-y3soXU0&r@xpO1jUbq3;Y^udD)P6FVlmSw6)E82(fm~V%rIJMYh@*@wnh2tX z6gr5Y0DasMSJqPEi!7#S;)o!2sNsbaM(E&z2o@+Xzd()GmM^|34Y@TCTY&5R~#m%6aqUHQ&DBP(}LL+VLyhlP8;x-LN=c$a`;x z0|%eB>G@wC9-X+X&vd##ZzFeNCKlZ1rcx`hL0`v8j>1$pTw@_<%oU MFM5)k44ofy`glX(f`lm_^OxB_V< z1rt{dn>0(q{xIwNg=#k!q`f;l>-Q(KnNI_<_8FK@$@9+C5As$qvaz(cFEL1Hiq3nO zJo|tA*(axO|M~y_|LnEfTk6^~v$7(?g36q_))*Px3{SpZy{mt^S69Blto64e@@Dy( zDjF+E+1S|3nllgVN6gXG| z>YM)mzj`ff@*&p~tarMOU$f=B)x1_Wt|Ua%VNKnG-41U(RVMMyFc5cWKE>iz=;y** zbn@@X)nX0@f{m{>2(dHNtbW4qxgq;R0hgkK{F2O)fQ0_Cj3QpY2Ptz}gcSn6HcTvF zTD+r^fvH@NeZu;5hFd2VHNJZPdVil#JEN35@0m{$4u`KZFkH7c4=69@T*E7E7CCiR Sr9mXnsSKX3elF{r5}E)@m$^m& literal 0 HcmV?d00001 diff --git a/addons/scaffold/assets/images/gui/go_icon_normal_large.png.import b/addons/scaffold/assets/images/gui/go_icon_normal_large.png.import new file mode 100644 index 00000000..cff94d7f --- /dev/null +++ b/addons/scaffold/assets/images/gui/go_icon_normal_large.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/go_icon_normal_large.png-12d3f8d01b3c5f0ddf9a5e1c630cfb63.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/scaffold/assets/images/gui/go_icon_normal_large.png" +dest_files=[ "res://.import/go_icon_normal_large.png-12d3f8d01b3c5f0ddf9a5e1c630cfb63.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/scaffold/assets/images/spinning_gear_icon.gif b/addons/scaffold/assets/images/spinning_gear_icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..bc4d64a3ae2c87f1d74c84e083cb0ff0fb61d9ad GIT binary patch literal 18825 zcmcHBcT`i0+UV;!)9EukK!7B)fQVEnq9)YPLsLZ5fT+Mi1qB5~O(66lARr=W=%Ap0 zsGz6`y{Q4QA!@*e9jsW^;>5l0_w94XJ?Fpg(gJg2Oa_dM^@mD|p{Qu6 zy#vb2fo5Mq91kdAFO+l;qEMi!TFAi;8t8`z5cK2;v?&C-ehm_&LMJLHFJD4TBk0pN z$jqFwv_$##4MU|s6L+C=%@{oz#9~A8k3W|vZ$A9_zW<{ys3jIZmSduEbf|XEaE$$F zX=A)cOUU^L&HF~*AGjfFP4qH7d3&zoz|CEkT{1h9*O0qD-Wl9}`{Q?=M1k*t!)XWk zDOn!E^uw9i1unUH$wv#1A1l@@Jsw7(_@5}Q@IGDX%TOik<5uU@dNK&A%?%zJxP!_U zz0ak$x-*myDyVf|a$+dy9%(7R>8ml8OdPz_o`$>Uemza>#^^c>Jt|<(_40IHxIWJJ zp{eG9itiF*Z{vMFNWJj4k?$@_%w!Kys-l!E$WJ0N#Zumd$#}6WM>fNN8*eKPaR$+* zwqK6PdJ&nf&V=}(nOd5P?hhL8qEtLmR*a$qGZ8vIODdGLvT4Xsh^lhZ%3l=COiL58 zob|-&vh5RPaG1=C##Om-me-5R>*F?8As{NDv6aV8gQ?QItlu_F>0_a>JtDEFsY&;A zu7#-8+@vdj(qW(#C)#|!m_eYHt+W#N`ykRc2a7+C^dMiy;#eq_Fs)Dl;gHX86o;mg z);-0}%xpki^;I+vE1NliewbM6R}GnGe|St`M#4M}a4v5O$hX0|y0iDvH4c!CQ5BhA zUaM{XJ|m`{2z0`kdj7bcp@51z%xN?{d6_%7?46C*<&js14Y5edtPY_(aWDgKtd8Sq z^qW@!2OcZ<$)H0b*cKhSm(5cGgUVVGL~DN2(>A9YgCqhaw-a3Np6o0EvGtQ^#Hywp zQ!B?N#6jG)m9IJK z&y$2F({s&Wq@4!+O$0T^=(AYeg#(fP_t=FaLBj*?3T=5IGq1TFqOyASjgav(!tr*y zWp4TmdJi1gXgl3n{4Qk4S+v18BLp01&0-_TD|-M^9!+wN=pS7KbTi^*jVR3IBe$em zZ_dnDOZR!E70uD5ffOhR3eoA!evPPaAUQfBj}&4hQHS)P4+C941V~ivr!Y1mQqShr z@DPvp0#$fQz}|VtHntM?>B|gwGqm-c8@SdG%NusyP48(Y>g72*9h%He$D}oDj5>zy zfB*G9FJt-2`(E8s=u_)=XpJJlj`!al#SSk2J{^ya6|nyPAo!;4d!MMZDPF1?9|z%+D^5mp^I{xBc^%CUP#rgO&b`F3^UmfQoc9um~< zg{_`3*86%Wnc7ZvC3-3JSghM}F!)T#_TOLJSrvJG>V}pdpC6vq9Me{f6x~3neCxP@ z+FpYQuwu1?$uu%G7(fwX@dux`V3#b?#kS6-d#%I0Wzv3{RpABAuadyJ6H2RMNXIby zcI>zwJ~;dCzLGZ|0zQnELY(@Zq1C+%Zlw4pb)xxGTYDV4~=r68u8nZ7^v1a!%Og;bzj4qh%h)~Ha1TdX52#oBUTA*kRiOUB! z?{#?}wzSN#@k;i+5t~(S1!=jd#?E%ywnf1%V3s*uvNGa6dP*fMLsi0iicrXZnfE+x zWUAW0xPQ>~r@7G(oRwX=AK_hB;N?G^ZA}?QyD5T2D6r%g^OcLznwl*C2Y0wXCy!l7 z{(!Gm8U-1jfS+2uhIJ!FS}H}LrgaK@cg?6pUfI>CJ>%;_qWgf(czfkiRP6Q{mlMBv zSgWX>lL68fZ#(<4H>}aye>A7T;g$RC157EzGJYx7B(@^c3!AgAihIurp@P=>^A7fCBUI zQp%Ne;NkD5@9gBUc6X9|RtUh?7yWCuaG&hs*`rjP^H)Vvj_cb%z^8{jwci+T;xQYt zYPLKCIF=uQVPNl58G^4)=@ouX8uD8?9ec>av87%yQQO~r(DC{e2OEVKUpd=A` zxV^*yNMy;xfuO-&;%IWoS@VaUTWGjyaU>svq_s}1JMtw0{PO4~08W`N?KBB830LV` zFLnrND^iAX6r;zsiMZJDLrr9P8dzV8^}8@vPIt$aUI)#30iS0Em%`-6`v1omud zkl*>ARex_F1KkgFTvmD*Qy266?B*33x$U)n=_h|K%lhKTww>%ePs#pq%TPloc9t6Y z*WJSh#b?}TK9QDkbN<>PimjqneJs(;Bz$E-XW!-@X4!XQXNjk)`b|yY)H&8O+Zfvc z+gok<`^TPX|5_YmskRqnD5ul@H&mbjG_Xhh`Y%+_XcV~z&NTnQ!-j!2n(Akb?vxx5t%hkgeSxOIVrz zk%n9p6v`iUOx%^DLQanVQBwf_K}E!;US*?yqXM=jZ+v?J-Ih?{%QLxDetT{&%`f`u zQ+-KF;kid2`+($+2C^l7kWO;4svu*#*E((CLB-4he;o=23?k*lQVT0MAQ7gopdF-o zVz*A^8Alze?rv0R0HR@6``JPe9upfMpnkFXazJmVJE#l^@%M{h4{)h>7cwxK81W+QVA*$b=MBHo%zU(I3Eqgy-pNM&qjzE8L9C-B1tjcd23sj_u zJ`7t|U~7ZuTQuh>eHloDwn8x~Tx%QAWFBkIQ}|{jM*Hx)Uktzyjjl^vFxiT~*#LKi z?h=$70nPY*eGh`jFiaSmt0Z=tg?2-qN3=1sZ2<--+j+r}UAYEN0s@u02Ek=7!)5|L zl+6SY>F=v5wNexBRuvm)?9WyQrLaNfS;1m)=8orcFY?wQ=AUauuBjUGdx!kY;@?d$ z+M=Zs+UgeiB(sVI>T>u9_-2=a^zwuCh11$9xi!H64*EF&+(fk2aJ{D3vhq!{aX2b1 zQOxqZXx%GVpPuMJZ#?~vU@o9PRDKWYt=)!RwLjOmxXL-1B}h8KMPN=Q1kMM70*17@ zvWqmc!+;#ha|7;N*UL9ljA1ovmT7B_U8LBS0BgZS?h>nV*O&BxvglIEUm9h$FFu$L z#r$-&N}y?OY0Pgw>5l3POxk=y7`)NBJBnvW;P<@?dv`UNCW+MuzaIaAAdH%gzDT zwlnWXqpq+8^&qAqz{lZEPFkGpvQQ7#ag6patql_d3bg|p1xyzI{yC7 z?~fDjsHC<3a`oiK61{YL5JK{<#hFaQbBnWh*-zn!zJu&L@%E*{ONPfMuUvp#U*7T7;47ix zc$(=)%gPmg6mFzu_&0wcCi4?Vd7(OU4uF(TTE@ z-|qL3tHqaHIWC)G%*22)gRht@hOL`HKPN3(9Rh_1-J*IC$E2(^1<##gWA8Ug$BRE& zF%>%sF^EKFuhFCw>&z2sE?Ofj7g~L&pSZZgdd1rPX1n}t!&S4my-LcxSpj20K(T-_ z;UZ0c%zUg|D00DIYeRQqZlgnrU2RV-F*uL;KM$5T_=ZK*x{Ae6eFs zIZ4ImK)ukU`Ro{rI#3zqv+dQm9`MN4;fj#-8E!+Uk;=W|2g_#*ujC*2QbSW|;;ari zYIX>jbmzhI5$z#i>6I^aOJ;dZUOV3So8qjT4}T6S$e3?WpaXo&h1Wtugm?G zbsQtA=*r}?k2gN3V9M&PooKrZ?93W|Y+t>F&d#W|PFI|NXMFU~)L(ZQ{Iwo_II;wY zj59iZ_3#T&lO{g+G7$09E*(&L5M!oYrYiBU(m_W8$Zw8(MQ0HJe;|&z;lFxo^FR%KZRQvo==W1e%7D^0>{VPdu@q4z<1|vgNP_)wTRCZ6O>+G)~euY zp*UYci?+W$b^8XR*neJm07L;+C1aPjzpO;1e3ne>30Z=zMW$fKJ>`IvjI(N8gWAqH z6$`lPtF@n(>&%W2(5=1nBAyv_4vSQ+FbA3YeD?nirmnsRgKM>-GvP(+TdfmTft|4m ze7ihp7YMuT_b7PESvu|>w(jXnOX*#p!1}-}TZ!_#3=cxQrVN$iH(Pg4C5nuvYbyWx zhGkJr3{SoMp}<>{c6y1LnY7aJmJsy?*6d*5Z1|Hh6R3Jc7L=|SPaoIKKuD{$PkcrVB!pQL==Zsu2 zatFy#Q(5r`L}uoHx`-S;a=*ycBPUN*&L7uo3;z>NUcUUFh0MRt_8-pF?!gFXrT=Oq zuEcVIWF|gD-bl(Y3YoX&TxIwXTKTiiWL0<3$Hn0pyN@|oZKZXX#I#6w^5N_NjH(Jl zAFUU>_-HtmZYhksB^_A!_w4>xTxwxsQv=fRE^EWweD}ZaH#Q2YqLL8 zd9|SZdbYae;Eql|4B-}dZDecJEe8IcD>Q|^pN$!~rRb+LMNfS^3%s71=6L&@zl99K zfC|GOTriS~O|bdx$6!jJhF+t{+xe>Q&s+1KcOXt(P*itNPLxUu9E`BzUbVIe-r%tk zGiTO3mov0V*B!>=w{Ndfgj;-BwQYdwwUmu1e@M;V4o}^@;?RdLZpRt}u;6s@JB7Cm zS4AuDD%*-^DKMlCDkgCOWd}o`k_|O-1bB#j$Epm9@o#?F=w9+2HX=Ef&G0H+V zW$Pqq;lx93P{abx~ae;Fp505fc%t(hY`5+j- z!;Cfn6D7p^P$&kGPpOK()3>=JY84(-Fj9WhQ!#xR1NldsWrik3`R3bB9)h?ShG%z` zJHm1uE{j1L5b!Gr9edWJR4J`NJ1|VhNc*p!eo@po*Fk@fPHk1wR*O%{1|zb$;3>CI zLq#MZ_`sdU^amUT?c8rwd39GrlX}FES#~z1;mP-HRA}XMNfKNZceYBGB$(5=vhs^0 zDRqx+|2fxW%_UcLraO;DuO0AHz`aRtd+x3>6yki50gTjRx=|*uYhMpbNFJ!E-kfgu z!40u%tY3Qyk%`Zjee61z;)nLQ{qj3G)?z%YZYBK1{%Q|fhon0s~`?M?DCvwh;a?{R6M}L^BzNo8xXriYVcT}q`H<7OL;4T7PRzrxu>((qlu&NyXUV`AP;j-=$--;l{ zQ_iU+=eR@!&kk^o-nx*N{@WDMZ@q!#`n-M_2!0yC2i$or`RMH6p{d8nd+$N^Z#S_1 z@yO=Ygc`92kMTM>=(IMQhA|&n1^52O2riKPws%hf{#Kt}=Ha6r+Byv!<+_i#Na<7F!vXEfxCAF#ER(lD1KNa2rnv-A&0-T zGp*k0y-gibr(`0q`6(F27a0^-CVY}53kfs}dwHcz4D~QPFf5tnB28DxczFUNn53I; z4qCjPKZuLvleAdc^w{VeDj^MUkR7*-WHZUZtjZ#EVe7*Y0F|Pq&ELm|`j(L3PbZDv z;WmiRm3^x)ky@I0G#e`~U}d>2pVUb^enhy_|LL=5^D$em%_|pSh{AqEZY=`pKqRCs zI_rI;IRJ}o^qY9cv0M8QE_Tnr3guK4%go}r;d2HBCSm#o7L6U5D4R5y<~!bOR~M^| zj*E2!r(X3jFcazunKR_Y{<Yi2H86{nHtb<7qNI1ZD8n zzAK+A=W`oY{lcE90v6P8eW@qPSVs^4{CpZvX=MGK<+Rft?woAlt-bG6zQL4GxHWM` z3mUmlWEP-FxH!2*3hAHv;pQ+^@KR@`hiLC7cP9n}pcT2diaur4E`17P8pK+;t&!E$ zy*U`=FbgA~08a#^pxQGA^vT;NgtdJ^Y6rC64lv=dyzi=d?FTLDW^X}Sna0kx^prQ7 zwx1ak15|J9nUG4h8*Kxhy9%*xrvop!kj`4+(td9PuYg(HHm2iPcX?IfSK~wa*8vucy`(C|Z?~O~@7jPjv8~^%|s#x*l9;8)=iL{BAD4V^!d~2v>mnK5J6cU{r zN{AYw{&gJ)X~x^KULQ40ybD5?xcx-_t+wg#($KbH3$Mknh&nu@kc6859sjL04he^Wktr!Q2Y z4>)0wSk@XjgJU@O^{neubQJb~v#PRDDO>ClNm0&KvJp!wF}(G~hJ#8oGm1}a2enrl ze5-E-sJ+3;G+S1R{_KqIovOd+i!4Wt$p}NYdZkJYJ}NTuMTzyq2>bsQQsg+G(f%|L zD&-F#J_|sVAGa7k9`8QMK`9%&6IaB1> zq`gDV6b#cyPK`fO*%mHOG;(=BaeM!`YMhBT8B5F z3ptMM-0P1!?A19!NDv9o&*j)1cjDdnu=~5AUN|m}Ye3zX6|P1{YaK4|2KC9vER{Xk zP_S$x3NLmOrge2hM|`M>gL^de}S2UdcDC02M=P* zY`@J+uQpYGvT3{k6u@z6G!7GxOte8LwP=M_S>@n{h3BE;i4nI3k7b`?tD{#uyM|+K z%~pS1`+%mRca3r^2?zIH(${x*U?j451wjtm?3rO^05WHvcBe8~T!T=hI9d&vg*&5^ z=+wDY29lmjfNrh6g;~P3jSSGr0az!NWFr0%6Y0F!Eh$)4)a-$IOL5Bv%_kNL^I{XL zEf+{auGny7ts)(J6WCMwU7Gb=daqJ)xBCYFCxr>#JCf4{LoTJb=ej@^kpQ z`uye%6otsS#!Lxj+Ih^=W7IP4pnd#?*h&f{t4ljvq&NS>y~@2x5Mr3ngG>n@3eeop zbJ2$65tG1Ps=^d8(POZ+E`u<@46W#}9+U-} zwHa@&-Y#NL;=&x^&`Mo4EP$Zk0-L!zF8WKqJ8|rg-%HFG0jwy)6faU^^-O!HbNZ&5 zb%vYs8tBqm23GlpP|K0_AWZ@8PxFCkMi)thf6YF0Lptc3YS zFxN)oiZWBayx0SBv$kF5I&l*-GG;R}CZK^H8VBm}J0tE$TtRvD;Mgru2*NrT_ zHn{(i8B#*EjR4Sj{-1>hv*s`DI`rPdSi?@|#GdmE-CD^9?1O!AXODFz>@{jocBaNP z{QYy(1;(7YG=HI@^!w{JL-m7wVF?f3&Q$6wQ$OhzVJtv`!2PQ8eo>-R2KyT zb)E>*9LuTQY<2bCJGZwYn^z_zLW`@two3FJw+r?+k<~iZI~~V92Hr%mFL_OUc~Q?WMN0P#qhk1cq`G`M$5yaESl!}Q zal!n`YT#6##K>Umbt;)6Spwc`eI&aVGJ78U@1?0CD$^f~7n}Cq@9QU@5}o z=Rr~g3QQ68IL!?E(*BM)wV-hBhp)oooxVopW0;C-jFsvSLl}s4$5>f{J*Zd!2D`{t z&7Mj9elkq~1diF4rD8H(^GaOxv*IdQpn~+oWdm84{ksB1n`B1}v8@+6^B0EgmD2mJ zRW*)w*2piuhj8CNbFY4ir`{Az<}} z+U(&xcTO^3ACJwhs*UhEXM@1Uo>zU97@@V2)^3_xm==4Y7BYUA>-$NXxVf`Vtxi{U zc@R*XmB@PS6?>&@zFozX(7O`19}WKzma|6B_X~lI?OOOqxzX-q;l(<=fx};Y2qS*; zMygBC-5aZ(I_ePD#^3WbESJIaUQTzDrf7T-$)_{yvx3rN6uwcoN?D9Tb|xO zZDnXzGCVIvr0g|zbaZWs^3vlU`^NdA1u?NfgxV|^W{xr+>b^{p;d&;5R*94XU}%OC z?@3PCYP;7Ovc^p0+zQi&1i0a8Zpyw-wE%3V3sFNqrS(7+4F1!Iz&dkEZ83mq*jj9$ z4b{*wthBq)?>x#AI}z_J%bSy4|CM_o%c{!@Y>UhN>(m(qe-z*S0*{5cC0b{UV1Xy% z8Y0PC!L3)epFL}PI+QN~uFC3G>;QMcEFcOGLalAVmX@N%@A^B|mu;x3Tz?%0Q+5zH zzKIVp&Im6rVv$bYOw_;WF;7+Flqza;%1jci3mFZ5GBRiN(N*_yaz1MdZR4B$)Lx&> zZk{kPjh)axf~UKk6*SeJVeUZC<^i0o45l8;xv#8j&|kl=`RN;PqpkK=j=$_f+>CsV zLo{dC`!6aK2ldbT^saXqd)Jr4KFjcWXHhic2y0p0=Kr{%rOeWUdomgK_`SeMy4(#gHa;}grU&d|R2TkkrA=AmGbKscI8Uq`SYai zZbCr;@#s;~)vH(o1AIgTd1eM{Xh?qg6dxXrwXnciS&<|XVpbM0JDYUl1}-|9^ym?m z$s|ur;Ugm{fB%hLz8q_2Mj9L>q@+M35@c+QH8xfwlL-O=e$O7t+#IpGntbODd3Kik z@gw==OY*&Y#O`j&>(}_WILbf&kZ#^2jgAry93UhmL57A{YisPXWwj=gtRn5Vj^Mxe!`I>gpv~S^XG)}a)`ko-MU5K z^Kou&l&@d$2M=Obt-`su5Dp(E-M&pYdX!jNiu3o!85v>azuxwC@{b?H!a|&`F4oPB z{QfybV{K^Lo;Pmv!)6-ZxJKWl}{Tp-Q=Yu(%2ZW ztqs3z8!jk_)ZC0uPR7fBYM~HkY)q`J#c6938ygA7juA34@UgL!SFZ@Uxsa9?PJUa` z(ZT8H5YL<;KX^c>sevplu^bNR;zd$9)_ z4GiF1U9l@x;A3L&2?@mFV%)N2*tKhk$B&b)Une#-5%ThgB_+gj=kQy$;G?4nnVDEi zOR`KxC@q!W_%TZWh@o;?MUqqu-Z*rqwW>D*($!F=v8q`hXc9d=)FzLPNM$OEhLwPD zBu05|sC`=x0z)w2Nk#SWEY;|hi2yxCh%imvQw;H7X^QpB!c7fKTK(e5!2axO zF&m(J4|~#ji7QC=g@UpcRA)*PU=Fhm=>#%W*tRj7)vB^@{ zMBi|VVP#b)S*z~C!5%;HIdZwv$gf`!4b7)?iWUD^vJaBzIIat2`#Zw`42`6}2^$); z!HSoXtP(ZTOH%x2FiknbuGWRD63Y!z+dNs@N9LK;x=_O74F)KoCM;L=?G*x74JF&E z^n>BeRY<3pj{SztMthc4-3QHjy!ls zqzN#NTv+Pw1ZS!SbqI^WK)7w8Y4dh`I=_#Y2GbJ6V!|@5P7IxiGnb?Hq+?XuP<~vK zB$E|lHOt(PF|R%jR!cHr9v$R!Th#b>HW0qkDG%RZchZN87HaWq|#!U|gu--|x zAoO2If&Q8OS?UHWoB?Ll^mon)XvU%7mTDAjvFV zS~h9q9~VbM%x;x&rsdKL7ZPW0F<>Ob;=Wz5SLi5nsViG@4Ayc*)un0OFi6NY&@jJt z*(HSLv5wF<{rII$oqZbHCF@mX+;vk0(0zU3Z|r4mOzi|w>-qLm76V#M?H=o!TLlk@ zo0{ld_YUkmtcTw;+;$w*692-(^X%IXMT|{(W>-8h9h;854@&r&{ZdOMwr`VK2-0)? z8<*Y3J=@~-M?>uNW(Yc?yRDSME{sjQeC0m=X%CkcAC%Lol`t>?9JD36d}Ft{tT!mQ zQR{W|fTxqpb=P=_Ngz_$pmkcZvbv+fh^xy>ZTJ@jvdl0?Vs}*tH)f{FP$^%MRk14RB5bIu_?kg%)v6b z@0^eA6P#w6WD9L9Pq{u2o&5FAkrvo}RHHq{rk)bvnG(iXHS0!EX7fn~?!z7-pNh)HY7H)m zdQ)YwdHLN(`GoeAFq4_$Mz1>K^}{3UuIy3ho#Q%oBRyCeJLq3E%S;#6LmNF_9$loP zOowL$_LMti8i5csR=T2LzKE6=S-XOK%q{KtgwYCSy7{G~+%>R9EP{WFTG<3e=sA@y zRw2~Y_S~%P7Kg((0Q};rCImmHLSa~9Bu!e<(eECoy`LOjrNFqo6c|8r%Jf=)%BX-E zdcJfK+e>`tUMd*Cv)0Duvc%$&G-GG@Qj@M)&0_Cs+y4Cu3X$F>#sw+=WFRxf0o-g4 z7vNVf>!Q6@TXh1W*z2p_YaX^pW(DeCBpXP^XUs6ia&cyG?0faT71=0sFh-=FAa(bC zR^arLZ)Qa2MVjJYLw3LW)kO+o%L-VYfCj8rehfqfclwmJ(i7bUy$CP_-@dZ1d0!Ta zU0X=tc(oX*@R(qI-LZ9E9s1O{5i9?x`x(GW)16vFcPdqdcR%!M9x))pwO= z@-MRSg8YtJL+{rf8?T_1HHPdyL>*TYIr&qY$`7i7+gucDajivTD|Q)LRX=tkyw)s0 z6oVK2<^$>QM#ue4pI`onq@P`L*73Yb5&Q;|qu55uN6jjW@O&~osm$!~nuXh6F}xvl z3o$0_WtLzyUCV={s`*@$FW4FW09|-r%mF&yM$$<)`)=RRa|A*>(l^CbIjhBlss~}h zwBoQ%-S79H))__sK4ztAR4A)6QG`K#%p|3NH_n;ywcd;Gg;NE){;Ib(ZNX)#UH2$e z>(rgaEvfSvq3?=y$B@7^#s#00e&z{y4|EF#p7i`j6)`zU$4LRLZr9SlU;(XWPy5n8 z(t4YOG~8X3+zsE!Yl5BB5D#uUg^JTR2B)?iP0grMF5*|d?Nc2-JOuDJ;c?QLeHyld z1(;MpKm?4y8xklbhe2EVoDjT%3{4+y+*M|n>gDt<&7XJE^Vim*IZ@)Qo;+yz*j8Db zI%@Ts@yuNn0>y~d!4-$ah!gwM5Z^OxDZ)Vf3c?kAY|r5B!Y8U8wGUTY@`SF-5Y@@S zb*wC3PRgzo>SJsKxZd_k6Uar*dZsImKII&$xIr;;SoKpG6ufRaf2?uq5juBn>^ojr zl;W100V-$qDXB_9J%@Pn*2Oi>nRiYwAUfC$u~i{HfXxJymO%)Ei!!b98lEQ39qA?yIZ*bDpncu2I>hrrM@fX%4^IAV9^bS5~R3NYqSc6Q4Fv zipJG+8zED!Rgnaymk2Fub<8P*rHrc^La8=P*kbEn5es`%{m3~2aza8Xz$gA_CGJ}w zhAkLvngO-=B*Kso!6vw3liX+2a5HL~K%#%)z7Si;jE=YR!!wcClRZthHUaD;Qm?1 zm!C(zW5;6uX}A-2|EId`f1l_76L6XBx=TT{xhmMDJ$hHYU`jW1)$u*uhqY2~sJFON2O=n=qQpt8H>_qr zdS8T?yw{7HR2!d((wan$aKK4j#@j*|=BY;D&MPCZxLiN(j-xqz^dyT}3{-<@Drl5* zqs2!@iCz%KxX|Xju91Sqdxe6_^yh_9+5tFwo<*q8MWUC*bw8$@kz;s!cp-MLd&yF` zbr31C%Zq=(4o86qVla|hf`}zyxnloxrSU7vE$;Co0tKRJXrtMTIHhJX^NM}sC}03$ zr6EPFVSK|)0gbVgR`!l&6k}2`so0fYzeOL!l<`J;;B_e($w@pq$>L&;rt@~od<_L` zkUO2idLZJ1KRCJvfJk2SkAp#ee85$X! z_N;`JJpXsMRBH0DU^fe1_rpxK_pJ&E+v*Q2kNImmt+IdBWw7G~XHmpvVKyp+tF5VM zmuN5l5cgTIOIMFC*wQ8xoeoFzefRX*h~S{`TEz|isM#nwEPfz#a4Aiw8;jTQhQ~=j z!M%Qx5_YdGJBSO9XXh^0_h_4imS2gia>I#r(+<^I$#n5n>~Sw|HRUA5BR$?bYCQas zWip$tS^;J9#c1DGfHvB0L6*R{QL2Ys(3Dei>! z5{*TI;~N~A5RTQesbA2ipLd*)WJUzHp1~d{3Kt;LzIqI-`rdauUuTlAy@@JwF!x7- zX7k|M8-7*n<-(ZHRk0Pbwvpu4(CFv+5%P^L5PFYU@+Y?)xLTKs$rp((P;YIm7nJ}T zoiA_1uBjT4%l68N>ZZ|f>x_t59(LPVP!7$wnZQx%W`W zf=7Fwvp?2&-nZ_m%elFy4AJ3MMtZU&KrI!STf3G}9sAxH-K8uR)9+Rk8Tll_TgTFG z&-{YK2jj0m#C873(OPy7g-^9Ej9;}F@BLlc+D86hYh*#jvgwfT*S|knw^au(zA*IL zw#_jvF|dCrk2qaDwXE zD8a_YDwydZupb+iF{aHFRvb%(QMt?85@c{?%qC#s)pg(H{b@d&S*k;^wjD3+KvSpl zgHo6D4=pq6gpt+XUFRvN2TSIDPBQr;{ZOq3fdwjKd{B;DL3o51z+%LHrH*UDT~hel zpKp_~!8X9GTuX$3Zz4}o`554*-?PoI`7mbN{eey1g1kMpzE}meM}WrG z0|MOwdk6gtwVzSI8Y;Wy3dhsqOhg$V0~V5NG~YMPWEW?;h%#v&7FMi;%NxTyiuCwu z1v$zs;)v|u@%+#FXzjZu@TgbeQ{8zxu_G56GaO=f*6Yl|+ir`lM)i*3N;G7fY@eRQR^N_eDn|f9QW2Y^FDgdGC!dog_>?E zvfIf%L3y5!^&!;SbOjdv=qq50?g4d+&s+9TyrX_5l%K&>1B}di^U|sFDDi*`-uCp? zV*iPzj&zGli|-VU#09Cl)GIO_JvM!)*4t#3wqhBwjElzicoYx~7xmK6-LO(6WxmPw zE}6~r>`5i%<_3Rk_?q`d1}n|Pdxk1b09LCuZHxh0Cb*_5ItL2X_Z=t5Hch6;^69?s zr#^M>rLAyH*&2L$JMp@(;Dyn|stXF$mlfe=ViboZxKdTq65wJ?=Rm9@U!35{f9s_v zwXcbuvr&k(a*g`SzGS+;I^A=*-h?^f9>x7(TjYLEMLBt52WQgZt`ig zeC194d1b|)T{gK@{@XV4Cl)%hpgj8+(ahFO7bkb9I7Rc&Xi)>=}0MmIPejC_jOD zdCxq1_tIH1HEG!{ew3l0%0P6|_~MidM{1I$S!*C`<(GOB$i_#CKx$Ef=f10n%pBB@ zF6YpyYDV1%o{C*e=8Hn4G9fp4*zzcP=>!m|+HMyiK&!4kHao*DER?#fB+$%=wGDcZxy+kaMi?vNQng8p@tPH1Gk9fv~^tj~JhV zAZkkLr&dr{+N7Py?4p&=c%W%LNlcphSp5;>jmrxFtFx+xNTPJRPrR?vk48**F3?U> zN>#`6mJeL?w5d-U+a4-7LsMB>VnTz!zDKs#>kbY5-j-O5giW=N7hE0s1SS?aU3Pc} zrpla~x9kv`A4NU^a#L>O1AM-?_4hSyksB$Mjbx@Ai%VIwJY_Mb-ll`Oj~zmx8D=sO z?dwCg&Dytz@3|j{2{vCkt^IaUlC?|$R-l;id&79B@BEk_MO)3}o3n3VpzNXNY1V!L zO()(4nHQKSdb~=XBoP<1B?&TOFC_~$`P-$piG}Lx+G?}B?d_^;R0&21Foi?gN?3me z?S`a(=@1m_vo%|Msav%QkdZRxPW?i}X z#~qKB*Ds%6dbfLa4I>7-{?uz3y#B{`T=P$r6zA^P&SP#@oK*2GMRyRIFP81=V99vJIXoaJM@19^M>$#WOc~J zfH1G4Ko!9di`>;X8|9bCTidqwl>Jl0UCU;%Sc4m#iWTuke{r6rYIHr+FyZz{ysJ`^ z8rQYoqX~k67U8Q;uD2US`3|+mhSJjD64ZME&AvHD z<=7d(OzpESpdk`pH`US}$dC)BzD?v>7l9^=^| zU#ju?J%xyIdpnbH{W7l*Y)51H=5a}tR#YM9HO+Tr=GU& zr==`^A7EfzqT~Y>T(4AYJaA#m!!sl0j%dQI(3v8jtVq%xN#q^#s!T=Cn*kXQoQi3S z;+6=3R>F3oJtvF5zC;GL+8grgcs*}p7A(wic`aOMSXYmB(@UCF`K0lzi7Rl^L%hOD z+?>txF1+pIK-0N)UACCtP282C5`Q=4nWu(EF@rKQ=CO}UzvnvvXHT!Uq~#@!vu4 zxi0`r1P^`$9#{TIa@jM_`_|rb*wFPFi2w5r{vT|}TgS-FKT47B+RH&Ak0dq+fByG@ ze2Y$w922Ae4j}(ipZv!swKy@|?)blU@L|e&sijs$5g57v6HnW4d(JAvFEjbc{9;Bp z_tD41S;t!$_doLmfr^I?ZBNO}a>J!1YpwImF5>Fu?NJUwku@`popRMHjZ+WOBItlh zM@~1Rs$&s>D0m!F`)sp+=auuj$*IW%*wrp~EqtFR3cQ97Krk8=Ysff0-Sc>S`uJZAW%8P zOf2XTOfOSJ;~*YCjRL0a{<7iZU8Y!9e}h>vT%ke0Ka#;Q3mB4yWT2~~HO8xX;?+x~ z$*91@A%916RqgHB8vIcf8dT+b9MZ3z(Sj=;&eqtM#_n$7DIrC#hEpe%bXA3$HgbZ@ z;qZqc#xzG321Yc7I%zT%*y67gd^451i;89#SL_XMX7<=wJ@3!UG(bz-?z9Kh=~gE^UqKHI{w}c4i+|W(^&(NXhpDK6s#PdX;qU-Q7>>7~iT!E5 z-+*9wMV+Z_;jMr2C~VS#joR=VYpA2th>c9%pKMhEThlX;fr2rm?9(1bfNhi1Ocn25wnpXCK&G7t16<=M)_ zLDK6u39?W*3@9!Aot@#hUjOF^ND1uC4D_j|FAe&-DxY!9(bt!P_FAxn#@f7&t7kP( zfl6-R*)B^_U=TZasKcf6WI8K(x?1USUZ5;mhr_HGh}{#6H0E@i`6cL}9pSe1?+Dy8 zOgIQ!tdjT_NB3Xaqr6NNh5ugxkOXi0sQ5|&f3`e@%Tj%zI(FAA-fB-Rd>e+#v z90jA11p^oO#D@TTCM~A8aPUVc2S|SKi`912n`F*Y92qm%c329Bkc2HK^MP8#E%)4X z*KPORaYLc@8~0vi!P!a}&_D!)7jF3Bh$pW2;t@39&fXt1OIX)$`)C+j?xegn*;4o{ zM+nOF;lKc-lm2&D0sPg7I~VNO1fey4Ky~1K6y*N|2^?T8m4Z&l83#HB=>7%;16Tt^IQ{@I|bw` zBhkDZ&ksTVbgT5+2k;QLH3htJ=-5ug2feWT;|llt06I3N5bhkLOSA)82PW8oEI@~X z9l%&41Tet_oMHe1_(lLKKmxC%FA0$AMf{Y(z~vq24V9~hCBkuqV8J0>27nDW;35^R z1r95*dxHaZ2*W9utPtq}KnIwEi(u{0U%dd`fjW?Y<(y1@MU=u3`;f#f4v`2>Ov1T< zl0@iWz;}i47Id;0g)IifQ4ooPm&~R>`3e6|g}czg1-fR5FIr9;5(uOO95#dw2vP#A zv%~-}Ac27hV*zTRKmr(`08Lp4iZ@f%1p3#97zT%c_5+JV>R_q~K5WHI@ zV}7+5A6S}p1uNEZC+q7428`fFkYH+n&XeU-%m)C^@gW(qk_s^jBNfL1lYYWX%__Kb z%$)!U4j$-$0t9f)IN)js$plIaVVR`I;O>qf;e-K3fW8yzfe&liLI!FU2Q>!AmaiBK zE5%|sPKpAP?hJ?(9XN!cNuX%E^pOpLvZha7E-X!9QbUtK0tgr*EM6*R={CyIj(YT? zAnj-;Toa5k!3m8Dp+LuO$I_O%^rinWjj2nCFajtd0}o>?!~p)WKDMEadVF*y9-twO z3Cv3fSK>peetLy=QUDWxNaVi)1|6|E$XO0y(g#EW2$)eo1cclPNyima842f>jOda@Kz=A@dNHb>&rZF*EcLxJtMHC1B~;Q3iOYb&q<0->&h>9D1=Uc z#b+w?dLRPms23Rp4hO8dsoV$xE8SFK885Sp+fdb1uF0iBO!AyoDr7TxTF}!r;7?I# zfU$sJU@s6ufW=sll}=b^1w;T)u>AEc?Nr$V4qz7o-~|kQQSIdr>xoi6R4xY?fmA^< zSGZpGx(s!gYgOpkbR-YFujT6?JQfw0f)oP~(--U5H7mn_oHTvzY1- zKz|ESfO6%m1K+*sNH{BsaXzgA2{?d1Cs4H{B$W>|e9M5dwhs;@mk-oEPzLyLBH$Px z1e{dqb?7UHc|1d^6gXgOJHX;M-1H!E6h-}Xk*EN0#A;Yc@EdqEg#`L{HsjcDSp@)? zUrJ%S;8_r51HpwFku?gb+#gd-RRLyDK*>rNaW8PY void: - print("ScaffoldConfig._init") - -func register_app_config(config: Dictionary) -> void: - self.debug = config.debug - self.playtest = config.playtest - self.debug_window_size = config.debug_window_size - self.app_name = config.app_name - self.app_id = config.app_id - self.app_version = config.app_version - self.main_font_normal = config.main_font_normal - self.main_font_large = config.main_font_large - self.main_font_xl = config.main_font_xl - self.cell_size = config.cell_size - self.aspect_ratio_max = config.aspect_ratio_max - self.aspect_ratio_min = config.aspect_ratio_min - self.screen_background_color = config.screen_background_color - self.button_normal_color = config.button_normal_color - self.button_hover_color = config.button_hover_color - self.button_pressed_color = config.button_pressed_color - self.shiny_button_highlight_color = config.shiny_button_highlight_color - self.key_value_even_row_color = config.key_value_even_row_color - self.option_button_normal_color = config.option_button_normal_color - self.option_button_hover_color = config.option_button_hover_color - self.option_button_pressed_color = config.option_button_pressed_color - self.screen_exclusions = config.screen_exclusions - self.screen_inclusions = config.screen_inclusions - self.main_menu_music = config.main_menu_music - self.third_party_license_text = \ - config.third_party_license_text.strip_edges() - self.special_thanks_text = config.special_thanks_text.strip_edges() - self.app_logo = config.app_logo - self.developer_name = config.developer_name - self.developer_url = config.developer_url - - if config.has("developer_logo"): - self.developer_logo = config.developer_logo - if config.has("developer_splash"): - self.developer_splash = config.developer_splash - if config.has("godot_splash_sound"): - self.godot_splash_sound = config.godot_splash_sound - if config.has("developer_splash_sound"): - self.developer_splash_sound = config.developer_splash_sound - if config.has("godot_splash_screen_duration_sec"): - self.godot_splash_screen_duration_sec = \ - config.godot_splash_screen_duration_sec - if config.has("developer_splash_screen_duration_sec"): - self.developer_splash_screen_duration_sec = \ - config.developer_splash_screen_duration_sec - if config.has("main_menu_image_scene_path"): - self.main_menu_image_scene_path = config.main_menu_image_scene_path - if config.has("fade_in_transition_texture"): - self.fade_in_transition_texture = config.fade_in_transition_texture - if config.has("fade_out_transition_texture"): - self.fade_out_transition_texture = config.fade_out_transition_texture - if config.has("google_analytics_id"): - self.google_analytics_id = config.google_analytics_id - if config.has("terms_and_conditions_url"): - self.terms_and_conditions_url = config.terms_and_conditions_url - if config.has("privacy_policy_url"): - self.privacy_policy_url = config.privacy_policy_url - if config.has("android_app_store_url"): - self.android_app_store_url = config.android_app_store_url - if config.has("ios_app_store_url"): - self.ios_app_store_url = config.ios_app_store_url - if config.has("support_url_base"): - self.support_url_base = config.support_url_base - if config.has("log_gestures_url"): - self.log_gestures_url = config.log_gestures_url - if config.has("input_vibrate_duration_sec"): - self.input_vibrate_duration_sec = \ - config.input_vibrate_duration_sec - if config.has("display_resize_throttle_interval_sec"): - self.display_resize_throttle_interval_sec = \ - config.display_resize_throttle_interval_sec - if config.has("recent_gesture_events_for_debugging_buffer_size"): - self.recent_gesture_events_for_debugging_buffer_size = \ - config.recent_gesture_events_for_debugging_buffer_size - - assert(self.google_analytics_id.empty() == \ - self.privacy_policy_url.empty() and \ - self.privacy_policy_url.empty() == \ - self.terms_and_conditions_url.empty()) - assert((self.developer_splash == null) == \ - self.developer_splash_sound.empty()) - - self.is_special_thanks_shown = !self.special_thanks_text.empty() - self.is_third_party_licenses_shown = !self.third_party_license_text.empty() - self.is_data_tracked = \ - !self.privacy_policy_url.empty() and \ - !self.terms_and_conditions_url.empty() and \ - !self.google_analytics_id.empty() - self.is_rate_app_shown = \ - !self.android_app_store_url.empty() and \ - !self.ios_app_store_url.empty() - self.is_support_shown = !self.support_url_base.empty() - self.is_gesture_logging_supported = !self.log_gestures_url.empty() - self.is_developer_logo_shown = config.has("developer_logo") - self.is_developer_splash_shown = \ - config.has("developer_splash") and \ - config.has("developer_splash_sound") - self.is_main_menu_image_shown = config.has("main_menu_image_scene_path") - -func register_main(main: Node) -> void: - camera_controller = CameraController.new() - main.add_child(camera_controller) - - canvas_layers = CanvasLayers.new() - main.add_child(canvas_layers) - - debug_panel = ScaffoldUtils.add_scene( \ - canvas_layers.layers.top, \ - _DEBUG_PANEL_RESOURCE_PATH, \ - true, \ - true) - debug_panel.z_index = 1000 - debug_panel.visible = is_debug_panel_shown - - if debug or playtest: - gesture_record = GestureRecord.new() - canvas_layers.layers.top.add_child(ScaffoldConfig.gesture_record) - -func load_state() -> void: - agreed_to_terms = SaveState.get_setting( \ - AGREED_TO_TERMS_SETTINGS_KEY, \ - false) - is_giving_haptic_feedback = SaveState.get_setting( \ - IS_GIVING_HAPTIC_FEEDBACK_SETTINGS_KEY, \ - ScaffoldUtils.get_is_android_device()) - is_debug_panel_shown = SaveState.get_setting( \ - IS_DEBUG_PANEL_SHOWN_SETTINGS_KEY, \ - false) - is_debug_time_shown = SaveState.get_setting( \ - IS_DEBUG_TIME_SHOWN_SETTINGS_KEY, \ - false) - Audio.is_music_enabled = SaveState.get_setting( \ - IS_MUSIC_ENABLED_SETTINGS_KEY, \ - true) - Audio.is_sound_effects_enabled = SaveState.get_setting( \ - IS_SOUND_EFFECTS_ENABLED_SETTINGS_KEY, \ - true) - -func set_agreed_to_terms() -> void: - agreed_to_terms = true - SaveState.set_setting( \ - ScaffoldConfig.AGREED_TO_TERMS_SETTINGS_KEY, \ - true) - -func _set_is_debug_panel_shown(is_visible: bool) -> void: - is_debug_panel_shown = is_visible - if debug_panel != null: - debug_panel.visible = is_visible - -func _get_is_debug_panel_shown() -> bool: - return is_debug_panel_shown diff --git a/addons/scaffold/audio.gd b/addons/scaffold/src/audio.gd similarity index 86% rename from addons/scaffold/audio.gd rename to addons/scaffold/src/audio.gd index 609ec0c7..c5af3855 100644 --- a/addons/scaffold/audio.gd +++ b/addons/scaffold/src/audio.gd @@ -5,11 +5,11 @@ const SILENT_VOLUME_DB := -80.0 const GLOBAL_AUDIO_VOLUME_OFFSET_DB := -10.0 -const _DEFAULT_SOUNDS_PATH_PREFIX := "res://assets/sounds/" +const _DEFAULT_SOUNDS_PATH_PREFIX := "res://addons/scaffold/assets/sounds/" const _DEFAULT_SOUND_FILE_SUFFIX := ".wav" const _DEFAULT_SOUNDS_BUS_INDEX := 1 -const _DEFAULT_MUSIC_PATH_PREFIX := "res://assets/music/" +const _DEFAULT_MUSIC_PATH_PREFIX := "res://addons/scaffold/assets/music/" const _DEFAULT_MUSIC_FILE_SUFFIX := ".ogg" const _DEFAULT_MUSIC_BUS_INDEX := 2 @@ -55,7 +55,15 @@ func register_sounds( \ assert(config.has("name")) assert(config.has("volume_db")) var player := AudioStreamPlayer.new() - var path: String = path_prefix + config.name + file_suffix + var prefix: String = \ + config.path_prefix if \ + config.has("path_prefix") else \ + path_prefix + var suffix: String = \ + config.file_suffix if \ + config.has("file_suffix") else \ + file_suffix + var path: String = prefix + config.name + suffix player.stream = load(path) player.bus = bus_name add_child(player) @@ -76,7 +84,15 @@ func register_music( \ assert(config.has("name")) assert(config.has("volume_db")) var player := AudioStreamPlayer.new() - var path: String = path_prefix + config.name + file_suffix + var prefix: String = \ + config.path_prefix if \ + config.has("path_prefix") else \ + path_prefix + var suffix: String = \ + config.file_suffix if \ + config.has("file_suffix") else \ + file_suffix + var path: String = prefix + config.name + suffix player.stream = load(path) player.bus = bus_name add_child(player) @@ -146,8 +162,8 @@ func _cross_fade_music( \ if previous_music_player == current_music_player and \ current_music_player.playing: if !_fade_in_tween.is_active(): - var loud_volume := \ - _get_current_music_player().volume_db + \ + var loud_volume: float = \ + _inflated_music_config[_current_music_name].volume_db + \ GLOBAL_AUDIO_VOLUME_OFFSET_DB if \ is_music_enabled else \ SILENT_VOLUME_DB @@ -161,8 +177,8 @@ func _cross_fade_music( \ if previous_music_player != null and \ previous_music_player.playing: - var previous_loud_volume := \ - _get_previous_music_player().volume_db + \ + var previous_loud_volume: float = \ + _inflated_music_config[_previous_music_name].volume_db + \ GLOBAL_AUDIO_VOLUME_OFFSET_DB if \ is_music_enabled else \ SILENT_VOLUME_DB @@ -180,8 +196,8 @@ func _cross_fade_music( \ current_music_player.volume_db = SILENT_VOLUME_DB current_music_player.play() - var current_loud_volume := \ - _get_current_music_player().volume_db + \ + var current_loud_volume: float = \ + _inflated_music_config[_current_music_name].volume_db + \ GLOBAL_AUDIO_VOLUME_OFFSET_DB if \ is_music_enabled else \ SILENT_VOLUME_DB diff --git a/addons/scaffold/camera_controller.gd b/addons/scaffold/src/camera_controller.gd similarity index 100% rename from addons/scaffold/camera_controller.gd rename to addons/scaffold/src/camera_controller.gd diff --git a/addons/scaffold/camera_shake.gd b/addons/scaffold/src/camera_shake.gd similarity index 100% rename from addons/scaffold/camera_shake.gd rename to addons/scaffold/src/camera_shake.gd diff --git a/addons/scaffold/camera_shake.tscn b/addons/scaffold/src/camera_shake.tscn similarity index 54% rename from addons/scaffold/camera_shake.tscn rename to addons/scaffold/src/camera_shake.tscn index 800f4daf..a4d3527b 100644 --- a/addons/scaffold/camera_shake.tscn +++ b/addons/scaffold/src/camera_shake.tscn @@ -1,6 +1,7 @@ [gd_scene load_steps=2 format=2] -[ext_resource path="res://addons/scaffold/camera_shake.gd" type="Script" id=1] +[ext_resource path="res://addons/scaffold/src/camera_shake.gd" type="Script" id=1] + [node name="CameraShake" type="Node2D"] script = ExtResource( 1 ) diff --git a/addons/scaffold/canvas_layers.gd b/addons/scaffold/src/canvas_layers.gd similarity index 89% rename from addons/scaffold/canvas_layers.gd rename to addons/scaffold/src/canvas_layers.gd index 909badbd..1e21a2aa 100644 --- a/addons/scaffold/canvas_layers.gd +++ b/addons/scaffold/src/canvas_layers.gd @@ -43,14 +43,16 @@ func _process(_delta_sec: float) -> void: var camera: Camera2D = \ ScaffoldConfig.camera_controller.get_current_camera() if is_instance_valid(camera): - layers.annotation_layer.transform = get_canvas_transform() + layers.annotation.transform = get_canvas_transform() func create_layer( \ name: String, \ z_index: int, \ - pause_mode: int) -> void: + pause_mode: int) -> CanvasLayer: var canvas_layer := CanvasLayer.new() + canvas_layer.name = name canvas_layer.layer = z_index canvas_layer.pause_mode = pause_mode ScaffoldUtils.add_overlay_to_current_scene(canvas_layer) layers[name] = canvas_layer + return canvas_layer diff --git a/addons/scaffold/data/analytics.gd b/addons/scaffold/src/data/analytics.gd similarity index 100% rename from addons/scaffold/data/analytics.gd rename to addons/scaffold/src/data/analytics.gd diff --git a/addons/scaffold/data/gesture_record.gd b/addons/scaffold/src/data/gesture_record.gd similarity index 100% rename from addons/scaffold/data/gesture_record.gd rename to addons/scaffold/src/data/gesture_record.gd diff --git a/addons/scaffold/data/log.gd b/addons/scaffold/src/data/log.gd similarity index 100% rename from addons/scaffold/data/log.gd rename to addons/scaffold/src/data/log.gd diff --git a/addons/scaffold/data/save_state.gd b/addons/scaffold/src/data/save_state.gd similarity index 100% rename from addons/scaffold/data/save_state.gd rename to addons/scaffold/src/data/save_state.gd diff --git a/addons/scaffold/gui/accordion_panel.gd b/addons/scaffold/src/gui/accordion_panel.gd similarity index 100% rename from addons/scaffold/gui/accordion_panel.gd rename to addons/scaffold/src/gui/accordion_panel.gd diff --git a/addons/scaffold/gui/accordion_panel.tscn b/addons/scaffold/src/gui/accordion_panel.tscn similarity index 74% rename from addons/scaffold/gui/accordion_panel.tscn rename to addons/scaffold/src/gui/accordion_panel.tscn index cf4eeb4a..9c85a704 100644 --- a/addons/scaffold/gui/accordion_panel.tscn +++ b/addons/scaffold/src/gui/accordion_panel.tscn @@ -1,6 +1,7 @@ [gd_scene load_steps=2 format=2] -[ext_resource path="res://addons/scaffold/gui/accordion_panel.gd" type="Script" id=1] +[ext_resource path="res://addons/scaffold/src/gui/accordion_panel.gd" type="Script" id=1] + [node name="AccordionPanel" type="Control"] anchor_right = 1.0 diff --git a/addons/scaffold/gui/centered_in_full_screen_panel.gd b/addons/scaffold/src/gui/centered_in_full_screen_panel.gd similarity index 97% rename from addons/scaffold/gui/centered_in_full_screen_panel.gd rename to addons/scaffold/src/gui/centered_in_full_screen_panel.gd index 682aa499..42cccc3c 100644 --- a/addons/scaffold/gui/centered_in_full_screen_panel.gd +++ b/addons/scaffold/src/gui/centered_in_full_screen_panel.gd @@ -10,7 +10,7 @@ export var stretches_vertically := false \ var configuration_warning := "" func _init() -> void: - add_font_override("font", ScaffoldConfig.main_font_normal) + add_font_override("font", ScaffoldConfig.main_font_m) func _ready() -> void: ScaffoldUtils.connect( \ diff --git a/addons/scaffold/gui/centered_in_full_screen_panel.tscn b/addons/scaffold/src/gui/centered_in_full_screen_panel.tscn similarity index 83% rename from addons/scaffold/gui/centered_in_full_screen_panel.tscn rename to addons/scaffold/src/gui/centered_in_full_screen_panel.tscn index 008f42e8..97c5d6f7 100644 --- a/addons/scaffold/gui/centered_in_full_screen_panel.tscn +++ b/addons/scaffold/src/gui/centered_in_full_screen_panel.tscn @@ -1,8 +1,9 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/scaffold/gui/centered_in_full_screen_panel.gd" type="Script" id=1] +[ext_resource path="res://addons/scaffold/src/gui/centered_in_full_screen_panel.gd" type="Script" id=1] [ext_resource path="res://assets/main_theme.tres" type="Theme" id=2] + [sub_resource type="StyleBoxFlat" id=1] bg_color = Color( 0.152941, 0.192157, 0.286275, 1 ) diff --git a/addons/scaffold/gui/centered_panel.gd b/addons/scaffold/src/gui/centered_panel.gd similarity index 96% rename from addons/scaffold/gui/centered_panel.gd rename to addons/scaffold/src/gui/centered_panel.gd index f40432d1..aa1a1523 100644 --- a/addons/scaffold/gui/centered_panel.gd +++ b/addons/scaffold/src/gui/centered_panel.gd @@ -8,7 +8,7 @@ export var stretches_vertically := false \ setget _set_stretches_vertically,_get_stretches_vertically func _init() -> void: - add_font_override("font", ScaffoldConfig.main_font_normal) + add_font_override("font", ScaffoldConfig.main_font_m) func _ready() -> void: ScaffoldUtils.connect( \ diff --git a/addons/scaffold/gui/centered_panel.tscn b/addons/scaffold/src/gui/centered_panel.tscn similarity index 83% rename from addons/scaffold/gui/centered_panel.tscn rename to addons/scaffold/src/gui/centered_panel.tscn index c97c5ab3..37ab7519 100644 --- a/addons/scaffold/gui/centered_panel.tscn +++ b/addons/scaffold/src/gui/centered_panel.tscn @@ -1,8 +1,9 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/scaffold/gui/centered_panel.gd" type="Script" id=1] +[ext_resource path="res://addons/scaffold/src/gui/centered_panel.gd" type="Script" id=1] [ext_resource path="res://assets/main_theme.tres" type="Theme" id=2] + [sub_resource type="StyleBoxFlat" id=1] bg_color = Color( 0.152941, 0.192157, 0.286275, 1 ) diff --git a/addons/scaffold/gui/debug_panel.gd b/addons/scaffold/src/gui/debug_panel.gd similarity index 100% rename from addons/scaffold/gui/debug_panel.gd rename to addons/scaffold/src/gui/debug_panel.gd diff --git a/addons/scaffold/gui/debug_panel.tscn b/addons/scaffold/src/gui/debug_panel.tscn similarity index 84% rename from addons/scaffold/gui/debug_panel.tscn rename to addons/scaffold/src/gui/debug_panel.tscn index 12049507..729aa04b 100644 --- a/addons/scaffold/gui/debug_panel.tscn +++ b/addons/scaffold/src/gui/debug_panel.tscn @@ -1,7 +1,9 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://assets/fonts/main_font_s.tres" type="DynamicFont" id=1] -[ext_resource path="res://addons/scaffold/gui/debug_panel.gd" type="Script" id=2] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_s.tres" type="DynamicFont" id=1] +[ext_resource path="res://addons/scaffold/src/gui/debug_panel.gd" type="Script" id=2] + + [sub_resource type="StyleBoxFlat" id=1] bg_color = Color( 0, 0, 0, 0.0941176 ) diff --git a/addons/scaffold/gui/full_screen_panel.gd b/addons/scaffold/src/gui/full_screen_panel.gd similarity index 87% rename from addons/scaffold/gui/full_screen_panel.gd rename to addons/scaffold/src/gui/full_screen_panel.gd index 8fdb34f5..434506f9 100644 --- a/addons/scaffold/gui/full_screen_panel.gd +++ b/addons/scaffold/src/gui/full_screen_panel.gd @@ -3,7 +3,7 @@ extends PanelContainer class_name FullScreenPanel func _init() -> void: - add_font_override("font", ScaffoldConfig.main_font_normal) + add_font_override("font", ScaffoldConfig.main_font_m) func _enter_tree() -> void: if Engine.editor_hint: diff --git a/addons/scaffold/gui/full_screen_panel.tscn b/addons/scaffold/src/gui/full_screen_panel.tscn similarity index 82% rename from addons/scaffold/gui/full_screen_panel.tscn rename to addons/scaffold/src/gui/full_screen_panel.tscn index 5e06c801..a1c7e678 100644 --- a/addons/scaffold/gui/full_screen_panel.tscn +++ b/addons/scaffold/src/gui/full_screen_panel.tscn @@ -1,8 +1,9 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/scaffold/gui/full_screen_panel.gd" type="Script" id=1] +[ext_resource path="res://addons/scaffold/src/gui/full_screen_panel.gd" type="Script" id=1] [ext_resource path="res://assets/main_theme.tres" type="Theme" id=2] + [sub_resource type="StyleBoxFlat" id=1] bg_color = Color( 0.152941, 0.192157, 0.286275, 1 ) diff --git a/addons/scaffold/gui/labeled_control_item_type.gd b/addons/scaffold/src/gui/labeled_control_item_type.gd similarity index 100% rename from addons/scaffold/gui/labeled_control_item_type.gd rename to addons/scaffold/src/gui/labeled_control_item_type.gd diff --git a/addons/scaffold/gui/labeled_control_list.gd b/addons/scaffold/src/gui/labeled_control_list.gd similarity index 100% rename from addons/scaffold/gui/labeled_control_list.gd rename to addons/scaffold/src/gui/labeled_control_list.gd diff --git a/addons/scaffold/gui/labeled_control_list.tscn b/addons/scaffold/src/gui/labeled_control_list.tscn similarity index 77% rename from addons/scaffold/gui/labeled_control_list.tscn rename to addons/scaffold/src/gui/labeled_control_list.tscn index f2372eef..b0e85767 100644 --- a/addons/scaffold/gui/labeled_control_list.tscn +++ b/addons/scaffold/src/gui/labeled_control_list.tscn @@ -1,8 +1,9 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://addons/scaffold/gui/labeled_control_list.gd" type="Script" id=1] +[ext_resource path="res://addons/scaffold/src/gui/labeled_control_list.gd" type="Script" id=1] [ext_resource path="res://assets/main_theme.tres" type="Theme" id=2] + [node name="LabeledControlList" type="VBoxContainer"] anchor_right = 1.0 anchor_bottom = 1.0 diff --git a/addons/scaffold/gui/nav_bar.gd b/addons/scaffold/src/gui/nav_bar.gd similarity index 91% rename from addons/scaffold/gui/nav_bar.gd rename to addons/scaffold/src/gui/nav_bar.gd index 0f5132b8..1d78df96 100644 --- a/addons/scaffold/gui/nav_bar.gd +++ b/addons/scaffold/src/gui/nav_bar.gd @@ -5,7 +5,8 @@ class_name NavBar export var text := "" setget _set_text export var shows_back := true setget _set_shows_back,_get_shows_back export var shows_about := false setget _set_shows_about,_get_shows_about -export var shows_settings := false setget _set_shows_settings,_get_shows_settings +export var shows_settings := false setget \ + _set_shows_settings,_get_shows_settings export var shows_logo := false setget _set_shows_logo,_get_shows_logo func _enter_tree() -> void: @@ -23,6 +24,8 @@ func _enter_tree() -> void: _set_shows_settings(shows_settings) _set_shows_logo(shows_logo) $MarginContainer/LogoControl/Control/Logo.texture = ScaffoldConfig.app_logo + $MarginContainer/LogoControl/Control/Logo.rect_position = \ + -ScaffoldConfig.app_logo.get_size() / 2.0 func _set_text(value: String) -> void: text = value diff --git a/addons/scaffold/gui/nav_bar.tscn b/addons/scaffold/src/gui/nav_bar.tscn similarity index 94% rename from addons/scaffold/gui/nav_bar.tscn rename to addons/scaffold/src/gui/nav_bar.tscn index 60a10ade..97cd1c89 100644 --- a/addons/scaffold/gui/nav_bar.tscn +++ b/addons/scaffold/src/gui/nav_bar.tscn @@ -1,10 +1,10 @@ [gd_scene load_steps=14 format=2] -[ext_resource path="res://addons/scaffold/gui/nav_bar.gd" type="Script" id=1] +[ext_resource path="res://addons/scaffold/src/gui/nav_bar.gd" type="Script" id=1] [ext_resource path="res://addons/scaffold/assets/images/gui/left_caret_normal.png" type="Texture" id=2] [ext_resource path="res://addons/scaffold/assets/images/gui/gear_icon_normal_large.png" type="Texture" id=3] [ext_resource path="res://addons/scaffold/assets/images/gui/left_caret_active.png" type="Texture" id=4] -[ext_resource path="res://assets/fonts/main_font_xl.tres" type="DynamicFont" id=5] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_xl.tres" type="DynamicFont" id=5] [ext_resource path="res://addons/scaffold/assets/images/gui/about_icon_normal_large.png" type="Texture" id=6] [ext_resource path="res://addons/scaffold/assets/images/gui/left_caret_hover.png" type="Texture" id=7] [ext_resource path="res://addons/scaffold/assets/images/gui/about_icon_active_large.png" type="Texture" id=8] @@ -13,6 +13,8 @@ [ext_resource path="res://addons/scaffold/assets/images/gui/about_icon_hover_large.png" type="Texture" id=11] [ext_resource path="res://assets/images/gui/logo.png" type="Texture" id=12] + + [sub_resource type="StyleBoxEmpty" id=1] [node name="NavBar" type="PanelContainer"] @@ -62,10 +64,8 @@ margin_right = 288.0 margin_bottom = 76.0 [node name="Logo" type="TextureRect" parent="MarginContainer/LogoControl/Control"] -margin_left = -209.0 -margin_top = -19.0 -margin_right = 208.0 -margin_bottom = 18.0 +margin_right = 258.0 +margin_bottom = 44.0 size_flags_horizontal = 0 size_flags_vertical = 0 texture = ExtResource( 12 ) diff --git a/addons/scaffold/gui/screen.gd b/addons/scaffold/src/gui/screen.gd similarity index 100% rename from addons/scaffold/gui/screen.gd rename to addons/scaffold/src/gui/screen.gd diff --git a/addons/scaffold/gui/screens/confirm_data_deletion_screen.gd b/addons/scaffold/src/gui/screens/confirm_data_deletion_screen.gd similarity index 100% rename from addons/scaffold/gui/screens/confirm_data_deletion_screen.gd rename to addons/scaffold/src/gui/screens/confirm_data_deletion_screen.gd diff --git a/addons/scaffold/gui/screens/confirm_data_deletion_screen.tscn b/addons/scaffold/src/gui/screens/confirm_data_deletion_screen.tscn similarity index 91% rename from addons/scaffold/gui/screens/confirm_data_deletion_screen.tscn rename to addons/scaffold/src/gui/screens/confirm_data_deletion_screen.tscn index d77ea424..c0126a82 100644 --- a/addons/scaffold/gui/screens/confirm_data_deletion_screen.tscn +++ b/addons/scaffold/src/gui/screens/confirm_data_deletion_screen.tscn @@ -1,12 +1,14 @@ [gd_scene load_steps=8 format=2] -[ext_resource path="res://addons/scaffold/gui/centered_panel.tscn" type="PackedScene" id=1] -[ext_resource path="res://assets/fonts/main_font_l.tres" type="DynamicFont" id=2] -[ext_resource path="res://addons/scaffold/gui/full_screen_panel.tscn" type="PackedScene" id=3] +[ext_resource path="res://addons/scaffold/src/gui/centered_panel.tscn" type="PackedScene" id=1] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_l.tres" type="DynamicFont" id=2] +[ext_resource path="res://addons/scaffold/src/gui/full_screen_panel.tscn" type="PackedScene" id=3] [ext_resource path="res://addons/scaffold/assets/images/gui/alert_icon_normal_large.png" type="Texture" id=4] -[ext_resource path="res://addons/scaffold/gui/screens/confirm_data_deletion_screen.gd" type="Script" id=5] -[ext_resource path="res://addons/scaffold/gui/shiny_button.tscn" type="PackedScene" id=6] -[ext_resource path="res://addons/scaffold/gui/nav_bar.tscn" type="PackedScene" id=12] +[ext_resource path="res://addons/scaffold/src/gui/screens/confirm_data_deletion_screen.gd" type="Script" id=5] +[ext_resource path="res://addons/scaffold/src/gui/shiny_button.tscn" type="PackedScene" id=6] +[ext_resource path="res://addons/scaffold/src/gui/nav_bar.tscn" type="PackedScene" id=12] + + [node name="ConfirmDataDeletionScreen" type="Node2D"] script = ExtResource( 5 ) diff --git a/addons/scaffold/gui/screens/credits_screen.gd b/addons/scaffold/src/gui/screens/credits_screen.gd similarity index 89% rename from addons/scaffold/gui/screens/credits_screen.gd rename to addons/scaffold/src/gui/screens/credits_screen.gd index a3cbab14..824fedbe 100644 --- a/addons/scaffold/gui/screens/credits_screen.gd +++ b/addons/scaffold/src/gui/screens/credits_screen.gd @@ -51,6 +51,12 @@ func _ready() -> void: $FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/ \ CenterContainer/VBoxContainer/VBoxContainer2/ \ PrivacyPolicyLink.visible = ScaffoldConfig.is_data_tracked + $FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/ \ + CenterContainer/VBoxContainer/AccordionPanel/VBoxContainer/ \ + DataDeletionButton.visible = ScaffoldConfig.is_data_tracked + $FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/ \ + CenterContainer/VBoxContainer/AccordionPanel/VBoxContainer/ \ + DataDeletionButtonPadding.visible = ScaffoldConfig.is_data_tracked $FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/ \ CenterContainer/VBoxContainer/VBoxContainer2/ \ diff --git a/addons/scaffold/gui/screens/credits_screen.tscn b/addons/scaffold/src/gui/screens/credits_screen.tscn similarity index 90% rename from addons/scaffold/gui/screens/credits_screen.tscn rename to addons/scaffold/src/gui/screens/credits_screen.tscn index 169ab359..5e9bf648 100644 --- a/addons/scaffold/gui/screens/credits_screen.tscn +++ b/addons/scaffold/src/gui/screens/credits_screen.tscn @@ -2,15 +2,19 @@ [ext_resource path="res://assets/images/gui/logo.png" type="Texture" id=1] [ext_resource path="res://addons/scaffold/assets/images/gui/godot_logo_about.png" type="Texture" id=2] -[ext_resource path="res://addons/scaffold/gui/screens/credits_screen.gd" type="Script" id=3] -[ext_resource path="res://addons/scaffold/gui/nav_bar.tscn" type="PackedScene" id=4] -[ext_resource path="res://addons/scaffold/gui/full_screen_panel.tscn" type="PackedScene" id=5] +[ext_resource path="res://addons/scaffold/src/gui/screens/credits_screen.gd" type="Script" id=3] +[ext_resource path="res://addons/scaffold/src/gui/nav_bar.tscn" type="PackedScene" id=4] +[ext_resource path="res://addons/scaffold/src/gui/full_screen_panel.tscn" type="PackedScene" id=5] [ext_resource path="res://addons/scaffold/assets/images/gui/snoring_cat_logo_about.png" type="Texture" id=6] -[ext_resource path="res://assets/fonts/main_font_normal.tres" type="DynamicFont" id=7] -[ext_resource path="res://addons/scaffold/gui/centered_panel.tscn" type="PackedScene" id=8] -[ext_resource path="res://assets/fonts/main_font_s.tres" type="DynamicFont" id=9] -[ext_resource path="res://addons/scaffold/gui/accordion_panel.tscn" type="PackedScene" id=10] -[ext_resource path="res://assets/fonts/main_font_normal_bold.tres" type="DynamicFont" id=11] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_m.tres" type="DynamicFont" id=7] +[ext_resource path="res://addons/scaffold/src/gui/centered_panel.tscn" type="PackedScene" id=8] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_s.tres" type="DynamicFont" id=9] +[ext_resource path="res://addons/scaffold/src/gui/accordion_panel.tscn" type="PackedScene" id=10] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_m_bold.tres" type="DynamicFont" id=11] + + + + [node name="CreditsScreen" type="Node2D"] script = ExtResource( 3 ) @@ -39,6 +43,7 @@ anchor_bottom = 0.0 margin_top = 132.0 margin_right = 480.0 margin_bottom = 612.0 +stretches_horizontally = false stretches_vertically = true [node name="ScrollContainer" type="ScrollContainer" parent="FullScreenPanel/VBoxContainer/CenteredPanel"] @@ -49,14 +54,14 @@ size_flags_vertical = 3 [node name="CenterContainer" type="CenterContainer" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer"] margin_right = 470.0 -margin_bottom = 777.0 +margin_bottom = 791.0 size_flags_horizontal = 3 size_flags_vertical = 3 [node name="VBoxContainer" type="VBoxContainer" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer"] margin_left = 26.0 margin_right = 443.0 -margin_bottom = 777.0 +margin_bottom = 791.0 [node name="Control" type="Control" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer"] margin_right = 417.0 @@ -205,7 +210,7 @@ size_flags_stretch_ratio = 0.6 [node name="SpecialThanksContainer" type="VBoxContainer" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer"] margin_top = 410.0 margin_right = 417.0 -margin_bottom = 524.0 +margin_bottom = 575.0 custom_constants/separation = 11 __meta__ = { "_edit_use_anchors_": false @@ -233,20 +238,20 @@ Jake Shoudy" align = 1 valign = 1 -[node name="Spacer5" type="Control" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer"] +[node name="Spacer5" type="Control" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer/SpecialThanksContainer"] margin_left = 208.0 -margin_top = 528.0 +margin_top = 125.0 margin_right = 208.0 -margin_bottom = 568.0 +margin_bottom = 165.0 rect_min_size = Vector2( 0, 40 ) size_flags_horizontal = 4 size_flags_vertical = 3 size_flags_stretch_ratio = 0.6 [node name="VBoxContainer2" type="VBoxContainer" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer"] -margin_top = 572.0 +margin_top = 579.0 margin_right = 417.0 -margin_bottom = 663.0 +margin_bottom = 711.0 custom_constants/separation = 11 __meta__ = { "_edit_use_anchors_": false @@ -275,11 +280,11 @@ margin_bottom = 91.0 size_flags_horizontal = 4 text = "Support" -[node name="Spacer2" type="Control" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer"] +[node name="Spacer2" type="Control" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer/VBoxContainer2"] margin_left = 208.0 -margin_top = 667.0 +margin_top = 102.0 margin_right = 208.0 -margin_bottom = 697.0 +margin_bottom = 132.0 rect_min_size = Vector2( 0, 30 ) size_flags_horizontal = 4 size_flags_vertical = 3 @@ -289,15 +294,20 @@ size_flags_stretch_ratio = 0.6 anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 68.0 -margin_top = 701.0 +margin_top = 715.0 margin_right = 348.0 -margin_bottom = 733.0 +margin_bottom = 747.0 rect_min_size = Vector2( 280, 32 ) size_flags_horizontal = 4 size_flags_vertical = 4 +is_open = false +includes_header = true header_text = "More details" +header_min_height = 0.0 +header_font = null is_caret_on_left = false padding = Vector2( 16, 8 ) +extra_scroll_height_for_custom_header = 0.0 [node name="VBoxContainer" type="VBoxContainer" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer/AccordionPanel"] margin_right = 40.0 @@ -326,7 +336,7 @@ size_flags_vertical = 4 custom_fonts/font = ExtResource( 9 ) text = "Request data deletion" -[node name="Spacer5" type="Control" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer/AccordionPanel/VBoxContainer"] +[node name="DataDeletionButtonPadding" type="Control" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer/AccordionPanel/VBoxContainer"] margin_left = 140.0 margin_top = 58.0 margin_right = 140.0 @@ -354,9 +364,9 @@ __meta__ = { [node name="PaddingBottom" type="Control" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer"] margin_left = 208.0 -margin_top = 737.0 +margin_top = 751.0 margin_right = 208.0 -margin_bottom = 777.0 +margin_bottom = 791.0 rect_min_size = Vector2( 0, 40 ) size_flags_horizontal = 4 size_flags_vertical = 3 diff --git a/addons/scaffold/gui/screens/data_agreement_screen.gd b/addons/scaffold/src/gui/screens/data_agreement_screen.gd similarity index 100% rename from addons/scaffold/gui/screens/data_agreement_screen.gd rename to addons/scaffold/src/gui/screens/data_agreement_screen.gd diff --git a/addons/scaffold/gui/screens/data_agreement_screen.tscn b/addons/scaffold/src/gui/screens/data_agreement_screen.tscn similarity index 90% rename from addons/scaffold/gui/screens/data_agreement_screen.tscn rename to addons/scaffold/src/gui/screens/data_agreement_screen.tscn index b5d9530f..371e32a8 100644 --- a/addons/scaffold/gui/screens/data_agreement_screen.tscn +++ b/addons/scaffold/src/gui/screens/data_agreement_screen.tscn @@ -1,11 +1,13 @@ [gd_scene load_steps=7 format=2] -[ext_resource path="res://addons/scaffold/gui/centered_panel.tscn" type="PackedScene" id=1] -[ext_resource path="res://assets/fonts/main_font_l.tres" type="DynamicFont" id=2] -[ext_resource path="res://addons/scaffold/gui/full_screen_panel.tscn" type="PackedScene" id=3] -[ext_resource path="res://addons/scaffold/gui/screens/data_agreement_screen.gd" type="Script" id=4] -[ext_resource path="res://addons/scaffold/gui/shiny_button.tscn" type="PackedScene" id=5] -[ext_resource path="res://addons/scaffold/gui/nav_bar.tscn" type="PackedScene" id=12] +[ext_resource path="res://addons/scaffold/src/gui/centered_panel.tscn" type="PackedScene" id=1] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_l.tres" type="DynamicFont" id=2] +[ext_resource path="res://addons/scaffold/src/gui/full_screen_panel.tscn" type="PackedScene" id=3] +[ext_resource path="res://addons/scaffold/src/gui/screens/data_agreement_screen.gd" type="Script" id=4] +[ext_resource path="res://addons/scaffold/src/gui/shiny_button.tscn" type="PackedScene" id=5] +[ext_resource path="res://addons/scaffold/src/gui/nav_bar.tscn" type="PackedScene" id=12] + + [node name="DataAgreementScreen" type="Node2D"] script = ExtResource( 4 ) diff --git a/addons/scaffold/gui/screens/developer_splash_screen.gd b/addons/scaffold/src/gui/screens/developer_splash_screen.gd similarity index 100% rename from addons/scaffold/gui/screens/developer_splash_screen.gd rename to addons/scaffold/src/gui/screens/developer_splash_screen.gd diff --git a/addons/scaffold/gui/screens/developer_splash_screen.tscn b/addons/scaffold/src/gui/screens/developer_splash_screen.tscn similarity index 81% rename from addons/scaffold/gui/screens/developer_splash_screen.tscn rename to addons/scaffold/src/gui/screens/developer_splash_screen.tscn index b9ee86ff..597817c9 100644 --- a/addons/scaffold/gui/screens/developer_splash_screen.tscn +++ b/addons/scaffold/src/gui/screens/developer_splash_screen.tscn @@ -1,7 +1,8 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/scaffold/gui/full_screen_panel.tscn" type="PackedScene" id=1] -[ext_resource path="res://addons/scaffold/gui/screens/developer_splash_screen.gd" type="Script" id=2] +[ext_resource path="res://addons/scaffold/src/gui/full_screen_panel.tscn" type="PackedScene" id=1] +[ext_resource path="res://addons/scaffold/src/gui/screens/developer_splash_screen.gd" type="Script" id=2] + [sub_resource type="StyleBoxFlat" id=1] bg_color = Color( 0.152941, 0.192157, 0.286275, 1 ) diff --git a/addons/scaffold/gui/screens/fade_transition.gd b/addons/scaffold/src/gui/screens/fade_transition.gd similarity index 100% rename from addons/scaffold/gui/screens/fade_transition.gd rename to addons/scaffold/src/gui/screens/fade_transition.gd diff --git a/addons/scaffold/gui/screens/fade_transition.tscn b/addons/scaffold/src/gui/screens/fade_transition.tscn similarity index 89% rename from addons/scaffold/gui/screens/fade_transition.tscn rename to addons/scaffold/src/gui/screens/fade_transition.tscn index e65bbc2e..7d59b215 100644 --- a/addons/scaffold/gui/screens/fade_transition.tscn +++ b/addons/scaffold/src/gui/screens/fade_transition.tscn @@ -1,6 +1,7 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/scaffold/gui/screens/fade_transition.gd" type="Script" id=1] +[ext_resource path="res://addons/scaffold/src/gui/screens/fade_transition.gd" type="Script" id=1] + [sub_resource type="Shader" id=1] code = "shader_type canvas_item; diff --git a/addons/scaffold/gui/screens/game_screen.gd b/addons/scaffold/src/gui/screens/game_screen.gd similarity index 95% rename from addons/scaffold/gui/screens/game_screen.gd rename to addons/scaffold/src/gui/screens/game_screen.gd index 4b975770..628288c9 100644 --- a/addons/scaffold/gui/screens/game_screen.gd +++ b/addons/scaffold/src/gui/screens/game_screen.gd @@ -15,7 +15,7 @@ func _init().( \ pass func _enter_tree() -> void: - Global.connect( \ + ScaffoldUtils.connect( \ "display_resized", \ self, \ "_update_viewport_region") @@ -35,6 +35,9 @@ func _update_viewport_region() -> void: self.visible = false call_deferred("set_visible", true) +func _on_activated() -> void: + start_level() + func start_level() -> void: if is_instance_valid(level): destroy_level() diff --git a/addons/scaffold/gui/screens/game_screen.tscn b/addons/scaffold/src/gui/screens/game_screen.tscn similarity index 89% rename from addons/scaffold/gui/screens/game_screen.tscn rename to addons/scaffold/src/gui/screens/game_screen.tscn index 0a961c37..00b21c8d 100644 --- a/addons/scaffold/gui/screens/game_screen.tscn +++ b/addons/scaffold/src/gui/screens/game_screen.tscn @@ -1,6 +1,7 @@ [gd_scene load_steps=3 format=2] -[ext_resource path="res://addons/scaffold/gui/screens/game_screen.gd" type="Script" id=1] +[ext_resource path="res://addons/scaffold/src/gui/screens/game_screen.gd" type="Script" id=1] + [sub_resource type="StyleBoxFlat" id=1] bg_color = Color( 0.345098, 0.431373, 0.603922, 1 ) diff --git a/addons/scaffold/gui/screens/godot_splash_screen.gd b/addons/scaffold/src/gui/screens/godot_splash_screen.gd similarity index 100% rename from addons/scaffold/gui/screens/godot_splash_screen.gd rename to addons/scaffold/src/gui/screens/godot_splash_screen.gd diff --git a/addons/scaffold/gui/screens/godot_splash_screen.tscn b/addons/scaffold/src/gui/screens/godot_splash_screen.tscn similarity index 83% rename from addons/scaffold/gui/screens/godot_splash_screen.tscn rename to addons/scaffold/src/gui/screens/godot_splash_screen.tscn index 82282c94..d0b67cc2 100644 --- a/addons/scaffold/gui/screens/godot_splash_screen.tscn +++ b/addons/scaffold/src/gui/screens/godot_splash_screen.tscn @@ -1,8 +1,9 @@ [gd_scene load_steps=5 format=2] [ext_resource path="res://addons/scaffold/assets/images/gui/godot_logo_splash.png" type="Texture" id=1] -[ext_resource path="res://addons/scaffold/gui/full_screen_panel.tscn" type="PackedScene" id=3] -[ext_resource path="res://addons/scaffold/gui/screens/godot_splash_screen.gd" type="Script" id=4] +[ext_resource path="res://addons/scaffold/src/gui/full_screen_panel.tscn" type="PackedScene" id=3] +[ext_resource path="res://addons/scaffold/src/gui/screens/godot_splash_screen.gd" type="Script" id=4] + [sub_resource type="StyleBoxFlat" id=1] bg_color = Color( 0.152941, 0.192157, 0.286275, 1 ) diff --git a/addons/scaffold/gui/screens/main_menu_screen.gd b/addons/scaffold/src/gui/screens/main_menu_screen.gd similarity index 73% rename from addons/scaffold/gui/screens/main_menu_screen.gd rename to addons/scaffold/src/gui/screens/main_menu_screen.gd index d25ce72b..7e9fbf7b 100644 --- a/addons/scaffold/gui/screens/main_menu_screen.gd +++ b/addons/scaffold/src/gui/screens/main_menu_screen.gd @@ -42,25 +42,13 @@ func _get_focused_button() -> ShinyButton: func _handle_display_resized() -> void: var viewport_size := get_viewport().size - var is_wide_enough_to_put_title_in_nav_bar := viewport_size.x > 600 + var is_wide_enough_to_put_title_in_nav_bar := \ + viewport_size.x > ScaffoldConfig.app_logo.get_width() + 256 $FullScreenPanel/VBoxContainer/NavBar.shows_logo = \ is_wide_enough_to_put_title_in_nav_bar $FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/ \ CenterContainer/VBoxContainer/LogoControl.visible = \ !is_wide_enough_to_put_title_in_nav_bar - - var is_tall_enough_to_have_large_animation := viewport_size.y > 600 - var image_container: Control = \ - $FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/ \ - CenterContainer/VBoxContainer/MainMenuImageContainer - if is_tall_enough_to_have_large_animation: - image_container.rect_min_size.y = 240 - projected_image.rect_scale = Vector2(4, 4) - projected_image.rect_position.y = 120 - else: - image_container.rect_min_size.y = 120 - projected_image.rect_scale = Vector2(2, 2) - projected_image.rect_position.y = 60 func _on_StartGameButton_pressed() -> void: ScaffoldUtils.give_button_press_feedback() diff --git a/addons/scaffold/gui/screens/main_menu_screen.tscn b/addons/scaffold/src/gui/screens/main_menu_screen.tscn similarity index 80% rename from addons/scaffold/gui/screens/main_menu_screen.tscn rename to addons/scaffold/src/gui/screens/main_menu_screen.tscn index 17950022..4e34e727 100644 --- a/addons/scaffold/gui/screens/main_menu_screen.tscn +++ b/addons/scaffold/src/gui/screens/main_menu_screen.tscn @@ -1,12 +1,13 @@ [gd_scene load_steps=8 format=2] -[ext_resource path="res://addons/scaffold/gui/centered_panel.tscn" type="PackedScene" id=1] +[ext_resource path="res://addons/scaffold/src/gui/centered_panel.tscn" type="PackedScene" id=1] [ext_resource path="res://assets/images/gui/logo.png" type="Texture" id=2] -[ext_resource path="res://addons/scaffold/gui/full_screen_panel.tscn" type="PackedScene" id=3] -[ext_resource path="res://addons/scaffold/gui/screens/main_menu_screen.gd" type="Script" id=4] -[ext_resource path="res://addons/scaffold/assets/images/gui/go_icon_normal.png" type="Texture" id=5] -[ext_resource path="res://addons/scaffold/gui/shiny_button.tscn" type="PackedScene" id=7] -[ext_resource path="res://addons/scaffold/gui/nav_bar.tscn" type="PackedScene" id=12] +[ext_resource path="res://addons/scaffold/src/gui/full_screen_panel.tscn" type="PackedScene" id=3] +[ext_resource path="res://addons/scaffold/src/gui/screens/main_menu_screen.gd" type="Script" id=4] +[ext_resource path="res://addons/scaffold/assets/images/gui/go_icon_normal_large.png" type="Texture" id=5] +[ext_resource path="res://addons/scaffold/src/gui/shiny_button.tscn" type="PackedScene" id=7] +[ext_resource path="res://addons/scaffold/src/gui/nav_bar.tscn" type="PackedScene" id=12] + [node name="MainMenuScreen" type="Node2D"] script = ExtResource( 4 ) @@ -40,6 +41,7 @@ anchor_bottom = 0.0 margin_top = 132.0 margin_right = 480.0 margin_bottom = 612.0 +stretches_horizontally = false stretches_vertically = true [node name="ScrollContainer" type="ScrollContainer" parent="FullScreenPanel/VBoxContainer/CenteredPanel"] @@ -56,9 +58,9 @@ size_flags_vertical = 3 [node name="VBoxContainer" type="VBoxContainer" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer"] margin_left = 100.0 -margin_top = 23.0 +margin_top = 128.0 margin_right = 380.0 -margin_bottom = 456.0 +margin_bottom = 351.0 rect_min_size = Vector2( 280, 0 ) [node name="LogoControl" type="Control" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer"] @@ -79,19 +81,17 @@ __meta__ = { "_edit_use_anchors_": false } -[node name="MainMenuImageContainer" type="Control" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer"] +[node name="MainMenuImageContainer" type="PanelContainer" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer"] margin_left = 140.0 margin_top = 41.0 margin_right = 140.0 -margin_bottom = 281.0 -rect_min_size = Vector2( 0, 240 ) +margin_bottom = 71.0 size_flags_horizontal = 4 -size_flags_vertical = 0 +size_flags_vertical = 4 size_flags_stretch_ratio = 3.0 [node name="Spacer2" type="Control" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer/MainMenuImageContainer"] -margin_top = -34.0 -margin_bottom = -4.0 +margin_bottom = 30.0 rect_min_size = Vector2( 0, 30 ) size_flags_horizontal = 4 size_flags_vertical = 3 @@ -101,9 +101,9 @@ __meta__ = { [node name="Spacer3" type="Control" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer"] margin_left = 140.0 -margin_top = 285.0 +margin_top = 75.0 margin_right = 140.0 -margin_bottom = 315.0 +margin_bottom = 105.0 rect_min_size = Vector2( 0, 30 ) size_flags_horizontal = 4 size_flags_vertical = 3 @@ -115,9 +115,9 @@ __meta__ = { anchor_right = 0.0 anchor_bottom = 0.0 margin_left = 60.0 -margin_top = 319.0 +margin_top = 109.0 margin_right = 220.0 -margin_bottom = 399.0 +margin_bottom = 189.0 rect_min_size = Vector2( 160, 80 ) size_flags_horizontal = 4 size_flags_vertical = 4 @@ -125,9 +125,9 @@ texture = ExtResource( 5 ) [node name="Spacer4" type="Control" parent="FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/CenterContainer/VBoxContainer"] margin_left = 140.0 -margin_top = 403.0 +margin_top = 193.0 margin_right = 140.0 -margin_bottom = 433.0 +margin_bottom = 223.0 rect_min_size = Vector2( 0, 30 ) size_flags_horizontal = 4 size_flags_vertical = 3 diff --git a/addons/scaffold/gui/screens/notification_screen.gd b/addons/scaffold/src/gui/screens/notification_screen.gd similarity index 100% rename from addons/scaffold/gui/screens/notification_screen.gd rename to addons/scaffold/src/gui/screens/notification_screen.gd diff --git a/addons/scaffold/gui/screens/notification_screen.tscn b/addons/scaffold/src/gui/screens/notification_screen.tscn similarity index 87% rename from addons/scaffold/gui/screens/notification_screen.tscn rename to addons/scaffold/src/gui/screens/notification_screen.tscn index 9f73273e..9da159ec 100644 --- a/addons/scaffold/gui/screens/notification_screen.tscn +++ b/addons/scaffold/src/gui/screens/notification_screen.tscn @@ -1,11 +1,13 @@ [gd_scene load_steps=7 format=2] -[ext_resource path="res://addons/scaffold/gui/centered_panel.tscn" type="PackedScene" id=1] -[ext_resource path="res://addons/scaffold/gui/shiny_button.tscn" type="PackedScene" id=2] -[ext_resource path="res://addons/scaffold/gui/full_screen_panel.tscn" type="PackedScene" id=3] -[ext_resource path="res://addons/scaffold/gui/screens/notification_screen.gd" type="Script" id=4] -[ext_resource path="res://assets/fonts/main_font_s.tres" type="DynamicFont" id=5] -[ext_resource path="res://addons/scaffold/gui/nav_bar.tscn" type="PackedScene" id=12] +[ext_resource path="res://addons/scaffold/src/gui/centered_panel.tscn" type="PackedScene" id=1] +[ext_resource path="res://addons/scaffold/src/gui/shiny_button.tscn" type="PackedScene" id=2] +[ext_resource path="res://addons/scaffold/src/gui/full_screen_panel.tscn" type="PackedScene" id=3] +[ext_resource path="res://addons/scaffold/src/gui/screens/notification_screen.gd" type="Script" id=4] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_s.tres" type="DynamicFont" id=5] +[ext_resource path="res://addons/scaffold/src/gui/nav_bar.tscn" type="PackedScene" id=12] + + [node name="NotificationScreen" type="Node2D"] script = ExtResource( 4 ) diff --git a/addons/scaffold/gui/screens/pause_screen.gd b/addons/scaffold/src/gui/screens/pause_screen.gd similarity index 98% rename from addons/scaffold/gui/screens/pause_screen.gd rename to addons/scaffold/src/gui/screens/pause_screen.gd index 586f9b57..8f0898ed 100644 --- a/addons/scaffold/gui/screens/pause_screen.gd +++ b/addons/scaffold/src/gui/screens/pause_screen.gd @@ -57,7 +57,7 @@ func _update_stats() -> void: func _on_ExitLevelButton_pressed() -> void: ScaffoldUtils.give_button_press_feedback() Nav.close_current_screen() - Global.level.quit() + ScaffoldConfig.level.quit() func _on_ResumeButton_pressed() -> void: ScaffoldUtils.give_button_press_feedback() diff --git a/addons/scaffold/gui/screens/pause_screen.tscn b/addons/scaffold/src/gui/screens/pause_screen.tscn similarity index 89% rename from addons/scaffold/gui/screens/pause_screen.tscn rename to addons/scaffold/src/gui/screens/pause_screen.tscn index 528c13e4..253635d7 100644 --- a/addons/scaffold/gui/screens/pause_screen.tscn +++ b/addons/scaffold/src/gui/screens/pause_screen.tscn @@ -1,14 +1,15 @@ [gd_scene load_steps=11 format=2] -[ext_resource path="res://addons/scaffold/gui/centered_panel.tscn" type="PackedScene" id=1] -[ext_resource path="res://addons/scaffold/gui/nav_bar.tscn" type="PackedScene" id=2] -[ext_resource path="res://addons/scaffold/gui/screens/pause_screen.gd" type="Script" id=3] -[ext_resource path="res://addons/scaffold/gui/full_screen_panel.tscn" type="PackedScene" id=4] +[ext_resource path="res://addons/scaffold/src/gui/centered_panel.tscn" type="PackedScene" id=1] +[ext_resource path="res://addons/scaffold/src/gui/nav_bar.tscn" type="PackedScene" id=2] +[ext_resource path="res://addons/scaffold/src/gui/screens/pause_screen.gd" type="Script" id=3] +[ext_resource path="res://addons/scaffold/src/gui/full_screen_panel.tscn" type="PackedScene" id=4] [ext_resource path="res://addons/scaffold/assets/images/gui/play_icon_normal.png" type="Texture" id=5] [ext_resource path="res://addons/scaffold/assets/images/gui/stop_normal.png" type="Texture" id=6] [ext_resource path="res://addons/scaffold/assets/images/gui/retry_icon_normal.png" type="Texture" id=7] -[ext_resource path="res://addons/scaffold/gui/labeled_control_list.tscn" type="PackedScene" id=9] -[ext_resource path="res://addons/scaffold/gui/shiny_button.tscn" type="PackedScene" id=10] +[ext_resource path="res://addons/scaffold/src/gui/labeled_control_list.tscn" type="PackedScene" id=9] +[ext_resource path="res://addons/scaffold/src/gui/shiny_button.tscn" type="PackedScene" id=10] + [sub_resource type="StyleBoxFlat" id=1] bg_color = Color( 0.152941, 0.192157, 0.286275, 1 ) diff --git a/addons/scaffold/gui/screens/rate_app_screen.gd b/addons/scaffold/src/gui/screens/rate_app_screen.gd similarity index 96% rename from addons/scaffold/gui/screens/rate_app_screen.gd rename to addons/scaffold/src/gui/screens/rate_app_screen.gd index 6d93351e..f8136566 100644 --- a/addons/scaffold/gui/screens/rate_app_screen.gd +++ b/addons/scaffold/src/gui/screens/rate_app_screen.gd @@ -21,7 +21,6 @@ func _init().( \ func _on_activated() -> void: ._on_activated() assert(ScaffoldConfig.is_rate_app_shown) - Audio.play_music(Music.MAIN_MENU_MUSIC_TYPE) func _get_focused_button() -> ShinyButton: return $FullScreenPanel/VBoxContainer/CenteredPanel/ScrollContainer/ \ diff --git a/addons/scaffold/gui/screens/rate_app_screen.tscn b/addons/scaffold/src/gui/screens/rate_app_screen.tscn similarity index 89% rename from addons/scaffold/gui/screens/rate_app_screen.tscn rename to addons/scaffold/src/gui/screens/rate_app_screen.tscn index ea2b3876..f2b9b68f 100644 --- a/addons/scaffold/gui/screens/rate_app_screen.tscn +++ b/addons/scaffold/src/gui/screens/rate_app_screen.tscn @@ -1,12 +1,14 @@ [gd_scene load_steps=8 format=2] -[ext_resource path="res://addons/scaffold/gui/centered_panel.tscn" type="PackedScene" id=1] -[ext_resource path="res://addons/scaffold/gui/shiny_button.tscn" type="PackedScene" id=2] -[ext_resource path="res://addons/scaffold/gui/full_screen_panel.tscn" type="PackedScene" id=3] -[ext_resource path="res://addons/scaffold/gui/screens/rate_app_screen.gd" type="Script" id=4] -[ext_resource path="res://assets/fonts/main_font_s.tres" type="DynamicFont" id=5] -[ext_resource path="res://assets/fonts/main_font_xl.tres" type="DynamicFont" id=11] -[ext_resource path="res://addons/scaffold/gui/nav_bar.tscn" type="PackedScene" id=12] +[ext_resource path="res://addons/scaffold/src/gui/centered_panel.tscn" type="PackedScene" id=1] +[ext_resource path="res://addons/scaffold/src/gui/shiny_button.tscn" type="PackedScene" id=2] +[ext_resource path="res://addons/scaffold/src/gui/full_screen_panel.tscn" type="PackedScene" id=3] +[ext_resource path="res://addons/scaffold/src/gui/screens/rate_app_screen.gd" type="Script" id=4] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_s.tres" type="DynamicFont" id=5] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_xl.tres" type="DynamicFont" id=11] +[ext_resource path="res://addons/scaffold/src/gui/nav_bar.tscn" type="PackedScene" id=12] + + [node name="RateAppScreen" type="Node2D"] script = ExtResource( 4 ) diff --git a/addons/scaffold/gui/screens/settings_screen.gd b/addons/scaffold/src/gui/screens/settings_screen.gd similarity index 100% rename from addons/scaffold/gui/screens/settings_screen.gd rename to addons/scaffold/src/gui/screens/settings_screen.gd diff --git a/addons/scaffold/gui/screens/settings_screen.tscn b/addons/scaffold/src/gui/screens/settings_screen.tscn similarity index 86% rename from addons/scaffold/gui/screens/settings_screen.tscn rename to addons/scaffold/src/gui/screens/settings_screen.tscn index 006874d5..67eae5c5 100644 --- a/addons/scaffold/gui/screens/settings_screen.tscn +++ b/addons/scaffold/src/gui/screens/settings_screen.tscn @@ -1,11 +1,12 @@ [gd_scene load_steps=8 format=2] -[ext_resource path="res://addons/scaffold/gui/screens/settings_screen.gd" type="Script" id=1] -[ext_resource path="res://addons/scaffold/gui/centered_panel.tscn" type="PackedScene" id=2] -[ext_resource path="res://addons/scaffold/gui/nav_bar.tscn" type="PackedScene" id=3] -[ext_resource path="res://addons/scaffold/gui/accordion_panel.tscn" type="PackedScene" id=4] -[ext_resource path="res://addons/scaffold/gui/full_screen_panel.tscn" type="PackedScene" id=5] -[ext_resource path="res://addons/scaffold/gui/labeled_control_list.tscn" type="PackedScene" id=6] +[ext_resource path="res://addons/scaffold/src/gui/screens/settings_screen.gd" type="Script" id=1] +[ext_resource path="res://addons/scaffold/src/gui/centered_panel.tscn" type="PackedScene" id=2] +[ext_resource path="res://addons/scaffold/src/gui/nav_bar.tscn" type="PackedScene" id=3] +[ext_resource path="res://addons/scaffold/src/gui/accordion_panel.tscn" type="PackedScene" id=4] +[ext_resource path="res://addons/scaffold/src/gui/full_screen_panel.tscn" type="PackedScene" id=5] +[ext_resource path="res://addons/scaffold/src/gui/labeled_control_list.tscn" type="PackedScene" id=6] + [sub_resource type="StyleBoxFlat" id=1] bg_color = Color( 0.152941, 0.192157, 0.286275, 1 ) diff --git a/addons/scaffold/gui/screens/third_party_licenses_screen.gd b/addons/scaffold/src/gui/screens/third_party_licenses_screen.gd similarity index 100% rename from addons/scaffold/gui/screens/third_party_licenses_screen.gd rename to addons/scaffold/src/gui/screens/third_party_licenses_screen.gd diff --git a/addons/scaffold/gui/screens/third_party_licenses_screen.tscn b/addons/scaffold/src/gui/screens/third_party_licenses_screen.tscn similarity index 76% rename from addons/scaffold/gui/screens/third_party_licenses_screen.tscn rename to addons/scaffold/src/gui/screens/third_party_licenses_screen.tscn index cf6d59ed..7d8ddfa9 100644 --- a/addons/scaffold/gui/screens/third_party_licenses_screen.tscn +++ b/addons/scaffold/src/gui/screens/third_party_licenses_screen.tscn @@ -1,10 +1,12 @@ [gd_scene load_steps=7 format=2] -[ext_resource path="res://addons/scaffold/gui/full_screen_panel.tscn" type="PackedScene" id=1] -[ext_resource path="res://assets/fonts/main_font_s.tres" type="DynamicFont" id=2] -[ext_resource path="res://addons/scaffold/gui/nav_bar.tscn" type="PackedScene" id=3] -[ext_resource path="res://addons/scaffold/gui/screens/third_party_licenses_screen.gd" type="Script" id=4] -[ext_resource path="res://addons/scaffold/gui/centered_panel.tscn" type="PackedScene" id=5] +[ext_resource path="res://addons/scaffold/src/gui/full_screen_panel.tscn" type="PackedScene" id=1] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_s.tres" type="DynamicFont" id=2] +[ext_resource path="res://addons/scaffold/src/gui/nav_bar.tscn" type="PackedScene" id=3] +[ext_resource path="res://addons/scaffold/src/gui/screens/third_party_licenses_screen.gd" type="Script" id=4] +[ext_resource path="res://addons/scaffold/src/gui/centered_panel.tscn" type="PackedScene" id=5] + + [sub_resource type="StyleBoxEmpty" id=1] content_margin_left = 12.0 diff --git a/addons/scaffold/gui/shiny_button.gd b/addons/scaffold/src/gui/shiny_button.gd similarity index 99% rename from addons/scaffold/gui/shiny_button.gd rename to addons/scaffold/src/gui/shiny_button.gd index 56e6f8e9..9d23042f 100644 --- a/addons/scaffold/gui/shiny_button.gd +++ b/addons/scaffold/src/gui/shiny_button.gd @@ -78,7 +78,7 @@ func _deferred_update() -> void: var font: Font = \ ScaffoldConfig.main_font_xl if \ is_font_xl else \ - ScaffoldConfig.main_font_normal + ScaffoldConfig.main_font_m $MarginContainer/BottomButton.add_font_override( \ "font", \ font) diff --git a/addons/scaffold/gui/shiny_button.tscn b/addons/scaffold/src/gui/shiny_button.tscn similarity index 91% rename from addons/scaffold/gui/shiny_button.tscn rename to addons/scaffold/src/gui/shiny_button.tscn index cf65c95b..cc0d9643 100644 --- a/addons/scaffold/gui/shiny_button.tscn +++ b/addons/scaffold/src/gui/shiny_button.tscn @@ -1,9 +1,12 @@ [gd_scene load_steps=10 format=2] -[ext_resource path="res://addons/scaffold/gui/shiny_button.gd" type="Script" id=1] +[ext_resource path="res://addons/scaffold/src/gui/shiny_button.gd" type="Script" id=1] [ext_resource path="res://addons/scaffold/assets/images/gui/shine_line.png" type="Texture" id=2] [ext_resource path="res://assets/main_theme.tres" type="Theme" id=3] -[ext_resource path="res://assets/fonts/main_font_normal.tres" type="DynamicFont" id=4] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_m.tres" type="DynamicFont" id=4] + + + [sub_resource type="StyleBoxEmpty" id=1] diff --git a/addons/scaffold/ios_model_names.gd b/addons/scaffold/src/ios_model_names.gd similarity index 100% rename from addons/scaffold/ios_model_names.gd rename to addons/scaffold/src/ios_model_names.gd diff --git a/addons/scaffold/ios_resolutions.gd b/addons/scaffold/src/ios_resolutions.gd similarity index 100% rename from addons/scaffold/ios_resolutions.gd rename to addons/scaffold/src/ios_resolutions.gd diff --git a/addons/scaffold/navigation.gd b/addons/scaffold/src/navigation.gd similarity index 99% rename from addons/scaffold/navigation.gd rename to addons/scaffold/src/navigation.gd index 77430373..cbe0e3ea 100644 --- a/addons/scaffold/navigation.gd +++ b/addons/scaffold/src/navigation.gd @@ -1,12 +1,13 @@ extends Node -const _DEFAULT_SCREEN_PATH_PREFIX := "res://addons/scaffold/gui/screens/" +const _DEFAULT_SCREEN_PATH_PREFIX := "res://addons/scaffold/src/gui/screens/" const _DEFAULT_SCREEN_FILENAMES := [ "godot_splash_screen.tscn", "developer_splash_screen.tscn", "main_menu_screen.tscn", "settings_screen.tscn", "pause_screen.tscn", + "game_screen.tscn", "third_party_licenses_screen.tscn", "credits_screen.tscn", "data_agreement_screen.tscn", diff --git a/addons/scaffold/priority_queue.gd b/addons/scaffold/src/priority_queue.gd similarity index 100% rename from addons/scaffold/priority_queue.gd rename to addons/scaffold/src/priority_queue.gd diff --git a/addons/scaffold/scaffold_bootstrap.gd b/addons/scaffold/src/scaffold_bootstrap.gd similarity index 59% rename from addons/scaffold/scaffold_bootstrap.gd rename to addons/scaffold/src/scaffold_bootstrap.gd index cf0bff35..cf78c564 100644 --- a/addons/scaffold/scaffold_bootstrap.gd +++ b/addons/scaffold/src/scaffold_bootstrap.gd @@ -4,13 +4,35 @@ class_name ScaffoldBootstrap func _init() -> void: ScaffoldUtils.print("ScaffoldBootstrap._init") -func on_app_ready(main: Node) -> void: +func on_app_ready( \ + app_manifest: Dictionary, \ + main: Node) -> void: + ScaffoldConfig.register_app_manifest(app_manifest) ScaffoldConfig.load_state() - ScaffoldConfig.register_main(main) - ScaffoldConfig.is_app_ready = true main.add_child(self) + ScaffoldConfig.camera_controller = CameraController.new() + main.add_child(ScaffoldConfig.camera_controller) + + ScaffoldConfig.canvas_layers = CanvasLayers.new() + main.add_child(ScaffoldConfig.canvas_layers) + + ScaffoldConfig.debug_panel = ScaffoldUtils.add_scene( \ + ScaffoldConfig.canvas_layers.layers.top, \ + ScaffoldConfig.DEBUG_PANEL_RESOURCE_PATH, \ + true, \ + true) + ScaffoldConfig.debug_panel.z_index = 1000 + ScaffoldConfig.debug_panel.visible = ScaffoldConfig.is_debug_panel_shown + + if ScaffoldConfig.debug or ScaffoldConfig.playtest: + ScaffoldConfig.gesture_record = GestureRecord.new() + ScaffoldConfig.canvas_layers.layers.top \ + .add_child(ScaffoldConfig.gesture_record) + + ScaffoldConfig.is_app_ready = true + _set_window_debug_size_and_position() get_tree().root.set_pause_mode(Node.PAUSE_MODE_PROCESS) diff --git a/addons/scaffold/src/scaffold_config.gd b/addons/scaffold/src/scaffold_config.gd new file mode 100644 index 00000000..e0802206 --- /dev/null +++ b/addons/scaffold/src/scaffold_config.gd @@ -0,0 +1,281 @@ +extends Node + +# --- Static configuration state --- + +var debug: bool +var playtest: bool +var test := false + +var debug_window_size: Vector2 + +var app_name: String +var app_id: String +var app_version: String + +var main_font_m: Font +var main_font_xs: Font +var main_font_l: Font +var main_font_xl: Font + +var cell_size: Vector2 + +var aspect_ratio_max: float +var aspect_ratio_min: float + +var screen_background_color: Color +var button_normal_color: Color +var button_hover_color: Color +var button_pressed_color: Color +var shiny_button_highlight_color: Color +var key_value_even_row_color: Color +var option_button_normal_color: Color +var option_button_hover_color: Color +var option_button_pressed_color: Color + +var screen_exclusions: Array +var screen_inclusions: Array + +var sounds_manifest: String +var default_sounds_path_prefix: String +var default_sounds_file_suffix: String +var default_sounds_bus_index: String +var music_manifest: String +var default_music_path_prefix: String +var default_music_file_suffix: String +var default_music_bus_index: String +var main_menu_music: String + +var third_party_license_text: String +var special_thanks_text: String + +var app_logo: Texture +var developer_name: String +var developer_url: String + +var developer_logo: Texture +var developer_splash: Texture + +var godot_splash_sound := "achievement" +var developer_splash_sound: String + +var godot_splash_screen_duration_sec := 0.8 +var developer_splash_screen_duration_sec := 1.0 + +var main_menu_image_scene_path: String + +var fade_in_transition_texture := \ + preload("res://addons/scaffold/assets/images/transition_in.png") +var fade_out_transition_texture := \ + preload("res://addons/scaffold/assets/images/transition_out.png") + +var google_analytics_id: String +var terms_and_conditions_url: String +var privacy_policy_url: String +var android_app_store_url: String +var ios_app_store_url: String +var support_url_base: String +var log_gestures_url: String + +var input_vibrate_duration_sec := 0.01 + +var display_resize_throttle_interval_sec := 0.1 + +var recent_gesture_events_for_debugging_buffer_size := 1000 + +# --- Derived configuration --- + +var is_special_thanks_shown: bool +var is_third_party_licenses_shown: bool +var is_data_tracked: bool +var is_rate_app_shown: bool +var is_support_shown: bool +var is_gesture_logging_supported: bool +var is_developer_logo_shown: bool +var is_developer_splash_shown: bool +var is_main_menu_image_shown: bool + +# --- Global state --- + +var is_app_ready := false +var agreed_to_terms: bool +var is_giving_haptic_feedback: bool +var is_debug_panel_shown: bool setget \ + _set_is_debug_panel_shown, _get_is_debug_panel_shown +var is_debug_time_shown: bool + +var canvas_layers: CanvasLayers +var camera_controller: CameraController +var debug_panel: DebugPanel +var gesture_record: GestureRecord +var next_level_resource_path: String +var level: ScaffoldLevel + +# --- + +const AGREED_TO_TERMS_SETTINGS_KEY := "agreed_to_terms" +const IS_GIVING_HAPTIC_FEEDBACK_SETTINGS_KEY := "is_giving_haptic_feedback" +const IS_DEBUG_PANEL_SHOWN_SETTINGS_KEY := "is_debug_panel_shown" +const IS_DEBUG_TIME_SHOWN_SETTINGS_KEY := "is_debug_time_shown" +const IS_MUSIC_ENABLED_SETTINGS_KEY := "is_music_enabled" +const IS_SOUND_EFFECTS_ENABLED_SETTINGS_KEY := "is_sound_effects_enabled" + +const DEBUG_PANEL_RESOURCE_PATH := "res://addons/scaffold/src/gui/debug_panel.tscn" + +# --- + +func _init() -> void: + print("ScaffoldConfig._init") + +func register_app_manifest(manifest: Dictionary) -> void: + self.debug = manifest.debug + self.playtest = manifest.playtest + self.debug_window_size = manifest.debug_window_size + self.app_name = manifest.app_name + self.app_id = manifest.app_id + self.app_version = manifest.app_version + self.main_font_m = manifest.main_font_m + self.main_font_xs = manifest.main_font_xs + self.main_font_l = manifest.main_font_l + self.main_font_xl = manifest.main_font_xl + self.cell_size = manifest.cell_size + self.aspect_ratio_max = manifest.aspect_ratio_max + self.aspect_ratio_min = manifest.aspect_ratio_min + self.screen_background_color = manifest.screen_background_color + self.button_normal_color = manifest.button_normal_color + self.button_hover_color = manifest.button_hover_color + self.button_pressed_color = manifest.button_pressed_color + self.shiny_button_highlight_color = manifest.shiny_button_highlight_color + self.key_value_even_row_color = manifest.key_value_even_row_color + self.option_button_normal_color = manifest.option_button_normal_color + self.option_button_hover_color = manifest.option_button_hover_color + self.option_button_pressed_color = manifest.option_button_pressed_color + self.screen_exclusions = manifest.screen_exclusions + self.screen_inclusions = manifest.screen_inclusions + self.sounds_manifest = manifest.sounds_manifest + self.default_sounds_path_prefix = manifest.default_sounds_path_prefix + self.default_sounds_file_suffix = manifest.default_sounds_file_suffix + self.default_sounds_bus_index = manifest.default_sounds_bus_index + self.music_manifest = manifest.music_manifest + self.default_music_path_prefix = manifest.default_music_path_prefix + self.default_music_file_suffix = manifest.default_music_file_suffix + self.default_music_bus_index = manifest.default_music_bus_index + self.main_menu_music = manifest.main_menu_music + self.third_party_license_text = \ + manifest.third_party_license_text.strip_edges() + self.special_thanks_text = manifest.special_thanks_text.strip_edges() + self.app_logo = manifest.app_logo + self.developer_name = manifest.developer_name + self.developer_url = manifest.developer_url + + if manifest.has("developer_logo"): + self.developer_logo = manifest.developer_logo + if manifest.has("developer_splash"): + self.developer_splash = manifest.developer_splash + if manifest.has("godot_splash_sound"): + self.godot_splash_sound = manifest.godot_splash_sound + if manifest.has("developer_splash_sound"): + self.developer_splash_sound = manifest.developer_splash_sound + if manifest.has("godot_splash_screen_duration_sec"): + self.godot_splash_screen_duration_sec = \ + manifest.godot_splash_screen_duration_sec + if manifest.has("developer_splash_screen_duration_sec"): + self.developer_splash_screen_duration_sec = \ + manifest.developer_splash_screen_duration_sec + if manifest.has("main_menu_image_scene_path"): + self.main_menu_image_scene_path = manifest.main_menu_image_scene_path + if manifest.has("fade_in_transition_texture"): + self.fade_in_transition_texture = manifest.fade_in_transition_texture + if manifest.has("fade_out_transition_texture"): + self.fade_out_transition_texture = manifest.fade_out_transition_texture + if manifest.has("google_analytics_id"): + self.google_analytics_id = manifest.google_analytics_id + if manifest.has("terms_and_conditions_url"): + self.terms_and_conditions_url = manifest.terms_and_conditions_url + if manifest.has("privacy_policy_url"): + self.privacy_policy_url = manifest.privacy_policy_url + if manifest.has("android_app_store_url"): + self.android_app_store_url = manifest.android_app_store_url + if manifest.has("ios_app_store_url"): + self.ios_app_store_url = manifest.ios_app_store_url + if manifest.has("support_url_base"): + self.support_url_base = manifest.support_url_base + if manifest.has("log_gestures_url"): + self.log_gestures_url = manifest.log_gestures_url + if manifest.has("input_vibrate_duration_sec"): + self.input_vibrate_duration_sec = \ + manifest.input_vibrate_duration_sec + if manifest.has("display_resize_throttle_interval_sec"): + self.display_resize_throttle_interval_sec = \ + manifest.display_resize_throttle_interval_sec + if manifest.has("recent_gesture_events_for_debugging_buffer_size"): + self.recent_gesture_events_for_debugging_buffer_size = \ + manifest.recent_gesture_events_for_debugging_buffer_size + + Audio.register_sounds( \ + manifest.sounds_manifest, \ + manifest.default_sounds_path_prefix, \ + manifest.default_sounds_file_suffix, \ + manifest.default_sounds_bus_index) + Audio.register_music( \ + manifest.music_manifest, \ + manifest.default_music_path_prefix, \ + manifest.default_music_file_suffix, \ + manifest.default_music_bus_index) + + assert(self.google_analytics_id.empty() == \ + self.privacy_policy_url.empty() and \ + self.privacy_policy_url.empty() == \ + self.terms_and_conditions_url.empty()) + assert((self.developer_splash == null) == \ + self.developer_splash_sound.empty()) + + self.is_special_thanks_shown = !self.special_thanks_text.empty() + self.is_third_party_licenses_shown = !self.third_party_license_text.empty() + self.is_data_tracked = \ + !self.privacy_policy_url.empty() and \ + !self.terms_and_conditions_url.empty() and \ + !self.google_analytics_id.empty() + self.is_rate_app_shown = \ + !self.android_app_store_url.empty() and \ + !self.ios_app_store_url.empty() + self.is_support_shown = !self.support_url_base.empty() + self.is_gesture_logging_supported = !self.log_gestures_url.empty() + self.is_developer_logo_shown = manifest.has("developer_logo") + self.is_developer_splash_shown = \ + manifest.has("developer_splash") and \ + manifest.has("developer_splash_sound") + self.is_main_menu_image_shown = manifest.has("main_menu_image_scene_path") + +func load_state() -> void: + agreed_to_terms = SaveState.get_setting( \ + AGREED_TO_TERMS_SETTINGS_KEY, \ + false) + is_giving_haptic_feedback = SaveState.get_setting( \ + IS_GIVING_HAPTIC_FEEDBACK_SETTINGS_KEY, \ + ScaffoldUtils.get_is_android_device()) + is_debug_panel_shown = SaveState.get_setting( \ + IS_DEBUG_PANEL_SHOWN_SETTINGS_KEY, \ + false) + is_debug_time_shown = SaveState.get_setting( \ + IS_DEBUG_TIME_SHOWN_SETTINGS_KEY, \ + false) + Audio.is_music_enabled = SaveState.get_setting( \ + IS_MUSIC_ENABLED_SETTINGS_KEY, \ + true) + Audio.is_sound_effects_enabled = SaveState.get_setting( \ + IS_SOUND_EFFECTS_ENABLED_SETTINGS_KEY, \ + true) + +func set_agreed_to_terms() -> void: + agreed_to_terms = true + SaveState.set_setting( \ + ScaffoldConfig.AGREED_TO_TERMS_SETTINGS_KEY, \ + true) + +func _set_is_debug_panel_shown(is_visible: bool) -> void: + is_debug_panel_shown = is_visible + if debug_panel != null: + debug_panel.visible = is_visible + +func _get_is_debug_panel_shown() -> bool: + return is_debug_panel_shown diff --git a/addons/scaffold/scaffold_level.gd b/addons/scaffold/src/scaffold_level.gd similarity index 100% rename from addons/scaffold/scaffold_level.gd rename to addons/scaffold/src/scaffold_level.gd diff --git a/addons/scaffold/scaffold_third_party_licenses.gd b/addons/scaffold/src/scaffold_third_party_licenses.gd similarity index 100% rename from addons/scaffold/scaffold_third_party_licenses.gd rename to addons/scaffold/src/scaffold_third_party_licenses.gd diff --git a/addons/scaffold/scaffold_utils.gd b/addons/scaffold/src/scaffold_utils.gd similarity index 98% rename from addons/scaffold/scaffold_utils.gd rename to addons/scaffold/src/scaffold_utils.gd index 447c3dd3..26e56e5f 100644 --- a/addons/scaffold/scaffold_utils.gd +++ b/addons/scaffold/src/scaffold_utils.gd @@ -182,6 +182,14 @@ func add_scene( \ node.visible = is_visible if is_attached: parent.add_child(node) + + var name := resource_path + if name.find_last("/") >= 0: + name = name.substr(name.find_last("/") + 1) + assert(resource_path.ends_with(".tscn")) + name = name.substr(0, name.length() - 5) + node.name = name + return node static func get_global_touch_position(input_event: InputEvent) -> Vector2: diff --git a/addons/scaffold/stopwatch.gd b/addons/scaffold/src/stopwatch.gd similarity index 100% rename from addons/scaffold/stopwatch.gd rename to addons/scaffold/src/stopwatch.gd diff --git a/addons/scaffold/time.gd b/addons/scaffold/src/time.gd similarity index 100% rename from addons/scaffold/time.gd rename to addons/scaffold/src/time.gd diff --git a/addons/scaffold/todo_sign.gd b/addons/scaffold/src/todo_sign.gd similarity index 100% rename from addons/scaffold/todo_sign.gd rename to addons/scaffold/src/todo_sign.gd diff --git a/addons/scaffold/todo_sign.tscn b/addons/scaffold/src/todo_sign.tscn similarity index 82% rename from addons/scaffold/todo_sign.tscn rename to addons/scaffold/src/todo_sign.tscn index c692a0f4..049c2a8b 100644 --- a/addons/scaffold/todo_sign.tscn +++ b/addons/scaffold/src/todo_sign.tscn @@ -1,7 +1,9 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/scaffold/todo_sign.gd" type="Script" id=1] -[ext_resource path="res://assets/fonts/main_font_l.tres" type="DynamicFont" id=2] +[ext_resource path="res://addons/scaffold/src/todo_sign.gd" type="Script" id=1] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_l.tres" type="DynamicFont" id=2] + + [sub_resource type="StyleBoxFlat" id=1] bg_color = Color( 0, 0, 0, 0.639216 ) diff --git a/addons/surfacer/LICENSE b/addons/surfacer/LICENSE new file mode 100644 index 00000000..65f2f708 --- /dev/null +++ b/addons/surfacer/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019-2021 Snoring Cat LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/addons/surfacer/README.md b/addons/surfacer/README.md new file mode 100644 index 00000000..9e351ee4 --- /dev/null +++ b/addons/surfacer/README.md @@ -0,0 +1,475 @@ +# Surfacer + +_**[Live demo](https://levi.dev/squirrel)**._ +_**[Demo source](https://github.com/snoringcatgames/squirrel-away)**._ + +_A procedural pathfinding 2D-platformer framework for [Godot](https://godotengine.org/)._ + +_"Surfacer": Like a platformer, but with walking, climbing, and jumping on all surfaces!_ + +-------- + +_**NOTE**: This framework is still in development._ + +-------- + +![Surfaces and edges in a plattform graph](./docs/surfaces-and-edges.png) + +**tl;dr**: Surfacer works by **pre-parsing** a level into a **"platform graph"**. The **nodes** are represented by points along the different surfaces in the level (floors, walls, and ceilings). The **edges** are represented by possible movement trajectories between points along surfaces. There are different types of edges for different types of movement (e.g., jumping from a floor to a floor, falling from a wall, walking along a floor). At run time, **[A* search](https://en.wikipedia.org/wiki/A*_search_algorithm)** is used to calculate a path to a given destination. + +Some features include: +- Walking on floors, climbing on walls, climbing on ceilings, jumping and falling from anywhere. +- [Variable-height jump and fast-fall](https://kotaku.com/the-mechanics-behind-satisfying-2d-jumping-1761940693). +- Adjusting movement trajectories around intermediate surfaces (such as jumping over a wall or under an overhang). +- Configurable movement parameters on a per-player basis (e.g., horizontal acceleration, jump power, gravity, collision boundary shape and size, which types of edge movement are allowed). +- Level creation using Godot's standard pattern with a [TileMap in the 2D scene editor](https://docs.godotengine.org/en/3.2/tutorials/2d/using_tilemaps.html). +- Preparsing the level into a platform graph, and using A* search for efficient path-finding at runtime. +- A powerful inspector for analyzing the platform graph, in order to debug and better understand how edges were calculated. + +## Getting set up + +TODO: Add more detail. + +- Add the [Godot Scaffold](https://github.com/snoringcatgames/godot-scaffold/) library to your `addons/` folder. + - This is a framework that provides some general-purpose infrastructure that can be useful for adding a bunch of app boilerplate that you might want for your game. + - Surfacer currently depends on this additional framework. +- Configure the Surfacer and Godot Scaffold frameworks. + - See the [Squirrel Away app](https://github.com/snoringcatgames/squirrel-away) for an example. + +## Buy why? + +Because there aren't many other good tools out there for intelligent pathfinding in a platformer. + +The vast majority of platformers use pretty simple computer-player AI for movement--for example: +- Walk to edge, turn around, repeat. +- Jump continuously, moving forward. +- Move with a regular bounce or surface-following pattern. +- Move horizontally toward the human player, "floating" vertically as needed in order to move around obstacles and platforms. + +Most examples of more sophisticated AI pathfinding behavior are usually still pretty limited. One common technique uses machine-learning and is trained by hundreds to thousands of human-generated jumps on an explicit pre-fabricated level. This makes level-generation difficult and is not flexible to dynamic platform creation/movement. + +There are two key reasons why good path-finding AI isn't really used in platformers: +1. It's hard to implement right; there is a lot of math involved, and there are a lot of different edge cases to account for. +2. Dumb AI is usually plenty effective on its own to create compelling gameplay. The user often doesn't really notice or care how simple the behavior is. + +But there are use-cases for which we really benefit from an AI that can accurately immitate the same movement mechanics of the player. One example is if we want to be able to control the player by tapping on locations that they should move through the level toward. Another example is if we want to have a flexible game mode in which a computer player can swap in for a human player depending on how many humans are present. + +## Platformer AI + +### The platform graph: Pre-parsing the world + +Surfacer depends on the level being represented as a [`TileMap`](https://docs.godotengine.org/en/stable/classes/class_tilemap.html#class-tilemap). + +In order for our AI to traverse our world, we first need to parse the world into a platform graph. We do this up-front, when the level is loaded, so that we can efficiently search the graph at run time. Dynamic updates to the graph can be performed at runtime, but these could be expensive if not done with care. + +The nodes of this graph correspond to positions along distinct surfaces. Since our players can walk on floors, climb on walls, and climb on ceilings, we store floor, wall, and ceiling surfaces. + +The edges of this graph correspond to a type of movement that the player could perform in order to move from one position on a surface node to another. +- These edges are directional, since the player may be able to move from A to B but not from B to A. +- The ends of an edge could be along the same surface or on different surfaces (e.g., for climbing up a wall vs jumping from a floor). +- There could be multiple edges between a single pair of nodes, since there could be multiple types of movement that could get the player from the one to the other. +- These edges are specific to a given player type. If we need to consider a different player that has different movement parameters, then we need to calculate a separate platform graph for that player. + +![Surfaces in a plattform graph](./docs/surfaces.png) + +![Edges in a plattform graph](./docs/edges.png) + +### Nodes: Parsing a Godot `TileMap` into surfaces + +**NOTE**: The following algorithm assumes that the given `TileMap` only uses tiles with convex collision boundaries. + +#### Parse individual tiles into their constituent surfaces + +- Map each `TileMap` cell into a polyline that corresponds to the top-side/floor portion of its collision polygon. + - Calculate whether the collision polygon's vertices are specified in a clockwise order. + - Use this to determine the iteration step size. + - `step_size = 1` if clockwise; `step_size = -1` if counter-clockwise. + - Regardless of whether the vertices are specified in a clockwise order, we will iterate over them in clockwise order. + - Find both the leftmost and rightmost vertices. + - Start with the leftmost vertex. + - If there is a wall segment on the left side of the polygon, then this vertex is part of it. + - If there is no wall segment on the left side of the polygon, then this vertex must be the cusp between a preceding bottom-side/ceiling segment and a following top-side/floor segment (i.e., the previous segment is underneath the next segment). + - Even if there is no segment along one side, we store a surface for that side; this surface is only represented by a single point. + - Iterate over the following vertices until we find a non-wall segment (this could be the first segment, the one connecting to the leftmost vertex). + - Wall segments are distinguished from floor/ceiling segments according to their angle. This is configurable, but typically, a segment up to 45-degrees is a floor/ceiling and a segment steeper than 45-degrees is a wall. + - This non-wall segment must be the start of the top-side/floor polyline. + - Iterate, adding segments to the result polyline, until we find either a wall segment or the rightmost vertex. + - We then also save a mapping from a `TileMap` cell index to each of the different surfaces we've calculated as existing in that cell. +- Repeat the above process for the right-side, left-side, and bottom-side surfaces. + +#### Remove internal surfaces + +**NOTE**: This will only detect internal surface segments that are equivalent with another internal segment. But for grid-based tiling systems, this can often be enough. + +- Check for pairs of floor+ceiling segments or left-wall+right-wall segments, such that both segments share the same vertices. +- Remove both segments in these pairs. + +#### Merge any connecting surfaces + +- Iterate across each floor surface A. +- Nested iterate across each other floor surface B. + - Ideally, we should be using a spatial data structure that allows us to only consider nearby surfaces during this nested iteration (such as an R-Tree). +- Check whether A and B form a "continuous" surface. + - A and B are both polylines that only have two end points. + - Just check whether either endpoint of A equals either endpoint of B. + - Actually, our original `TileMap` parsing results in every surface polyline being stored in clockwise order, so we only need to compare the end of A with the start of B and the start of A with the end of B. +- If they do: + - Merge B into A. + - Optionally, remove any newly created redundant internal colinear points. + - Remove B from the surface collection. +- Repeat the iteration until no merges were performed. + +#### Record adjacent neighbor surfaces + +- Every surface should have both adjacent clockwise and counter-clockwise neighbor surfaces. +- Use a similar process as above for finding surfaces with matching end positions. + +### Edges: Calculating jump movement trajectories + +**tl;dr**: The Surfacer framework uses a procedural approach to calculate trajectories for movement between surfaces. The algorithms used rely heavily on the classic [one-dimensional equations of motion for constant acceleration](https://physics.info/motion-equations/). These trajectories are calculated to match to the same abilities and limitations that are exhibited by corresponding human-controlled movement. After the trajectory for an edge is calculated, it is translated into a simple instruction/input-key start/end sequence that should reproduce the calculated trajectory. + +**NOTE**: A machine-learning-based approach would probably be a good alternate way to solve this general problem. However, one perk of a procedural approach is that it's relatively easy to understand how it works and to modify it to perform better for any given edge-case (and there are a _ton_ of edge-cases). + +#### The high-level steps + +- Determine how high we need to jump in order to reach the destination. +- If the destination is out of reach (vertically or horizontally), ignore it. +- Calculate how long it will take for vertical motion to reach the destination from the origin. +- We will define the movement trajectory as a combination of two independent components: a "vertical step" and a "horizontal step". The vertical step is based primarily on on the jump duration calculated above. +- Calculate the horizontal step that would reach the destination displacement over the given duration. +- Check for any unexpected collisions along the trajectory represented by the vertical and horizontal steps. + - If there is an intermediate surface that the player would collide with, we need to try adjusting the jump trajectory to go around either side of the colliding surface. + - We call these points that movement must go through in order to avoid collisions, "waypoints". + - Recursively check whether the jump is valid to and from either side of the colliding surface. + - If we can't reach the destination when moving around the colliding surface, then try backtracking and consider whether a higher jump height from the start would get us there. + - If there is no intermediate collision, then we can calculate the ultimate edge movement instructions for playback based on the vertical and horizontal steps we've calculated. + +#### Some important aspects + +- We treat horizontal and vertical motion as independent to each other. This greatly simplifies our calculations. + - We calculate the necessary jump duration--and from that the vertical component of motion--up-front, and use this to determine times for each potential step and waypoint of the motion. Knowing these times up-front makes the horizontal min/max calculations easier. +- We have a broad-phase check to quickly eliminate possible surfaces that are obviously out of reach. + - This primarily looks at the horizontal and vertical distance from the origin to the destination. + +#### Calculating "good" jump and land positions + +Deciding which jump and land positions to base an edge calculation off of is non-trivial. We could just try calculating edges for a bunch of different jump/land positions for a given pair of surfaces. But edge calculations aren't cheap, and executing too many of them impacts performance. So it's important that we carefully choose "good" jump/land positions that have a relatively high likelihood of producing a valid and efficient edge. + +Additionally, when jumping from a floor, we need to determine what initial horizontal velocity to use for the edge calculation. This horizontal start velocity can then influence the jump/land positions. + +- Some interesting jump/land positions for a surface include the following: + - Either end of the surface. + - The closest position along the surface to either end of the other surface. + - This closest position, but with a slight offset to account for the width of the player. + - This closest position, but with an additional offset to account for horizontal or vertical displacement with minimum jump time and maximum horizontal velocity. + - This offset becomes important when considering jumps that start with max-speed horizontal velocity, which could otherwise overshoot the land position if we didn't account for the offset. + - The closest interior position along the surface to the closest interior position along the other surface. + - The position along a horizontal surface that is behind the overall connected region that the vertical land surface is a part of. + - This position is important if we need to consider movement around behind a wall that then lands on the top of the wall. +- We try to minimize the number of jump/land positions returned, since having more of these greatly increases the overall time to parse the platform graph. +- We usually consider surface-interior points before surface-end points (which usually puts shortest distances first). +- We also decide start velocity when we decide the jump/land positions. + - We only ever consider start velocities with zero or max speed. +- Additionally, we often quit early as soon as we've calculated the first valid edge for a given pair of surfaces. + - In order to decide whether to skip an edge calculation for a given jump/land position pair, we look at how far away it is from any other jump/land position pair that we already found a valid edge for, on the same surface, for the same surface pair. If it's too close, we skip it. + - This is another important performance optimization. + +Unfortunately, most jump/land position calculations are highly dependent on the types and spatial arrangement of the two surfaces. There are many possible combinations, and the most of these combinations must be considered individually. The following diagrams illustrate the many different jump/land combinations. + +![A legend for the illustrations of jump-land-position combinations](./docs/jump-land-positions-legend.png) + +![Illustrations of floor-to-floor jump-land-position combinations](./docs/jump-land-positions-floor-to-floor.png) + +![Illustrations of floor-to-wall jump-land-position combinations](./docs/jump-land-positions-floor-to-wall.png) + +![Illustrations of wall-to-floor jump-land-position combinations](./docs/jump-land-positions-wall-to-floor.png) + +![Illustrations of wall-to-opposite-facing-wall jump-land-position combinations](./docs/jump-land-positions-wall-to-opposite-wall.png) + +![Illustrations of wall-to-same-facing-wall jump-land-position combinations](./docs/jump-land-positions-wall-to-same-wall.png) + +![Illustrations of floor-to-ceiling jump-land-position combinations](./docs/jump-land-positions-floor-to-ceiling.png) + +#### Calculating the start velocity for a jump + +- In the general case, we can't know at build-time what direction along a surface the player will + be moving from when they need to start a jump. +- Unfortunately, using start velocity x values of zero for all jump edges tends to produce very + unnatural composite trajectories (similar to using perpendicular Manhatten distance routes + instead of more diagonal routes). +- So, we can assume that for surface-end jump-off positions, we'll be approaching the jump-off + point from the center of the edge. +- And for most edges we should have enough run-up distance in order to hit max horizontal speed + before reaching the jump-off point--since horizontal acceleration is relatively quick. +- Also, we only ever consider velocity-start values of zero or max horizontal speed. Since the + horizontal acceleration is quick, most jumps at run time shouldn't need some medium-speed. And + even if they did, we force the initial velocity of the jump to match expected velocity, so the + jump trajectory should proceed as expected, and any sudden change in velocity at the jump start + should be acceptably small. + +#### Calculating the total jump duration (and the vertical step for the edge) + +- At the start of each edge-calculation traversal, we calculate the minimum total time needed to reach the destination. + - If the destination is above, this might be the time needed to rise that far in the jump. + - If the destination is below, this might be the time needed to fall that far (still taking into account any initial upward jump-off velocity). + - If the destination is far away horizontally, this might be the time needed to move that far horizontally (taking into account the horizontal movement acceleration and max speed). + - The greatest of these three possibilities is the minimum required total duration of the jump. +- The minimum peak jump height can be determined from this total duration. +- All of this takes into account our variable-height jump mechanic and the difference in slow-ascent and fast-fall gravities. + - With our variable-height jump mechanic, there is a greater acceleration of gravity when the player either is moving downward or has released the jump button. + - If the player releases the jump button before reaching the maximum peak of the jump, then their current velocity will continue pushing them upward, but with the new stronger gravity. + - To determine the duration to the jump peak height in this scenario, we first construct two instances of one of the basic equations of motion--one for the former part of the ascent, with the slow-ascent gravity, and one for the latter part of the ascent, with the fast-fall gravity. We then use algebra to substitute the equations and solve for the duration. + +#### Calculating the horizontal steps in an edge + +- If we decide whether a surface could be within reach, we then check for possible collisions between the origin and destination. + - To do this, we simulate frame-by-frame motion using the same physics timestep and the same movement-update function calls that would be used when running the game normally. We then check for any collisions between each frame. +- If we detect a collision, then we define two possible "waypoints"--one for each end of the collided surface. + - In order to make it around this intermediate surface, we know the player must pass around one of the ends of this surface. + - These waypoints we calculate represent the minimum required deviation from the player's original path. +- We then recursively check whether the player could move to and from each of the waypoints. + - We keep the original vertical step and overall duration the same. + - We can use that to calculate the time and vertical state that must be used for the waypoint. + - Then we only really consider whether the horizontal movement could be valid within the the given time limit. +- If so, we concatenate and return the horizontal steps required to reach the waypoint from the original starting position and the horizontal steps required to reach the original destination from the waypoint. + +#### Backtracking to consider a higher max jump height + +- Sometimes, a waypoint may be out of reach, when we're calculating horizontal steps, given the current step's starting position and velocity. +- However, maybe the waypoint could be within reach, if we had originally jumped a little higher. +- To account for this, we backtrack to the start of the overall movement traversal and consider whether a higher jump could reach the waypoint. + - The destination waypoint is first updated to support a new jump height that would allow for a previously-out-of-reach intermediate waypoint to also be reached. + - Then all steps are re-calculated from the start of the movement, while considering the new destination state. +- If it could, we return that result instead. + +#### Waypoint calculations + +- We calculate waypoints before steps. + - We calculate a lot of state to store on them, and then depend on this state during step calculation. + - Some of this state includes: + - The time for passing through the waypoint (corresponding to the overall jump height and edge duration). + - The horizontal direction of movement through the waypoint (according to the direction of travel from the previous waypoint or according to the direction of the surface). + - The min and max possible x-velocity when the movement passes through this waypoint. + - With a higher speed through a waypoint, we could reach further for the next waypoint, or we could be stuck overshooting the next waypoint. So it's useful to calculate the range of possible horizontal velocities through a waypoint. + - The actual x-velocity for movement through the waypoint is calculated later when calculating the cooresponding movement step. + - We typically try to use an x-velocity that will minimize speed through the waypoint, while still satisfying the horizontal step displacement and the waypoint's min/max limitations. +- Here's the sequence of events for waypoint calculations: + - Start by calculating origin and destination waypoints. + - For the origin waypoint, min, max, and actual x-velocity are all zero. + - For the destination waypoint, min and max are assigned according to how acceleration can be applied during the step (e.g., at the start or at the end of the interval). + - Then, during step calculation traversal, when a new intermediate waypoint is created, its min and max x-velocity are assigned according to both the min and max x-velocity of the following waypoint and the actual displacement and duration of the step from the new waypoint to the next waypoint. + - Intermediate waypoints are calculated with pre-order tree traversal. + - This poses a small problem: + - The calculation of a waypoint depends on the accuracy of the min/max x-velocity of it's next waypoint. + - However, the min/max x-velocity of the next waypoint could need to be updated if it in turn has a new next waypoint later on. + - Additionally, a new waypoint could be created later on that would become the new next waypoint instead of the old next waypoint. + - To ameliorate this problem, everytime a new waypoint is created, we update its immediate neighbor waypoints. + - These updates do not solve all cases, since we may in turn need to update the min/max x-velocities and movement sign for all other waypoints. And these updates could then result in the addition/removal of other intermediate waypoints. But we have found that these two updates are enough for most cases. If we detect that a neigbor waypoint would be invalidated during an update, we abandon the edge calculation, which could result in a false-negative result. + - Steps are calculated with in-order tree traversal (i.e., in the same order they'd be executed when moving from origin to destination). + +#### Fake waypoints + +- When calcuting steps to navigate around a collision with a ceiling or floor surface, sometimes one of the two possible waypoints is what we call "fake". +- A fake waypoint corresponds to the left side of the floor/ceiling surface when movement from the previous waypoint is rightward (or to the right side when movement is leftward). +- In this case, movement will need to go around both the floor/ceiling as well as its adjacent wall surface. +- The final movement trajectory should not end-up moving through the fake waypoint. +- The actual waypoint that the final movement should move through, is instead the "real" waypoint that cooresponds to the far edge of this adjacent wall surface. +- So, when we find a fake waypoint, we immediately replace it with its adjacent real waypoint. +- Example scenario: + - Origin is waypoint #0, Destination is waypoint #3 + - Assume we are jumping from a low-left platform to a high-right platform, and there is an intermediate block in the way. + - Our first step attempt hits the underside of the block, so we try waypoints on either side. + - After trying the left-hand waypoint (#1), we then hit the left side of the block. So we then try a top-side waypoint (#2). + - (Bottom-side fails the surface-already-encountered check). + - After going through this new left-side (right-wall), top-side waypoint (#2), we can successfully reach the destination. + - With the resulting scenario, we shouldn't actually move through both of the intermediate waypoints (#1 and #2). We should should instead skip the first intermediate waypoint (#1) and go straight from the origin to the second intermediate waypoint (#2). + +TODO: screenshot of example scenario + +#### Collision calculation madness + +**tl;dr**: Godot's collision-detection engine is very broken. We try to make it work for our +pathfinding, but there are still false negatives and rough edges. + +Here's a direct quote from a comment in Godot's underlying collision-calculation logic: + +> give me back regular physics engine logic
+> this is madness
+> and most people using this function will think
+> what it does is simpler than using physics
+> this took about a week to get right..
+> but is it right? who knows at this point..
+ +(https://github.com/godotengine/godot/blob/a7f49ac9a107820a62677ee3fb49d38982a25165/servers/physics_2d/space_2d_sw.cpp#L692) + +Some known limitations and rough edges include: +- When a [`KinematicBody2D`](https://docs.godotengine.org/en/stable/classes/class_kinematicbody2d.html) is sliding around a corner of another collidable, Godot can sometimes calculate the wrong results (oppositite direction) for `is_floor()`/`is_ceiling()`. +- Inconsistency between the behavior of the [`KinematicBody2D`](https://docs.godotengine.org/en/stable/classes/class_kinematicbody2d.html) and [`Physics2DDirectSpaceState`](https://docs.godotengine.org/en/stable/classes/class_physics2ddirectspacestate.html) collision APIs. + - We were originally using the Physics2DDirectSpaceState for most of our graph calculations. However, this API seems to be more broken than the KinematicBody2D API. Also, we're using the KinematicBody2D API at run time, so we see more consistent results by using the KinematicBody2D API at build time as well. + +### Navigator: Using the platform graph to move from A to B + +Once the platform graph has been parsed, finding and moving along a path through the graph is relatively straight-forward. The sequence of events looks like the following: + +- Given a target point to navigate towards and the player's current position. +- Find the closest point along the closest surface to the target point. +- Use A* search to find a path through the graph from the origin to the destination. + - We can use distance or duration as the edge weights. +- Execute playback of the instruction set for each edge of the path, in sequence. + +![Navigator finding a path to a destination](./docs/navigator-preselection.png) + +#### Dynamic edge optimization according to runtime approach + +At runtime, after finding a path through build-time-calculated edges, we try to optimize the jump-off points of the edges to better account for the direction that the player will be approaching the edge from. This produces more efficient and natural movement. The build-time-calculated edge state would only use surface end-points or closest points. We also take this opportunity to update start velocities to exactly match what is allowed from the ramp-up distance along the edge, rather than either the fixed zero or max-speed value used for the build-time-calculated edge state. + +#### Edge instructions playback + +When we create the edges, we represent the movement trajectories according to the sequence of instructions that would produce the trajectory. Each instruction is simply represented by an ID for the relevant input key, whether the key is being pressed or released, and the time. The player movement system can then handle these input key events in the same way as actual human-triggered input key events. + +#### Correcting for runtime vs buildtime trajectory discrepancies + +When executing edge instructions, the resulting run-time trajectory is usually slightly off from the expected trajectory that was pre-calculated when creating the edge. This variance is usually pretty minor, but, just in case, a given player can be configured to use the exact pre-calculated edge trajectory rather than the run-time version. + +Theoretically, this discrepancy shouldn't exist, and we should be able to eliminate it at some point. + +## Platform graph inspector + +As you might imagine, the calculations for these edges can get quite complicated. To make these calculations easier to understand and debug, we created a powerful platform graph inspector. This can be accessed from the utility menu (the gear icon in the top-right corner of the screen). + +![Platform graph inspector](./docs/platform-graph.png) + +The inspector is a tree-view widget with the following structure: + +``` + - Platform graph [player_name] + - Edges [#] + - [#] Edges calculated with increasing jump height + - JUMP_INTER_SURFACE_EDGEs [#] + - [(x,y), (x,y)] + - Profiler + - ... + - EDGE_VALID_WITH_INCREASING_JUMP_HEIGHT [1] + - 1: Movement is valid. + - ... + - ... + - ... + - [#] Edges calculated without increasing jump height + - ... + - [#] Edges calculated with one step + - ... + - Surfaces [#] + - FLOORs [#] + - [(x,y), (x,y)] + - _# valid outbound edges_ + - _Destination surfaces:_ + - FLOOR [(x,y), (x,y)] + - JUMP_INTER_SURFACE_EDGEs [#] + - [(x,y), (x,y)] + - Profiler + - ... + - EDGE_VALID_WITH_INCREASING_JUMP_HEIGHT [1] + - 1: Movement is valid. + - ... + - ... + - Failed edge calculations [#] + - REASON_FOR_FAILING [(x,y), (x,y)] + - Profiler + - ... + - REASON_FOR_FAILING [#] + - 1: Step result info + - 2: Step result info + - ... + - ... + - ... + - ... + - ... + - ... + - ... + - ... + - Profiler + - ... + - Global counts + - # total surfaces + - # total edges + - # JUMP_INTER_SURFACE_EDGEs + - ... +``` + +Each entry in this inspector tree is encoded with annotation information which will render debugging info over the level for the corresponding entity. Additionally, each entry contains a detailed description. These are both shown when selecting the entry. + +![Edge-step calculation debugging annotation](./docs/edge-step-calculation-debugging.png) + +## Annotators + +We include a large collection of annotators that are useful for visually debugging calculation of the platform graph. Some of these are rendered by selecting entries in the platform graph inspector and some of them can be toggled through checkboxes in the utility panel. + +## Movement parameters + +We support a large number of flags and parameters for adjusting various aspects of player/movement/platform-graph behavior. For a complete list of these params, see [movement_params.gd](./framework/platform_graph/edge/models/movement_params.gd). + +## Notable limitations + +- Our build-time graph calculations take a long time, especially for a level with lots of surfaces (such as a big level, or a level with a small cell size). +- There is slight discrepancy between discrete and continuous trajectories. The former is what we see from movement produced by the frame-by-frame application of gravity and input actions on the player. The latter is what we see from our precise numerical analysis of algebraic equations when pre-calculating the platform graph. We support a few different techniques for reconciling this: + - `MovementParams.syncs_player_velocity_to_edge_trajectory`: When this flag is enabled, the player's run-time _velocity_ will be forced to match the expected pre-calculated (continuous) velocity for the current frame in the currently executing platform graph edge. + - `MovementParams.syncs_player_position_to_edge_trajectory`: When this flag is enabled, the player's run-time _position_ will be forced to match the expected pre-calculated (continuous) velocity for the current frame in the currently executing platform graph edge. + - `MovementParams.retries_navigation_when_interrupted`: When this flag is enabled, the navigator will re-attempt navigation to the original destination from the current position whenever it detects that the player has hit an unexpected surface, which is what can happen when the run-time discrete trajectories don't match build-time continuous trajectories. +- When two surfaces face each other and are too close for thte player to fit between (plus a margin of a handful of extra pixels), our graph calculations can produce some false positives. +- Surfacer doesn't currently fully support surfaces that consist of one point. +- Our platform graph calculations produce false negatives for some types of jump edge scenarios: + - An jump edge that needs to displace the jump position in order to make it around an intermediate waypoint with enough horizontal velocity to then reach the destination. + - For example, if the player is jumping from the bottom of a set of stair-like surfaces, the jump position ideally wouldn't be as close as possible to the first rise of the first step (because they can't start accelerating horizontally until vertically clearing the top of the rise). Instead, if the player jumps from a slight offset from the rise, then they can pass over the rise with more speed, which lets them travel further during the jump. + - A single horizontal step that needs multiple different sideways-movement instructions (i.e., accelerating to both one side and then the other in the same jump): + - For example, backward acceleration in order to not overshoot the end position as well as forward acceleration to then have enough step-end x velocity in order to reach the following waypoint for the next step. +- Surfacer is opinionated. It requires that you structure your app using TileMaps, specific node groups, and by subclassing certain framework classes in order to create players. + - You need to define a set of input actions with the following names (via Project Settings > Input Map): + - jump + - move_up + - move_down + - move_left + - move_right + - dash + - zoom_in + - zoom_out + - pan_up + - pan_down + - pan_left + - pan_right + - face_left + - face_right + - grab_wall + - Your level collidable foreground tiles must be defined in a TileMap that belongs to the "surfaces" node group. + - The Surfacer framework isn't yet decoupled from the Squirrel Away demo app logic. + +## Future work + +For a list of planned future work items / TODOs, see [main.gd](./main.gd). + +Some high-level planned future features include: +- Add an option for saving/loading the platform graph instead of parsing it each time. +- Bypass the Godot collision system at runtime, and use only the pre-calculated expected edge trajectories from the platform graph. +- More intelligent squirral avoidance. +- Better game-play goal, with an event that happens when you catch the squirrel. +- Decouple the Surface framework logic from the Squirrel Away demo logic. +- Add Surfacer to the Godot Asset Library. +- Use an R-Tree for faster surface lookup. +- Support for fall-through floors and walls in the platform graph. +- Support for double jumps in the platform graph. +- Support for dashes in the platform graph. +- Support for surfaces that face each other and are too close for player to fit between. +- Support for surfaces of one point. +- Support an alternate, template-based edge calculation pattern, which should be able to offer faster build times and still have quick run times. +- Add networking. +- Procedural level generation. + +## Tests + +_**NOTE**: Sadly, the tests are not set up to automatically run on presubmit, so some of the tests are severely out-of-date and broken._ + +Surfacer uses the [Gut tool](https://github.com/bitwes/Gut) for writing and running unit tests. + +## Licenses + +- All code is published under the [MIT license](LICENSE). +- This project depends on various pieces of third-party code that are licensed separately. [Here is a list of these third-party licenses](./src/surfacer_third_party_licenses.gd). diff --git a/addons/surfacer/global.gd b/addons/surfacer/global.gd deleted file mode 100644 index 4819ef43..00000000 --- a/addons/surfacer/global.gd +++ /dev/null @@ -1,36 +0,0 @@ -extends Node - -const PLAYER_ACTIONS := {} - -const EDGE_MOVEMENTS := {} - -# Dictionary -var player_params := {} - -var canvas_layers: CanvasLayers -var current_level: SurfacerLevel -var current_player_for_clicks: Player -var element_annotator: ElementAnnotator -var platform_graph_inspector: PlatformGraphInspector -var legend: Legend -var selection_description: SelectionDescription -var utility_panel: UtilityPanel -var welcome_panel: WelcomePanel - -var is_level_ready := false - -func register_player_actions(player_action_classes: Array) -> void: - # Instantiate the various PlayerActions. - for player_action_class in player_action_classes: - PLAYER_ACTIONS[player_action_class.NAME] = player_action_class.new() - -func register_edge_movements(edge_movement_classes: Array) -> void: - # Instantiate the various EdgeMovements. - for edge_movement_class in edge_movement_classes: - EDGE_MOVEMENTS[edge_movement_class.NAME] = edge_movement_class.new() - -func register_player_params(player_param_classes: Array) -> void: - var player_params: PlayerParams - for param_class in player_param_classes: - player_params = PlayerParamsUtils.create_player_params(param_class) - self.player_params[player_params.name] = player_params diff --git a/addons/surfacer/gui/panels/credits_panel.gd b/addons/surfacer/gui/panels/credits_panel.gd deleted file mode 100644 index 363da88b..00000000 --- a/addons/surfacer/gui/panels/credits_panel.gd +++ /dev/null @@ -1,22 +0,0 @@ -extends WindowDialog -class_name CreditsPanel - -const LEVI_URL := "https://levi.dev" -const GODOT_URL := "https://godotengine.org" -const MIT_LICENSE_URL := "https://github.com/levilindsey/surfacer/blob/master/LICENSE" -const CC_LICENSE_URL := "https://creativecommons.org/publicdomain/zero/1.0/deed.en" - -func _on_third_party_licenses_button_pressed(): - $ThirdPartyLicensesPanel.popup() - -func _on_levi_link_pressed(): - OS.shell_open(LEVI_URL) - -func _on_godot_link_pressed(): - OS.shell_open(GODOT_URL) - -func _on_mit_license_link_pressed(): - OS.shell_open(MIT_LICENSE_URL) - -func _on_cc_license_link_pressed(): - OS.shell_open(CC_LICENSE_URL) diff --git a/addons/surfacer/gui/panels/credits_panel.tscn b/addons/surfacer/gui/panels/credits_panel.tscn deleted file mode 100644 index a0bbbbde..00000000 --- a/addons/surfacer/gui/panels/credits_panel.tscn +++ /dev/null @@ -1,294 +0,0 @@ -[gd_scene load_steps=9 format=2] - -[ext_resource path="res://assets/images/gui/logo.png" type="Texture" id=1] -[ext_resource path="res://assets/images/godot_logo_small.png" type="Texture" id=2] -[ext_resource path="res://addons/surfacer/gui/panels/credits_panel.gd" type="Script" id=3] -[ext_resource path="res://addons/surfacer/gui/panels/third_party_licenses_panel.tscn" type="PackedScene" id=4] -[ext_resource path="res://assets/main_theme.tres" type="Theme" id=5] -[ext_resource path="res://assets/fonts/main_font_s.tres" type="DynamicFont" id=6] -[ext_resource path="res://assets/fonts/main_font_xs.tres" type="DynamicFont" id=7] - - - - - - -[sub_resource type="StyleBoxFlat" id=1] -bg_color = Color( 1, 1, 1, 0.835294 ) - -[node name="CreditsPanel" type="WindowDialog"] -visible = true -anchor_left = 0.5 -anchor_top = 0.5 -anchor_right = 0.5 -anchor_bottom = 0.5 -margin_left = -150.0 -margin_top = -150.0 -margin_right = 150.0 -margin_bottom = 150.0 -theme = ExtResource( 5 ) -window_title = "Credits" -script = ExtResource( 3 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="HBoxContainer" type="HBoxContainer" parent="."] -margin_right = 300.0 -margin_bottom = 300.0 -rect_min_size = Vector2( 300, 300 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="PaddingLeft" type="Control" parent="HBoxContainer"] -margin_right = 29.0 -margin_bottom = 400.0 -size_flags_horizontal = 3 - -[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer"] -margin_left = 33.0 -margin_right = 266.0 -margin_bottom = 300.0 -size_flags_horizontal = 3 -size_flags_stretch_ratio = 8.0 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="PaddingTop" type="Control" parent="HBoxContainer/VBoxContainer"] -margin_right = 233.0 -margin_bottom = 18.0 -size_flags_vertical = 3 - -[node name="Control" type="Control" parent="HBoxContainer/VBoxContainer"] -margin_top = 22.0 -margin_right = 233.0 -margin_bottom = 40.0 -size_flags_vertical = 3 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Title" type="TextureRect" parent="HBoxContainer/VBoxContainer/Control"] -margin_left = 14.7018 -margin_top = -7.60669 -margin_right = 272.702 -margin_bottom = 36.3933 -rect_scale = Vector2( 0.8, 0.8 ) -texture = ExtResource( 1 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Control4" type="Control" parent="HBoxContainer/VBoxContainer"] -margin_top = 44.0 -margin_right = 233.0 -margin_bottom = 55.0 -size_flags_vertical = 3 -size_flags_stretch_ratio = 0.6 - -[node name="Control6" type="Control" parent="HBoxContainer/VBoxContainer"] -anchor_top = -0.00333333 -anchor_bottom = -0.00333333 -margin_top = 59.0 -margin_right = 233.0 -margin_bottom = 96.0 -size_flags_vertical = 3 -size_flags_stretch_ratio = 2.0 - -[node name="Label" type="LinkButton" parent="HBoxContainer/VBoxContainer/Control6"] -margin_left = 27.1006 -margin_top = 6.20584 -margin_right = 260.101 -margin_bottom = 29.2058 -text = "Created by Levi Lindsey." -underline = 2 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="URL" type="LinkButton" parent="HBoxContainer/VBoxContainer/Control6"] -margin_left = 59.8734 -margin_top = 27.3824 -margin_right = 172.873 -margin_bottom = 53.3824 -text = "https://levi.dev" -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Control5" type="Control" parent="HBoxContainer/VBoxContainer"] -margin_top = 100.0 -margin_right = 233.0 -margin_bottom = 118.0 -size_flags_vertical = 3 - -[node name="Control7" type="Control" parent="HBoxContainer/VBoxContainer"] -margin_top = 122.0 -margin_right = 233.0 -margin_bottom = 178.0 -size_flags_vertical = 3 -size_flags_stretch_ratio = 3.0 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Label" type="Label" parent="HBoxContainer/VBoxContainer/Control7"] -margin_left = -27.1892 -margin_top = 2.0 -margin_right = 260.811 -margin_bottom = 26.0 -custom_fonts/font = ExtResource( 7 ) -text = "Code published under the" -align = 1 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="LinkButton2" type="LinkButton" parent="HBoxContainer/VBoxContainer/Control7"] -margin_left = 88.0 -margin_top = 16.0 -margin_right = 156.0 -margin_bottom = 39.0 -custom_fonts/font = ExtResource( 7 ) -text = "MIT license." -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Label2" type="Label" parent="HBoxContainer/VBoxContainer/Control7"] -margin_left = -15.4917 -margin_top = 36.2832 -margin_right = 250.508 -margin_bottom = 59.2832 -custom_fonts/font = ExtResource( 7 ) -text = "Art and sound published under the" -align = 1 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="LinkButton" type="LinkButton" parent="HBoxContainer/VBoxContainer/Control7"] -margin_left = 55.7568 -margin_top = 50.1081 -margin_right = 200.757 -margin_bottom = 73.1081 -custom_fonts/font = ExtResource( 7 ) -text = "CC0 1.0 Universal license." -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Control8" type="Control" parent="HBoxContainer/VBoxContainer"] -margin_top = 182.0 -margin_right = 233.0 -margin_bottom = 193.0 -size_flags_vertical = 3 -size_flags_stretch_ratio = 0.6 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Control2" type="LinkButton" parent="HBoxContainer/VBoxContainer"] -anchor_top = -0.00666667 -anchor_bottom = -0.00666667 -margin_top = 197.0 -margin_right = 233.0 -margin_bottom = 243.0 -size_flags_vertical = 3 -size_flags_stretch_ratio = 2.5 - -[node name="Panel" type="Panel" parent="HBoxContainer/VBoxContainer/Control2"] -margin_left = 61.1648 -margin_top = 1.49451 -margin_right = 173.165 -margin_bottom = 45.4945 -size_flags_horizontal = 3 -size_flags_vertical = 3 -custom_styles/panel = SubResource( 1 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Control" type="Control" parent="HBoxContainer/VBoxContainer/Control2/Panel"] -margin_left = 7.0 -margin_top = 7.0 -margin_right = 91.0 -margin_bottom = 27.0 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="GodotLogo" type="TextureRect" parent="HBoxContainer/VBoxContainer/Control2/Panel/Control"] -margin_left = -1.94739 -margin_top = -1.83856 -margin_right = 724.053 -margin_bottom = 247.161 -rect_scale = Vector2( 0.14, 0.14 ) -texture = ExtResource( 2 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Label2" type="Label" parent="HBoxContainer/VBoxContainer/Control2"] -margin_left = 0.349182 -margin_top = 38.5009 -margin_right = 233.349 -margin_bottom = 64.5009 -size_flags_vertical = 1 -custom_fonts/font = ExtResource( 7 ) -text = "Created using Godot." -align = 1 -valign = 1 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Spacer" type="Control" parent="HBoxContainer/VBoxContainer"] -margin_top = 247.0 -margin_right = 233.0 -margin_bottom = 250.0 -size_flags_vertical = 3 -size_flags_stretch_ratio = 0.2 - -[node name="Control3" type="Control" parent="HBoxContainer/VBoxContainer"] -margin_top = 254.0 -margin_right = 233.0 -margin_bottom = 272.0 -size_flags_vertical = 3 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Button" type="Button" parent="HBoxContainer/VBoxContainer/Control3"] -margin_left = 37.408 -margin_top = 7.8689 -margin_right = 197.408 -margin_bottom = 31.8689 -custom_fonts/font = ExtResource( 6 ) -text = "Show third-party licenses" -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="PaddingBottom" type="Control" parent="HBoxContainer/VBoxContainer"] -margin_top = 276.0 -margin_right = 233.0 -margin_bottom = 300.0 -size_flags_vertical = 3 - -[node name="PaddingRight" type="Control" parent="HBoxContainer"] -margin_left = 270.0 -margin_right = 300.0 -margin_bottom = 300.0 -size_flags_horizontal = 3 - -[node name="ThirdPartyLicensesPanel" parent="." instance=ExtResource( 4 )] -visible = false -[connection signal="pressed" from="HBoxContainer/VBoxContainer/Control6/Label" to="." method="_on_levi_link_pressed"] -[connection signal="pressed" from="HBoxContainer/VBoxContainer/Control6/URL" to="." method="_on_levi_link_pressed"] -[connection signal="pressed" from="HBoxContainer/VBoxContainer/Control7/LinkButton2" to="." method="_on_mit_license_link_pressed"] -[connection signal="pressed" from="HBoxContainer/VBoxContainer/Control7/LinkButton" to="." method="_on_cc_license_link_pressed"] -[connection signal="pressed" from="HBoxContainer/VBoxContainer/Control2" to="." method="_on_godot_link_pressed"] -[connection signal="pressed" from="HBoxContainer/VBoxContainer/Control3/Button" to="." method="_on_third_party_licenses_button_pressed"] diff --git a/addons/surfacer/gui/panels/third_party_licenses_panel.tscn b/addons/surfacer/gui/panels/third_party_licenses_panel.tscn deleted file mode 100644 index d728e965..00000000 --- a/addons/surfacer/gui/panels/third_party_licenses_panel.tscn +++ /dev/null @@ -1,473 +0,0 @@ -[gd_scene load_steps=2 format=2] - -[ext_resource path="res://assets/main_theme.tres" type="Theme" id=1] - - - -[node name="ThirdPartyLicensesPanel" type="WindowDialog"] -visible = true -anchor_left = 0.5 -anchor_top = 0.5 -anchor_right = 0.5 -anchor_bottom = 0.5 -margin_left = -150.0 -margin_top = -150.0 -margin_right = 150.0 -margin_bottom = 150.0 -theme = ExtResource( 1 ) -window_title = "Credits" -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="HBoxContainer" type="HBoxContainer" parent="."] -margin_right = 302.0 -margin_bottom = 302.0 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="PaddingLeft" type="Control" parent="HBoxContainer"] -margin_bottom = 302.0 - -[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer"] -margin_left = 4.0 -margin_right = 298.0 -margin_bottom = 302.0 - -[node name="PaddingTop" type="Control" parent="HBoxContainer/VBoxContainer"] -margin_right = 294.0 - -[node name="ScrollContainer" type="ScrollContainer" parent="HBoxContainer/VBoxContainer"] -margin_top = 4.0 -margin_right = 294.0 -margin_bottom = 298.0 -rect_min_size = Vector2( 280, 294 ) -scroll_horizontal_enabled = false - -[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer/VBoxContainer/ScrollContainer"] -margin_right = 282.0 -margin_bottom = 22253.0 - -[node name="Label" type="Label" parent="HBoxContainer/VBoxContainer/ScrollContainer/VBoxContainer"] -margin_right = 282.0 -margin_bottom = 22253.0 -rect_min_size = Vector2( 282, 294 ) -text = "------------------------------------------------------------------------------- ---- Godot Engine - -The MIT License (MIT) -===================== - -Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. -Copyright (c) 2014-2020 Godot Engine contributors. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the \"Software\"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - --- Godot Engine -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- ---- Gut (Godot unit-testing framework) - -The MIT License (MIT) -===================== - -Copyright (c) 2018 Tom \"Butch\" Wesley - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the \"Software\"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- ---- Segment-polygon intersection calculation is based on the ---- \"parametric line-clipping\" approach described by Dan Sunday ---- - -Copyright 2001 softSurfer, 2012 Dan Sunday -This code may be freely used and modified for any purpose -providing that this copyright notice is included with it. -SoftSurfer makes no warranty for this code, and cannot be held -liable for any real or imagined damage resulting from its use. -Users of this code must verify correctness for their application. -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- ---- Priority queue implementation based on a version by Hamfist McMutton ---- - -License: CC0 1.0 Universal - -Statement of Purpose -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator and -subsequent owner(s) (each and all, an \"owner\") of an original work of -authorship and/or a database (each, a \"Work\"). - -Certain owners wish to permanently relinquish those rights to a Work for the -purpose of contributing to a commons of creative, cultural and scientific works -(\"Commons\") that the public can reliably and without fear of later claims of -infringement build upon, modify, incorporate in other works, reuse and -redistribute as freely as possible in any form whatsoever and for any purposes, -including without limitation commercial purposes. These owners may contribute -to the Commons to promote the ideal of a free culture and the further -production of creative, cultural and scientific works, or to gain reputation or -greater distribution for their Work in part through the use and efforts of -others. - -For these and/or other purposes and motivations, and without any expectation of -additional consideration or compensation, the person associating CC0 with a -Work (the \"Affirmer\"), to the extent that he or she is an owner of Copyright -and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and -publicly distribute the Work under its terms, with knowledge of his or her -Copyright and Related Rights in the Work and the meaning and intended legal -effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights (\"Copyright and -Related Rights\"). Copyright and Related Rights include, but are not limited to, -the following: - - i. the right to reproduce, adapt, distribute, perform, display, communicate, - and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); - iii. publicity and privacy rights pertaining to a person's image or likeness - depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data in - a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation thereof, - including any amended or successor version of such directive); and - vii. other similar, equivalent or corresponding rights throughout the world - based on applicable law or treaty, and any national implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention of, -applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and -unconditionally waives, abandons, and surrenders all of Affirmer's Copyright -and Related Rights and associated claims and causes of action, whether now -known or unknown (including existing as well as future claims and causes of -action), in the Work (i) in all territories worldwide, (ii) for the maximum -duration provided by applicable law or treaty (including future time -extensions), (iii) in any current or future medium and for any number of -copies, and (iv) for any purpose whatsoever, including without limitation -commercial, advertising or promotional purposes (the \"Waiver\"). Affirmer makes -the Waiver for the benefit of each member of the public at large and to the -detriment of Affirmer's heirs and successors, fully intending that such Waiver -shall not be subject to revocation, rescission, cancellation, termination, or -any other legal or equitable action to disrupt the quiet enjoyment of the Work -by the public as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason be -judged legally invalid or ineffective under applicable law, then the Waiver -shall be preserved to the maximum extent permitted taking into account -Affirmer's express Statement of Purpose. In addition, to the extent the Waiver -is so judged Affirmer hereby grants to each affected person a royalty-free, non -transferable, non sublicensable, non exclusive, irrevocable and unconditional -license to exercise Affirmer's Copyright and Related Rights in the Work (i) in -all territories worldwide, (ii) for the maximum duration provided by applicable -law or treaty (including future time extensions), (iii) in any current or -future medium and for any number of copies, and (iv) for any purpose -whatsoever, including without limitation commercial, advertising or promotional -purposes (the \"License\"). The License shall be deemed effective as of the date -CC0 was applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder of the -License, and in such case Affirmer hereby affirms that he or she will not (i) -exercise any of his or her remaining Copyright and Related Rights in the Work -or (ii) assert any associated claims and causes of action with respect to the -Work, in either case contrary to Affirmer's express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or warranties - of any kind concerning the Work, express, implied, statutory or otherwise, - including without limitation warranties of title, merchantability, fitness - for a particular purpose, non infringement, or the absence of latent or other - defects, accuracy, or the present or absence of errors, whether or not - discoverable, all to the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without limitation - any person's Copyright and Related Rights in the Work. Further, Affirmer - disclaims responsibility for obtaining any necessary consents, permissions or - other rights required for any use of the Work. - d. Affirmer understands and acknowledges that Creative Commons is not a party - to this document and has no duty or obligation with respect to this CC0 or - use of the Work. -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- ---- Open Sans font - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - \"License\" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - \"Licensor\" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - \"Legal Entity\" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - \"control\" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - \"You\" (or \"Your\") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - \"Source\" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - \"Object\" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - \"Work\" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - \"Derivative Works\" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - \"Contribution\" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, \"submitted\" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as \"Not a Contribution.\" - - \"Contributor\" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a \"NOTICE\" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an \"AS IS\" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- ---- FreeType (indirectly used through Godot) - -Portions of this software are copyright © The FreeType Project -(www.freetype.org). All rights reserved. -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- ---- ENet (indirectly used through Godot) - -Copyright (c) 2002-2016 Lee Salzman - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the “Software”), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- ---- MBedTLS (indirectly used through Godot) - -MBedTLS is Copyright (C) 2013-2019 ARM - -Licensed under the Apache License, Version 2.0 (the “License”); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the -specific language governing permissions and limitations under the License. -------------------------------------------------------------------------------- -" -autowrap = true - -[node name="PaddingBottom" type="Control" parent="HBoxContainer/VBoxContainer"] -margin_top = 302.0 -margin_right = 294.0 -margin_bottom = 302.0 - -[node name="PaddingRight" type="Control" parent="HBoxContainer"] -margin_left = 302.0 -margin_right = 302.0 -margin_bottom = 302.0 diff --git a/addons/surfacer/preloads.gd b/addons/surfacer/preloads.gd deleted file mode 100644 index cba41f7c..00000000 --- a/addons/surfacer/preloads.gd +++ /dev/null @@ -1,44 +0,0 @@ -extends Node - -const PLAYER_ACTION_CLASSES := [ - preload("res://addons/surfacer/player/action/action_handlers/air_dash_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/air_default_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/air_jump_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/all_default_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/cap_velocity_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/floor_dash_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/floor_default_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/floor_fall_through_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/floor_friction_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/floor_jump_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/floor_walk_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/match_expected_edge_trajectory_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/wall_climb_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/wall_dash_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/wall_default_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/wall_fall_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/wall_jump_action.gd"), - preload("res://addons/surfacer/player/action/action_handlers/wall_walk_action.gd"), -] - -const EDGE_MOVEMENT_CLASSES := [ - preload("res://addons/surfacer/platform_graph/edge/calculators/air_to_surface_calculator.gd"), - preload("res://addons/surfacer/platform_graph/edge/calculators/climb_down_wall_to_floor_calculator.gd"), - preload("res://addons/surfacer/platform_graph/edge/calculators/climb_over_wall_to_floor_calculator.gd"), - preload("res://addons/surfacer/platform_graph/edge/calculators/fall_from_floor_calculator.gd"), - preload("res://addons/surfacer/platform_graph/edge/calculators/fall_from_wall_calculator.gd"), - preload("res://addons/surfacer/platform_graph/edge/calculators/jump_inter_surface_calculator.gd"), - preload("res://addons/surfacer/platform_graph/edge/calculators/jump_from_surface_to_air_calculator.gd"), - preload("res://addons/surfacer/platform_graph/edge/calculators/walk_to_ascend_wall_from_floor_calculator.gd"), -] - -const PLAYER_PARAM_CLASSES := [ - preload("res://src/players/cat/cat_params.gd"), - preload("res://src/players/squirrel/squirrel_params.gd"), -# preload("res://test/data/test_player_params.gd"), -] - -func _init() -> void: - Global.register_player_actions(PLAYER_ACTION_CLASSES) - Global.register_edge_movements(EDGE_MOVEMENT_CLASSES) - Global.register_player_params(PLAYER_PARAM_CLASSES) diff --git a/addons/surfacer/annotators/annotation_elements/annotation_element.gd b/addons/surfacer/src/annotators/annotation_elements/annotation_element.gd similarity index 100% rename from addons/surfacer/annotators/annotation_elements/annotation_element.gd rename to addons/surfacer/src/annotators/annotation_elements/annotation_element.gd diff --git a/addons/surfacer/annotators/annotation_elements/annotation_element_defaults.gd b/addons/surfacer/src/annotators/annotation_elements/annotation_element_defaults.gd similarity index 100% rename from addons/surfacer/annotators/annotation_elements/annotation_element_defaults.gd rename to addons/surfacer/src/annotators/annotation_elements/annotation_element_defaults.gd diff --git a/addons/surfacer/annotators/annotation_elements/annotation_element_type.gd b/addons/surfacer/src/annotators/annotation_elements/annotation_element_type.gd similarity index 100% rename from addons/surfacer/annotators/annotation_elements/annotation_element_type.gd rename to addons/surfacer/src/annotators/annotation_elements/annotation_element_type.gd diff --git a/addons/surfacer/annotators/annotation_elements/destination_surface_annotation_element.gd b/addons/surfacer/src/annotators/annotation_elements/destination_surface_annotation_element.gd similarity index 100% rename from addons/surfacer/annotators/annotation_elements/destination_surface_annotation_element.gd rename to addons/surfacer/src/annotators/annotation_elements/destination_surface_annotation_element.gd diff --git a/addons/surfacer/annotators/annotation_elements/edge_annotation_element.gd b/addons/surfacer/src/annotators/annotation_elements/edge_annotation_element.gd similarity index 100% rename from addons/surfacer/annotators/annotation_elements/edge_annotation_element.gd rename to addons/surfacer/src/annotators/annotation_elements/edge_annotation_element.gd diff --git a/addons/surfacer/annotators/annotation_elements/edge_step_annotation_element.gd b/addons/surfacer/src/annotators/annotation_elements/edge_step_annotation_element.gd similarity index 98% rename from addons/surfacer/annotators/annotation_elements/edge_step_annotation_element.gd rename to addons/surfacer/src/annotators/annotation_elements/edge_step_annotation_element.gd index 02b8b2b4..34f67430 100644 --- a/addons/surfacer/annotators/annotation_elements/edge_step_annotation_element.gd +++ b/addons/surfacer/src/annotators/annotation_elements/edge_step_annotation_element.gd @@ -1,8 +1,6 @@ extends AnnotationElement class_name EdgeStepAnnotationElement -const MAIN_FONT_NORMAL: Font = preload("res://assets/fonts/main_font_normal.tres") - const TYPE := AnnotationElementType.EDGE_STEP var step_result_metadata: EdgeStepCalcResultMetadata @@ -79,11 +77,11 @@ func _calculate_color(renders_faintly: bool) -> Color: func _create_labels() -> void: step_label = Label.new() - step_label.add_font_override("font", MAIN_FONT_NORMAL) + step_label.add_font_override("font", ScaffoldConfig.main_font_m) previous_out_of_reach_waypoint_label = Label.new() previous_out_of_reach_waypoint_label \ - .add_font_override("font", MAIN_FONT_NORMAL) + .add_font_override("font", ScaffoldConfig.main_font_m) func draw(canvas: CanvasItem) -> void: _attach_labels(canvas) diff --git a/addons/surfacer/annotators/annotation_elements/failed_edge_attempt_annotation_element.gd b/addons/surfacer/src/annotators/annotation_elements/failed_edge_attempt_annotation_element.gd similarity index 100% rename from addons/surfacer/annotators/annotation_elements/failed_edge_attempt_annotation_element.gd rename to addons/surfacer/src/annotators/annotation_elements/failed_edge_attempt_annotation_element.gd diff --git a/addons/surfacer/annotators/annotation_elements/fall_range_with_jump_distance_annotation_element.gd b/addons/surfacer/src/annotators/annotation_elements/fall_range_with_jump_distance_annotation_element.gd similarity index 100% rename from addons/surfacer/annotators/annotation_elements/fall_range_with_jump_distance_annotation_element.gd rename to addons/surfacer/src/annotators/annotation_elements/fall_range_with_jump_distance_annotation_element.gd diff --git a/addons/surfacer/annotators/annotation_elements/fall_range_without_jump_distance_annotation_element.gd b/addons/surfacer/src/annotators/annotation_elements/fall_range_without_jump_distance_annotation_element.gd similarity index 100% rename from addons/surfacer/annotators/annotation_elements/fall_range_without_jump_distance_annotation_element.gd rename to addons/surfacer/src/annotators/annotation_elements/fall_range_without_jump_distance_annotation_element.gd diff --git a/addons/surfacer/annotators/annotation_elements/jump_land_positions_annotation_element.gd b/addons/surfacer/src/annotators/annotation_elements/jump_land_positions_annotation_element.gd similarity index 100% rename from addons/surfacer/annotators/annotation_elements/jump_land_positions_annotation_element.gd rename to addons/surfacer/src/annotators/annotation_elements/jump_land_positions_annotation_element.gd diff --git a/addons/surfacer/annotators/annotation_elements/origin_surface_annotation_element.gd b/addons/surfacer/src/annotators/annotation_elements/origin_surface_annotation_element.gd similarity index 100% rename from addons/surfacer/annotators/annotation_elements/origin_surface_annotation_element.gd rename to addons/surfacer/src/annotators/annotation_elements/origin_surface_annotation_element.gd diff --git a/addons/surfacer/annotators/annotation_elements/polyline_annotation_element.gd b/addons/surfacer/src/annotators/annotation_elements/polyline_annotation_element.gd similarity index 100% rename from addons/surfacer/annotators/annotation_elements/polyline_annotation_element.gd rename to addons/surfacer/src/annotators/annotation_elements/polyline_annotation_element.gd diff --git a/addons/surfacer/annotators/annotation_elements/surface_annotation_element.gd b/addons/surfacer/src/annotators/annotation_elements/surface_annotation_element.gd similarity index 100% rename from addons/surfacer/annotators/annotation_elements/surface_annotation_element.gd rename to addons/surfacer/src/annotators/annotation_elements/surface_annotation_element.gd diff --git a/addons/surfacer/annotators/annotator_type.gd b/addons/surfacer/src/annotators/annotator_type.gd similarity index 100% rename from addons/surfacer/annotators/annotator_type.gd rename to addons/surfacer/src/annotators/annotator_type.gd diff --git a/addons/surfacer/annotators/annotators.gd b/addons/surfacer/src/annotators/annotators.gd similarity index 86% rename from addons/surfacer/annotators/annotators.gd rename to addons/surfacer/src/annotators/annotators.gd index b33a67ae..a1d7c0ce 100644 --- a/addons/surfacer/annotators/annotators.gd +++ b/addons/surfacer/src/annotators/annotators.gd @@ -38,15 +38,20 @@ var element_annotator: ElementAnnotator var _annotator_enablement := {} +var annotation_layer: CanvasLayer +var ruler_layer: CanvasLayer + +func _init() -> void: + annotation_layer = ScaffoldConfig.canvas_layers.layers.annotation + func _enter_tree() -> void: - ScaffoldConfig.canvas_layers.create_layer( \ + ruler_layer = ScaffoldConfig.canvas_layers.create_layer( \ "ruler", \ - ScaffoldConfig.canvas_layers.layers.annotation.layer + 50, \ + annotation_layer.layer + 50, \ Node.PAUSE_MODE_STOP) element_annotator = ElementAnnotator.new() - ScaffoldConfig.canvas_layers.layers.annotation.add_child(element_annotator) - Global.element_annotator = element_annotator + annotation_layer.add_child(element_annotator) for annotator_type in _DEFAULT_ENABLEMENT: set_annotator_enabled( \ @@ -116,27 +121,27 @@ func _create_annotator(annotator_type: int) -> void: ruler_annotator = RulerAnnotator.new() ruler_layer.add_child(ruler_annotator) AnnotatorType.GRID_INDICES: - if Global.current_level != null and \ - Global.current_level.surface_parser != null: + if ScaffoldConfig.level != null and \ + ScaffoldConfig.level.surface_parser != null: grid_indices_annotator = GridIndicesAnnotator.new( \ - Global.current_level.surface_parser) + ScaffoldConfig.level.surface_parser) annotation_layer.add_child(grid_indices_annotator) AnnotatorType.CLICK: click_annotator = ClickAnnotator.new() annotation_layer.add_child(click_annotator) AnnotatorType.SURFACE_SELECTION: - if Global.current_player_for_clicks != null: + if SurfacerConfig.current_player_for_clicks != null: surface_selection_annotator = \ SurfaceSelectionAnnotator.new( \ - Global.current_player_for_clicks) + SurfacerConfig.current_player_for_clicks) annotation_layer.add_child(surface_selection_annotator) surface_preselection_annotator = \ SurfacePreselectionAnnotator.new( \ - Global.current_player_for_clicks) + SurfacerConfig.current_player_for_clicks) annotation_layer.add_child(surface_preselection_annotator) AnnotatorType.LEVEL: - if Global.current_level != null: - Global.current_level.set_level_visibility(true) + if ScaffoldConfig.level != null: + ScaffoldConfig.level.set_level_visibility(true) _: ScaffoldUtils.static_error() @@ -167,7 +172,7 @@ func _destroy_annotator(annotator_type: int) -> void: surface_preselection_annotator.queue_free() surface_preselection_annotator = null AnnotatorType.LEVEL: - if Global.current_level != null: - Global.current_level.set_level_visibility(false) + if ScaffoldConfig.level != null: + ScaffoldConfig.level.set_level_visibility(false) _: ScaffoldUtils.static_error() diff --git a/addons/surfacer/annotators/click_annotator.gd b/addons/surfacer/src/annotators/click_annotator.gd similarity index 97% rename from addons/surfacer/annotators/click_annotator.gd rename to addons/surfacer/src/annotators/click_annotator.gd index 998fc468..f80e6c7f 100644 --- a/addons/surfacer/annotators/click_annotator.gd +++ b/addons/surfacer/src/annotators/click_annotator.gd @@ -26,7 +26,7 @@ func _unhandled_input(event: InputEvent) -> void: if event is InputEventMouseButton and \ event.button_index == BUTTON_LEFT and \ !event.pressed: - position = Global.current_level.get_global_mouse_position() + position = ScaffoldConfig.level.get_global_mouse_position() elif event is InputEventScreenTouch and \ !event.pressed: diff --git a/addons/surfacer/annotators/color_params/color_params.gd b/addons/surfacer/src/annotators/color_params/color_params.gd similarity index 100% rename from addons/surfacer/annotators/color_params/color_params.gd rename to addons/surfacer/src/annotators/color_params/color_params.gd diff --git a/addons/surfacer/annotators/color_params/color_params_factory.gd b/addons/surfacer/src/annotators/color_params/color_params_factory.gd similarity index 100% rename from addons/surfacer/annotators/color_params/color_params_factory.gd rename to addons/surfacer/src/annotators/color_params/color_params_factory.gd diff --git a/addons/surfacer/annotators/color_params/color_params_type.gd b/addons/surfacer/src/annotators/color_params/color_params_type.gd similarity index 100% rename from addons/surfacer/annotators/color_params/color_params_type.gd rename to addons/surfacer/src/annotators/color_params/color_params_type.gd diff --git a/addons/surfacer/annotators/color_params/hsv_color_params.gd b/addons/surfacer/src/annotators/color_params/hsv_color_params.gd similarity index 100% rename from addons/surfacer/annotators/color_params/hsv_color_params.gd rename to addons/surfacer/src/annotators/color_params/hsv_color_params.gd diff --git a/addons/surfacer/annotators/color_params/hsv_range_color_params.gd b/addons/surfacer/src/annotators/color_params/hsv_range_color_params.gd similarity index 100% rename from addons/surfacer/annotators/color_params/hsv_range_color_params.gd rename to addons/surfacer/src/annotators/color_params/hsv_range_color_params.gd diff --git a/addons/surfacer/annotators/element_annotator.gd b/addons/surfacer/src/annotators/element_annotator.gd similarity index 83% rename from addons/surfacer/annotators/element_annotator.gd rename to addons/surfacer/src/annotators/element_annotator.gd index 07e205c3..bb4e7b82 100644 --- a/addons/surfacer/annotators/element_annotator.gd +++ b/addons/surfacer/src/annotators/element_annotator.gd @@ -4,11 +4,6 @@ class_name ElementAnnotator # Dictionary var _elements_set := {} -var legend: Legend - -func _ready() -> void: - legend = $"/root/Global".legend - func add(element: AnnotationElement) -> void: _elements_set[element] = element update() @@ -44,6 +39,7 @@ func _draw() -> void: for legend_item in element.get_legend_items(): legend_items[legend_item.type] = legend_item - legend.clear() - for legend_item_type in legend_items: - legend.add(legend_items[legend_item_type]) + if is_instance_valid(SurfacerConfig.legend): + SurfacerConfig.legend.clear() + for legend_item_type in legend_items: + SurfacerConfig.legend.add(legend_items[legend_item_type]) diff --git a/addons/surfacer/annotators/grid_indices_annotator.gd b/addons/surfacer/src/annotators/grid_indices_annotator.gd similarity index 94% rename from addons/surfacer/annotators/grid_indices_annotator.gd rename to addons/surfacer/src/annotators/grid_indices_annotator.gd index 7205e3f1..4520068a 100644 --- a/addons/surfacer/annotators/grid_indices_annotator.gd +++ b/addons/surfacer/src/annotators/grid_indices_annotator.gd @@ -1,8 +1,6 @@ extends Node2D class_name GridIndicesAnnotator -const MAIN_FONT_XS: Font = preload("res://assets/fonts/main_font_xs.tres") - var TILE_INDICES_COLOR := Colors.opacify(Colors.WHITE, Colors.ALPHA_FAINT) var surface_parser: SurfaceParser @@ -48,7 +46,7 @@ func _draw_tile_indices(only_render_used_indices := false) -> void: position, \ tile_map) draw_string( \ - MAIN_FONT_XS, \ + ScaffoldConfig.main_font_xs, \ cell_center, \ str(tile_map_index), \ color) diff --git a/addons/surfacer/annotators/navigator_annotator.gd b/addons/surfacer/src/annotators/navigator_annotator.gd similarity index 100% rename from addons/surfacer/annotators/navigator_annotator.gd rename to addons/surfacer/src/annotators/navigator_annotator.gd diff --git a/addons/surfacer/annotators/player_annotator.gd b/addons/surfacer/src/annotators/player_annotator.gd similarity index 100% rename from addons/surfacer/annotators/player_annotator.gd rename to addons/surfacer/src/annotators/player_annotator.gd diff --git a/addons/surfacer/annotators/player_position_annotator.gd b/addons/surfacer/src/annotators/player_position_annotator.gd similarity index 100% rename from addons/surfacer/annotators/player_position_annotator.gd rename to addons/surfacer/src/annotators/player_position_annotator.gd diff --git a/addons/surfacer/annotators/player_recent_movement_annotator.gd b/addons/surfacer/src/annotators/player_recent_movement_annotator.gd similarity index 100% rename from addons/surfacer/annotators/player_recent_movement_annotator.gd rename to addons/surfacer/src/annotators/player_recent_movement_annotator.gd diff --git a/addons/surfacer/annotators/player_surface_annotator.gd b/addons/surfacer/src/annotators/player_surface_annotator.gd similarity index 100% rename from addons/surfacer/annotators/player_surface_annotator.gd rename to addons/surfacer/src/annotators/player_surface_annotator.gd diff --git a/addons/surfacer/annotators/player_tile_annotator.gd b/addons/surfacer/src/annotators/player_tile_annotator.gd similarity index 100% rename from addons/surfacer/annotators/player_tile_annotator.gd rename to addons/surfacer/src/annotators/player_tile_annotator.gd diff --git a/addons/surfacer/annotators/ruler_annotator.gd b/addons/surfacer/src/annotators/ruler_annotator.gd similarity index 96% rename from addons/surfacer/annotators/ruler_annotator.gd rename to addons/surfacer/src/annotators/ruler_annotator.gd index 6bcad54c..c3b10d80 100644 --- a/addons/surfacer/annotators/ruler_annotator.gd +++ b/addons/surfacer/src/annotators/ruler_annotator.gd @@ -1,8 +1,6 @@ extends Node2D class_name RulerAnnotator -const MAIN_FONT_XS: Font = preload("res://assets/fonts/main_font_xs.tres") - const GRID_SPACING := 64.0 const LINE_WIDTH := 1.0 @@ -72,7 +70,7 @@ func _draw() -> void: ScaffoldConfig.camera_controller.zoom)) text = "0" if text == "-0" else text draw_string( \ - MAIN_FONT_XS, \ + ScaffoldConfig.main_font_xs, \ Vector2(start_position.x + 2, 14), \ text, \ TEXT_COLOR) @@ -93,7 +91,7 @@ func _draw() -> void: ScaffoldConfig.camera_controller.zoom)) text = "0" if text == "-0" else text draw_string( \ - MAIN_FONT_XS, \ + ScaffoldConfig.main_font_xs, \ Vector2(2, start_position.y + 14), \ text, \ TEXT_COLOR) diff --git a/addons/surfacer/annotators/surface_preselection_annotator.gd b/addons/surfacer/src/annotators/surface_preselection_annotator.gd similarity index 99% rename from addons/surfacer/annotators/surface_preselection_annotator.gd rename to addons/surfacer/src/annotators/surface_preselection_annotator.gd index 333d0ae1..804a006b 100644 --- a/addons/surfacer/annotators/surface_preselection_annotator.gd +++ b/addons/surfacer/src/annotators/surface_preselection_annotator.gd @@ -16,7 +16,7 @@ var INVALID_POSITION_INDICATOR_COLOR: Color = \ const PRESELECTION_MIN_OPACITY := 0.5 const PRESELECTION_MAX_OPACITY := 1.0 const PRESELECTION_DURATION_SEC := 0.6 -const PRESELECTION_SURFACE_DEPTH := DrawUtils.SURFACE_DEPTH * 4.0 +var PRESELECTION_SURFACE_DEPTH: float = DrawUtils.SURFACE_DEPTH * 4.0 const PRESELECTION_SURFACE_OUTWARD_OFFSET := 64.0 const PRESELECTION_SURFACE_LENGTH_PADDING := 64.0 const PRESELECTION_POSITION_INDICATOR_LENGTH := 128.0 diff --git a/addons/surfacer/annotators/surface_selection_annotator.gd b/addons/surfacer/src/annotators/surface_selection_annotator.gd similarity index 100% rename from addons/surfacer/annotators/surface_selection_annotator.gd rename to addons/surfacer/src/annotators/surface_selection_annotator.gd diff --git a/addons/surfacer/gui/legend/legend.gd b/addons/surfacer/src/gui/legend/legend.gd similarity index 100% rename from addons/surfacer/gui/legend/legend.gd rename to addons/surfacer/src/gui/legend/legend.gd diff --git a/addons/surfacer/gui/legend/legend.tscn b/addons/surfacer/src/gui/legend/legend.tscn similarity index 80% rename from addons/surfacer/gui/legend/legend.tscn rename to addons/surfacer/src/gui/legend/legend.tscn index 8ea794a5..d4388737 100644 --- a/addons/surfacer/gui/legend/legend.tscn +++ b/addons/surfacer/src/gui/legend/legend.tscn @@ -1,8 +1,10 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/surfacer/gui/legend/legend.gd" type="Script" id=1] +[ext_resource path="res://addons/surfacer/src/gui/legend/legend.gd" type="Script" id=1] [ext_resource path="res://assets/main_theme.tres" type="Theme" id=2] -[ext_resource path="res://assets/fonts/main_font_xs_italic.tres" type="DynamicFont" id=3] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_xs_italic.tres" type="DynamicFont" id=3] + + diff --git a/addons/surfacer/gui/legend/legend_items/continuous_edge_trajectory_legend_item.gd b/addons/surfacer/src/gui/legend/legend_items/continuous_edge_trajectory_legend_item.gd similarity index 100% rename from addons/surfacer/gui/legend/legend_items/continuous_edge_trajectory_legend_item.gd rename to addons/surfacer/src/gui/legend/legend_items/continuous_edge_trajectory_legend_item.gd diff --git a/addons/surfacer/gui/legend/legend_items/destination_legend_item.gd b/addons/surfacer/src/gui/legend/legend_items/destination_legend_item.gd similarity index 87% rename from addons/surfacer/gui/legend/legend_items/destination_legend_item.gd rename to addons/surfacer/src/gui/legend/legend_items/destination_legend_item.gd index d9fec8e1..a84061bf 100644 --- a/addons/surfacer/gui/legend/legend_items/destination_legend_item.gd +++ b/addons/surfacer/src/gui/legend/legend_items/destination_legend_item.gd @@ -15,8 +15,8 @@ func _init().( \ func _draw_shape( \ center: Vector2, \ size: Vector2) -> void: - var cone_length := DrawUtils.EDGE_END_CONE_LENGTH * SCALE - var radius := DrawUtils.EDGE_END_RADIUS * SCALE + var cone_length: float = DrawUtils.EDGE_END_CONE_LENGTH * SCALE + var radius: float = DrawUtils.EDGE_END_RADIUS * SCALE var length := cone_length + radius var cone_end_point := Vector2( \ center.x, \ diff --git a/addons/surfacer/gui/legend/legend_items/destination_surface_legend_item.gd b/addons/surfacer/src/gui/legend/legend_items/destination_surface_legend_item.gd similarity index 100% rename from addons/surfacer/gui/legend/legend_items/destination_surface_legend_item.gd rename to addons/surfacer/src/gui/legend/legend_items/destination_surface_legend_item.gd diff --git a/addons/surfacer/gui/legend/legend_items/discrete_edge_trajectory_legend_item.gd b/addons/surfacer/src/gui/legend/legend_items/discrete_edge_trajectory_legend_item.gd similarity index 100% rename from addons/surfacer/gui/legend/legend_items/discrete_edge_trajectory_legend_item.gd rename to addons/surfacer/src/gui/legend/legend_items/discrete_edge_trajectory_legend_item.gd diff --git a/addons/surfacer/gui/legend/legend_items/failed_edge_trajectory_legend_item.gd b/addons/surfacer/src/gui/legend/legend_items/failed_edge_trajectory_legend_item.gd similarity index 100% rename from addons/surfacer/gui/legend/legend_items/failed_edge_trajectory_legend_item.gd rename to addons/surfacer/src/gui/legend/legend_items/failed_edge_trajectory_legend_item.gd diff --git a/addons/surfacer/gui/legend/legend_items/fall_range_with_jump_distance_legend_item.gd b/addons/surfacer/src/gui/legend/legend_items/fall_range_with_jump_distance_legend_item.gd similarity index 100% rename from addons/surfacer/gui/legend/legend_items/fall_range_with_jump_distance_legend_item.gd rename to addons/surfacer/src/gui/legend/legend_items/fall_range_with_jump_distance_legend_item.gd diff --git a/addons/surfacer/gui/legend/legend_items/fall_range_without_jump_distance_legend_item.gd b/addons/surfacer/src/gui/legend/legend_items/fall_range_without_jump_distance_legend_item.gd similarity index 100% rename from addons/surfacer/gui/legend/legend_items/fall_range_without_jump_distance_legend_item.gd rename to addons/surfacer/src/gui/legend/legend_items/fall_range_without_jump_distance_legend_item.gd diff --git a/addons/surfacer/gui/legend/legend_items/hypothetical_edge_trajectory_legend_item.gd b/addons/surfacer/src/gui/legend/legend_items/hypothetical_edge_trajectory_legend_item.gd similarity index 100% rename from addons/surfacer/gui/legend/legend_items/hypothetical_edge_trajectory_legend_item.gd rename to addons/surfacer/src/gui/legend/legend_items/hypothetical_edge_trajectory_legend_item.gd diff --git a/addons/surfacer/gui/legend/legend_items/instruction_end_legend_item.gd b/addons/surfacer/src/gui/legend/legend_items/instruction_end_legend_item.gd similarity index 100% rename from addons/surfacer/gui/legend/legend_items/instruction_end_legend_item.gd rename to addons/surfacer/src/gui/legend/legend_items/instruction_end_legend_item.gd diff --git a/addons/surfacer/gui/legend/legend_items/instruction_start_legend_item.gd b/addons/surfacer/src/gui/legend/legend_items/instruction_start_legend_item.gd similarity index 100% rename from addons/surfacer/gui/legend/legend_items/instruction_start_legend_item.gd rename to addons/surfacer/src/gui/legend/legend_items/instruction_start_legend_item.gd diff --git a/addons/surfacer/gui/legend/legend_items/legend_item.gd b/addons/surfacer/src/gui/legend/legend_items/legend_item.gd similarity index 91% rename from addons/surfacer/gui/legend/legend_items/legend_item.gd rename to addons/surfacer/src/gui/legend/legend_items/legend_item.gd index bde470d5..5fc91c62 100644 --- a/addons/surfacer/gui/legend/legend_items/legend_item.gd +++ b/addons/surfacer/src/gui/legend/legend_items/legend_item.gd @@ -1,8 +1,6 @@ extends Control class_name LegendItem -const MAIN_FONT_XS: Font = preload("res://assets/fonts/main_font_xs.tres") - const HEIGHT := 32.0 const MARGIN_VERTICAL := 1.0 const MARGIN_HORIZONTAL := 4.0 @@ -34,7 +32,7 @@ func _enter_tree() -> void: label.rect_size.y = SHAPE_REGION_HEIGHT label.valign = Label.VALIGN_CENTER label.max_lines_visible = 2 - label.add_font_override("font", MAIN_FONT_XS) + label.add_font_override("font", ScaffoldConfig.main_font_xs) label.text = text add_child(label) diff --git a/addons/surfacer/gui/legend/legend_items/legend_item_type.gd b/addons/surfacer/src/gui/legend/legend_items/legend_item_type.gd similarity index 100% rename from addons/surfacer/gui/legend/legend_items/legend_item_type.gd rename to addons/surfacer/src/gui/legend/legend_items/legend_item_type.gd diff --git a/addons/surfacer/gui/legend/legend_items/origin_legend_item.gd b/addons/surfacer/src/gui/legend/legend_items/origin_legend_item.gd similarity index 91% rename from addons/surfacer/gui/legend/legend_items/origin_legend_item.gd rename to addons/surfacer/src/gui/legend/legend_items/origin_legend_item.gd index 6fa0e349..dd3acaf3 100644 --- a/addons/surfacer/gui/legend/legend_items/origin_legend_item.gd +++ b/addons/surfacer/src/gui/legend/legend_items/origin_legend_item.gd @@ -17,7 +17,7 @@ func _draw_shape( \ size: Vector2) -> void: var color: Color = \ AnnotationElementDefaults.DEFAULT_WAYPOINT_COLOR_PARAMS.get_color() - var radius := DrawUtils.EDGE_START_RADIUS * SCALE + var radius: float = DrawUtils.EDGE_START_RADIUS * SCALE DrawUtils.draw_origin_marker( \ self, \ center, \ diff --git a/addons/surfacer/gui/legend/legend_items/origin_surface_legend_item.gd b/addons/surfacer/src/gui/legend/legend_items/origin_surface_legend_item.gd similarity index 100% rename from addons/surfacer/gui/legend/legend_items/origin_surface_legend_item.gd rename to addons/surfacer/src/gui/legend/legend_items/origin_surface_legend_item.gd diff --git a/addons/surfacer/gui/legend/legend_items/polyline_legend_item.gd b/addons/surfacer/src/gui/legend/legend_items/polyline_legend_item.gd similarity index 100% rename from addons/surfacer/gui/legend/legend_items/polyline_legend_item.gd rename to addons/surfacer/src/gui/legend/legend_items/polyline_legend_item.gd diff --git a/addons/surfacer/gui/legend/legend_items/surface_legend_item.gd b/addons/surfacer/src/gui/legend/legend_items/surface_legend_item.gd similarity index 100% rename from addons/surfacer/gui/legend/legend_items/surface_legend_item.gd rename to addons/surfacer/src/gui/legend/legend_items/surface_legend_item.gd diff --git a/addons/surfacer/gui/legend/legend_items/valid_edge_trajectory_legend_item.gd b/addons/surfacer/src/gui/legend/legend_items/valid_edge_trajectory_legend_item.gd similarity index 100% rename from addons/surfacer/gui/legend/legend_items/valid_edge_trajectory_legend_item.gd rename to addons/surfacer/src/gui/legend/legend_items/valid_edge_trajectory_legend_item.gd diff --git a/addons/surfacer/gui/panels/utility_panel.gd b/addons/surfacer/src/gui/panels/utility_panel.gd similarity index 74% rename from addons/surfacer/gui/panels/utility_panel.gd rename to addons/surfacer/src/gui/panels/utility_panel.gd index 60011a86..7555d356 100644 --- a/addons/surfacer/gui/panels/utility_panel.gd +++ b/addons/surfacer/src/gui/panels/utility_panel.gd @@ -5,12 +5,12 @@ const PANEL_WIDTH := 240.0 const PANEL_HEIGHT := 500.0 const PANEL_MARGIN_RIGHT := 20.0 -const FOOTER_HEIGHT := 20.0 -const FOOTER_PADDING_TOTAL_HEIGHT := 8.0 +const HEADER_HEIGHT := 20.0 +const HEADER_PADDING_TOTAL_HEIGHT := 8.0 const SECTIONS_HEIGHT := \ PANEL_HEIGHT - \ - FOOTER_HEIGHT - \ - FOOTER_PADDING_TOTAL_HEIGHT + HEADER_HEIGHT - \ + HEADER_PADDING_TOTAL_HEIGHT const POSITION_Y_OPEN := 0.0 const POSITION_Y_CLOSED := -PANEL_HEIGHT @@ -35,20 +35,20 @@ func _ready() -> void: _toggle_open_tween = Tween.new() add_child(_toggle_open_tween) - Global.platform_graph_inspector = \ + SurfacerConfig.platform_graph_inspector = \ $VBoxContainer/Sections/InspectorContainer/PlatformGraphInspector - Global.legend = \ + SurfacerConfig.legend = \ $VBoxContainer/Sections/Legend - Global.selection_description = \ + SurfacerConfig.selection_description = \ $VBoxContainer/Sections/SelectionDescription - if (SurfacerConfig.UTILITY_PANEL_STARTS_OPEN or \ - SurfacerConfig.DEBUG_PARAMS.has("limit_parsing")) and \ - SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled and \ + if (SurfacerConfig.utility_panel_starts_open or \ + SurfacerConfig.debug_params.has("limit_parsing")) and \ + SurfacerConfig.debug_params.is_inspector_enabled and \ !OS.has_touchscreen_ui_hint(): set_is_open(true) - if !SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled: + if !SurfacerConfig.debug_params.is_inspector_enabled: $VBoxContainer/Sections.remove_child( \ $VBoxContainer/Sections/SelectionDescription) $VBoxContainer/Sections.remove_child( \ @@ -59,17 +59,21 @@ func _ready() -> void: $VBoxContainer/Sections/InspectorContainer) $VBoxContainer/Sections/Annotators/RulerGridCheckbox.pressed = \ - Global.canvas_layers.is_annotator_enabled(AnnotatorType.RULER) + SurfacerConfig.annotators.is_annotator_enabled(AnnotatorType.RULER) $VBoxContainer/Sections/Annotators/LevelCheckbox.pressed = \ - Global.canvas_layers.is_annotator_enabled(AnnotatorType.LEVEL) + SurfacerConfig.annotators.is_annotator_enabled(AnnotatorType.LEVEL) $VBoxContainer/Sections/Annotators/PlayerPositionCheckbox.pressed = \ - Global.canvas_layers.is_annotator_enabled( \ + SurfacerConfig.annotators.is_annotator_enabled( \ AnnotatorType.PLAYER_POSITION) $VBoxContainer/Sections/Annotators/PlayerTrajectoryCheckbox.pressed = \ - Global.canvas_layers.is_annotator_enabled( \ + SurfacerConfig.annotators.is_annotator_enabled( \ AnnotatorType.PLAYER_TRAJECTORY) $VBoxContainer/Sections/Annotators/LogEventsCheckbox.pressed = \ SurfacerConfig.is_logging_events + + # Tell the element annotator to populate the legend, now that it's + # available. + SurfacerConfig.annotators.element_annotator.update() func _initialize_dimensions() -> void: self.anchor_left = 1.0 @@ -87,8 +91,10 @@ func _initialize_dimensions() -> void: $VBoxContainer/Sections.rect_size.y = SECTIONS_HEIGHT $VBoxContainer/Sections.rect_min_size.y = SECTIONS_HEIGHT - $VBoxContainer/Footer.rect_size.y = FOOTER_HEIGHT - $VBoxContainer/Footer.rect_min_size.y = FOOTER_HEIGHT + $VBoxContainer/Header.rect_size.y = \ + HEADER_HEIGHT + HEADER_PADDING_TOTAL_HEIGHT + $VBoxContainer/Header.rect_min_size.y = \ + HEADER_HEIGHT + HEADER_PADDING_TOTAL_HEIGHT func _on_credits_button_pressed(): $CreditsPanel.popup() @@ -128,9 +134,9 @@ func _toggle_open() -> void: $VBoxContainer/GearContainer/GearButton.visible = !is_open if is_open: - Global.platform_graph_inspector.select_first_item() + SurfacerConfig.platform_graph_inspector.select_first_item() else: - Global.platform_graph_inspector.collapse() + SurfacerConfig.platform_graph_inspector.collapse() func _set_position_y(value: float) -> void: rect_position.y = value @@ -139,22 +145,22 @@ func _get_position_y() -> float: return rect_position.y func _on_ruler_grid_checkbox_toggled(pressed: bool) -> void: - Global.canvas_layers.set_annotator_enabled( \ + SurfacerConfig.annotators.set_annotator_enabled( \ AnnotatorType.RULER, \ pressed) func _on_level_checkbox_toggled(pressed: bool) -> void: - Global.canvas_layers.set_annotator_enabled( \ + SurfacerConfig.annotators.set_annotator_enabled( \ AnnotatorType.LEVEL, \ pressed) func _on_player_position_checkbox_toggled(pressed: bool) -> void: - Global.canvas_layers.set_annotator_enabled( \ + SurfacerConfig.annotators.set_annotator_enabled( \ AnnotatorType.PLAYER_POSITION, \ pressed) func _on_player_trajectory_checkbox_toggled(pressed: bool) -> void: - Global.canvas_layers.set_annotator_enabled( \ + SurfacerConfig.annotators.set_annotator_enabled( \ AnnotatorType.PLAYER_TRAJECTORY, \ pressed) diff --git a/addons/surfacer/gui/panels/utility_panel.tscn b/addons/surfacer/src/gui/panels/utility_panel.tscn similarity index 64% rename from addons/surfacer/gui/panels/utility_panel.tscn rename to addons/surfacer/src/gui/panels/utility_panel.tscn index 2f224473..9a174ffe 100644 --- a/addons/surfacer/gui/panels/utility_panel.tscn +++ b/addons/surfacer/src/gui/panels/utility_panel.tscn @@ -1,7 +1,6 @@ -[gd_scene load_steps=15 format=2] +[gd_scene load_steps=14 format=2] -[ext_resource path="res://addons/surfacer/gui/panels/utility_panel.gd" type="Script" id=1] -[ext_resource path="res://addons/surfacer/gui/panels/credits_panel.tscn" type="PackedScene" id=2] +[ext_resource path="res://addons/surfacer/src/gui/panels/utility_panel.gd" type="Script" id=1] [ext_resource path="res://assets/images/gui/gear-active.png" type="Texture" id=3] [ext_resource path="res://assets/images/gui/gear-hover.png" type="Texture" id=4] [ext_resource path="res://assets/images/gui/gear-normal.png" type="Texture" id=5] @@ -9,14 +8,10 @@ [ext_resource path="res://assets/images/gui/x-hover.png" type="Texture" id=7] [ext_resource path="res://assets/images/gui/x-active.png" type="Texture" id=8] [ext_resource path="res://assets/main_theme.tres" type="Theme" id=9] -[ext_resource path="res://addons/surfacer/gui/selection_description.tscn" type="PackedScene" id=10] -[ext_resource path="res://addons/surfacer/gui/legend/legend.tscn" type="PackedScene" id=11] +[ext_resource path="res://addons/surfacer/src/gui/selection_description.tscn" type="PackedScene" id=10] +[ext_resource path="res://addons/surfacer/src/gui/legend/legend.tscn" type="PackedScene" id=11] [ext_resource path="res://assets/header_theme.tres" type="Theme" id=12] -[ext_resource path="res://addons/surfacer/gui/platform_graph_inspector/platform_graph_inspector.tscn" type="PackedScene" id=13] - - - - +[ext_resource path="res://addons/surfacer/src/gui/platform_graph_inspector/platform_graph_inspector.tscn" type="PackedScene" id=13] [sub_resource type="StyleBoxFlat" id=1] bg_color = Color( 0.12549, 0.12549, 0.12549, 1 ) @@ -27,9 +22,10 @@ corner_radius_bottom_left = 5 anchor_left = 1.0 anchor_right = 1.0 margin_left = -260.0 -margin_right = -20.0 -margin_bottom = 328.0 -rect_min_size = Vector2( 240, 328 ) +margin_top = -1.0 +margin_right = -19.9999 +margin_bottom = 379.0 +rect_min_size = Vector2( 240, 380 ) theme = ExtResource( 9 ) custom_styles/panel = SubResource( 1 ) script = ExtResource( 1 ) @@ -45,9 +41,41 @@ __meta__ = { "_edit_use_anchors_": false } +[node name="Header" type="HBoxContainer" parent="VBoxContainer"] +margin_left = 215.0 +margin_right = 240.0 +margin_bottom = 27.0 +rect_min_size = Vector2( 0, 20 ) +size_flags_horizontal = 8 +custom_constants/separation = 0 + +[node name="Control" type="Control" parent="VBoxContainer/Header"] +margin_left = -1.0 +margin_top = -1.0 +margin_right = 24.0 +margin_bottom = 26.0 +rect_min_size = Vector2( 25, 27 ) +size_flags_horizontal = 4 +size_flags_vertical = 4 + +[node name=" XButton" type="TextureButton" parent="VBoxContainer/Header/Control"] +margin_top = 4.0 +margin_right = 80.0 +margin_bottom = 84.0 +rect_scale = Vector2( 0.3, 0.3 ) +size_flags_horizontal = 4 +size_flags_vertical = 4 +texture_normal = ExtResource( 6 ) +texture_pressed = ExtResource( 8 ) +texture_hover = ExtResource( 7 ) +__meta__ = { +"_edit_use_anchors_": false +} + [node name="Sections" type="VBoxContainer" parent="VBoxContainer"] +margin_top = 27.0 margin_right = 240.0 -margin_bottom = 300.0 +margin_bottom = 380.0 rect_min_size = Vector2( 0, 300 ) size_flags_vertical = 3 custom_constants/separation = 0 @@ -76,7 +104,7 @@ margin_bottom = 63.0 [node name="InspectorContainer" type="VBoxContainer" parent="VBoxContainer/Sections"] margin_top = 63.0 margin_right = 240.0 -margin_bottom = 231.0 +margin_bottom = 284.0 size_flags_vertical = 3 size_flags_stretch_ratio = 4.0 custom_constants/separation = 0 @@ -93,13 +121,13 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_top = 23.0 margin_right = 240.0 -margin_bottom = 168.0 +margin_bottom = 221.0 size_flags_vertical = 3 [node name="Annotators" type="GridContainer" parent="VBoxContainer/Sections"] -margin_top = 231.0 +margin_top = 284.0 margin_right = 240.0 -margin_bottom = 300.0 +margin_bottom = 353.0 size_flags_vertical = 3 custom_constants/vseparation = 0 custom_constants/hseparation = 0 @@ -151,92 +179,10 @@ __meta__ = { "_edit_use_anchors_": false } -[node name="FooterPaddingTop" type="Control" parent="VBoxContainer"] -margin_top = 300.0 -margin_right = 240.0 -margin_bottom = 304.0 -rect_min_size = Vector2( 0, 4 ) - -[node name="Footer" type="Control" parent="VBoxContainer"] -margin_top = 304.0 -margin_right = 240.0 -margin_bottom = 324.0 -rect_min_size = Vector2( 0, 20 ) - -[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/Footer"] -margin_right = 240.0 -margin_bottom = 80.0 -rect_min_size = Vector2( 240, 20 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Control3" type="Control" parent="VBoxContainer/Footer/HBoxContainer"] -size_flags_horizontal = 3 -size_flags_vertical = 0 -size_flags_stretch_ratio = 0.05 - -[node name="CreditsButton" type="Button" parent="VBoxContainer/Footer/HBoxContainer"] -margin_left = 4.0 -margin_right = 203.0 -margin_bottom = 23.0 -size_flags_horizontal = 3 -size_flags_vertical = 0 -size_flags_stretch_ratio = 10.0 -text = "Credits" -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Control" type="Control" parent="VBoxContainer/Footer/HBoxContainer"] -margin_left = 207.0 -margin_right = 208.0 -size_flags_horizontal = 3 -size_flags_vertical = 0 -size_flags_stretch_ratio = 0.1 - -[node name="Control2" type="Control" parent="VBoxContainer/Footer/HBoxContainer"] -margin_left = 212.0 -margin_right = 231.0 -size_flags_horizontal = 3 -size_flags_vertical = 0 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name=" XButton" type="TextureButton" parent="VBoxContainer/Footer/HBoxContainer/Control2"] -margin_left = 2.1936 -margin_top = -1.54059 -margin_right = 82.1936 -margin_bottom = 78.4594 -rect_scale = Vector2( 0.3, 0.3 ) -texture_normal = ExtResource( 6 ) -texture_pressed = ExtResource( 8 ) -texture_hover = ExtResource( 7 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Control4" type="Control" parent="VBoxContainer/Footer/HBoxContainer"] -margin_left = 235.0 -margin_right = 240.0 -size_flags_horizontal = 3 -size_flags_vertical = 0 -size_flags_stretch_ratio = 0.05 - -[node name="FooterPaddingBottom" type="Control" parent="VBoxContainer"] -margin_top = 324.0 -margin_right = 240.0 -margin_bottom = 328.0 -rect_min_size = Vector2( 0, 4 ) -__meta__ = { -"_edit_use_anchors_": false -} - [node name="GearContainer" type="Panel" parent="VBoxContainer"] -margin_top = 328.0 +margin_top = 380.0 margin_right = 240.0 -margin_bottom = 328.0 +margin_bottom = 380.0 [node name="GearButton" type="TextureButton" parent="VBoxContainer/GearContainer"] margin_left = 199.447 @@ -250,14 +196,10 @@ texture_hover = ExtResource( 4 ) __meta__ = { "_edit_use_anchors_": false } - -[node name="CreditsPanel" parent="." instance=ExtResource( 2 )] -visible = false +[connection signal="pressed" from="VBoxContainer/Header/Control/ XButton" to="." method="_toggle_open"] [connection signal="toggled" from="VBoxContainer/Sections/Annotators/RulerGridCheckbox" to="." method="_on_ruler_grid_checkbox_toggled"] [connection signal="toggled" from="VBoxContainer/Sections/Annotators/LevelCheckbox" to="." method="_on_level_checkbox_toggled"] [connection signal="toggled" from="VBoxContainer/Sections/Annotators/PlayerPositionCheckbox" to="." method="_on_player_position_checkbox_toggled"] [connection signal="toggled" from="VBoxContainer/Sections/Annotators/PlayerTrajectoryCheckbox" to="." method="_on_player_trajectory_checkbox_toggled"] [connection signal="toggled" from="VBoxContainer/Sections/Annotators/LogEventsCheckbox" to="." method="_on_log_events_checkbox_toggled"] -[connection signal="pressed" from="VBoxContainer/Footer/HBoxContainer/CreditsButton" to="." method="_on_credits_button_pressed"] -[connection signal="pressed" from="VBoxContainer/Footer/HBoxContainer/Control2/ XButton" to="." method="_toggle_open"] [connection signal="pressed" from="VBoxContainer/GearContainer/GearButton" to="." method="_toggle_open"] diff --git a/addons/surfacer/gui/panels/welcome_panel.gd b/addons/surfacer/src/gui/panels/welcome_panel.gd similarity index 91% rename from addons/surfacer/gui/panels/welcome_panel.gd rename to addons/surfacer/src/gui/panels/welcome_panel.gd index 5672ec89..f29c818f 100644 --- a/addons/surfacer/gui/panels/welcome_panel.gd +++ b/addons/surfacer/src/gui/panels/welcome_panel.gd @@ -13,7 +13,7 @@ const CONTROLS_LEGEND = [ func _ready() -> void: for mapping in CONTROLS_LEGEND: - if !SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled and \ + if !SurfacerConfig.debug_params.is_inspector_enabled and \ mapping[0] == "Inspect graph": continue diff --git a/addons/surfacer/gui/panels/welcome_panel.tscn b/addons/surfacer/src/gui/panels/welcome_panel.tscn similarity index 84% rename from addons/surfacer/gui/panels/welcome_panel.tscn rename to addons/surfacer/src/gui/panels/welcome_panel.tscn index 2d005d34..77f27cd8 100644 --- a/addons/surfacer/gui/panels/welcome_panel.tscn +++ b/addons/surfacer/src/gui/panels/welcome_panel.tscn @@ -1,14 +1,11 @@ [gd_scene load_steps=6 format=2] -[ext_resource path="res://addons/surfacer/gui/panels/welcome_panel.gd" type="Script" id=1] -[ext_resource path="res://assets/fonts/main_font_xs_italic.tres" type="DynamicFont" id=2] +[ext_resource path="res://addons/surfacer/src/gui/panels/welcome_panel.gd" type="Script" id=1] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_xs_italic.tres" type="DynamicFont" id=2] [ext_resource path="res://assets/main_theme.tres" type="Theme" id=3] -[ext_resource path="res://assets/fonts/main_font_s.tres" type="DynamicFont" id=4] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_s.tres" type="DynamicFont" id=4] [ext_resource path="res://assets/header_theme.tres" type="Theme" id=5] - - - [node name="PanelContainer" type="PanelContainer"] anchor_right = 1.0 anchor_bottom = 1.0 diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/description_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/description_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/description_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/description_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edge_attempt_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edge_attempt_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edge_attempt_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edge_attempt_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edge_calc_profiler_group_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edge_calc_profiler_group_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edge_calc_profiler_group_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edge_calc_profiler_group_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edge_calc_result_metadata_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edge_calc_result_metadata_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edge_calc_result_metadata_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edge_calc_result_metadata_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edge_step_calc_result_metadata_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edge_step_calc_result_metadata_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edge_step_calc_result_metadata_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edge_step_calc_result_metadata_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edge_step_calc_result_metadata_item_controller_factory.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edge_step_calc_result_metadata_item_controller_factory.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edge_step_calc_result_metadata_item_controller_factory.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edge_step_calc_result_metadata_item_controller_factory.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edge_type_in_edges_group_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edge_type_in_edges_group_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edge_type_in_edges_group_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edge_type_in_edges_group_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_filtered_by_result_type_group_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_filtered_by_result_type_group_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_filtered_by_result_type_group_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_filtered_by_result_type_group_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_group_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_group_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_group_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_group_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_with_increasing_jump_height_group_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_with_increasing_jump_height_group_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_with_increasing_jump_height_group_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_with_increasing_jump_height_group_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_with_one_step_group_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_with_one_step_group_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_with_one_step_group_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_with_one_step_group_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_without_increasing_jump_height_group_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_without_increasing_jump_height_group_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_without_increasing_jump_height_group_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_without_increasing_jump_height_group_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/inspector_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/inspector_item_controller.gd similarity index 97% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/inspector_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/inspector_item_controller.gd index bcc880fb..d79e02b4 100644 --- a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/inspector_item_controller.gd +++ b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/inspector_item_controller.gd @@ -64,19 +64,19 @@ func destroy() -> void: parent_item = null func on_item_selected() -> void: - if Global.utility_panel.is_open and \ + if SurfacerConfig.utility_panel.is_open and \ !tree.get_is_find_and_expand_in_progress(): print_msg("Inspector item selected: %s", to_string()) func on_item_expanded() -> void: _create_children_if_needed() - if Global.utility_panel.is_open and \ + if SurfacerConfig.utility_panel.is_open and \ !tree.get_is_find_and_expand_in_progress(): print_msg("Inspector item expanded: %s", to_string()) func on_item_collapsed() -> void: _destroy_children_if_needed() - if Global.utility_panel.is_open and \ + if SurfacerConfig.utility_panel.is_open and \ !tree.get_is_find_and_expand_in_progress() and \ get_has_children(): print_msg("Inspector item collapsed: %s", to_string()) diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/inspector_item_type.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/inspector_item_type.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/inspector_item_type.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/inspector_item_type.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/platform_graph_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/platform_graph_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/platform_graph_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/platform_graph_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/global_counts_group_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/global_counts_group_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/global_counts_group_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/global_counts_group_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_count_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_count_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_count_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_count_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_group_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_group_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_group_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_group_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_timing_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_timing_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_timing_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_timing_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/surface_parser_group_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/surface_parser_group_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/surface_parser_group_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/surface_parser_group_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/ceilings_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/ceilings_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/ceilings_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/ceilings_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/destination_surface_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/destination_surface_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/destination_surface_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/destination_surface_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/edge_type_in_surfaces_group_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/edge_type_in_surfaces_group_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/edge_type_in_surfaces_group_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/edge_type_in_surfaces_group_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/failed_edge_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/failed_edge_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/failed_edge_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/failed_edge_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/failed_edges_group_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/failed_edges_group_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/failed_edges_group_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/failed_edges_group_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/floors_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/floors_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/floors_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/floors_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/left_walls_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/left_walls_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/left_walls_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/left_walls_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/origin_surface_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/origin_surface_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/origin_surface_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/origin_surface_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/right_walls_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/right_walls_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/right_walls_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/right_walls_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/surfaces_group_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/surfaces_group_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/surfaces_group_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/surfaces_group_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/surfaces_of_side_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/surfaces_of_side_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/surfaces_of_side_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/surfaces_of_side_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/valid_edge_item_controller.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/valid_edge_item_controller.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/valid_edge_item_controller.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/valid_edge_item_controller.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/inspector_search_type.gd b/addons/surfacer/src/gui/platform_graph_inspector/inspector_search_type.gd similarity index 100% rename from addons/surfacer/gui/platform_graph_inspector/inspector_search_type.gd rename to addons/surfacer/src/gui/platform_graph_inspector/inspector_search_type.gd diff --git a/addons/surfacer/gui/platform_graph_inspector/platform_graph_inspector.gd b/addons/surfacer/src/gui/platform_graph_inspector/platform_graph_inspector.gd similarity index 93% rename from addons/surfacer/gui/platform_graph_inspector/platform_graph_inspector.gd rename to addons/surfacer/src/gui/platform_graph_inspector/platform_graph_inspector.gd index ffbc626a..fb582aee 100644 --- a/addons/surfacer/gui/platform_graph_inspector/platform_graph_inspector.gd +++ b/addons/surfacer/src/gui/platform_graph_inspector/platform_graph_inspector.gd @@ -89,16 +89,17 @@ func _init() -> void: "_on_tree_item_expansion_toggled") func _ready() -> void: - if !SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled: + if !SurfacerConfig.debug_params.is_inspector_enabled: return inspector_selector = PlatformGraphInspectorSelector.new(self) - Global.canvas_layers.annotation_layer.add_child(inspector_selector) + ScaffoldConfig.canvas_layers.layers.annotation \ + .add_child(inspector_selector) _populate() func _process(delta_sec: float) -> void: - if !SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled: + if !SurfacerConfig.debug_params.is_inspector_enabled: return var next_focused_control := get_focus_owner() @@ -130,7 +131,7 @@ func release_focus() -> void: .release_focus() func _populate() -> void: - if !SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled: + if !SurfacerConfig.debug_params.is_inspector_enabled: return _should_be_populated = true @@ -149,7 +150,7 @@ func _populate() -> void: call_deferred("_select_initial_item") func clear() -> void: - if !SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled: + if !SurfacerConfig.debug_params.is_inspector_enabled: return release_focus() @@ -158,7 +159,7 @@ func clear() -> void: .clear() func collapse() -> void: - if !SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled: + if !SurfacerConfig.debug_params.is_inspector_enabled: return for graph_item_controller in graph_item_controllers.values(): @@ -168,7 +169,7 @@ func collapse() -> void: _clear_selection() func set_graphs(graphs: Array) -> void: - if !SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled: + if !SurfacerConfig.debug_params.is_inspector_enabled: return self.graphs = graphs @@ -183,15 +184,15 @@ func select_first_item() -> void: graph_item_controllers.values().front().select() func _select_initial_item() -> void: - if !Global.utility_panel.is_open: + if !SurfacerConfig.utility_panel.is_open: # Don't auto-select anything if the panel isn't open. return - if !SurfacerConfig.DEBUG_PARAMS.has("limit_parsing") or \ - !SurfacerConfig.DEBUG_PARAMS.limit_parsing.has("player_name"): + if !SurfacerConfig.debug_params.has("limit_parsing") or \ + !SurfacerConfig.debug_params.limit_parsing.has("player_name"): select_first_item() else: - var limit_parsing: Dictionary = SurfacerConfig.DEBUG_PARAMS.limit_parsing + var limit_parsing: Dictionary = SurfacerConfig.debug_params.limit_parsing var player_name: String = limit_parsing.player_name if limit_parsing.has("edge") and \ @@ -313,13 +314,15 @@ func _on_tree_item_selected() -> void: var item := get_selected() var controller: InspectorItemController = item.get_metadata(0) - Global.element_annotator.erase_all(current_annotation_elements) + SurfacerConfig.annotators.element_annotator \ + .erase_all(current_annotation_elements) current_annotation_elements = controller.get_annotation_elements() - Global.element_annotator.add_all(current_annotation_elements) + SurfacerConfig.annotators.element_annotator \ + .add_all(current_annotation_elements) if !get_is_find_and_expand_in_progress(): - Global.selection_description.set_text(controller.get_description()) + SurfacerConfig.selection_description.set_text(controller.get_description()) controller.call_deferred("on_item_selected") @@ -340,7 +343,7 @@ func select_edge_or_surface( \ edge_type: int, \ graph: PlatformGraph) -> void: # Ensure that the utility panel is open. - Global.utility_panel.set_is_open(true) + SurfacerConfig.utility_panel.set_is_open(true) if start_position.surface == end_position.surface: _select_canonical_origin_surface_item_controller( \ @@ -492,9 +495,9 @@ func _on_find_and_expand_complete( \ InspectorSearchType.get_type_string(search_type)) if selection_failure_message != "": - Global.selection_description.set_text(selection_failure_message) + SurfacerConfig.selection_description.set_text(selection_failure_message) else: - Global.selection_description.set_text(controller.get_description()) + SurfacerConfig.selection_description.set_text(controller.get_description()) func get_is_find_and_expand_in_progress() -> bool: return _find_and_expand_controller_recursive_count > 0 @@ -528,7 +531,8 @@ func _clear_selection() -> void: item.deselect(0) # Remove the current annotations. - Global.element_annotator.erase_all(current_annotation_elements) + SurfacerConfig.annotators.element_annotator \ + .erase_all(current_annotation_elements) current_annotation_elements = [] static func _find_closest_jump_land_positions( \ @@ -557,8 +561,8 @@ func print_msg( \ message_template: String, \ message_args = null) -> void: if SurfacerConfig.is_logging_events and \ - Global.current_player_for_clicks != null and \ - Global.current_player_for_clicks.movement_params \ + SurfacerConfig.current_player_for_clicks != null and \ + SurfacerConfig.current_player_for_clicks.movement_params \ .logs_inspector_events: if message_args != null: print(message_template % message_args) diff --git a/addons/surfacer/gui/platform_graph_inspector/platform_graph_inspector.tscn b/addons/surfacer/src/gui/platform_graph_inspector/platform_graph_inspector.tscn similarity index 59% rename from addons/surfacer/gui/platform_graph_inspector/platform_graph_inspector.tscn rename to addons/surfacer/src/gui/platform_graph_inspector/platform_graph_inspector.tscn index 33147172..06e1ff21 100644 --- a/addons/surfacer/gui/platform_graph_inspector/platform_graph_inspector.tscn +++ b/addons/surfacer/src/gui/platform_graph_inspector/platform_graph_inspector.tscn @@ -1,8 +1,10 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/surfacer/gui/platform_graph_inspector/platform_graph_inspector.gd" type="Script" id=1] +[ext_resource path="res://addons/surfacer/src/gui/platform_graph_inspector/platform_graph_inspector.gd" type="Script" id=1] [ext_resource path="res://assets/main_theme.tres" type="Theme" id=2] -[ext_resource path="res://assets/fonts/main_font_s.tres" type="DynamicFont" id=3] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_s.tres" type="DynamicFont" id=3] + + diff --git a/addons/surfacer/gui/platform_graph_inspector/platform_graph_inspector_selector.gd b/addons/surfacer/src/gui/platform_graph_inspector/platform_graph_inspector_selector.gd similarity index 89% rename from addons/surfacer/gui/platform_graph_inspector/platform_graph_inspector_selector.gd rename to addons/surfacer/src/gui/platform_graph_inspector/platform_graph_inspector_selector.gd index be3c72bf..6fd5b353 100644 --- a/addons/surfacer/gui/platform_graph_inspector/platform_graph_inspector_selector.gd +++ b/addons/surfacer/src/gui/platform_graph_inspector/platform_graph_inspector_selector.gd @@ -41,11 +41,11 @@ func _unhandled_input(event: InputEvent) -> void: # The user is ctrl+clicking. var click_position: Vector2 = \ - Global.current_level.get_global_mouse_position() + ScaffoldConfig.level.get_global_mouse_position() var surface_position := \ SurfaceParser.find_closest_position_on_a_surface( \ click_position, \ - Global.current_player_for_clicks) + SurfacerConfig.current_player_for_clicks) if first_target == null: # Selecting the jump position. @@ -56,7 +56,7 @@ func _unhandled_input(event: InputEvent) -> void: possible_jump_land_positions = JumpLandPositionsUtils \ .calculate_jump_land_positions_for_surface_pair( \ - Global.current_player_for_clicks.movement_params, \ + SurfacerConfig.current_player_for_clicks.movement_params, \ first_target.surface, \ surface_position.surface) @@ -68,7 +68,7 @@ func _unhandled_input(event: InputEvent) -> void: first_target, \ surface_position, \ EdgeType.JUMP_INTER_SURFACE_EDGE, \ - Global.current_player_for_clicks.graph) + SurfacerConfig.current_player_for_clicks.graph) first_target = null elif event is InputEventKey and \ @@ -78,7 +78,8 @@ func _unhandled_input(event: InputEvent) -> void: first_target = null func _draw() -> void: - Global.element_annotator.erase_all(current_annotation_elements) + SurfacerConfig.annotators.element_annotator \ + .erase_all(current_annotation_elements) current_annotation_elements.clear() if first_target != null: @@ -109,7 +110,8 @@ func _draw_possible_jump_land_positions() -> void: element = JumpLandPositionsAnnotationElement.new(jump_land_positions) current_annotation_elements.push_back(element) - Global.element_annotator.add_all(current_annotation_elements) + SurfacerConfig.annotators.element_annotator \ + .add_all(current_annotation_elements) func clear() -> void: first_target = null diff --git a/addons/surfacer/gui/selection_description.gd b/addons/surfacer/src/gui/selection_description.gd similarity index 100% rename from addons/surfacer/gui/selection_description.gd rename to addons/surfacer/src/gui/selection_description.gd diff --git a/addons/surfacer/gui/selection_description.tscn b/addons/surfacer/src/gui/selection_description.tscn similarity index 75% rename from addons/surfacer/gui/selection_description.tscn rename to addons/surfacer/src/gui/selection_description.tscn index 8cf2b356..6aee95a7 100644 --- a/addons/surfacer/gui/selection_description.tscn +++ b/addons/surfacer/src/gui/selection_description.tscn @@ -1,8 +1,10 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/surfacer/gui/selection_description.gd" type="Script" id=1] +[ext_resource path="res://addons/surfacer/src/gui/selection_description.gd" type="Script" id=1] [ext_resource path="res://assets/main_theme.tres" type="Theme" id=2] -[ext_resource path="res://assets/fonts/main_font_xs.tres" type="DynamicFont" id=3] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_xs.tres" type="DynamicFont" id=3] + + diff --git a/addons/surfacer/input_wrapper.gd b/addons/surfacer/src/input_wrapper.gd similarity index 83% rename from addons/surfacer/input_wrapper.gd rename to addons/surfacer/src/input_wrapper.gd index 65c11736..a308dee4 100644 --- a/addons/surfacer/input_wrapper.gd +++ b/addons/surfacer/src/input_wrapper.gd @@ -21,5 +21,5 @@ func is_key_pressed(code: int) -> bool: Input.is_key_pressed(code) func is_focus_for_actions() -> bool: - return Global.platform_graph_inspector == null or \ - !Global.platform_graph_inspector.has_focus + return !is_instance_valid(SurfacerConfig.platform_graph_inspector) or \ + !SurfacerConfig.platform_graph_inspector.has_focus diff --git a/addons/surfacer/platform_graph/edge/calculators/air_to_surface_calculator.gd b/addons/surfacer/src/platform_graph/edge/calculators/air_to_surface_calculator.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/calculators/air_to_surface_calculator.gd rename to addons/surfacer/src/platform_graph/edge/calculators/air_to_surface_calculator.gd diff --git a/addons/surfacer/platform_graph/edge/calculators/climb_down_wall_to_floor_calculator.gd b/addons/surfacer/src/platform_graph/edge/calculators/climb_down_wall_to_floor_calculator.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/calculators/climb_down_wall_to_floor_calculator.gd rename to addons/surfacer/src/platform_graph/edge/calculators/climb_down_wall_to_floor_calculator.gd diff --git a/addons/surfacer/platform_graph/edge/calculators/climb_over_wall_to_floor_calculator.gd b/addons/surfacer/src/platform_graph/edge/calculators/climb_over_wall_to_floor_calculator.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/calculators/climb_over_wall_to_floor_calculator.gd rename to addons/surfacer/src/platform_graph/edge/calculators/climb_over_wall_to_floor_calculator.gd diff --git a/addons/surfacer/platform_graph/edge/calculators/edge_calculator.gd b/addons/surfacer/src/platform_graph/edge/calculators/edge_calculator.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/calculators/edge_calculator.gd rename to addons/surfacer/src/platform_graph/edge/calculators/edge_calculator.gd diff --git a/addons/surfacer/platform_graph/edge/calculators/fall_from_floor_calculator.gd b/addons/surfacer/src/platform_graph/edge/calculators/fall_from_floor_calculator.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/calculators/fall_from_floor_calculator.gd rename to addons/surfacer/src/platform_graph/edge/calculators/fall_from_floor_calculator.gd diff --git a/addons/surfacer/platform_graph/edge/calculators/fall_from_wall_calculator.gd b/addons/surfacer/src/platform_graph/edge/calculators/fall_from_wall_calculator.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/calculators/fall_from_wall_calculator.gd rename to addons/surfacer/src/platform_graph/edge/calculators/fall_from_wall_calculator.gd diff --git a/addons/surfacer/platform_graph/edge/calculators/jump_from_surface_to_air_calculator.gd b/addons/surfacer/src/platform_graph/edge/calculators/jump_from_surface_to_air_calculator.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/calculators/jump_from_surface_to_air_calculator.gd rename to addons/surfacer/src/platform_graph/edge/calculators/jump_from_surface_to_air_calculator.gd diff --git a/addons/surfacer/platform_graph/edge/calculators/jump_inter_surface_calculator.gd b/addons/surfacer/src/platform_graph/edge/calculators/jump_inter_surface_calculator.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/calculators/jump_inter_surface_calculator.gd rename to addons/surfacer/src/platform_graph/edge/calculators/jump_inter_surface_calculator.gd diff --git a/addons/surfacer/platform_graph/edge/calculators/walk_to_ascend_wall_from_floor_calculator.gd b/addons/surfacer/src/platform_graph/edge/calculators/walk_to_ascend_wall_from_floor_calculator.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/calculators/walk_to_ascend_wall_from_floor_calculator.gd rename to addons/surfacer/src/platform_graph/edge/calculators/walk_to_ascend_wall_from_floor_calculator.gd diff --git a/addons/surfacer/platform_graph/edge/edges/air_to_air_edge.gd b/addons/surfacer/src/platform_graph/edge/edges/air_to_air_edge.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/edges/air_to_air_edge.gd rename to addons/surfacer/src/platform_graph/edge/edges/air_to_air_edge.gd diff --git a/addons/surfacer/platform_graph/edge/edges/air_to_surface_edge.gd b/addons/surfacer/src/platform_graph/edge/edges/air_to_surface_edge.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/edges/air_to_surface_edge.gd rename to addons/surfacer/src/platform_graph/edge/edges/air_to_surface_edge.gd diff --git a/addons/surfacer/platform_graph/edge/edges/climb_down_wall_to_floor_edge.gd b/addons/surfacer/src/platform_graph/edge/edges/climb_down_wall_to_floor_edge.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/edges/climb_down_wall_to_floor_edge.gd rename to addons/surfacer/src/platform_graph/edge/edges/climb_down_wall_to_floor_edge.gd diff --git a/addons/surfacer/platform_graph/edge/edges/climb_over_wall_to_floor_edge.gd b/addons/surfacer/src/platform_graph/edge/edges/climb_over_wall_to_floor_edge.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/edges/climb_over_wall_to_floor_edge.gd rename to addons/surfacer/src/platform_graph/edge/edges/climb_over_wall_to_floor_edge.gd diff --git a/addons/surfacer/platform_graph/edge/edges/edge.gd b/addons/surfacer/src/platform_graph/edge/edges/edge.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/edges/edge.gd rename to addons/surfacer/src/platform_graph/edge/edges/edge.gd diff --git a/addons/surfacer/platform_graph/edge/edges/edge_type.gd b/addons/surfacer/src/platform_graph/edge/edges/edge_type.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/edges/edge_type.gd rename to addons/surfacer/src/platform_graph/edge/edges/edge_type.gd diff --git a/addons/surfacer/platform_graph/edge/edges/fall_from_floor_edge.gd b/addons/surfacer/src/platform_graph/edge/edges/fall_from_floor_edge.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/edges/fall_from_floor_edge.gd rename to addons/surfacer/src/platform_graph/edge/edges/fall_from_floor_edge.gd diff --git a/addons/surfacer/platform_graph/edge/edges/fall_from_wall_edge.gd b/addons/surfacer/src/platform_graph/edge/edges/fall_from_wall_edge.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/edges/fall_from_wall_edge.gd rename to addons/surfacer/src/platform_graph/edge/edges/fall_from_wall_edge.gd diff --git a/addons/surfacer/platform_graph/edge/edges/intra_surface_edge.gd b/addons/surfacer/src/platform_graph/edge/edges/intra_surface_edge.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/edges/intra_surface_edge.gd rename to addons/surfacer/src/platform_graph/edge/edges/intra_surface_edge.gd diff --git a/addons/surfacer/platform_graph/edge/edges/jump_from_surface_to_air_edge.gd b/addons/surfacer/src/platform_graph/edge/edges/jump_from_surface_to_air_edge.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/edges/jump_from_surface_to_air_edge.gd rename to addons/surfacer/src/platform_graph/edge/edges/jump_from_surface_to_air_edge.gd diff --git a/addons/surfacer/platform_graph/edge/edges/jump_inter_surface_edge.gd b/addons/surfacer/src/platform_graph/edge/edges/jump_inter_surface_edge.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/edges/jump_inter_surface_edge.gd rename to addons/surfacer/src/platform_graph/edge/edges/jump_inter_surface_edge.gd diff --git a/addons/surfacer/platform_graph/edge/edges/walk_to_ascend_wall_from_floor_edge.gd b/addons/surfacer/src/platform_graph/edge/edges/walk_to_ascend_wall_from_floor_edge.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/edges/walk_to_ascend_wall_from_floor_edge.gd rename to addons/surfacer/src/platform_graph/edge/edges/walk_to_ascend_wall_from_floor_edge.gd diff --git a/addons/surfacer/platform_graph/edge/models/collision_calc_result_metadata.gd b/addons/surfacer/src/platform_graph/edge/models/collision_calc_result_metadata.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/collision_calc_result_metadata.gd rename to addons/surfacer/src/platform_graph/edge/models/collision_calc_result_metadata.gd diff --git a/addons/surfacer/platform_graph/edge/models/collision_calculation_params.gd b/addons/surfacer/src/platform_graph/edge/models/collision_calculation_params.gd similarity index 93% rename from addons/surfacer/platform_graph/edge/models/collision_calculation_params.gd rename to addons/surfacer/src/platform_graph/edge/models/collision_calculation_params.gd index b4439431..5f46e08a 100644 --- a/addons/surfacer/platform_graph/edge/models/collision_calculation_params.gd +++ b/addons/surfacer/src/platform_graph/edge/models/collision_calculation_params.gd @@ -6,7 +6,7 @@ var debug_params: Dictionary var movement_params: MovementParams var surface_parser: SurfaceParser var player: KinematicBody2D -var thread_id := Profiler.DEFAULT_THREAD_ID +var thread_id: String = Profiler.DEFAULT_THREAD_ID func _init( \ debug_params: Dictionary, \ diff --git a/addons/surfacer/platform_graph/edge/models/collision_tile_map_coord_result.gd b/addons/surfacer/src/platform_graph/edge/models/collision_tile_map_coord_result.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/collision_tile_map_coord_result.gd rename to addons/surfacer/src/platform_graph/edge/models/collision_tile_map_coord_result.gd diff --git a/addons/surfacer/platform_graph/edge/models/edge_attempt.gd b/addons/surfacer/src/platform_graph/edge/models/edge_attempt.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/edge_attempt.gd rename to addons/surfacer/src/platform_graph/edge/models/edge_attempt.gd diff --git a/addons/surfacer/platform_graph/edge/models/edge_calc_params.gd b/addons/surfacer/src/platform_graph/edge/models/edge_calc_params.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/edge_calc_params.gd rename to addons/surfacer/src/platform_graph/edge/models/edge_calc_params.gd diff --git a/addons/surfacer/platform_graph/edge/models/edge_calc_result.gd b/addons/surfacer/src/platform_graph/edge/models/edge_calc_result.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/edge_calc_result.gd rename to addons/surfacer/src/platform_graph/edge/models/edge_calc_result.gd diff --git a/addons/surfacer/platform_graph/edge/models/edge_calc_result_metadata.gd b/addons/surfacer/src/platform_graph/edge/models/edge_calc_result_metadata.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/edge_calc_result_metadata.gd rename to addons/surfacer/src/platform_graph/edge/models/edge_calc_result_metadata.gd diff --git a/addons/surfacer/platform_graph/edge/models/edge_calc_result_type.gd b/addons/surfacer/src/platform_graph/edge/models/edge_calc_result_type.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/edge_calc_result_type.gd rename to addons/surfacer/src/platform_graph/edge/models/edge_calc_result_type.gd diff --git a/addons/surfacer/platform_graph/edge/models/edge_instruction.gd b/addons/surfacer/src/platform_graph/edge/models/edge_instruction.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/edge_instruction.gd rename to addons/surfacer/src/platform_graph/edge/models/edge_instruction.gd diff --git a/addons/surfacer/platform_graph/edge/models/edge_instructions.gd b/addons/surfacer/src/platform_graph/edge/models/edge_instructions.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/edge_instructions.gd rename to addons/surfacer/src/platform_graph/edge/models/edge_instructions.gd diff --git a/addons/surfacer/platform_graph/edge/models/edge_step.gd b/addons/surfacer/src/platform_graph/edge/models/edge_step.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/edge_step.gd rename to addons/surfacer/src/platform_graph/edge/models/edge_step.gd diff --git a/addons/surfacer/platform_graph/edge/models/edge_step_calc_params.gd b/addons/surfacer/src/platform_graph/edge/models/edge_step_calc_params.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/edge_step_calc_params.gd rename to addons/surfacer/src/platform_graph/edge/models/edge_step_calc_params.gd diff --git a/addons/surfacer/platform_graph/edge/models/edge_step_calc_result_metadata.gd b/addons/surfacer/src/platform_graph/edge/models/edge_step_calc_result_metadata.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/edge_step_calc_result_metadata.gd rename to addons/surfacer/src/platform_graph/edge/models/edge_step_calc_result_metadata.gd diff --git a/addons/surfacer/platform_graph/edge/models/edge_step_calc_result_type.gd b/addons/surfacer/src/platform_graph/edge/models/edge_step_calc_result_type.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/edge_step_calc_result_type.gd rename to addons/surfacer/src/platform_graph/edge/models/edge_step_calc_result_type.gd diff --git a/addons/surfacer/platform_graph/edge/models/edge_trajectory.gd b/addons/surfacer/src/platform_graph/edge/models/edge_trajectory.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/edge_trajectory.gd rename to addons/surfacer/src/platform_graph/edge/models/edge_trajectory.gd diff --git a/addons/surfacer/platform_graph/edge/models/failed_edge_attempt.gd b/addons/surfacer/src/platform_graph/edge/models/failed_edge_attempt.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/failed_edge_attempt.gd rename to addons/surfacer/src/platform_graph/edge/models/failed_edge_attempt.gd diff --git a/addons/surfacer/platform_graph/edge/models/inter_surface_edges_result.gd b/addons/surfacer/src/platform_graph/edge/models/inter_surface_edges_result.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/inter_surface_edges_result.gd rename to addons/surfacer/src/platform_graph/edge/models/inter_surface_edges_result.gd diff --git a/addons/surfacer/platform_graph/edge/models/jump_land_positions.gd b/addons/surfacer/src/platform_graph/edge/models/jump_land_positions.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/jump_land_positions.gd rename to addons/surfacer/src/platform_graph/edge/models/jump_land_positions.gd diff --git a/addons/surfacer/platform_graph/edge/models/movement_params.gd b/addons/surfacer/src/platform_graph/edge/models/movement_params.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/movement_params.gd rename to addons/surfacer/src/platform_graph/edge/models/movement_params.gd diff --git a/addons/surfacer/platform_graph/edge/models/surface_collision.gd b/addons/surfacer/src/platform_graph/edge/models/surface_collision.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/surface_collision.gd rename to addons/surfacer/src/platform_graph/edge/models/surface_collision.gd diff --git a/addons/surfacer/platform_graph/edge/models/vertical_edge_step.gd b/addons/surfacer/src/platform_graph/edge/models/vertical_edge_step.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/vertical_edge_step.gd rename to addons/surfacer/src/platform_graph/edge/models/vertical_edge_step.gd diff --git a/addons/surfacer/platform_graph/edge/models/waypoint.gd b/addons/surfacer/src/platform_graph/edge/models/waypoint.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/waypoint.gd rename to addons/surfacer/src/platform_graph/edge/models/waypoint.gd diff --git a/addons/surfacer/platform_graph/edge/models/waypoint_validity.gd b/addons/surfacer/src/platform_graph/edge/models/waypoint_validity.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/models/waypoint_validity.gd rename to addons/surfacer/src/platform_graph/edge/models/waypoint_validity.gd diff --git a/addons/surfacer/platform_graph/edge/utils/collision_check_utils.gd b/addons/surfacer/src/platform_graph/edge/utils/collision_check_utils.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/utils/collision_check_utils.gd rename to addons/surfacer/src/platform_graph/edge/utils/collision_check_utils.gd diff --git a/addons/surfacer/platform_graph/edge/utils/edge_instructions_utils.gd b/addons/surfacer/src/platform_graph/edge/utils/edge_instructions_utils.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/utils/edge_instructions_utils.gd rename to addons/surfacer/src/platform_graph/edge/utils/edge_instructions_utils.gd diff --git a/addons/surfacer/platform_graph/edge/utils/edge_step_utils.gd b/addons/surfacer/src/platform_graph/edge/utils/edge_step_utils.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/utils/edge_step_utils.gd rename to addons/surfacer/src/platform_graph/edge/utils/edge_step_utils.gd diff --git a/addons/surfacer/platform_graph/edge/utils/edge_trajectory_utils.gd b/addons/surfacer/src/platform_graph/edge/utils/edge_trajectory_utils.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/utils/edge_trajectory_utils.gd rename to addons/surfacer/src/platform_graph/edge/utils/edge_trajectory_utils.gd diff --git a/addons/surfacer/platform_graph/edge/utils/fall_movement_utils.gd b/addons/surfacer/src/platform_graph/edge/utils/fall_movement_utils.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/utils/fall_movement_utils.gd rename to addons/surfacer/src/platform_graph/edge/utils/fall_movement_utils.gd diff --git a/addons/surfacer/platform_graph/edge/utils/horizontal_movement_utils.gd b/addons/surfacer/src/platform_graph/edge/utils/horizontal_movement_utils.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/utils/horizontal_movement_utils.gd rename to addons/surfacer/src/platform_graph/edge/utils/horizontal_movement_utils.gd diff --git a/addons/surfacer/platform_graph/edge/utils/jump_land_positions_utils.gd b/addons/surfacer/src/platform_graph/edge/utils/jump_land_positions_utils.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/utils/jump_land_positions_utils.gd rename to addons/surfacer/src/platform_graph/edge/utils/jump_land_positions_utils.gd diff --git a/addons/surfacer/platform_graph/edge/utils/movement_utils.gd b/addons/surfacer/src/platform_graph/edge/utils/movement_utils.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/utils/movement_utils.gd rename to addons/surfacer/src/platform_graph/edge/utils/movement_utils.gd diff --git a/addons/surfacer/platform_graph/edge/utils/vertical_movement_utils.gd b/addons/surfacer/src/platform_graph/edge/utils/vertical_movement_utils.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/utils/vertical_movement_utils.gd rename to addons/surfacer/src/platform_graph/edge/utils/vertical_movement_utils.gd diff --git a/addons/surfacer/platform_graph/edge/utils/waypoint_utils.gd b/addons/surfacer/src/platform_graph/edge/utils/waypoint_utils.gd similarity index 100% rename from addons/surfacer/platform_graph/edge/utils/waypoint_utils.gd rename to addons/surfacer/src/platform_graph/edge/utils/waypoint_utils.gd diff --git a/addons/surfacer/platform_graph/navigator.gd b/addons/surfacer/src/platform_graph/navigator.gd similarity index 99% rename from addons/surfacer/platform_graph/navigator.gd rename to addons/surfacer/src/platform_graph/navigator.gd index fc1e64df..9d003292 100644 --- a/addons/surfacer/platform_graph/navigator.gd +++ b/addons/surfacer/src/platform_graph/navigator.gd @@ -52,7 +52,8 @@ func navigate_to_position( \ Profiler.start(ProfilerMetric.NAVIGATOR_FIND_PATH) var path := find_path(destination) - var duration_find_path := Profiler.stop(ProfilerMetric.NAVIGATOR_FIND_PATH) + var duration_find_path: float = \ + Profiler.stop(ProfilerMetric.NAVIGATOR_FIND_PATH) var previous_navigation_attempt_count := current_navigation_attempt_count reset() @@ -77,7 +78,7 @@ func navigate_to_position( \ graph.collision_params, \ path, \ player.velocity) - var duration_optimize_edges_for_approach := Profiler.stop( \ + var duration_optimize_edges_for_approach: float = Profiler.stop( \ ProfilerMetric.NAVIGATOR_OPTIMIZE_EDGES_FOR_APPROACH) current_destination = destination @@ -87,7 +88,7 @@ func navigate_to_position( \ just_reached_destination = false current_navigation_attempt_count += 1 - var duration_navigate_to_position := \ + var duration_navigate_to_position: float = \ Profiler.stop(ProfilerMetric.NAVIGATOR_NAVIGATE_TO_POSITION) var format_string_template := "STARTING PATH NAV: %8.3fs; {" + \ @@ -233,7 +234,7 @@ func _start_edge( \ current_edge, \ Time.elapsed_play_time_actual_sec) - var duration_start_edge := \ + var duration_start_edge: float = \ Profiler.stop(ProfilerMetric.NAVIGATOR_START_EDGE) var format_string_template := \ diff --git a/addons/surfacer/platform_graph/platform_graph.gd b/addons/surfacer/src/platform_graph/platform_graph.gd similarity index 99% rename from addons/surfacer/platform_graph/platform_graph.gd rename to addons/surfacer/src/platform_graph/platform_graph.gd index 4e8ba2fd..da460c4c 100644 --- a/addons/surfacer/platform_graph/platform_graph.gd +++ b/addons/surfacer/src/platform_graph/platform_graph.gd @@ -374,12 +374,12 @@ func _calculate_inter_surface_edges_total() -> void: for origin_surface in surfaces_set: surfaces_to_inter_surface_edges_results[origin_surface] = [] - if SurfacerConfig.USES_THREADS: + if SurfacerConfig.uses_threads: var threads := [] - threads.resize(SurfacerConfig.THREAD_COUNT) + threads.resize(SurfacerConfig.thread_count) # Use child threads to parallelize graph parsing. - for i in SurfacerConfig.THREAD_COUNT: + for i in SurfacerConfig.thread_count: var thread := Thread.new() Profiler.init_thread("parse_edges:" + str(i)) threads[i] = thread diff --git a/addons/surfacer/platform_graph/platform_graph_path.gd b/addons/surfacer/src/platform_graph/platform_graph_path.gd similarity index 100% rename from addons/surfacer/platform_graph/platform_graph_path.gd rename to addons/surfacer/src/platform_graph/platform_graph_path.gd diff --git a/addons/surfacer/platform_graph/surface/position_along_surface.gd b/addons/surfacer/src/platform_graph/surface/position_along_surface.gd similarity index 100% rename from addons/surfacer/platform_graph/surface/position_along_surface.gd rename to addons/surfacer/src/platform_graph/surface/position_along_surface.gd diff --git a/addons/surfacer/platform_graph/surface/surface.gd b/addons/surfacer/src/platform_graph/surface/surface.gd similarity index 100% rename from addons/surfacer/platform_graph/surface/surface.gd rename to addons/surfacer/src/platform_graph/surface/surface.gd diff --git a/addons/surfacer/platform_graph/surface/surface_parser.gd b/addons/surfacer/src/platform_graph/surface/surface_parser.gd similarity index 100% rename from addons/surfacer/platform_graph/surface/surface_parser.gd rename to addons/surfacer/src/platform_graph/surface/surface_parser.gd diff --git a/addons/surfacer/platform_graph/surface/surface_side.gd b/addons/surfacer/src/platform_graph/surface/surface_side.gd similarity index 100% rename from addons/surfacer/platform_graph/surface/surface_side.gd rename to addons/surfacer/src/platform_graph/surface/surface_side.gd diff --git a/addons/surfacer/platform_graph/surface/surface_type.gd b/addons/surfacer/src/platform_graph/surface/surface_type.gd similarity index 100% rename from addons/surfacer/platform_graph/surface/surface_type.gd rename to addons/surfacer/src/platform_graph/surface/surface_type.gd diff --git a/addons/surfacer/player/action/action_handlers/air_dash_action.gd b/addons/surfacer/src/player/action/action_handlers/air_dash_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/air_dash_action.gd rename to addons/surfacer/src/player/action/action_handlers/air_dash_action.gd diff --git a/addons/surfacer/player/action/action_handlers/air_default_action.gd b/addons/surfacer/src/player/action/action_handlers/air_default_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/air_default_action.gd rename to addons/surfacer/src/player/action/action_handlers/air_default_action.gd diff --git a/addons/surfacer/player/action/action_handlers/air_jump_action.gd b/addons/surfacer/src/player/action/action_handlers/air_jump_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/air_jump_action.gd rename to addons/surfacer/src/player/action/action_handlers/air_jump_action.gd diff --git a/addons/surfacer/player/action/action_handlers/all_default_action.gd b/addons/surfacer/src/player/action/action_handlers/all_default_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/all_default_action.gd rename to addons/surfacer/src/player/action/action_handlers/all_default_action.gd diff --git a/addons/surfacer/player/action/action_handlers/cap_velocity_action.gd b/addons/surfacer/src/player/action/action_handlers/cap_velocity_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/cap_velocity_action.gd rename to addons/surfacer/src/player/action/action_handlers/cap_velocity_action.gd diff --git a/addons/surfacer/player/action/action_handlers/floor_dash_action.gd b/addons/surfacer/src/player/action/action_handlers/floor_dash_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/floor_dash_action.gd rename to addons/surfacer/src/player/action/action_handlers/floor_dash_action.gd diff --git a/addons/surfacer/player/action/action_handlers/floor_default_action.gd b/addons/surfacer/src/player/action/action_handlers/floor_default_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/floor_default_action.gd rename to addons/surfacer/src/player/action/action_handlers/floor_default_action.gd diff --git a/addons/surfacer/player/action/action_handlers/floor_fall_through_action.gd b/addons/surfacer/src/player/action/action_handlers/floor_fall_through_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/floor_fall_through_action.gd rename to addons/surfacer/src/player/action/action_handlers/floor_fall_through_action.gd diff --git a/addons/surfacer/player/action/action_handlers/floor_friction_action.gd b/addons/surfacer/src/player/action/action_handlers/floor_friction_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/floor_friction_action.gd rename to addons/surfacer/src/player/action/action_handlers/floor_friction_action.gd diff --git a/addons/surfacer/player/action/action_handlers/floor_jump_action.gd b/addons/surfacer/src/player/action/action_handlers/floor_jump_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/floor_jump_action.gd rename to addons/surfacer/src/player/action/action_handlers/floor_jump_action.gd diff --git a/addons/surfacer/player/action/action_handlers/floor_walk_action.gd b/addons/surfacer/src/player/action/action_handlers/floor_walk_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/floor_walk_action.gd rename to addons/surfacer/src/player/action/action_handlers/floor_walk_action.gd diff --git a/addons/surfacer/player/action/action_handlers/match_expected_edge_trajectory_action.gd b/addons/surfacer/src/player/action/action_handlers/match_expected_edge_trajectory_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/match_expected_edge_trajectory_action.gd rename to addons/surfacer/src/player/action/action_handlers/match_expected_edge_trajectory_action.gd diff --git a/addons/surfacer/player/action/action_handlers/wall_climb_action.gd b/addons/surfacer/src/player/action/action_handlers/wall_climb_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/wall_climb_action.gd rename to addons/surfacer/src/player/action/action_handlers/wall_climb_action.gd diff --git a/addons/surfacer/player/action/action_handlers/wall_dash_action.gd b/addons/surfacer/src/player/action/action_handlers/wall_dash_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/wall_dash_action.gd rename to addons/surfacer/src/player/action/action_handlers/wall_dash_action.gd diff --git a/addons/surfacer/player/action/action_handlers/wall_default_action.gd b/addons/surfacer/src/player/action/action_handlers/wall_default_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/wall_default_action.gd rename to addons/surfacer/src/player/action/action_handlers/wall_default_action.gd diff --git a/addons/surfacer/player/action/action_handlers/wall_fall_action.gd b/addons/surfacer/src/player/action/action_handlers/wall_fall_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/wall_fall_action.gd rename to addons/surfacer/src/player/action/action_handlers/wall_fall_action.gd diff --git a/addons/surfacer/player/action/action_handlers/wall_jump_action.gd b/addons/surfacer/src/player/action/action_handlers/wall_jump_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/wall_jump_action.gd rename to addons/surfacer/src/player/action/action_handlers/wall_jump_action.gd diff --git a/addons/surfacer/player/action/action_handlers/wall_walk_action.gd b/addons/surfacer/src/player/action/action_handlers/wall_walk_action.gd similarity index 100% rename from addons/surfacer/player/action/action_handlers/wall_walk_action.gd rename to addons/surfacer/src/player/action/action_handlers/wall_walk_action.gd diff --git a/addons/surfacer/player/action/instructions_action_source.gd b/addons/surfacer/src/player/action/instructions_action_source.gd similarity index 100% rename from addons/surfacer/player/action/instructions_action_source.gd rename to addons/surfacer/src/player/action/instructions_action_source.gd diff --git a/addons/surfacer/player/action/instructions_playback.gd b/addons/surfacer/src/player/action/instructions_playback.gd similarity index 100% rename from addons/surfacer/player/action/instructions_playback.gd rename to addons/surfacer/src/player/action/instructions_playback.gd diff --git a/addons/surfacer/player/action/player_action_handler.gd b/addons/surfacer/src/player/action/player_action_handler.gd similarity index 100% rename from addons/surfacer/player/action/player_action_handler.gd rename to addons/surfacer/src/player/action/player_action_handler.gd diff --git a/addons/surfacer/player/action/player_action_source.gd b/addons/surfacer/src/player/action/player_action_source.gd similarity index 100% rename from addons/surfacer/player/action/player_action_source.gd rename to addons/surfacer/src/player/action/player_action_source.gd diff --git a/addons/surfacer/player/action/player_action_state.gd b/addons/surfacer/src/player/action/player_action_state.gd similarity index 100% rename from addons/surfacer/player/action/player_action_state.gd rename to addons/surfacer/src/player/action/player_action_state.gd diff --git a/addons/surfacer/player/action/player_action_type.gd b/addons/surfacer/src/player/action/player_action_type.gd similarity index 100% rename from addons/surfacer/player/action/player_action_type.gd rename to addons/surfacer/src/player/action/player_action_type.gd diff --git a/addons/surfacer/player/action/user_action_source.gd b/addons/surfacer/src/player/action/user_action_source.gd similarity index 100% rename from addons/surfacer/player/action/user_action_source.gd rename to addons/surfacer/src/player/action/user_action_source.gd diff --git a/addons/surfacer/player/animator/fake_player_animator.gd b/addons/surfacer/src/player/animator/fake_player_animator.gd similarity index 100% rename from addons/surfacer/player/animator/fake_player_animator.gd rename to addons/surfacer/src/player/animator/fake_player_animator.gd diff --git a/addons/surfacer/player/animator/player_animator.gd b/addons/surfacer/src/player/animator/player_animator.gd similarity index 100% rename from addons/surfacer/player/animator/player_animator.gd rename to addons/surfacer/src/player/animator/player_animator.gd diff --git a/addons/surfacer/player/animator/player_animator_params.gd b/addons/surfacer/src/player/animator/player_animator_params.gd similarity index 100% rename from addons/surfacer/player/animator/player_animator_params.gd rename to addons/surfacer/src/player/animator/player_animator_params.gd diff --git a/addons/surfacer/player/player.gd b/addons/surfacer/src/player/player.gd similarity index 99% rename from addons/surfacer/player/player.gd rename to addons/surfacer/src/player/player.gd index f2ce8b15..8200dadf 100644 --- a/addons/surfacer/player/player.gd +++ b/addons/surfacer/src/player/player.gd @@ -56,9 +56,9 @@ var _dash_fade_tween: Tween func _init(player_name: String) -> void: self.player_name = player_name - self.level = Global.current_level + self.level = ScaffoldConfig.level - var player_params: PlayerParams = Global.player_params[player_name] + var player_params: PlayerParams = SurfacerConfig.player_params[player_name] self.can_grab_walls = player_params.movement_params.can_grab_walls self.can_grab_ceilings = player_params.movement_params.can_grab_ceilings self.can_grab_floors = player_params.movement_params.can_grab_floors diff --git a/addons/surfacer/player/player_navigation_state.gd b/addons/surfacer/src/player/player_navigation_state.gd similarity index 100% rename from addons/surfacer/player/player_navigation_state.gd rename to addons/surfacer/src/player/player_navigation_state.gd diff --git a/addons/surfacer/player/player_params.gd b/addons/surfacer/src/player/player_params.gd similarity index 100% rename from addons/surfacer/player/player_params.gd rename to addons/surfacer/src/player/player_params.gd diff --git a/addons/surfacer/player/player_params_utils.gd b/addons/surfacer/src/player/player_params_utils.gd similarity index 98% rename from addons/surfacer/player/player_params_utils.gd rename to addons/surfacer/src/player/player_params_utils.gd index ef3feea3..771402e3 100644 --- a/addons/surfacer/player/player_params_utils.gd +++ b/addons/surfacer/src/player/player_params_utils.gd @@ -25,7 +25,7 @@ static func _get_action_handlers(movement_params: MovementParams) -> Array: var name: String for i in range(names.size()): name = names[i] - action_handlers[i] = Global.PLAYER_ACTIONS[name] + action_handlers[i] = SurfacerConfig.player_actions[name] action_handlers.sort_custom(ActionHandlersComparator, "sort") @@ -41,7 +41,7 @@ static func _get_edge_calculators(movement_params: MovementParams) -> Array: var name: String for i in range(names.size()): name = names[i] - edge_calculators[i] = Global.EDGE_MOVEMENTS[name] + edge_calculators[i] = SurfacerConfig.edge_movements[name] return edge_calculators diff --git a/addons/surfacer/player/player_pointer_handler.gd b/addons/surfacer/src/player/player_pointer_handler.gd similarity index 93% rename from addons/surfacer/player/player_pointer_handler.gd rename to addons/surfacer/src/player/player_pointer_handler.gd index a78abc17..9f608d24 100644 --- a/addons/surfacer/player/player_pointer_handler.gd +++ b/addons/surfacer/src/player/player_pointer_handler.gd @@ -13,7 +13,7 @@ func _init(player) -> void: self.player = player func _unhandled_input(event: InputEvent) -> void: - if Global.current_player_for_clicks != player: + if SurfacerConfig.current_player_for_clicks != player: return var pointer_up_position := Vector2.INF @@ -26,7 +26,7 @@ func _unhandled_input(event: InputEvent) -> void: !event.pressed and \ !event.control: event_type = "MOUSE_UP " - pointer_up_position = Global.current_level.get_global_mouse_position() + pointer_up_position = ScaffoldConfig.level.get_global_mouse_position() # Mouse-down: Position pre-selection. if event is InputEventMouseButton and \ @@ -35,14 +35,14 @@ func _unhandled_input(event: InputEvent) -> void: !event.control: event_type = "MOUSE_DOWN " pointer_drag_position = \ - Global.current_level.get_global_mouse_position() + ScaffoldConfig.level.get_global_mouse_position() # Mouse-move: Position pre-selection. if event is InputEventMouseMotion and \ last_pointer_drag_position != Vector2.INF: event_type = "MOUSE_DRAG " pointer_drag_position = \ - Global.current_level.get_global_mouse_position() + ScaffoldConfig.level.get_global_mouse_position() # Touch-up: Position selection. if event is InputEventScreenTouch and \ diff --git a/addons/surfacer/player/player_surface_state.gd b/addons/surfacer/src/player/player_surface_state.gd similarity index 100% rename from addons/surfacer/player/player_surface_state.gd rename to addons/surfacer/src/player/player_surface_state.gd diff --git a/addons/surfacer/player/player_type.gd b/addons/surfacer/src/player/player_type.gd similarity index 100% rename from addons/surfacer/player/player_type.gd rename to addons/surfacer/src/player/player_type.gd diff --git a/addons/surfacer/src/surfacer_bootstrap.gd b/addons/surfacer/src/surfacer_bootstrap.gd new file mode 100644 index 00000000..c364674a --- /dev/null +++ b/addons/surfacer/src/surfacer_bootstrap.gd @@ -0,0 +1,36 @@ +extends Node +class_name SurfacerBootstrap + +func _init() -> void: + ScaffoldUtils.print("SurfacerBootstrap._init") + +func on_app_ready( \ + app_manifest: Dictionary, \ + main: Node) -> void: + var scaffold_bootstrap := ScaffoldBootstrap.new() + scaffold_bootstrap.on_app_ready(app_manifest, main) + + SurfacerConfig.annotators = Annotators.new() + main.add_child(SurfacerConfig.annotators) + + register_player_actions(SurfacerConfig.player_action_classes) + register_edge_movements(SurfacerConfig.edge_movement_classes) + register_player_params(SurfacerConfig.player_param_classes) + +func register_player_actions(player_action_classes: Array) -> void: + # Instantiate the various PlayerActions. + for player_action_class in player_action_classes: + SurfacerConfig.player_actions[player_action_class.NAME] = \ + player_action_class.new() + +func register_edge_movements(edge_movement_classes: Array) -> void: + # Instantiate the various EdgeMovements. + for edge_movement_class in edge_movement_classes: + SurfacerConfig.edge_movements[edge_movement_class.NAME] = \ + edge_movement_class.new() + +func register_player_params(player_param_classes: Array) -> void: + for param_class in player_param_classes: + var player_params: PlayerParams = \ + PlayerParamsUtils.create_player_params(param_class) + SurfacerConfig.player_params[player_params.name] = player_params diff --git a/addons/surfacer/src/surfacer_config.gd b/addons/surfacer/src/surfacer_config.gd new file mode 100644 index 00000000..ef3fb9f8 --- /dev/null +++ b/addons/surfacer/src/surfacer_config.gd @@ -0,0 +1,110 @@ +extends Node + +var uses_threads := false and OS.can_use_threads() + +var utility_panel_starts_open := false + +var default_player_name := "cat" + +var group_name_human_players := "human_players" +var group_name_computer_players := "computer_players" +var group_name_surfaces := "surfaces" +var group_name_squirrel_destinations := "squirrel_destinations" + +var thread_count := \ + 4 if \ + uses_threads else \ + 1 + +var is_logging_events := false + +var debug_params := { + is_inspector_enabled = true, +# limit_parsing = { +# player_name = "cat", +# +# edge_type = EdgeType.CLIMB_OVER_WALL_TO_FLOOR_EDGE, +# edge_type = EdgeType.FALL_FROM_WALL_EDGE, +# edge_type = EdgeType.FALL_FROM_FLOOR_EDGE, +# edge_type = EdgeType.JUMP_INTER_SURFACE_EDGE, +# edge_type = EdgeType.CLIMB_DOWN_WALL_TO_FLOOR_EDGE, +# edge_type = EdgeType.WALK_TO_ASCEND_WALL_FROM_FLOOR_EDGE, +# +# edge = { +# origin = { +# surface_side = SurfaceSide.RIGHT_WALL, +# surface_start_vertex = Vector2(64, 768), +# #position = Vector2(64, 704), +# epsilon = 10, +# }, +# destination = { +# surface_side = SurfaceSide.LEFT_WALL, +# surface_start_vertex = Vector2(-384, 704), +# #position = Vector2(-384, 737), +# epsilon = 10, +# }, +# #velocity_start = Vector2(0, -1000), +# }, +# }, + extra_annotations = {}, +} + +var player_actions := {} + +var edge_movements := {} + +# Dictionary +var player_params := {} + +var current_player_for_clicks: Player +var platform_graph_inspector: PlatformGraphInspector +var legend: Legend +var selection_description: SelectionDescription +var utility_panel: UtilityPanel +var welcome_panel: WelcomePanel +var annotators: Annotators + +var is_level_ready := false + +# --- + +var player_action_classes := [ + preload("res://addons/surfacer/src/player/action/action_handlers/air_dash_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/air_default_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/air_jump_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/all_default_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/cap_velocity_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/floor_dash_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/floor_default_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/floor_fall_through_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/floor_friction_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/floor_jump_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/floor_walk_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/match_expected_edge_trajectory_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/wall_climb_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/wall_dash_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/wall_default_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/wall_fall_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/wall_jump_action.gd"), + preload("res://addons/surfacer/src/player/action/action_handlers/wall_walk_action.gd"), +] + +var edge_movement_classes := [ + preload("res://addons/surfacer/src/platform_graph/edge/calculators/air_to_surface_calculator.gd"), + preload("res://addons/surfacer/src/platform_graph/edge/calculators/climb_down_wall_to_floor_calculator.gd"), + preload("res://addons/surfacer/src/platform_graph/edge/calculators/climb_over_wall_to_floor_calculator.gd"), + preload("res://addons/surfacer/src/platform_graph/edge/calculators/fall_from_floor_calculator.gd"), + preload("res://addons/surfacer/src/platform_graph/edge/calculators/fall_from_wall_calculator.gd"), + preload("res://addons/surfacer/src/platform_graph/edge/calculators/jump_inter_surface_calculator.gd"), + preload("res://addons/surfacer/src/platform_graph/edge/calculators/jump_from_surface_to_air_calculator.gd"), + preload("res://addons/surfacer/src/platform_graph/edge/calculators/walk_to_ascend_wall_from_floor_calculator.gd"), +] + +var player_param_classes := [ + preload("res://src/players/cat/cat_params.gd"), + preload("res://src/players/squirrel/squirrel_params.gd"), +# preload("res://test/data/test_player_params.gd"), +] + +func _init() -> void: + ScaffoldUtils.print("SurfacerConfig._init") diff --git a/addons/surfacer/surfacer_level.gd b/addons/surfacer/src/surfacer_level.gd similarity index 83% rename from addons/surfacer/surfacer_level.gd rename to addons/surfacer/src/surfacer_level.gd index 47c6df43..34ade7dc 100644 --- a/addons/surfacer/surfacer_level.gd +++ b/addons/surfacer/src/surfacer_level.gd @@ -1,9 +1,10 @@ extends ScaffoldLevel class_name SurfacerLevel -const TILE_MAP_COLLISION_LAYER := 7 +const _UTILITY_PANEL_RESOURCE_PATH := \ + "res://addons/surfacer/src/gui/panels/utility_panel.tscn" -const MUSIC_STREAM := preload("res://assets/music/on_a_quest.ogg") +const TILE_MAP_COLLISION_LAYER := 7 # The TileMaps that define the collision boundaries of this level. # Array @@ -15,43 +16,42 @@ var fake_players := {} var surface_parser: SurfaceParser # Dictionary var platform_graphs: Dictionary -var music_player: AudioStreamPlayer func _enter_tree() -> void: - Global.current_level = self - - music_player = AudioStreamPlayer.new() - add_child(music_player) + ScaffoldConfig.level = self -func _ready() -> void: - var scene_tree := get_tree() +func start() -> void: + ScaffoldConfig.level = self + + var utility_panel: UtilityPanel = ScaffoldUtils.add_scene( \ + ScaffoldConfig.canvas_layers.layers.hud, \ + _UTILITY_PANEL_RESOURCE_PATH) + SurfacerConfig.utility_panel = utility_panel # Get references to the TileMaps that define the collision boundaries of # this level. surface_tile_maps = \ - scene_tree.get_nodes_in_group(SurfacerConfig.GROUP_NAME_SURFACES) + get_tree().get_nodes_in_group(SurfacerConfig.group_name_surfaces) assert(surface_tile_maps.size() > 0) # Set up the PlatformGraphs for this level. surface_parser = SurfaceParser.new(surface_tile_maps) platform_graphs = _create_platform_graphs( \ surface_parser, \ - Global.player_params, \ - SurfacerConfig.DEBUG_PARAMS) - Global.platform_graph_inspector.set_graphs(platform_graphs.values()) + SurfacerConfig.player_params, \ + SurfacerConfig.debug_params) + SurfacerConfig.platform_graph_inspector.set_graphs(platform_graphs.values()) _parse_squirrel_destinations() - _start_music() - - Global.is_level_ready = true + SurfacerConfig.is_level_ready = true func _unhandled_input(event: InputEvent) -> void: if event is InputEventMouseButton or \ event is InputEventScreenTouch: # This ensures that pressing arrow keys won't change selections in the # inspector. - Global.platform_graph_inspector.release_focus() + SurfacerConfig.platform_graph_inspector.release_focus() func _create_platform_graphs( \ surface_parser: SurfaceParser, \ @@ -115,10 +115,10 @@ func add_player( \ if is_fake: player.collision_layer = 0 else: - var group := \ - SurfacerConfig.GROUP_NAME_HUMAN_PLAYERS if \ + var group: String = \ + SurfacerConfig.group_name_human_players if \ is_human_player else \ - SurfacerConfig.GROUP_NAME_COMPUTER_PLAYERS + SurfacerConfig.group_name_computer_players player.add_to_group(group) _record_player_reference(is_human_player) @@ -128,10 +128,10 @@ func add_player( \ func _record_player_reference(is_human_player: bool) -> void: var scene_tree := get_tree() - var group := \ - SurfacerConfig.GROUP_NAME_HUMAN_PLAYERS if \ + var group: String = \ + SurfacerConfig.group_name_human_players if \ is_human_player else \ - SurfacerConfig.GROUP_NAME_COMPUTER_PLAYERS + SurfacerConfig.group_name_computer_players var players := scene_tree.get_nodes_in_group(group) var player: Player = \ @@ -146,12 +146,12 @@ func _record_player_reference(is_human_player: bool) -> void: if is_human_player: player.init_human_player_state() - Global.current_player_for_clicks = player + SurfacerConfig.current_player_for_clicks = player else: player.init_computer_player_state() # Set up some annotators to help with debugging. - Global.canvas_layers.create_player_annotator( \ + SurfacerConfig.annotators.create_player_annotator( \ player, \ is_human_player) @@ -174,7 +174,7 @@ var squirrel_destinations := [] func _parse_squirrel_destinations() -> void: squirrel_destinations.clear() var configured_destinations := get_tree().get_nodes_in_group( \ - SurfacerConfig.GROUP_NAME_SQUIRREL_DESTINATIONS) + SurfacerConfig.group_name_squirrel_destinations) if !configured_destinations.empty(): assert(configured_destinations.size() == 1) var squirrel_player: SquirrelPlayer = \ @@ -200,7 +200,3 @@ func _create_random_squirrel_spawn_position() -> PositionAlongSurface: return SurfaceParser.find_closest_position_on_a_surface( \ point, \ fake_players["squirrel"]) - -func _start_music() -> void: - music_player.stream = MUSIC_STREAM - music_player.play() diff --git a/addons/surfacer/surfacer_third_party_licenses.gd b/addons/surfacer/src/surfacer_third_party_licenses.gd similarity index 100% rename from addons/surfacer/surfacer_third_party_licenses.gd rename to addons/surfacer/src/surfacer_third_party_licenses.gd diff --git a/addons/surfacer/utils/colors.gd b/addons/surfacer/src/utils/colors.gd similarity index 100% rename from addons/surfacer/utils/colors.gd rename to addons/surfacer/src/utils/colors.gd diff --git a/addons/surfacer/utils/draw_utils.gd b/addons/surfacer/src/utils/draw_utils.gd similarity index 100% rename from addons/surfacer/utils/draw_utils.gd rename to addons/surfacer/src/utils/draw_utils.gd diff --git a/addons/surfacer/utils/geometry.gd b/addons/surfacer/src/utils/geometry.gd similarity index 100% rename from addons/surfacer/utils/geometry.gd rename to addons/surfacer/src/utils/geometry.gd diff --git a/addons/surfacer/utils/profiler.gd b/addons/surfacer/src/utils/profiler.gd similarity index 92% rename from addons/surfacer/utils/profiler.gd rename to addons/surfacer/src/utils/profiler.gd index 3c7594fd..a2a04d19 100644 --- a/addons/surfacer/utils/profiler.gd +++ b/addons/surfacer/src/utils/profiler.gd @@ -27,7 +27,7 @@ func init_thread(thread_id: String) -> void: func start( \ metric: int, \ thread_id := DEFAULT_THREAD_ID) -> void: - if !SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled: + if !SurfacerConfig.debug_params.is_inspector_enabled: return _stopwatches[thread_id].start(metric) @@ -36,7 +36,7 @@ func stop( \ thread_id := DEFAULT_THREAD_ID, \ records := true, \ additional_timings_storage = null) -> float: - if !SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled: + if !SurfacerConfig.debug_params.is_inspector_enabled: return -1.0 var duration: float = _stopwatches[thread_id].stop(metric) @@ -95,7 +95,7 @@ func increment_count( \ func get_timing( \ metric: int, \ metadata_container = null) -> float: - assert(SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled) + assert(SurfacerConfig.debug_params.is_inspector_enabled) if metadata_container != null: var list: Array = metadata_container.timings[metric] assert(list.size() == 1) @@ -109,7 +109,7 @@ func get_timing( \ func get_timing_list( \ metric: int, \ metadata_container = null) -> Array: - assert(SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled) + assert(SurfacerConfig.debug_params.is_inspector_enabled) if metadata_container != null: var timings: Dictionary = metadata_container.timings return timings[metric] if \ @@ -127,7 +127,7 @@ func get_timing_list( \ func get_mean( \ metric: int, \ metadata_container = null) -> float: - assert(SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled) + assert(SurfacerConfig.debug_params.is_inspector_enabled) var count := get_count( \ metric, \ metadata_container) @@ -141,7 +141,7 @@ func get_mean( \ func get_min( \ metric: int, \ metadata_container = null) -> float: - assert(SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled) + assert(SurfacerConfig.debug_params.is_inspector_enabled) if get_count( \ metric, \ metadata_container) == 0: @@ -154,7 +154,7 @@ func get_min( \ func get_max( \ metric: int, \ metadata_container = null) -> float: - assert(SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled) + assert(SurfacerConfig.debug_params.is_inspector_enabled) if get_count( \ metric, \ metadata_container) == 0: @@ -167,7 +167,7 @@ func get_max( \ func get_sum( \ metric: int, \ metadata_container = null) -> float: - assert(SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled) + assert(SurfacerConfig.debug_params.is_inspector_enabled) var sum := 0.0 for timing in get_timing_list( \ metric, \ @@ -178,7 +178,7 @@ func get_sum( \ func get_count( \ metric: int, \ metadata_container = null) -> int: - assert(SurfacerConfig.DEBUG_PARAMS.is_inspector_enabled) + assert(SurfacerConfig.debug_params.is_inspector_enabled) var is_timing := is_timing( \ metric, \ diff --git a/addons/surfacer/utils/profiler_metric.gd b/addons/surfacer/src/utils/profiler_metric.gd similarity index 100% rename from addons/surfacer/utils/profiler_metric.gd rename to addons/surfacer/src/utils/profiler_metric.gd diff --git a/addons/surfacer/surfacer_config.gd b/addons/surfacer/surfacer_config.gd deleted file mode 100644 index 6bbd44d3..00000000 --- a/addons/surfacer/surfacer_config.gd +++ /dev/null @@ -1,55 +0,0 @@ -extends Node - -const IN_DEBUG_MODE := true -const IN_TEST_MODE := false -var USES_THREADS := false and OS.can_use_threads() - -const UTILITY_PANEL_STARTS_OPEN := false - -const DEFAULT_PLAYER_NAME := "cat" - -const GROUP_NAME_HUMAN_PLAYERS := "human_players" -const GROUP_NAME_COMPUTER_PLAYERS := "computer_players" -const GROUP_NAME_SURFACES := "surfaces" -const GROUP_NAME_SQUIRREL_DESTINATIONS := "squirrel_destinations" - -var THREAD_COUNT := \ - 4 if \ - USES_THREADS else \ - 1 - -var is_logging_events := false - -const DEBUG_PARAMS := \ - {} if \ - !IN_DEBUG_MODE else \ - { - is_inspector_enabled = true, -# limit_parsing = { -# player_name = "cat", -# -# edge_type = EdgeType.CLIMB_OVER_WALL_TO_FLOOR_EDGE, -# edge_type = EdgeType.FALL_FROM_WALL_EDGE, -# edge_type = EdgeType.FALL_FROM_FLOOR_EDGE, -# edge_type = EdgeType.JUMP_INTER_SURFACE_EDGE, -# edge_type = EdgeType.CLIMB_DOWN_WALL_TO_FLOOR_EDGE, -# edge_type = EdgeType.WALK_TO_ASCEND_WALL_FROM_FLOOR_EDGE, -# -# edge = { -# origin = { -# surface_side = SurfaceSide.RIGHT_WALL, -# surface_start_vertex = Vector2(64, 768), -# #position = Vector2(64, 704), -# epsilon = 10, -# }, -# destination = { -# surface_side = SurfaceSide.LEFT_WALL, -# surface_start_vertex = Vector2(-384, 704), -# #position = Vector2(-384, 737), -# epsilon = 10, -# }, -# #velocity_start = Vector2(0, -1000), -# }, -# }, - extra_annotations = {}, -} diff --git a/addons/surfacer/test/data/integration_test_bed.gd b/addons/surfacer/test/data/integration_test_bed.gd index e71ec45b..275b2726 100644 --- a/addons/surfacer/test/data/integration_test_bed.gd +++ b/addons/surfacer/test/data/integration_test_bed.gd @@ -2,7 +2,7 @@ extends "res://addons/gut/test.gd" class_name IntegrationTestBed var TEST_LEVEL_LONG_FALL := { - scene_resource_path = "res://addons/surfacer/test/data/test_level_long_fall.tscn", + scene_resource_path = "res://addons/surfacer/src/test/data/test_level_long_fall.tscn", start = { surface = Surface.new( \ [Vector2(128, 64), Vector2(192, 64)], \ @@ -30,7 +30,7 @@ var TEST_LEVEL_LONG_FALL := { } var TEST_LEVEL_LONG_RISE := { - scene_resource_path = "res://addons/surfacer/test/data/test_level_long_rise.tscn", + scene_resource_path = "res://addons/surfacer/src/test/data/test_level_long_rise.tscn", start = { surface = Surface.new( \ [Vector2(128, 64), Vector2(192, 64)], \ @@ -58,7 +58,7 @@ var TEST_LEVEL_LONG_RISE := { } var TEST_LEVEL_FAR_DISTANCE := { - scene_resource_path = "res://addons/surfacer/test/data/test_level_far_distance.tscn", + scene_resource_path = "res://addons/surfacer/src/test/data/test_level_far_distance.tscn", start = { surface = Surface.new( \ [Vector2(128, 64), Vector2(192, 64)], \ @@ -86,9 +86,9 @@ var TEST_LEVEL_FAR_DISTANCE := { } const GROUPS := [ - SurfacerConfig.GROUP_NAME_HUMAN_PLAYERS, - SurfacerConfig.GROUP_NAME_COMPUTER_PLAYERS, - SurfacerConfig.GROUP_NAME_SURFACES, + SurfacerConfig.group_name_human_players, + SurfacerConfig.group_name_computer_players, + SurfacerConfig.group_name_surfaces, ] const END_COORDINATE_CLOSE_THRESHOLD := UnitTestBed.END_COORDINATE_CLOSE_THRESHOLD @@ -126,7 +126,7 @@ func set_up(data := TEST_LEVEL_LONG_FALL) -> void: # data.scene_resource_path.find("test_") >= 0 else \ # Vector2.ZERO # level.add_player( \ -# Global.player_params[SurfacerConfig.DEFAULT_PLAYER_NAME] \ +# SurfacerConfig.player_params[SurfacerConfig.default_player_name] \ # .player_resource_path, \ # position, \ # false, \ @@ -162,7 +162,7 @@ func set_up_level(data: Dictionary) -> void: level = level_scene.instance() sandbox.add_child(level) - player = Global.current_player_for_clicks + player = SurfacerConfig.current_player_for_clicks platform_graph = player.graph movement_params = player.movement_params surface_parser = level.surface_parser diff --git a/assets/fonts/main_font_italic.tres b/assets/fonts/main_font_italic.tres deleted file mode 100644 index 876e2a54..00000000 --- a/assets/fonts/main_font_italic.tres +++ /dev/null @@ -1,6 +0,0 @@ -[gd_resource type="DynamicFont" load_steps=2 format=2] - -[ext_resource path="res://assets/fonts/Open_Sans/OpenSans-Italic.ttf" type="DynamicFontData" id=1] - -[resource] -font_data = ExtResource( 1 ) diff --git a/assets/fonts/main_font_l.tres b/assets/fonts/main_font_l.tres deleted file mode 100644 index 70018af1..00000000 --- a/assets/fonts/main_font_l.tres +++ /dev/null @@ -1,7 +0,0 @@ -[gd_resource type="DynamicFont" load_steps=2 format=2] - -[ext_resource path="res://assets/fonts/Open_Sans/OpenSans-Regular.ttf" type="DynamicFontData" id=1] - -[resource] -size = 28 -font_data = ExtResource( 1 ) diff --git a/assets/fonts/main_font_normal.tres b/assets/fonts/main_font_normal.tres deleted file mode 100644 index 558f591a..00000000 --- a/assets/fonts/main_font_normal.tres +++ /dev/null @@ -1,6 +0,0 @@ -[gd_resource type="DynamicFont" load_steps=2 format=2] - -[ext_resource path="res://assets/fonts/Open_Sans/OpenSans-Regular.ttf" type="DynamicFontData" id=1] - -[resource] -font_data = ExtResource( 1 ) diff --git a/assets/fonts/main_font_normal_bold.tres b/assets/fonts/main_font_normal_bold.tres deleted file mode 100644 index 724e9618..00000000 --- a/assets/fonts/main_font_normal_bold.tres +++ /dev/null @@ -1,7 +0,0 @@ -[gd_resource type="DynamicFont" load_steps=2 format=2] - -[ext_resource path="res://assets/fonts/Open_Sans/OpenSans-Bold.ttf" type="DynamicFontData" id=1] - -[resource] -size = 20 -font_data = ExtResource( 1 ) diff --git a/assets/fonts/main_font_normal_italic.tres b/assets/fonts/main_font_normal_italic.tres deleted file mode 100644 index b2e9ed22..00000000 --- a/assets/fonts/main_font_normal_italic.tres +++ /dev/null @@ -1,7 +0,0 @@ -[gd_resource type="DynamicFont" load_steps=2 format=2] - -[ext_resource path="res://assets/fonts/Open_Sans/OpenSans-Italic.ttf" type="DynamicFontData" id=1] - -[resource] -size = 20 -font_data = ExtResource( 1 ) diff --git a/assets/fonts/main_font_s.tres b/assets/fonts/main_font_s.tres deleted file mode 100644 index 7c9e16af..00000000 --- a/assets/fonts/main_font_s.tres +++ /dev/null @@ -1,7 +0,0 @@ -[gd_resource type="DynamicFont" load_steps=2 format=2] - -[ext_resource path="res://assets/fonts/Open_Sans/OpenSans-Regular.ttf" type="DynamicFontData" id=1] - -[resource] -size = 12 -font_data = ExtResource( 1 ) diff --git a/assets/fonts/main_font_xl.tres b/assets/fonts/main_font_xl.tres deleted file mode 100644 index 56f789a7..00000000 --- a/assets/fonts/main_font_xl.tres +++ /dev/null @@ -1,7 +0,0 @@ -[gd_resource type="DynamicFont" load_steps=2 format=2] - -[ext_resource path="res://assets/fonts/Open_Sans/OpenSans-Regular.ttf" type="DynamicFontData" id=1] - -[resource] -size = 32 -font_data = ExtResource( 1 ) diff --git a/assets/squirrel-running.gif b/assets/images/loading.gif similarity index 100% rename from assets/squirrel-running.gif rename to assets/images/loading.gif diff --git a/assets/images/players/squirrel-running-loader-spritesheet.png b/assets/images/players/squirrel-running-loader-spritesheet.png new file mode 100644 index 0000000000000000000000000000000000000000..7000a106657c0e36e0643416a60ef77109afb39d GIT binary patch literal 3294 zcmV<43?cK0P)6Y7+d)KEc9nUXpgt|HfvA{j2=OgcI!PsTg=j8SCk zl`Q`)YgcE^^0K8@k7Td)?XB;Fm-q<<6bgKx7#l-FftLU#AW$g~z^LTX4SxIe@87lV zc=OFq$LW8Z!Mc#G87+ZwGDHE4GgCdVl&0)jeN4c3h_b67J^Xm+Lf79-ClxR^2x0|h zgf`ihouGk$87an&qG+MHNuMS#GlbZ^1S9aw(rJfEQw3(02wXsR5C#DyjhU^}YHe6x zW{Yq#G_$qZ4w%^jocvCrw0)*-E1~&Kg_-FzTJl$lgW5>Pjn;9cCIO6<3gEtx;H-k? zJuoAk1GH@pStU-d-6Jc{Dop|yZz>e?^(N^GXqE$0bDD~|LL5cxU507_TA>MahT#m; zI+qlc9L#g(apfA)y)F^kXc9!<6`DXF4b0Gy!ch}!g-A2}Z>`aSXSN>8f#JmX+rNMJ z^7$Wsx#A$Kg>m&(y$l%YcnJvt46?;(gK^S$x_!^GeL65wML}W70?jVTvjQWn!|6Cf zi>1JDhg&T$H&&XJXPW82aG8TV5v2QSFwMv;DdT5dN3@DtXUOAs=$a2R{+z31{J9#)T*Zn575eFYH2~QjYyzvDohr(^|+0S-+D7W zLPXRq>$nlXSQBVFV5E|aicY~u0;LT6@`txa_+0v#ZO<<=J*tfLW0#}Elg>F5rV^U( zK6~@7e0zLSrJ=yIl7@q+^#QMDd|LM?V35Oc4VqOiy3mT)8kcQH&T_3W6damFr42R6 zjswO5O)D5DRGQYO_|!K9s+JyK{PRyQfBp0y)!!^Q5*P^@L^MelkILXNNA0X3eZ*3( zo%F~*(ucZPmpq;()Um+Spg~|s_m;x!TxDv&r0s+P$-#i?QG@$Yz;MuT0wJR93QgFlf>kpN&k-u<{j|f`D(z>dAVQhEVV%WeK28V6317I0GX% zd1@FKFIc!2XOn%7V8+5zk9txpgWO{gdMssbhj7!^kY z(y2mPwK&z^6jL=Y0nKky!3xc()zt*ds4eQ$%)1GiE?`E06VPZj^Z8?4fbra>P6eh{ zgH!x=1EyE7GFMI!kIV0;Z%?kkctLYAFg+Ta;I}(4Ugw$<#A}@(td(YWzlQbH9%?Pn?CkdxV0tRe&f<*%X6Gt14Hzpl0StoW zyfIUOv2IZT%{(Bam6iab1?N^^cHEkl0)v8cIxyDlcqTAt8`dp=Da+vK-&#Y3kxH}W zy5)&!6f{z2&RUXg2MhvF9)naKt1uQIkb8E4CfULDj**&0ZVe1l$|Y#5!XUx7j@bno zPT%9ZXd>cD&{%}A!hqg~_{GhI`08l`UGMk`BW+J;U_1kX1`Mg7HE677Jyeg{+38qd zq&A_w!f1j%Vywpg-t{Fd%lVH5COLt&6m1E*s^rKHEvz*wL`h0z9d*7zDY zQu0Xcz~bO0F0jzyt#-1p*kATroI+2?kUO1TZSOVsHQx z45$*ER+7sh24Nj z?njk569SFZ0gOhi7>oZt404W%D)W4zpbCQ?eB-GpfO)R~T4AEfJR6!J6(*p0E;KMO z+HEPIc_uVNfjJ!-YnP{IqVhklh68glH0ZhQruR=OU@Y6xPEStS9=#|qTt#^*MALv- zQE8CBl9U450}Z-0Nj9MK^o&E3X(}+Yp=kjl^`p(=&j4n26{deZ%5}YP?F8N{;_Qs# z>_vg;*@mqdKU$yfK6~>n+eTp-(h0m5m{pag7C&O=*osAjq~LV>Ra%tB+Cu zx$B%=xp`2npB=hRt3!C2Lz6&5fI%Ih<7(g_AaKz1_M}Dquv8rhTrXHkUDCfbFX=e{ z9}P_JAr}S4dmP%2m#&K>R;@3f1aMyK2w=*D;%+c|a>Obe4GF|=#U9KS_{Ner;R!gGmqNC;GSyn3-7-YxyYfeoh83ep*7``cf_zpH@4Hf67$SUpt_FoB~f&7&M|}oEIqE z@;k#5z!-oT3Cr$VmMbulkUM7%%8leBI*(@DPP(}OqZM%{0W^Wr`l*>)8oP^TUBL7R zxQhT%pz`$|U(q$BaXV;c0>)Fk9Yl}<<>{}q7IJ;1W@=zYh__MzBtRp4M%HbOS*4i@ zn32M*5;??gAZwpHRMa{<%+jt2%q&nwzkA4jXhogr zKWAIHzSOKBYpC^6N*H?m|A3h(lGa$O7@ok?Y|!Y2_+f!%1~jk0Xq?psx%KM145Zcu zM0EN{JgZ4!k4BshXmuG~snh&ZfhmK`bwScXqsgfB4IaH6Bzr)R?rni$0Vb{2N-AsB zeZM7HgCz+;4X?E+vx-93uR%%2Nni7V_~ki<>R%pmd$f_ZP)((NUtwtJ_7tKth{8g< zU2+w`)0T2B>1$p_tt-t-J4PjtdVr}_nhYp6cMGCnhh7RwGQ4~wq>qV`DAIK)5YlyR zrb+X8T}LWEq7CO?ZJTawXY6A&Vq{Ga36#X%Tu|+qqGC=imWLvN6xIdqvUe z-LoS|Yf-I+03#W}U2j2yKKbN%Il$8Yozy~JtDzN|Rx)ylwGA*yAkJy28la_`_Sx44 z#)SxM=OADIE0#nPfEXGaHNDmpDCbcKsM*~v| zwaag;t*$ub`qD!N*Q);-U^t;}uQIJFT+`-CV0Oy#U2Kt_t};LY%q|hz#Eu#`0n8== cI?as#0^YM?DFKNgUH||907*qoM6N<$g2hY;kN^Mx literal 0 HcmV?d00001 diff --git a/assets/images/players/squirrel-running-loader-spritesheet.png.import b/assets/images/players/squirrel-running-loader-spritesheet.png.import new file mode 100644 index 00000000..c8e63f95 --- /dev/null +++ b/assets/images/players/squirrel-running-loader-spritesheet.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/squirrel-running-loader-spritesheet.png-71897b31cbf354ffa08347de5f3a6455.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/images/players/squirrel-running-loader-spritesheet.png" +dest_files=[ "res://.import/squirrel-running-loader-spritesheet.png-71897b31cbf354ffa08347de5f3a6455.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/assets/main_theme.tres b/assets/main_theme.tres index d51a3567..c0c6fc81 100644 --- a/assets/main_theme.tres +++ b/assets/main_theme.tres @@ -1,6 +1,6 @@ [gd_resource type="Theme" load_steps=20 format=2] -[ext_resource path="res://assets/fonts/main_font_normal.tres" type="DynamicFont" id=1] +[ext_resource path="res://addons/scaffold/assets/fonts/main_font_m.tres" type="DynamicFont" id=1] [ext_resource path="res://assets/images/gui/x-normal-small.png" type="Texture" id=2] [sub_resource type="StyleBoxFlat" id=1] diff --git a/assets/music/on_a_quest.ogg.import b/assets/music/on_a_quest.ogg.import deleted file mode 100644 index 6d8b46de..00000000 --- a/assets/music/on_a_quest.ogg.import +++ /dev/null @@ -1,15 +0,0 @@ -[remap] - -importer="ogg_vorbis" -type="AudioStreamOGGVorbis" -path="res://.import/on_a_quest.ogg-a0d6cd15fe6a33d63141ff97cb8c2d97.oggstr" - -[deps] - -source_file="res://assets/music/on_a_quest.ogg" -dest_files=[ "res://.import/on_a_quest.ogg-a0d6cd15fe6a33d63141ff97cb8c2d97.oggstr" ] - -[params] - -loop=true -loop_offset=0 diff --git a/assets/sfx/squirrel_jump.wav.import b/assets/sfx/squirrel_jump.wav.import deleted file mode 100644 index 9a7ed2bb..00000000 --- a/assets/sfx/squirrel_jump.wav.import +++ /dev/null @@ -1,21 +0,0 @@ -[remap] - -importer="wav" -type="AudioStreamSample" -path="res://.import/squirrel_jump.wav-edab118998a145e863fba2586be6425f.sample" - -[deps] - -source_file="res://assets/sfx/squirrel_jump.wav" -dest_files=[ "res://.import/squirrel_jump.wav-edab118998a145e863fba2586be6425f.sample" ] - -[params] - -force/8_bit=false -force/mono=false -force/max_rate=false -force/max_rate_hz=44100 -edit/trim=true -edit/normalize=false -edit/loop=false -compress/mode=0 diff --git a/assets/sfx/squirrel_land.wav.import b/assets/sfx/squirrel_land.wav.import deleted file mode 100644 index 433656f8..00000000 --- a/assets/sfx/squirrel_land.wav.import +++ /dev/null @@ -1,21 +0,0 @@ -[remap] - -importer="wav" -type="AudioStreamSample" -path="res://.import/squirrel_land.wav-ae10738f906812788c32752a3a3debb0.sample" - -[deps] - -source_file="res://assets/sfx/squirrel_land.wav" -dest_files=[ "res://.import/squirrel_land.wav-ae10738f906812788c32752a3a3debb0.sample" ] - -[params] - -force/8_bit=false -force/mono=false -force/max_rate=false -force/max_rate_hz=44100 -edit/trim=true -edit/normalize=false -edit/loop=false -compress/mode=0 diff --git a/assets/sfx/squirrel_yell.wav.import b/assets/sfx/squirrel_yell.wav.import deleted file mode 100644 index a70b4a2c..00000000 --- a/assets/sfx/squirrel_yell.wav.import +++ /dev/null @@ -1,21 +0,0 @@ -[remap] - -importer="wav" -type="AudioStreamSample" -path="res://.import/squirrel_yell.wav-bf4f3995b09c1ba32f06a72fcf0dd171.sample" - -[deps] - -source_file="res://assets/sfx/squirrel_yell.wav" -dest_files=[ "res://.import/squirrel_yell.wav-bf4f3995b09c1ba32f06a72fcf0dd171.sample" ] - -[params] - -force/8_bit=false -force/mono=false -force/max_rate=false -force/max_rate_hz=44100 -edit/trim=true -edit/normalize=false -edit/loop=false -compress/mode=0 diff --git a/assets/sounds/achievement.wav.import b/assets/sounds/achievement.wav.import deleted file mode 100644 index 70fab123..00000000 --- a/assets/sounds/achievement.wav.import +++ /dev/null @@ -1,21 +0,0 @@ -[remap] - -importer="wav" -type="AudioStreamSample" -path="res://.import/achievement.wav-dc016ae0e63af1f3e47fe2cebab79c90.sample" - -[deps] - -source_file="res://assets/sounds/achievement.wav" -dest_files=[ "res://.import/achievement.wav-dc016ae0e63af1f3e47fe2cebab79c90.sample" ] - -[params] - -force/8_bit=false -force/mono=false -force/max_rate=false -force/max_rate_hz=44100 -edit/trim=false -edit/normalize=false -edit/loop=false -compress/mode=0 diff --git a/assets/sfx/cat_jump.wav b/assets/sounds/cat_jump.wav similarity index 100% rename from assets/sfx/cat_jump.wav rename to assets/sounds/cat_jump.wav diff --git a/assets/sfx/cat_jump.wav.import b/assets/sounds/cat_jump.wav.import similarity index 51% rename from assets/sfx/cat_jump.wav.import rename to assets/sounds/cat_jump.wav.import index 9e9a1d21..2d59eb62 100644 --- a/assets/sfx/cat_jump.wav.import +++ b/assets/sounds/cat_jump.wav.import @@ -2,12 +2,12 @@ importer="wav" type="AudioStreamSample" -path="res://.import/cat_jump.wav-49543b0834ee033ebca3aece7e11a336.sample" +path="res://.import/cat_jump.wav-c9b91609a1d40337a120468bd41074e9.sample" [deps] -source_file="res://assets/sfx/cat_jump.wav" -dest_files=[ "res://.import/cat_jump.wav-49543b0834ee033ebca3aece7e11a336.sample" ] +source_file="res://assets/sounds/cat_jump.wav" +dest_files=[ "res://.import/cat_jump.wav-c9b91609a1d40337a120468bd41074e9.sample" ] [params] diff --git a/assets/sfx/cat_land.wav b/assets/sounds/cat_land.wav similarity index 100% rename from assets/sfx/cat_land.wav rename to assets/sounds/cat_land.wav diff --git a/assets/sfx/cat_land.wav.import b/assets/sounds/cat_land.wav.import similarity index 51% rename from assets/sfx/cat_land.wav.import rename to assets/sounds/cat_land.wav.import index c8cecf22..f65f6a63 100644 --- a/assets/sfx/cat_land.wav.import +++ b/assets/sounds/cat_land.wav.import @@ -2,12 +2,12 @@ importer="wav" type="AudioStreamSample" -path="res://.import/cat_land.wav-f02f7b4ef4b697a3f85fbf08d6da769b.sample" +path="res://.import/cat_land.wav-96089233349d78ce4717b7b63405331f.sample" [deps] -source_file="res://assets/sfx/cat_land.wav" -dest_files=[ "res://.import/cat_land.wav-f02f7b4ef4b697a3f85fbf08d6da769b.sample" ] +source_file="res://assets/sounds/cat_land.wav" +dest_files=[ "res://.import/cat_land.wav-96089233349d78ce4717b7b63405331f.sample" ] [params] diff --git a/assets/sfx/contact.wav b/assets/sounds/contact.wav similarity index 100% rename from assets/sfx/contact.wav rename to assets/sounds/contact.wav diff --git a/assets/sfx/contact.wav.import b/assets/sounds/contact.wav.import similarity index 53% rename from assets/sfx/contact.wav.import rename to assets/sounds/contact.wav.import index 3d80b2a5..f3310b90 100644 --- a/assets/sfx/contact.wav.import +++ b/assets/sounds/contact.wav.import @@ -2,12 +2,12 @@ importer="wav" type="AudioStreamSample" -path="res://.import/contact.wav-ff1607988eac8b09a2476e9d3a2beeea.sample" +path="res://.import/contact.wav-3bebb958db78e6af5a5bec39ed7095df.sample" [deps] -source_file="res://assets/sfx/contact.wav" -dest_files=[ "res://.import/contact.wav-ff1607988eac8b09a2476e9d3a2beeea.sample" ] +source_file="res://assets/sounds/contact.wav" +dest_files=[ "res://.import/contact.wav-3bebb958db78e6af5a5bec39ed7095df.sample" ] [params] diff --git a/assets/sounds/menu_select.wav.import b/assets/sounds/menu_select.wav.import deleted file mode 100644 index bdd5d08a..00000000 --- a/assets/sounds/menu_select.wav.import +++ /dev/null @@ -1,21 +0,0 @@ -[remap] - -importer="wav" -type="AudioStreamSample" -path="res://.import/menu_select.wav-c679bd17fb76c04cd2d2c80c1298604b.sample" - -[deps] - -source_file="res://assets/sounds/menu_select.wav" -dest_files=[ "res://.import/menu_select.wav-c679bd17fb76c04cd2d2c80c1298604b.sample" ] - -[params] - -force/8_bit=false -force/mono=false -force/max_rate=false -force/max_rate_hz=44100 -edit/trim=false -edit/normalize=false -edit/loop=false -compress/mode=0 diff --git a/assets/sounds/menu_select_fancy.wav.import b/assets/sounds/menu_select_fancy.wav.import deleted file mode 100644 index 65713dc3..00000000 --- a/assets/sounds/menu_select_fancy.wav.import +++ /dev/null @@ -1,21 +0,0 @@ -[remap] - -importer="wav" -type="AudioStreamSample" -path="res://.import/menu_select_fancy.wav-061b397242e28d45bcd3395f586e8365.sample" - -[deps] - -source_file="res://assets/sounds/menu_select_fancy.wav" -dest_files=[ "res://.import/menu_select_fancy.wav-061b397242e28d45bcd3395f586e8365.sample" ] - -[params] - -force/8_bit=false -force/mono=false -force/max_rate=false -force/max_rate_hz=44100 -edit/trim=false -edit/normalize=false -edit/loop=false -compress/mode=0 diff --git a/assets/sounds/single_cat_snore.wav.import b/assets/sounds/single_cat_snore.wav.import deleted file mode 100644 index 88f604ed..00000000 --- a/assets/sounds/single_cat_snore.wav.import +++ /dev/null @@ -1,21 +0,0 @@ -[remap] - -importer="wav" -type="AudioStreamSample" -path="res://.import/single_cat_snore.wav-3f192dee2019cb22da229105f763c190.sample" - -[deps] - -source_file="res://assets/sounds/single_cat_snore.wav" -dest_files=[ "res://.import/single_cat_snore.wav-3f192dee2019cb22da229105f763c190.sample" ] - -[params] - -force/8_bit=false -force/mono=false -force/max_rate=false -force/max_rate_hz=44100 -edit/trim=false -edit/normalize=false -edit/loop=false -compress/mode=0 diff --git a/assets/sfx/squirrel_jump.wav b/assets/sounds/squirrel_jump.wav similarity index 100% rename from assets/sfx/squirrel_jump.wav rename to assets/sounds/squirrel_jump.wav diff --git a/assets/sounds/squirrel_jump.wav.import b/assets/sounds/squirrel_jump.wav.import new file mode 100644 index 00000000..35512086 --- /dev/null +++ b/assets/sounds/squirrel_jump.wav.import @@ -0,0 +1,21 @@ +[remap] + +importer="wav" +type="AudioStreamSample" +path="res://.import/squirrel_jump.wav-834e3b0a81c5c04115d8650e08520cff.sample" + +[deps] + +source_file="res://assets/sounds/squirrel_jump.wav" +dest_files=[ "res://.import/squirrel_jump.wav-834e3b0a81c5c04115d8650e08520cff.sample" ] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=true +edit/normalize=false +edit/loop=false +compress/mode=0 diff --git a/assets/sfx/squirrel_land.wav b/assets/sounds/squirrel_land.wav similarity index 100% rename from assets/sfx/squirrel_land.wav rename to assets/sounds/squirrel_land.wav diff --git a/assets/sounds/squirrel_land.wav.import b/assets/sounds/squirrel_land.wav.import new file mode 100644 index 00000000..7f080c09 --- /dev/null +++ b/assets/sounds/squirrel_land.wav.import @@ -0,0 +1,21 @@ +[remap] + +importer="wav" +type="AudioStreamSample" +path="res://.import/squirrel_land.wav-5e0eb5035bd1daceb7e7acd36034b951.sample" + +[deps] + +source_file="res://assets/sounds/squirrel_land.wav" +dest_files=[ "res://.import/squirrel_land.wav-5e0eb5035bd1daceb7e7acd36034b951.sample" ] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=true +edit/normalize=false +edit/loop=false +compress/mode=0 diff --git a/assets/sfx/squirrel_yell.wav b/assets/sounds/squirrel_yell.wav similarity index 100% rename from assets/sfx/squirrel_yell.wav rename to assets/sounds/squirrel_yell.wav diff --git a/assets/sounds/squirrel_yell.wav.import b/assets/sounds/squirrel_yell.wav.import new file mode 100644 index 00000000..33186c1d --- /dev/null +++ b/assets/sounds/squirrel_yell.wav.import @@ -0,0 +1,21 @@ +[remap] + +importer="wav" +type="AudioStreamSample" +path="res://.import/squirrel_yell.wav-9efbf8eb07caf87de8b4159c3b95a823.sample" + +[deps] + +source_file="res://assets/sounds/squirrel_yell.wav" +dest_files=[ "res://.import/squirrel_yell.wav-9efbf8eb07caf87de8b4159c3b95a823.sample" ] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=true +edit/normalize=false +edit/loop=false +compress/mode=0 diff --git a/design/logo.aseprite b/design/logo.aseprite index 9952371a85c5d8f4f4cd5d6ccc539ef01b241655..95a89da053e02e84f45ef2b2042d64e41db11121 100644 GIT binary patch delta 3990 zcmZXW2{hDg`^RUDMm;rANJeEs)RQckkuc0t)+moGV~FgAp-B>BFf&R*wx{gbl4R_J zWSCL*r5V``hU}6h#**#N|9#K@|2*$|opYb-KHuxQ?%z4T^ZWe1cd1~x#98HI0KiBV z5CGr>@E!#0Wq{+}`u~uKIeV9s-KS(v!pmjMGqgPa%@n$sk zQ=1;I>_EfF3`t*G$Y0u#C#*qKO(XmH4eE9x`OS|mh9{GPaRc#OpePI3-9B5%2UieR zT$e9bNm*DIJN!(=*sAo}Dy=+-EQk<>t{)9fEeXIQbK@Mvpz8pABW+IN@@l>Fwsok| z*Sc$723bPpK{l3{m8Y&BWJdXNjm<$r6XBfL3^9ZzNi?z1Gd$F>FCneXzAkEch;O6$ z^6CvJwjs1^$!{d?Qff2XB*H?j+O128Nnal-dTKX^g^XLTA#D49hdwh9=zb@~B8MRP z>G|#)%NV=j#o8AR;U~?TqvS5zF1x>%$_yL{MIFhm7V*35YJ0W@o`+~m0_Ta!kJ2V$ z8g8;kWX5qye?bzsJbJSd2sZbe7%Re{-%{2t%f*hb{<@Esc7ws28zX<{D@#EB z^s?CfG}z|I=mp%BB_h&=iqN3LF^|pY?*yQvgDU2r(Cis`?R0p0kUj*i2OHOeyh-ii zteA8%;YBFW)karFOWyPFzff-|YpR_9siM)SwqBHA>SL%anA!P0Sx^|~sdtD6YGIr| z0?E=TPRap#x&QG*`uNvn_ePqG6hl$d{^q>^EznJZ%8L$Xv*2u?HC2UYF3Nb!>HrB> z2-dSSBb#L6LJ_uo8Nkq2Irq9{;OU(oQ{Q%Qubg+{ z*auVgKU2ZOc*)A!?DT#3{vKbLMqA<^G+29px^Hcb%y_|FzN^6Rt9PnuxcX)(L>&qx ze+yAKWqbQ{B6AFQ%s;3a+Lv)gm?Yy#P=^KO&{TIMPyY6hSCYKLcN=0d0 zTh!~X5%EoNIj#p^ba=IngBve#*+8G|N5|JD1Y(Vir91AWJPtZe!2MpNW#bS zSlcD|qCjgq7$T(5Sghc!04WN#ftQ^94@1$fVbKZ@-1HdBX+!25VQ^*tP z4J%&ua`0_(7XTp^1^hn6r$_#o6tW>YbmuuoaK4j#n_)wO$Z8!8&jk{9SN+XEp;Lzy zi5GaXfHRJ?->&fhL)>6o|Fbnd7a^<}7pO%#Q&s23$~G>ool|`CJzR zhd$!sy)x(}2r*siS})uhjHnSZRB+fw!XK5rJM?qgROj#^>~xxlJ6&ev43~d;g93*8 zbTKM$>uVogf)`JotRQeR~c?pJ5&h9|~A-B4Yun}9~cl3BzF^VvfOLiF^4X821 z3Dm|Dc9?z5`kyZbQw%lg(>8WRYom`?CQAn05K_OWQMcT${LAcqI#}9?=Qx$DDKU*C zy#hNs@dQmRH12L}LNa!%YV8(4EQX732_C>a1~HUK!9NCTd@@nr(IqJ-pp-e>s&2)J z!I0wYU0pJ`=DHlPhxD*#xBs(V13R6po; z-KijgefYE)=7OEoZ(^5R+X06JQs;c?a}UQvKZETxGS!VDgmu9v?e9(}b@nC{UN7 znO!_}4fwhHzYXG`?-?qku5%?`;!o(GwQs;sDS-!Xz_*QN@xOBZ#l)*II82G?6*Ei$ z4}T{af}#PV8!w;6xuzd;7-J*<( zXEdW_)5M6rgJ{w*7_))ECq@l*lFfuu!4Gr39kkfhnBn9U?zWAWb@Nin&>%-k_!mC- zzH2luck^#I9&j5Zy)DkyDQQX!Y<+ZEG!5 zCH*X3z3e-ecUTz5m3ttQd%NM;R;EgzZYldZC=R*sI37m_`z>5l%NbjbDI2P)XHU9h z1R5hey9vSGzFo49NmG4FJ7SucZS&ymHSWhlki~bHr(UkseFXtQQS;mC*5v)9Z=eetjJ9@V*_ zX~bVsG(DwxOb%T>)jE^&n0AHuQD9A)9vY9xRh$nyEvY)CO&t=1E+UtceKC!ae#hp{ zcU)R#6A9(W&5JX=X`iXa91Ul4k#B2Gt<3MYe|WqP)>?bMp!#U@om{SrP5bs$QXZ81 z!@=2m6bo6Q!oo*;Z7QqLvAu$YmJ8o&e3URm!>r-ihyc1ucz1lN7<>InL_TuLA=#q> zw^l-23&l&~qH?;ds*4vyTtvIc>XJEHi#V&A?1$8ThT;F(s3%q6!p@`3uRro(Ua9(#5btA9rGp_pnNO-)j+$Mn{)X*d z5aqJR6}O;U(*u)ccKwYsn$-ZJWkB*_uT(0@G-^Rumz@iwOKS$*y*{7l$_P`KbmHXi z^a!1GaQh}(UV*MmLzZlGo6e8BwEX0nCU1DCIoPZYrBeo~w+t~gq*OO0I_*^Wlrtb%(+4K z9&NYL<2KKwuB2C3VdmU5I9(`GpaDUyFe95fy^;+dA+9v!ZT3zHvd0XEBgKDIvwhU) zU=Jq#Ot1KmPfafp5zSGe%F!pD;U`79KQ!hJ&lE%5qokYW9x|DuQ}dzDDUo8 zT87yUn|F}rMrD%R2*Mwroyfa?_`5~o{Vh4v-qxCYv=PF2h`rqWQ`b6YV-xfG#n+<{ zQ^~bW$BoQ_HWo@F^G2Opb@5(%*?V^GBlb>$By`2?=kGu0x(}VDpzuEk0!^Y3c z|6?jCbh=dO;?C6m-*B`53TOmE09e2&gcx>&h64Fay<6aAF$htg);w%6eJpW}0 ozjyEGCxZcS!2Ts?zx|2`b|mlARgv=}c_bUl2RhI^bigjiMfoQ-}9X3oagzypXc*@?*F|$A2IIHdi_VM5C~~55`j=c zD5)Y=Ji>Ry{*}H^-v>onC5*+dm9A7VSpC0ySYgHM)xj%?(*L&f)2<;oX^TibI7bD6 zP{tw<4CF7!Wz^rp2qk18BI4F~Moj8gva0Q1n?Sx?J2exY3f%x$p2^mp1yx?k2E$Rp z@%D=FQjcXxx6Z@lO$2Bo!9Maq2cNbi_Xj7k@iP%Q{^Xtx1m8yv2TaUwg4sV+e3l&M-g@T~WkY+pJGDSA9-Lz`@U8Xt^?tR5-- z-TdB$*fqTLv52+eOP)LZWDiWWLq`ft{6B36H6TDyNI_qNUlOhuM(dCyT%!r)ASE_%phCh^GOtbu$KwsT4soh!KSyGeJw zNq`Q~g;cAZGE3~#2q%h?E?ub54CMCN?_p51DWGbTN&W3Qg}(@7>q?BEpI@my{; zV(DMXzQXAPdnMF78--K4xoRXJoiRe&NR4<~L*$@5YfV4riHHf)EI4H_#QXuRA?6wO~G;1 zHoc6+`d`h6K1FxDTzCG)^XZ3SURc^JJf*K!wbHRT^M*Cwf!4J7>!f^f zq`L3yayPg&-lf8GD|phcmi@FIzq#fH*IcE+6;K(@q-3RXGr=$Z188=^>&t)EyMfM3 z*^O$a=L0W_D=sQKn!p~{<}{+B)_?xy-jIYTK%KBY;8MUf=h4_Zt&9)-oMFABygl{K zvGASe4mB3`U7s5*)e@}n$K4A2v~lrE4%12^-r?_UIp%bgDf=O4E9=J1KHDzUoL~Nt z_gl=JMky_P(J56cxSu0Z1=?^sS%%oU3y<-T#^lgVU0-S?9)?T>^(e>0I#yjV4i)Tn z_#!Cw`q10|+W$`0i(fei^JbR|s+c4EOtW~R-igMW9#^{yl%~jDUS`4D4T|(|$O_H+!=9^uj zF4c$>&Yc_Pb`3ANg01Rl38iepw5e=4dm-Hw1T?jHhruO5DTh%0Jy8QB{X^sb2TxBF z!vn|E-CNWlzFG#J((Tubg%?S{8JBg!f=t2-OjL9O!Ln-`X;hBSpA@Fa%1#mBMDZK> zZ9hcwu1M1}iljYd^SoWKp~BXsRoD`KMmC+t3EjZ6bqVV~@~W$=GEy0xQIzmx?U9+v zSnCY8lCZ4?`|L%IyPLcTUGtoM6~ba>afILUPJYx_@xoK~-BQ+}Fml|q`@>tWSJN)n zJA^+|Inwy+MpDEfoy4cpZ!<{WVJ$!v8t!NduA4o?2fEJo|6gf{GL}~<_O^)e0;8w1l91oeQXXa=6 zsI{KQ1gKhKdYUO{-*^5ZHXcJzNc3*T87@FU$}|THlKKJ6vukAx_>cq>{lRsyhR@Z@-RdXj*=d?vxHIQnHBn((>c); z?G>hVb`~T=l$;0YYQ_?O(cVEUI$dV`N47<*SrCzm1FCW`=hmQ&Er&%7)JmVDu9lDY zEyH2>hXdGya7z6#V_jf(Fe3siX7t4N9qzKRP3eD0<(r{~h}g3WxU>|K1HH~XFV{wD?c{Ur zy+sLei|swS;fJCskr}_P)WotiIGAwpqv1PxhbroN{dYc_FgjEO@%4C$>It2dw@5cJ W0#wBPr2RFKny5zUo^037?f(U`S-Cm@ diff --git a/design/logo.png b/design/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..48f1b10fc9754e84621b174d0b895fd5b52dddfa GIT binary patch literal 1646 zcmV-!29f!RP)Px#W>8F2MF0Q*A|NzHC_H94F^^U|-*G0{pl0sFn)~uLndMMwzA!hGZcAw|QcEN< zJUKrB{|MwYHpk=!7ULyEB5o$JjYXVsst}C!4}Tdo3GfX<}58w@?=hx z;Qx7P3E~1=W#V_1;8~uGsS+ILl_lU6s1mGjJjIioDnUChEP<-P6(*h)SCybj@V*kT z*ZpHmoILBkul^xgoGQUMFDrqP`U5O{VOC$>9e+?4rb-aaYfEsqk|#}-pypjAI71|6 zz`PHSWw8Wf1s?6TN)S(#VB&Vf!^_b>iLmV%-=k1iHN!CXXj*QSf^+J6>7OW-0}1s- zh;XFJew83P*EwJ>{S&1!6r7np%8>^%qZb*~;_n&Wa>Ow;T(wp>lMG{uce69ki>JSN z&Vq2QqChhdt3dFUDnaB#>2IF%C>*0W&`iV;mhBkrDmAWZFGMdHmV#0^pAFj@GO{3C zt0+#)yKZzxdMIBtQaF=xeBKha#VXGqfpJrs`j+!2pxZyErGsoS<8!KRUV17d5>_phVVxe{dVTh?3=>;!W-20Vod z)z3Vqy8*Ga=lj>u>8&Nm|2kqPn8Pu^_05!Ejnn5xe8-bbDi=VV=^1cG0Rf0Kw z#CJU1zm89pviM1>Chsc{`kP9y&WZSazVY?6r|TtX&-1*HraeTII@wvyuwhzyh`1qnPEh9H$SF^cZ5QoQ^QJ}Lp zKHIkV++$+fhv#Tjf6jk}orBHT_021{Iswk~} zB5mPGl%r>ra|Y)mmvf=+P-!lmx|Lxck+$$8%F(mRIfHYO%ehc@gg8y5@8txK$b|3| zO6iGF4r8P|gX0REf4=WX;-f;`H`nE$;bXnC3xyw`d+F6Pn{}3jd(Nv0bx;h%;d$V$N&HU07*qoM6N<$g6Co&00000 literal 0 HcmV?d00001 diff --git a/dist/squirrel-running.gif b/dist/loading.gif similarity index 100% rename from dist/squirrel-running.gif rename to dist/loading.gif diff --git a/export_presets.cfg b/export_presets.cfg index d10221ac..9a7aec4f 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -16,7 +16,7 @@ script_encryption_key="" vram_texture_compression/for_desktop=false vram_texture_compression/for_mobile=false -html/custom_html_shell="res://export-shell.html" +html/custom_html_shell="res://src/export_shell.html" html/head_include="" custom_template/release="" custom_template/debug="" diff --git a/index.html b/index.html index 78a0067f..91d1c1e4 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,5 @@ Redirecting to game... - - + + diff --git a/project.godot b/project.godot index 1b489169..a458370e 100644 --- a/project.godot +++ b/project.godot @@ -12,82 +12,82 @@ _global_script_classes=[ { "base": "Control", "class": "AccordionPanel", "language": "GDScript", -"path": "res://addons/scaffold/gui/accordion_panel.gd" +"path": "res://addons/scaffold/src/gui/accordion_panel.gd" }, { "base": "PlayerActionHandler", "class": "AirDashAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/air_dash_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/air_dash_action.gd" }, { "base": "PlayerActionHandler", "class": "AirDefaultAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/air_default_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/air_default_action.gd" }, { "base": "PlayerActionHandler", "class": "AirJumpAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/air_jump_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/air_jump_action.gd" }, { "base": "Edge", "class": "AirToAirEdge", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/edges/air_to_air_edge.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/edges/air_to_air_edge.gd" }, { "base": "EdgeCalculator", "class": "AirToSurfaceCalculator", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/calculators/air_to_surface_calculator.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/calculators/air_to_surface_calculator.gd" }, { "base": "Edge", "class": "AirToSurfaceEdge", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/edges/air_to_surface_edge.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/edges/air_to_surface_edge.gd" }, { "base": "PlayerActionHandler", "class": "AllDefaultAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/all_default_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/all_default_action.gd" }, { "base": "Reference", "class": "AnnotationElement", "language": "GDScript", -"path": "res://addons/surfacer/annotators/annotation_elements/annotation_element.gd" +"path": "res://addons/surfacer/src/annotators/annotation_elements/annotation_element.gd" }, { "base": "Reference", "class": "AnnotationElementType", "language": "GDScript", -"path": "res://addons/surfacer/annotators/annotation_elements/annotation_element_type.gd" +"path": "res://addons/surfacer/src/annotators/annotation_elements/annotation_element_type.gd" }, { "base": "Reference", "class": "AnnotatorType", "language": "GDScript", -"path": "res://addons/surfacer/annotators/annotator_type.gd" +"path": "res://addons/surfacer/src/annotators/annotator_type.gd" }, { "base": "Node2D", "class": "Annotators", "language": "GDScript", -"path": "res://addons/surfacer/annotators/annotators.gd" +"path": "res://addons/surfacer/src/annotators/annotators.gd" }, { "base": "Node2D", "class": "CameraController", "language": "GDScript", -"path": "res://addons/scaffold/camera_controller.gd" +"path": "res://addons/scaffold/src/camera_controller.gd" }, { "base": "Node2D", "class": "CameraShake", "language": "GDScript", -"path": "res://addons/scaffold/camera_shake.gd" +"path": "res://addons/scaffold/src/camera_shake.gd" }, { "base": "Node2D", "class": "CanvasLayers", "language": "GDScript", -"path": "res://addons/scaffold/canvas_layers.gd" +"path": "res://addons/scaffold/src/canvas_layers.gd" }, { "base": "PlayerActionHandler", "class": "CapVelocityAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/cap_velocity_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/cap_velocity_action.gd" }, { "base": "PlayerAnimator", "class": "CatAnimator", @@ -107,597 +107,592 @@ _global_script_classes=[ { "base": "SurfacesOfSideGroupItemController", "class": "CeilingsItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/ceilings_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/ceilings_item_controller.gd" }, { "base": "PanelContainer", "class": "CenteredInFullScreenPanel", "language": "GDScript", -"path": "res://addons/scaffold/gui/centered_in_full_screen_panel.gd" +"path": "res://addons/scaffold/src/gui/centered_in_full_screen_panel.gd" }, { "base": "PanelContainer", "class": "CenteredPanel", "language": "GDScript", -"path": "res://addons/scaffold/gui/centered_panel.gd" +"path": "res://addons/scaffold/src/gui/centered_panel.gd" }, { "base": "Node2D", "class": "ClickAnnotator", "language": "GDScript", -"path": "res://addons/surfacer/annotators/click_annotator.gd" +"path": "res://addons/surfacer/src/annotators/click_annotator.gd" }, { "base": "EdgeCalculator", "class": "ClimbDownWallToFloorCalculator", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/calculators/climb_down_wall_to_floor_calculator.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/calculators/climb_down_wall_to_floor_calculator.gd" }, { "base": "Edge", "class": "ClimbDownWallToFloorEdge", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/edges/climb_down_wall_to_floor_edge.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/edges/climb_down_wall_to_floor_edge.gd" }, { "base": "EdgeCalculator", "class": "ClimbOverWallToFloorCalculator", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/calculators/climb_over_wall_to_floor_calculator.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/calculators/climb_over_wall_to_floor_calculator.gd" }, { "base": "Edge", "class": "ClimbOverWallToFloorEdge", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/edges/climb_over_wall_to_floor_edge.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/edges/climb_over_wall_to_floor_edge.gd" }, { "base": "Reference", "class": "CollisionCalcParams", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/collision_calculation_params.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/collision_calculation_params.gd" }, { "base": "Reference", "class": "CollisionCalcResultMetadata", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/collision_calc_result_metadata.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/collision_calc_result_metadata.gd" }, { "base": "Reference", "class": "CollisionCheckUtils", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/utils/collision_check_utils.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/utils/collision_check_utils.gd" }, { "base": "Reference", "class": "CollisionTileMapCoordResult", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/collision_tile_map_coord_result.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/collision_tile_map_coord_result.gd" }, { "base": "Reference", "class": "ColorParams", "language": "GDScript", -"path": "res://addons/surfacer/annotators/color_params/color_params.gd" +"path": "res://addons/surfacer/src/annotators/color_params/color_params.gd" }, { "base": "Reference", "class": "ColorParamsFactory", "language": "GDScript", -"path": "res://addons/surfacer/annotators/color_params/color_params_factory.gd" +"path": "res://addons/surfacer/src/annotators/color_params/color_params_factory.gd" }, { "base": "Reference", "class": "ColorParamsType", "language": "GDScript", -"path": "res://addons/surfacer/annotators/color_params/color_params_type.gd" +"path": "res://addons/surfacer/src/annotators/color_params/color_params_type.gd" }, { "base": "Reference", "class": "Colors", "language": "GDScript", -"path": "res://addons/surfacer/utils/colors.gd" +"path": "res://addons/surfacer/src/utils/colors.gd" }, { "base": "Screen", "class": "ConfirmDataDeletionScreen", "language": "GDScript", -"path": "res://addons/scaffold/gui/screens/confirm_data_deletion_screen.gd" +"path": "res://addons/scaffold/src/gui/screens/confirm_data_deletion_screen.gd" }, { "base": "ValidEdgeTrajectoryLegendItem", "class": "ContinuousEdgeTrajectoryLegendItem", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/continuous_edge_trajectory_legend_item.gd" -}, { -"base": "WindowDialog", -"class": "CreditsPanel", -"language": "GDScript", -"path": "res://addons/surfacer/gui/panels/credits_panel.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/continuous_edge_trajectory_legend_item.gd" }, { "base": "Screen", "class": "CreditsScreen", "language": "GDScript", -"path": "res://addons/scaffold/gui/screens/credits_screen.gd" +"path": "res://addons/scaffold/src/gui/screens/credits_screen.gd" }, { "base": "Screen", "class": "DataAgreementScreen", "language": "GDScript", -"path": "res://addons/scaffold/gui/screens/data_agreement_screen.gd" +"path": "res://addons/scaffold/src/gui/screens/data_agreement_screen.gd" }, { "base": "Node2D", "class": "DebugPanel", "language": "GDScript", -"path": "res://addons/scaffold/gui/debug_panel.gd" +"path": "res://addons/scaffold/src/gui/debug_panel.gd" }, { "base": "InspectorItemController", "class": "DescriptionItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/description_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/description_item_controller.gd" }, { "base": "LegendItem", "class": "DestinationLegendItem", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/destination_legend_item.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/destination_legend_item.gd" }, { "base": "SurfaceAnnotationElement", "class": "DestinationSurfaceAnnotationElement", "language": "GDScript", -"path": "res://addons/surfacer/annotators/annotation_elements/destination_surface_annotation_element.gd" +"path": "res://addons/surfacer/src/annotators/annotation_elements/destination_surface_annotation_element.gd" }, { "base": "InspectorItemController", "class": "DestinationSurfaceItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/destination_surface_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/destination_surface_item_controller.gd" }, { "base": "SurfaceLegendItem", "class": "DestinationSurfaceLegendItem", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/destination_surface_legend_item.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/destination_surface_legend_item.gd" }, { "base": "Screen", "class": "DeveloperSplashScreen", "language": "GDScript", -"path": "res://addons/scaffold/gui/screens/developer_splash_screen.gd" +"path": "res://addons/scaffold/src/gui/screens/developer_splash_screen.gd" }, { "base": "ValidEdgeTrajectoryLegendItem", "class": "DiscreteEdgeTrajectoryLegendItem", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/discrete_edge_trajectory_legend_item.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/discrete_edge_trajectory_legend_item.gd" }, { "base": "EdgeAttempt", "class": "Edge", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/edges/edge.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/edges/edge.gd" }, { "base": "AnnotationElement", "class": "EdgeAnnotationElement", "language": "GDScript", -"path": "res://addons/surfacer/annotators/annotation_elements/edge_annotation_element.gd" +"path": "res://addons/surfacer/src/annotators/annotation_elements/edge_annotation_element.gd" }, { "base": "Reference", "class": "EdgeAttempt", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/edge_attempt.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/edge_attempt.gd" }, { "base": "InspectorItemController", "class": "EdgeAttemptItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edge_attempt_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edge_attempt_item_controller.gd" }, { "base": "Reference", "class": "EdgeCalcParams", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/edge_calc_params.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/edge_calc_params.gd" }, { "base": "InspectorItemController", "class": "EdgeCalcProfilerGroupItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edge_calc_profiler_group_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edge_calc_profiler_group_item_controller.gd" }, { "base": "Reference", "class": "EdgeCalcResult", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/edge_calc_result.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/edge_calc_result.gd" }, { "base": "Reference", "class": "EdgeCalcResultMetadata", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/edge_calc_result_metadata.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/edge_calc_result_metadata.gd" }, { "base": "InspectorItemController", "class": "EdgeCalcResultMetadataItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edge_calc_result_metadata_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edge_calc_result_metadata_item_controller.gd" }, { "base": "Reference", "class": "EdgeCalcResultType", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/edge_calc_result_type.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/edge_calc_result_type.gd" }, { "base": "Reference", "class": "EdgeCalculator", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/calculators/edge_calculator.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/calculators/edge_calculator.gd" }, { "base": "Reference", "class": "EdgeInstruction", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/edge_instruction.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/edge_instruction.gd" }, { "base": "Reference", "class": "EdgeInstructions", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/edge_instructions.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/edge_instructions.gd" }, { "base": "Reference", "class": "EdgeInstructionsUtils", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/utils/edge_instructions_utils.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/utils/edge_instructions_utils.gd" }, { "base": "Reference", "class": "EdgeStep", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/edge_step.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/edge_step.gd" }, { "base": "AnnotationElement", "class": "EdgeStepAnnotationElement", "language": "GDScript", -"path": "res://addons/surfacer/annotators/annotation_elements/edge_step_annotation_element.gd" +"path": "res://addons/surfacer/src/annotators/annotation_elements/edge_step_annotation_element.gd" }, { "base": "Reference", "class": "EdgeStepCalcParams", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/edge_step_calc_params.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/edge_step_calc_params.gd" }, { "base": "Reference", "class": "EdgeStepCalcResultMetadata", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/edge_step_calc_result_metadata.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/edge_step_calc_result_metadata.gd" }, { "base": "InspectorItemController", "class": "EdgeStepCalcResultMetadataItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edge_step_calc_result_metadata_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edge_step_calc_result_metadata_item_controller.gd" }, { "base": "Reference", "class": "EdgeStepCalcResultMetadataItemControllerFactory", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edge_step_calc_result_metadata_item_controller_factory.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edge_step_calc_result_metadata_item_controller_factory.gd" }, { "base": "Reference", "class": "EdgeStepCalcResultType", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/edge_step_calc_result_type.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/edge_step_calc_result_type.gd" }, { "base": "Reference", "class": "EdgeStepUtils", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/utils/edge_step_utils.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/utils/edge_step_utils.gd" }, { "base": "Reference", "class": "EdgeTrajectory", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/edge_trajectory.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/edge_trajectory.gd" }, { "base": "Reference", "class": "EdgeTrajectoryUtils", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/utils/edge_trajectory_utils.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/utils/edge_trajectory_utils.gd" }, { "base": "Reference", "class": "EdgeType", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/edges/edge_type.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/edges/edge_type.gd" }, { "base": "InspectorItemController", "class": "EdgeTypeInEdgesGroupItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edge_type_in_edges_group_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edge_type_in_edges_group_item_controller.gd" }, { "base": "InspectorItemController", "class": "EdgeTypeInSurfacesGroupItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/edge_type_in_surfaces_group_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/edge_type_in_surfaces_group_item_controller.gd" }, { "base": "InspectorItemController", "class": "EdgesFilteredByResultTypeGroupItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_filtered_by_result_type_group_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_filtered_by_result_type_group_item_controller.gd" }, { "base": "InspectorItemController", "class": "EdgesGroupItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_group_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_group_item_controller.gd" }, { "base": "EdgesFilteredByResultTypeGroupItemController", "class": "EdgesWithIncreasingJumpHeightGroupItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_with_increasing_jump_height_group_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_with_increasing_jump_height_group_item_controller.gd" }, { "base": "EdgesFilteredByResultTypeGroupItemController", "class": "EdgesWithOneStepGroupItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_with_one_step_group_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_with_one_step_group_item_controller.gd" }, { "base": "EdgesFilteredByResultTypeGroupItemController", "class": "EdgesWithoutIncreasingJumpHeightGroupItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_without_increasing_jump_height_group_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/edges_group/edges_without_increasing_jump_height_group_item_controller.gd" }, { "base": "Node2D", "class": "ElementAnnotator", "language": "GDScript", -"path": "res://addons/surfacer/annotators/element_annotator.gd" +"path": "res://addons/surfacer/src/annotators/element_annotator.gd" }, { "base": "ColorRect", "class": "FadeTransition", "language": "GDScript", -"path": "res://addons/scaffold/gui/screens/fade_transition.gd" +"path": "res://addons/scaffold/src/gui/screens/fade_transition.gd" }, { "base": "EdgeAttempt", "class": "FailedEdgeAttempt", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/failed_edge_attempt.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/failed_edge_attempt.gd" }, { "base": "AnnotationElement", "class": "FailedEdgeAttemptAnnotationElement", "language": "GDScript", -"path": "res://addons/surfacer/annotators/annotation_elements/failed_edge_attempt_annotation_element.gd" +"path": "res://addons/surfacer/src/annotators/annotation_elements/failed_edge_attempt_annotation_element.gd" }, { "base": "EdgeAttemptItemController", "class": "FailedEdgeItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/failed_edge_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/failed_edge_item_controller.gd" }, { "base": "LegendItem", "class": "FailedEdgeTrajectoryLegendItem", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/failed_edge_trajectory_legend_item.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/failed_edge_trajectory_legend_item.gd" }, { "base": "InspectorItemController", "class": "FailedEdgesGroupItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/failed_edges_group_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/failed_edges_group_item_controller.gd" }, { "base": "PlayerAnimator", "class": "FakePlayerAnimator", "language": "GDScript", -"path": "res://addons/surfacer/player/animator/fake_player_animator.gd" +"path": "res://addons/surfacer/src/player/animator/fake_player_animator.gd" }, { "base": "EdgeCalculator", "class": "FallFromFloorCalculator", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/calculators/fall_from_floor_calculator.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/calculators/fall_from_floor_calculator.gd" }, { "base": "Edge", "class": "FallFromFloorEdge", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/edges/fall_from_floor_edge.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/edges/fall_from_floor_edge.gd" }, { "base": "EdgeCalculator", "class": "FallFromWallCalculator", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/calculators/fall_from_wall_calculator.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/calculators/fall_from_wall_calculator.gd" }, { "base": "Edge", "class": "FallFromWallEdge", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/edges/fall_from_wall_edge.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/edges/fall_from_wall_edge.gd" }, { "base": "Reference", "class": "FallMovementUtils", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/utils/fall_movement_utils.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/utils/fall_movement_utils.gd" }, { "base": "PolylineAnnotationElement", "class": "FallRangeWithJumpDistanceAnnotationElement", "language": "GDScript", -"path": "res://addons/surfacer/annotators/annotation_elements/fall_range_with_jump_distance_annotation_element.gd" +"path": "res://addons/surfacer/src/annotators/annotation_elements/fall_range_with_jump_distance_annotation_element.gd" }, { "base": "PolylineLegendItem", "class": "FallRangeWithJumpDistanceLegendItem", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/fall_range_with_jump_distance_legend_item.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/fall_range_with_jump_distance_legend_item.gd" }, { "base": "PolylineAnnotationElement", "class": "FallRangeWithoutJumpDistanceAnnotationElement", "language": "GDScript", -"path": "res://addons/surfacer/annotators/annotation_elements/fall_range_without_jump_distance_annotation_element.gd" +"path": "res://addons/surfacer/src/annotators/annotation_elements/fall_range_without_jump_distance_annotation_element.gd" }, { "base": "PolylineLegendItem", "class": "FallRangeWithoutJumpDistanceLegendItem", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/fall_range_without_jump_distance_legend_item.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/fall_range_without_jump_distance_legend_item.gd" }, { "base": "PlayerActionHandler", "class": "FloorDashAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/floor_dash_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/floor_dash_action.gd" }, { "base": "PlayerActionHandler", "class": "FloorDefaultAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/floor_default_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/floor_default_action.gd" }, { "base": "PlayerActionHandler", "class": "FloorFallThroughAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/floor_fall_through_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/floor_fall_through_action.gd" }, { "base": "PlayerActionHandler", "class": "FloorFrictionAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/floor_friction_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/floor_friction_action.gd" }, { "base": "PlayerActionHandler", "class": "FloorJumpAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/floor_jump_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/floor_jump_action.gd" }, { "base": "PlayerActionHandler", "class": "FloorWalkAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/floor_walk_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/floor_walk_action.gd" }, { "base": "SurfacesOfSideGroupItemController", "class": "FloorsItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/floors_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/floors_item_controller.gd" }, { "base": "PanelContainer", "class": "FullScreenPanel", "language": "GDScript", -"path": "res://addons/scaffold/gui/full_screen_panel.gd" +"path": "res://addons/scaffold/src/gui/full_screen_panel.gd" }, { "base": "Screen", "class": "GameScreen", "language": "GDScript", -"path": "res://addons/scaffold/gui/screens/game_screen.gd" +"path": "res://addons/scaffold/src/gui/screens/game_screen.gd" }, { "base": "Node2D", "class": "GestureRecord", "language": "GDScript", -"path": "res://addons/scaffold/data/gesture_record.gd" +"path": "res://addons/scaffold/src/data/gesture_record.gd" }, { "base": "InspectorItemController", "class": "GlobalCountsGroupItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/global_counts_group_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/global_counts_group_item_controller.gd" }, { "base": "Screen", "class": "GodotSplashScreen", "language": "GDScript", -"path": "res://addons/scaffold/gui/screens/godot_splash_screen.gd" +"path": "res://addons/scaffold/src/gui/screens/godot_splash_screen.gd" }, { "base": "Node2D", "class": "GridIndicesAnnotator", "language": "GDScript", -"path": "res://addons/surfacer/annotators/grid_indices_annotator.gd" +"path": "res://addons/surfacer/src/annotators/grid_indices_annotator.gd" }, { "base": "Reference", "class": "HorizontalMovementUtils", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/utils/horizontal_movement_utils.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/utils/horizontal_movement_utils.gd" }, { "base": "ColorParams", "class": "HsvColorParams", "language": "GDScript", -"path": "res://addons/surfacer/annotators/color_params/hsv_color_params.gd" +"path": "res://addons/surfacer/src/annotators/color_params/hsv_color_params.gd" }, { "base": "ColorParams", "class": "HsvRangeColorParams", "language": "GDScript", -"path": "res://addons/surfacer/annotators/color_params/hsv_range_color_params.gd" +"path": "res://addons/surfacer/src/annotators/color_params/hsv_range_color_params.gd" }, { "base": "LegendItem", "class": "HypotheticalEdgeTrajectoryLegendItem", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/hypothetical_edge_trajectory_legend_item.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/hypothetical_edge_trajectory_legend_item.gd" }, { "base": "Reference", "class": "InspectorItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/inspector_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/inspector_item_controller.gd" }, { "base": "Reference", "class": "InspectorItemType", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/inspector_item_type.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/inspector_item_type.gd" }, { "base": "Reference", "class": "InspectorSearchType", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_search_type.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_search_type.gd" }, { "base": "LegendItem", "class": "InstructionEndLegendItem", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/instruction_end_legend_item.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/instruction_end_legend_item.gd" }, { "base": "LegendItem", "class": "InstructionStartLegendItem", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/instruction_start_legend_item.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/instruction_start_legend_item.gd" }, { "base": "PlayerActionSource", "class": "InstructionsActionSource", "language": "GDScript", -"path": "res://addons/surfacer/player/action/instructions_action_source.gd" +"path": "res://addons/surfacer/src/player/action/instructions_action_source.gd" }, { "base": "Reference", "class": "InstructionsPlayback", "language": "GDScript", -"path": "res://addons/surfacer/player/action/instructions_playback.gd" +"path": "res://addons/surfacer/src/player/action/instructions_playback.gd" }, { "base": "Reference", "class": "InterSurfaceEdgesResult", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/inter_surface_edges_result.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/inter_surface_edges_result.gd" }, { "base": "Edge", "class": "IntraSurfaceEdge", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/edges/intra_surface_edge.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/edges/intra_surface_edge.gd" }, { "base": "Reference", "class": "IosModelNames", "language": "GDScript", -"path": "res://addons/scaffold/ios_model_names.gd" +"path": "res://addons/scaffold/src/ios_model_names.gd" }, { "base": "Reference", "class": "IosResolutions", "language": "GDScript", -"path": "res://addons/scaffold/ios_resolutions.gd" +"path": "res://addons/scaffold/src/ios_resolutions.gd" }, { "base": "EdgeCalculator", "class": "JumpFromSurfaceToAirCalculator", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/calculators/jump_from_surface_to_air_calculator.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/calculators/jump_from_surface_to_air_calculator.gd" }, { "base": "Edge", "class": "JumpFromSurfaceToAirEdge", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/edges/jump_from_surface_to_air_edge.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/edges/jump_from_surface_to_air_edge.gd" }, { "base": "EdgeCalculator", "class": "JumpInterSurfaceCalculator", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/calculators/jump_inter_surface_calculator.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/calculators/jump_inter_surface_calculator.gd" }, { "base": "Edge", "class": "JumpInterSurfaceEdge", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/edges/jump_inter_surface_edge.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/edges/jump_inter_surface_edge.gd" }, { "base": "Reference", "class": "JumpLandPositions", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/jump_land_positions.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/jump_land_positions.gd" }, { "base": "AnnotationElement", "class": "JumpLandPositionsAnnotationElement", "language": "GDScript", -"path": "res://addons/surfacer/annotators/annotation_elements/jump_land_positions_annotation_element.gd" +"path": "res://addons/surfacer/src/annotators/annotation_elements/jump_land_positions_annotation_element.gd" }, { "base": "Reference", "class": "JumpLandPositionsUtils", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/utils/jump_land_positions_utils.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/utils/jump_land_positions_utils.gd" }, { "base": "Reference", "class": "LabeledControlItemType", "language": "GDScript", -"path": "res://addons/scaffold/gui/labeled_control_item_type.gd" +"path": "res://addons/scaffold/src/gui/labeled_control_item_type.gd" }, { "base": "VBoxContainer", "class": "LabeledControlList", "language": "GDScript", -"path": "res://addons/scaffold/gui/labeled_control_list.gd" +"path": "res://addons/scaffold/src/gui/labeled_control_list.gd" }, { "base": "SurfacesOfSideGroupItemController", "class": "LeftWallsItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/left_walls_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/left_walls_item_controller.gd" }, { "base": "VBoxContainer", "class": "Legend", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend.gd" +"path": "res://addons/surfacer/src/gui/legend/legend.gd" }, { "base": "Control", "class": "LegendItem", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/legend_item.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/legend_item.gd" }, { "base": "Reference", "class": "LegendItemType", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/legend_item_type.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/legend_item_type.gd" }, { "base": "Node2D", "class": "Main", @@ -707,283 +702,278 @@ _global_script_classes=[ { "base": "Screen", "class": "MainMenuScreen", "language": "GDScript", -"path": "res://addons/scaffold/gui/screens/main_menu_screen.gd" +"path": "res://addons/scaffold/src/gui/screens/main_menu_screen.gd" }, { "base": "PlayerActionHandler", "class": "MatchExpectedEdgeTrajectoryAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/match_expected_edge_trajectory_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/match_expected_edge_trajectory_action.gd" }, { "base": "Reference", "class": "MovementParams", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/movement_params.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/movement_params.gd" }, { "base": "Reference", "class": "MovementUtils", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/utils/movement_utils.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/utils/movement_utils.gd" }, { "base": "PanelContainer", "class": "NavBar", "language": "GDScript", -"path": "res://addons/scaffold/gui/nav_bar.gd" +"path": "res://addons/scaffold/src/gui/nav_bar.gd" }, { "base": "Reference", "class": "Navigator", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/navigator.gd" +"path": "res://addons/surfacer/src/platform_graph/navigator.gd" }, { "base": "Node2D", "class": "NavigatorAnnotator", "language": "GDScript", -"path": "res://addons/surfacer/annotators/navigator_annotator.gd" +"path": "res://addons/surfacer/src/annotators/navigator_annotator.gd" }, { "base": "Screen", "class": "NotificationScreen", "language": "GDScript", -"path": "res://addons/scaffold/gui/screens/notification_screen.gd" +"path": "res://addons/scaffold/src/gui/screens/notification_screen.gd" }, { "base": "LegendItem", "class": "OriginLegendItem", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/origin_legend_item.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/origin_legend_item.gd" }, { "base": "SurfaceAnnotationElement", "class": "OriginSurfaceAnnotationElement", "language": "GDScript", -"path": "res://addons/surfacer/annotators/annotation_elements/origin_surface_annotation_element.gd" +"path": "res://addons/surfacer/src/annotators/annotation_elements/origin_surface_annotation_element.gd" }, { "base": "InspectorItemController", "class": "OriginSurfaceItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/origin_surface_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/origin_surface_item_controller.gd" }, { "base": "SurfaceLegendItem", "class": "OriginSurfaceLegendItem", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/origin_surface_legend_item.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/origin_surface_legend_item.gd" }, { "base": "Screen", "class": "PauseScreen", "language": "GDScript", -"path": "res://addons/scaffold/gui/screens/pause_screen.gd" +"path": "res://addons/scaffold/src/gui/screens/pause_screen.gd" }, { "base": "Reference", "class": "PlatformGraph", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/platform_graph.gd" +"path": "res://addons/surfacer/src/platform_graph/platform_graph.gd" }, { "base": "Tree", "class": "PlatformGraphInspector", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/platform_graph_inspector.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/platform_graph_inspector.gd" }, { "base": "Node2D", "class": "PlatformGraphInspectorSelector", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/platform_graph_inspector_selector.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/platform_graph_inspector_selector.gd" }, { "base": "InspectorItemController", "class": "PlatformGraphItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/platform_graph_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/platform_graph_item_controller.gd" }, { "base": "Reference", "class": "PlatformGraphPath", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/platform_graph_path.gd" +"path": "res://addons/surfacer/src/platform_graph/platform_graph_path.gd" }, { "base": "KinematicBody2D", "class": "Player", "language": "GDScript", -"path": "res://addons/surfacer/player/player.gd" +"path": "res://addons/surfacer/src/player/player.gd" }, { "base": "Reference", "class": "PlayerActionHandler", "language": "GDScript", -"path": "res://addons/surfacer/player/action/player_action_handler.gd" +"path": "res://addons/surfacer/src/player/action/player_action_handler.gd" }, { "base": "Reference", "class": "PlayerActionSource", "language": "GDScript", -"path": "res://addons/surfacer/player/action/player_action_source.gd" +"path": "res://addons/surfacer/src/player/action/player_action_source.gd" }, { "base": "Reference", "class": "PlayerActionState", "language": "GDScript", -"path": "res://addons/surfacer/player/action/player_action_state.gd" +"path": "res://addons/surfacer/src/player/action/player_action_state.gd" }, { "base": "Reference", "class": "PlayerActionType", "language": "GDScript", -"path": "res://addons/surfacer/player/action/player_action_type.gd" +"path": "res://addons/surfacer/src/player/action/player_action_type.gd" }, { "base": "Node2D", "class": "PlayerAnimator", "language": "GDScript", -"path": "res://addons/surfacer/player/animator/player_animator.gd" +"path": "res://addons/surfacer/src/player/animator/player_animator.gd" }, { "base": "Reference", "class": "PlayerAnimatorParams", "language": "GDScript", -"path": "res://addons/surfacer/player/animator/player_animator_params.gd" +"path": "res://addons/surfacer/src/player/animator/player_animator_params.gd" }, { "base": "Node2D", "class": "PlayerAnnotator", "language": "GDScript", -"path": "res://addons/surfacer/annotators/player_annotator.gd" +"path": "res://addons/surfacer/src/annotators/player_annotator.gd" }, { "base": "Reference", "class": "PlayerNavigationState", "language": "GDScript", -"path": "res://addons/surfacer/player/player_navigation_state.gd" +"path": "res://addons/surfacer/src/player/player_navigation_state.gd" }, { "base": "Reference", "class": "PlayerParams", "language": "GDScript", -"path": "res://addons/surfacer/player/player_params.gd" +"path": "res://addons/surfacer/src/player/player_params.gd" }, { "base": "Reference", "class": "PlayerParamsUtils", "language": "GDScript", -"path": "res://addons/surfacer/player/player_params_utils.gd" +"path": "res://addons/surfacer/src/player/player_params_utils.gd" }, { "base": "Node2D", "class": "PlayerPointerHandler", "language": "GDScript", -"path": "res://addons/surfacer/player/player_pointer_handler.gd" +"path": "res://addons/surfacer/src/player/player_pointer_handler.gd" }, { "base": "Node2D", "class": "PlayerPositionAnnotator", "language": "GDScript", -"path": "res://addons/surfacer/annotators/player_position_annotator.gd" +"path": "res://addons/surfacer/src/annotators/player_position_annotator.gd" }, { "base": "Node2D", "class": "PlayerRecentMovementAnnotator", "language": "GDScript", -"path": "res://addons/surfacer/annotators/player_recent_movement_annotator.gd" +"path": "res://addons/surfacer/src/annotators/player_recent_movement_annotator.gd" }, { "base": "Node2D", "class": "PlayerSurfaceAnnotator", "language": "GDScript", -"path": "res://addons/surfacer/annotators/player_surface_annotator.gd" +"path": "res://addons/surfacer/src/annotators/player_surface_annotator.gd" }, { "base": "Reference", "class": "PlayerSurfaceState", "language": "GDScript", -"path": "res://addons/surfacer/player/player_surface_state.gd" +"path": "res://addons/surfacer/src/player/player_surface_state.gd" }, { "base": "Node2D", "class": "PlayerTileAnnotator", "language": "GDScript", -"path": "res://addons/surfacer/annotators/player_tile_annotator.gd" +"path": "res://addons/surfacer/src/annotators/player_tile_annotator.gd" }, { "base": "Reference", "class": "PlayerType", "language": "GDScript", -"path": "res://addons/surfacer/player/player_type.gd" +"path": "res://addons/surfacer/src/player/player_type.gd" }, { "base": "AnnotationElement", "class": "PolylineAnnotationElement", "language": "GDScript", -"path": "res://addons/surfacer/annotators/annotation_elements/polyline_annotation_element.gd" +"path": "res://addons/surfacer/src/annotators/annotation_elements/polyline_annotation_element.gd" }, { "base": "LegendItem", "class": "PolylineLegendItem", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/polyline_legend_item.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/polyline_legend_item.gd" }, { "base": "Reference", "class": "PositionAlongSurface", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/surface/position_along_surface.gd" +"path": "res://addons/surfacer/src/platform_graph/surface/position_along_surface.gd" }, { "base": "Reference", "class": "PriorityQueue", "language": "GDScript", -"path": "res://addons/scaffold/priority_queue.gd" +"path": "res://addons/scaffold/src/priority_queue.gd" }, { "base": "InspectorItemController", "class": "ProfilerCountItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_count_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_count_item_controller.gd" }, { "base": "InspectorItemController", "class": "ProfilerGroupItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_group_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_group_item_controller.gd" }, { "base": "Reference", "class": "ProfilerMetric", "language": "GDScript", -"path": "res://addons/surfacer/utils/profiler_metric.gd" +"path": "res://addons/surfacer/src/utils/profiler_metric.gd" }, { "base": "InspectorItemController", "class": "ProfilerTimingItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_timing_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/profiler_timing_item_controller.gd" }, { "base": "Screen", "class": "RateAppScreen", "language": "GDScript", -"path": "res://addons/scaffold/gui/screens/rate_app_screen.gd" +"path": "res://addons/scaffold/src/gui/screens/rate_app_screen.gd" }, { "base": "SurfacesOfSideGroupItemController", "class": "RightWallsItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/right_walls_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/right_walls_item_controller.gd" }, { "base": "Node2D", "class": "RulerAnnotator", "language": "GDScript", -"path": "res://addons/surfacer/annotators/ruler_annotator.gd" +"path": "res://addons/surfacer/src/annotators/ruler_annotator.gd" }, { "base": "Node", "class": "ScaffoldBootstrap", "language": "GDScript", -"path": "res://addons/scaffold/scaffold_bootstrap.gd" +"path": "res://addons/scaffold/src/scaffold_bootstrap.gd" }, { "base": "Node2D", "class": "ScaffoldLevel", "language": "GDScript", -"path": "res://addons/scaffold/scaffold_level.gd" +"path": "res://addons/scaffold/src/scaffold_level.gd" }, { "base": "Node", "class": "ScaffoldThirdPartyLicenses", "language": "GDScript", -"path": "res://addons/scaffold/scaffold_third_party_licenses.gd" +"path": "res://addons/scaffold/src/scaffold_third_party_licenses.gd" }, { "base": "Node2D", "class": "Screen", "language": "GDScript", -"path": "res://addons/scaffold/gui/screen.gd" +"path": "res://addons/scaffold/src/gui/screen.gd" }, { "base": "MarginContainer", "class": "SelectionDescription", "language": "GDScript", -"path": "res://addons/surfacer/gui/selection_description.gd" +"path": "res://addons/surfacer/src/gui/selection_description.gd" }, { "base": "Screen", "class": "SettingsScreen", "language": "GDScript", -"path": "res://addons/scaffold/gui/screens/settings_screen.gd" +"path": "res://addons/scaffold/src/gui/screens/settings_screen.gd" }, { "base": "Button", "class": "ShinyButton", "language": "GDScript", -"path": "res://addons/scaffold/gui/shiny_button.gd" +"path": "res://addons/scaffold/src/gui/shiny_button.gd" }, { "base": "PlayerAnimator", "class": "SquirrelAnimator", "language": "GDScript", "path": "res://src/players/squirrel/squirrel_animator.gd" }, { -"base": "Node", -"class": "SquirrelAwayConfig", -"language": "GDScript", -"path": "res://src/squirrel_away_config.gd" -}, { "base": "SurfacerLevel", "class": "SquirrelAwayLevel", "language": "GDScript", @@ -1007,92 +997,92 @@ _global_script_classes=[ { "base": "Reference", "class": "Stopwatch", "language": "GDScript", -"path": "res://addons/scaffold/stopwatch.gd" +"path": "res://addons/scaffold/src/stopwatch.gd" }, { "base": "Reference", "class": "Surface", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/surface/surface.gd" +"path": "res://addons/surfacer/src/platform_graph/surface/surface.gd" }, { "base": "AnnotationElement", "class": "SurfaceAnnotationElement", "language": "GDScript", -"path": "res://addons/surfacer/annotators/annotation_elements/surface_annotation_element.gd" +"path": "res://addons/surfacer/src/annotators/annotation_elements/surface_annotation_element.gd" }, { "base": "Reference", "class": "SurfaceCollision", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/surface_collision.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/surface_collision.gd" }, { "base": "LegendItem", "class": "SurfaceLegendItem", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/surface_legend_item.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/surface_legend_item.gd" }, { "base": "Reference", "class": "SurfaceParser", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/surface/surface_parser.gd" +"path": "res://addons/surfacer/src/platform_graph/surface/surface_parser.gd" }, { "base": "InspectorItemController", "class": "SurfaceParserGroupItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/surface_parser_group_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/profiler_group/surface_parser_group_item_controller.gd" }, { "base": "Node2D", "class": "SurfacePreselectionAnnotator", "language": "GDScript", -"path": "res://addons/surfacer/annotators/surface_preselection_annotator.gd" +"path": "res://addons/surfacer/src/annotators/surface_preselection_annotator.gd" }, { "base": "Node2D", "class": "SurfaceSelectionAnnotator", "language": "GDScript", -"path": "res://addons/surfacer/annotators/surface_selection_annotator.gd" +"path": "res://addons/surfacer/src/annotators/surface_selection_annotator.gd" }, { "base": "Reference", "class": "SurfaceSide", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/surface/surface_side.gd" +"path": "res://addons/surfacer/src/platform_graph/surface/surface_side.gd" }, { "base": "Reference", "class": "SurfaceType", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/surface/surface_type.gd" +"path": "res://addons/surfacer/src/platform_graph/surface/surface_type.gd" +}, { +"base": "Node", +"class": "SurfacerBootstrap", +"language": "GDScript", +"path": "res://addons/surfacer/src/surfacer_bootstrap.gd" }, { "base": "ScaffoldLevel", "class": "SurfacerLevel", "language": "GDScript", -"path": "res://addons/surfacer/surfacer_level.gd" +"path": "res://addons/surfacer/src/surfacer_level.gd" }, { "base": "Node", "class": "SurfacerThirdPartyLicenses", "language": "GDScript", -"path": "res://addons/surfacer/surfacer_third_party_licenses.gd" +"path": "res://addons/surfacer/src/surfacer_third_party_licenses.gd" }, { "base": "InspectorItemController", "class": "SurfacesGroupItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/surfaces_group_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/surfaces_group_item_controller.gd" }, { "base": "InspectorItemController", "class": "SurfacesOfSideGroupItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/surfaces_of_side_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/surfaces_group/surfaces_of_side_item_controller.gd" }, { "base": "Screen", "class": "ThirdPartyLicensesScreen", "language": "GDScript", -"path": "res://addons/scaffold/gui/screens/third_party_licenses_screen.gd" -}, { -"base": "TileMap", -"class": "TierTileMap", -"language": "GDScript", -"path": "res://tier_tile_map.gd" +"path": "res://addons/scaffold/src/gui/screens/third_party_licenses_screen.gd" }, { "base": "Node2D", "class": "TodoSign", "language": "GDScript", -"path": "res://addons/scaffold/todo_sign.gd" +"path": "res://addons/scaffold/src/todo_sign.gd" }, { "base": "Reference", "class": "UUID", @@ -1102,92 +1092,92 @@ _global_script_classes=[ { "base": "PlayerActionSource", "class": "UserActionSource", "language": "GDScript", -"path": "res://addons/surfacer/player/action/user_action_source.gd" +"path": "res://addons/surfacer/src/player/action/user_action_source.gd" }, { "base": "Panel", "class": "UtilityPanel", "language": "GDScript", -"path": "res://addons/surfacer/gui/panels/utility_panel.gd" +"path": "res://addons/surfacer/src/gui/panels/utility_panel.gd" }, { "base": "EdgeAttemptItemController", "class": "ValidEdgeItemController", "language": "GDScript", -"path": "res://addons/surfacer/gui/platform_graph_inspector/inspector_item_controllers/valid_edge_item_controller.gd" +"path": "res://addons/surfacer/src/gui/platform_graph_inspector/inspector_item_controllers/valid_edge_item_controller.gd" }, { "base": "LegendItem", "class": "ValidEdgeTrajectoryLegendItem", "language": "GDScript", -"path": "res://addons/surfacer/gui/legend/legend_items/valid_edge_trajectory_legend_item.gd" +"path": "res://addons/surfacer/src/gui/legend/legend_items/valid_edge_trajectory_legend_item.gd" }, { "base": "EdgeStep", "class": "VerticalEdgeStep", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/vertical_edge_step.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/vertical_edge_step.gd" }, { "base": "Reference", "class": "VerticalMovementUtils", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/utils/vertical_movement_utils.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/utils/vertical_movement_utils.gd" }, { "base": "EdgeCalculator", "class": "WalkToAscendWallFromFloorCalculator", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/calculators/walk_to_ascend_wall_from_floor_calculator.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/calculators/walk_to_ascend_wall_from_floor_calculator.gd" }, { "base": "Edge", "class": "WalkToAscendWallFromFloorEdge", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/edges/walk_to_ascend_wall_from_floor_edge.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/edges/walk_to_ascend_wall_from_floor_edge.gd" }, { "base": "PlayerActionHandler", "class": "WallClimbAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/wall_climb_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/wall_climb_action.gd" }, { "base": "PlayerActionHandler", "class": "WallDashAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/wall_dash_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/wall_dash_action.gd" }, { "base": "PlayerActionHandler", "class": "WallDefaultAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/wall_default_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/wall_default_action.gd" }, { "base": "PlayerActionHandler", "class": "WallFallAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/wall_fall_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/wall_fall_action.gd" }, { "base": "PlayerActionHandler", "class": "WallJumpAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/wall_jump_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/wall_jump_action.gd" }, { "base": "PlayerActionHandler", "class": "WallWalkAction", "language": "GDScript", -"path": "res://addons/surfacer/player/action/action_handlers/wall_walk_action.gd" +"path": "res://addons/surfacer/src/player/action/action_handlers/wall_walk_action.gd" }, { "base": "Reference", "class": "Waypoint", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/waypoint.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/waypoint.gd" }, { "base": "Reference", "class": "WaypointUtils", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/utils/waypoint_utils.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/utils/waypoint_utils.gd" }, { "base": "Reference", "class": "WaypointValidity", "language": "GDScript", -"path": "res://addons/surfacer/platform_graph/edge/models/waypoint_validity.gd" +"path": "res://addons/surfacer/src/platform_graph/edge/models/waypoint_validity.gd" }, { "base": "PanelContainer", "class": "WelcomePanel", "language": "GDScript", -"path": "res://addons/surfacer/gui/panels/welcome_panel.gd" +"path": "res://addons/surfacer/src/gui/panels/welcome_panel.gd" } ] _global_script_class_icons={ "AccordionPanel": "", @@ -1227,7 +1217,6 @@ _global_script_class_icons={ "Colors": "", "ConfirmDataDeletionScreen": "", "ContinuousEdgeTrajectoryLegendItem": "", -"CreditsPanel": "", "CreditsScreen": "", "DataAgreementScreen": "", "DebugPanel": "", @@ -1384,7 +1373,6 @@ _global_script_class_icons={ "SettingsScreen": "", "ShinyButton": "", "SquirrelAnimator": "", -"SquirrelAwayConfig": "", "SquirrelAwayLevel": "", "SquirrelAwayThirdPartyLicenses": "", "SquirrelParams": "", @@ -1400,12 +1388,12 @@ _global_script_class_icons={ "SurfaceSelectionAnnotator": "", "SurfaceSide": "", "SurfaceType": "", +"SurfacerBootstrap": "", "SurfacerLevel": "", "SurfacerThirdPartyLicenses": "", "SurfacesGroupItemController": "", "SurfacesOfSideGroupItemController": "", "ThirdPartyLicensesScreen": "", -"TierTileMap": "", "TodoSign": "", "UUID": "", "UserActionSource": "", @@ -1433,35 +1421,35 @@ _global_script_class_icons={ config/name="Surfacer" run/main_scene="res://src/main.tscn" boot_splash/image="res://addons/scaffold/assets/images/gui/godot_logo_splash.png" +boot_splash/bg_color=Color( 0.152941, 0.192157, 0.286275, 1 ) config/icon="res://assets/images/icon.png" config/quit_on_go_back=false [autoload] -ScaffoldConfig="*res://addons/scaffold/scaffold_config.gd" -ScaffoldUtils="*res://addons/scaffold/scaffold_utils.gd" -SaveState="*res://addons/scaffold/data/save_state.gd" -Analytics="*res://addons/scaffold/data/analytics.gd" -Log="*res://addons/scaffold/data/log.gd" -Audio="*res://addons/scaffold/audio.gd" -Nav="*res://addons/scaffold/navigation.gd" -SurfacerConfig="*res://addons/surfacer/surfacer_config.gd" -Time="*res://addons/scaffold/time.gd" -Geometry="*res://addons/surfacer/utils/geometry.gd" -DrawUtils="*res://addons/surfacer/utils/draw_utils.gd" -Profiler="*res://addons/surfacer/utils/profiler.gd" -Global="*res://addons/surfacer/global.gd" -AnnotationElementDefaults="*res://addons/surfacer/annotators/annotation_elements/annotation_element_defaults.gd" -InputWrapper="*res://addons/surfacer/input_wrapper.gd" -Preloads="*res://addons/surfacer/preloads.gd" +ScaffoldConfig="*res://addons/scaffold/src/scaffold_config.gd" +ScaffoldUtils="*res://addons/scaffold/src/scaffold_utils.gd" +Time="*res://addons/scaffold/src/time.gd" +SaveState="*res://addons/scaffold/src/data/save_state.gd" +Analytics="*res://addons/scaffold/src/data/analytics.gd" +Log="*res://addons/scaffold/src/data/log.gd" +Audio="*res://addons/scaffold/src/audio.gd" +Nav="*res://addons/scaffold/src/navigation.gd" +SurfacerConfig="*res://addons/surfacer/src/surfacer_config.gd" +Geometry="*res://addons/surfacer/src/utils/geometry.gd" +DrawUtils="*res://addons/surfacer/src/utils/draw_utils.gd" +Profiler="*res://addons/surfacer/src/utils/profiler.gd" +AnnotationElementDefaults="*res://addons/surfacer/src/annotators/annotation_elements/annotation_element_defaults.gd" +InputWrapper="*res://addons/surfacer/src/input_wrapper.gd" +SquirrelAwayConfig="*res://src/squirrel_away_config.gd" [display] mouse_cursor/custom_image="res://assets/images/paw_cursor.png" mouse_cursor/custom_image_hotspot=Vector2( 5, 4 ) mouse_cursor/tooltip_position_offset=Vector2( 0, 0 ) -window/stretch/mode="2d" -window/stretch/aspect="keep" +window/stretch/mode="viewport" +window/stretch/aspect="expand" [editor_plugins] @@ -1584,6 +1572,16 @@ face_right={ "deadzone": 0.5, "events": [ ] } +screenshot={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":76,"unicode":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":80,"unicode":0,"echo":false,"script":null) + ] +} + +[input_devices] + +pointing/emulate_touch_from_mouse=true [layer_names] @@ -1595,5 +1593,8 @@ face_right={ [rendering] +quality/intended_usage/framebuffer_allocation=1 +quality/intended_usage/framebuffer_allocation.mobile=1 quality/2d/use_pixel_snap=true +environment/default_clear_color=Color( 0.152941, 0.192157, 0.286275, 1 ) environment/default_environment="res://assets/default_env.tres" diff --git a/src/export-shell.html b/src/export_shell.html similarity index 99% rename from src/export-shell.html rename to src/export_shell.html index e839b956..ab3a1046 100644 --- a/src/export-shell.html +++ b/src/export_shell.html @@ -151,7 +151,7 @@ diff --git a/src/levels/level_1.tscn b/src/levels/level_1.tscn index 8684e9e6..d5879518 100644 --- a/src/levels/level_1.tscn +++ b/src/levels/level_1.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/surfacer/surfacer_level.gd" type="Script" id=1] +[ext_resource path="res://src/squirrel_away_level.gd" type="Script" id=1] [ext_resource path="res://assets/images/foreground/tileset_old.tres" type="TileSet" id=2] [ext_resource path="res://src/background.tscn" type="PackedScene" id=3] diff --git a/src/levels/level_2.tscn b/src/levels/level_2.tscn index 4df04f14..738279e9 100644 --- a/src/levels/level_2.tscn +++ b/src/levels/level_2.tscn @@ -1,15 +1,9 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/surfacer/surfacer_level.gd" type="Script" id=1] +[ext_resource path="res://src/squirrel_away_level.gd" type="Script" id=1] [ext_resource path="res://assets/images/foreground/tileset_old.tres" type="TileSet" id=2] [ext_resource path="res://src/background.tscn" type="PackedScene" id=3] - - - - - - [node name="Level2" type="Node2D"] script = ExtResource( 1 ) diff --git a/src/levels/level_3.tscn b/src/levels/level_3.tscn index 4b2330f4..bdf6c668 100644 --- a/src/levels/level_3.tscn +++ b/src/levels/level_3.tscn @@ -1,15 +1,9 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/surfacer/surfacer_level.gd" type="Script" id=1] +[ext_resource path="res://src/squirrel_away_level.gd" type="Script" id=1] [ext_resource path="res://assets/images/foreground/tileset_old.tres" type="TileSet" id=2] [ext_resource path="res://src/background.tscn" type="PackedScene" id=3] - - - - - - [node name="Level3" type="Node2D"] script = ExtResource( 1 ) diff --git a/src/levels/level_4.tscn b/src/levels/level_4.tscn index f4892976..d1912fdc 100644 --- a/src/levels/level_4.tscn +++ b/src/levels/level_4.tscn @@ -1,15 +1,9 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/surfacer/surfacer_level.gd" type="Script" id=1] +[ext_resource path="res://src/squirrel_away_level.gd" type="Script" id=1] [ext_resource path="res://assets/images/foreground/tileset_old.tres" type="TileSet" id=2] [ext_resource path="res://src/background.tscn" type="PackedScene" id=3] - - - - - - [node name="Level4" type="Node2D"] script = ExtResource( 1 ) diff --git a/src/levels/level_5.tscn b/src/levels/level_5.tscn index a09d70a4..905656aa 100644 --- a/src/levels/level_5.tscn +++ b/src/levels/level_5.tscn @@ -1,15 +1,9 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/surfacer/surfacer_level.gd" type="Script" id=1] +[ext_resource path="res://src/squirrel_away_config.gd" type="Script" id=1] [ext_resource path="res://assets/images/foreground/tileset_old.tres" type="TileSet" id=2] [ext_resource path="res://src/background.tscn" type="PackedScene" id=3] - - - - - - [node name="Level5" type="Node2D"] script = ExtResource( 1 ) diff --git a/src/levels/level_6.tscn b/src/levels/level_6.tscn index 46c499aa..b4e8f617 100644 --- a/src/levels/level_6.tscn +++ b/src/levels/level_6.tscn @@ -1,13 +1,9 @@ [gd_scene load_steps=4 format=2] -[ext_resource path="res://addons/surfacer/surfacer_level.gd" type="Script" id=1] +[ext_resource path="res://src/squirrel_away_level.gd" type="Script" id=1] [ext_resource path="res://src/background.tscn" type="PackedScene" id=3] [ext_resource path="res://assets/images/foreground/tileset.tres" type="TileSet" id=4] - - - - [node name="Level6" type="Node2D"] script = ExtResource( 1 ) diff --git a/src/levels/level_7.tscn b/src/levels/level_7.tscn index 7c0f2198..9a969fb9 100644 --- a/src/levels/level_7.tscn +++ b/src/levels/level_7.tscn @@ -2,11 +2,7 @@ [ext_resource path="res://src/background.tscn" type="PackedScene" id=1] [ext_resource path="res://assets/images/foreground/tileset.tres" type="TileSet" id=2] -[ext_resource path="res://addons/surfacer/surfacer_level.gd" type="Script" id=3] - - - - +[ext_resource path="res://src/squirrel_away_level.gd" type="Script" id=3] [node name="Level7" type="Node2D"] script = ExtResource( 3 ) diff --git a/src/main.gd b/src/main.gd index 993102cc..68c5da50 100644 --- a/src/main.gd +++ b/src/main.gd @@ -488,7 +488,17 @@ class_name Main # ############################################################################### -const TEST_RUNNER_SCENE_RESOURCE_PATH := "res://test/test_runner.tscn" +func _init() -> void: + ScaffoldUtils.print("Main._init") + +func _enter_tree() -> void: + var surfacer_bootstrap := SurfacerBootstrap.new() + surfacer_bootstrap.on_app_ready(SquirrelAwayConfig.app_manifest, self) + ScaffoldConfig.next_level_resource_path = \ + SquirrelAwayConfig.level_resource_path + + if OS.get_name() == "HTML5": + JavaScript.eval("window.onAppReady()") func _notification(what): if what == MainLoop.NOTIFICATION_WM_GO_BACK_REQUEST: @@ -496,33 +506,12 @@ func _notification(what): # quitting the app. get_tree().quit() -func _enter_tree() -> void: - if SurfacerConfig.IN_TEST_MODE: - _bootstrap_test() - else: - _bootstrap_app() - func _input(event: InputEvent) -> void: # Close the welcome panel on any mouse or key click event. - if is_instance_valid(Global.welcome_panel) and \ + if is_instance_valid(SurfacerConfig.welcome_panel) and \ (event is InputEventMouseButton or \ event is InputEventScreenTouch or \ event is InputEventKey) and \ - Global.is_level_ready: - ScaffoldConfig.canvas_layers.layers.hud.remove_child( \ - Global.welcome_panel) - Global.welcome_panel.queue_free() - Global.welcome_panel = null - -func _bootstrap_app() -> void: - var scaffold_config := SquirrelAwayConfig.new() - scaffold_config.configure_scaffolding(self) - - if OS.get_name() == "HTML5": - JavaScript.eval("window.onAppReady()") - -func _bootstrap_test() -> void: - var scene_path := TEST_RUNNER_SCENE_RESOURCE_PATH - var test_scene = ScaffoldUtils.add_scene( \ - self, \ - scene_path) + SurfacerConfig.is_level_ready: + SurfacerConfig.welcome_panel.queue_free() + SurfacerConfig.welcome_panel = null diff --git a/src/main_menu_image.tscn b/src/main_menu_image.tscn index dc3a3325..53401cd8 100644 --- a/src/main_menu_image.tscn +++ b/src/main_menu_image.tscn @@ -50,6 +50,8 @@ __meta__ = { } [node name="AnimatedSprite" type="AnimatedSprite" parent="."] +position = Vector2( -21, 0 ) +scale = Vector2( 2, 2 ) frames = SubResource( 9 ) -frame = 4 +frame = 6 playing = true diff --git a/src/players/cat/cat_player.gd b/src/players/cat/cat_player.gd index fcb58b94..c238ad4a 100644 --- a/src/players/cat/cat_player.gd +++ b/src/players/cat/cat_player.gd @@ -1,43 +1,22 @@ extends Player class_name CatPlayer -const JUMP_SFX_STREAM := preload("res://assets/sfx/cat_jump.wav") -const LAND_SFX_STREAM := preload("res://assets/sfx/cat_land.wav") -const CONTACT_SFX_STREAM := preload("res://assets/sfx/contact.wav") - # Dictionary var current_colliding_computer_players := {} var just_collided_with_new_computer_player := false -var jump_sfx_player: AudioStreamPlayer -var land_sfx_player: AudioStreamPlayer -var contact_sfx_player: AudioStreamPlayer - func _init().("cat") -> void: - _init_sfx_players() - -func _init_sfx_players() -> void: - jump_sfx_player = AudioStreamPlayer.new() - jump_sfx_player.stream = JUMP_SFX_STREAM - add_child(jump_sfx_player) - - land_sfx_player = AudioStreamPlayer.new() - land_sfx_player.stream = LAND_SFX_STREAM - add_child(land_sfx_player) - - contact_sfx_player = AudioStreamPlayer.new() - contact_sfx_player.stream = CONTACT_SFX_STREAM - add_child(contact_sfx_player) + pass func _process_sfx() -> void: if just_triggered_jump: - jump_sfx_player.play() + Audio.play_sound("cat_jump") if surface_state.just_left_air: - land_sfx_player.play() + Audio.play_sound("cat_land") if just_collided_with_new_computer_player: - contact_sfx_player.play() + Audio.play_sound("contact") func _update_surface_state(preserves_just_changed_state := false) -> void: ._update_surface_state(preserves_just_changed_state) @@ -61,7 +40,7 @@ func _check_for_squirrel_collision() -> void: # Calculate current computer-player collisions. var colliding_computer_players := [] for computer_player in get_tree().get_nodes_in_group( \ - SurfacerConfig.GROUP_NAME_COMPUTER_PLAYERS): + SurfacerConfig.group_name_computer_players): collider_half_width_height = \ computer_player.movement_params.collider_half_width_height if collider_half_width_height.x > collider_half_width_height.y: diff --git a/src/players/squirrel/squirrel_player.gd b/src/players/squirrel/squirrel_player.gd index c7d72314..ab87e0e0 100644 --- a/src/players/squirrel/squirrel_player.gd +++ b/src/players/squirrel/squirrel_player.gd @@ -1,46 +1,25 @@ extends Player class_name SquirrelPlayer -const JUMP_SFX_STREAM := preload("res://assets/sfx/squirrel_jump.wav") -const LAND_SFX_STREAM := preload("res://assets/sfx/squirrel_land.wav") -const YELL_SFX_STREAM := preload("res://assets/sfx/squirrel_yell.wav") - const TILE_MAP_COLLISION_LAYER := 7 const SQUIRREL_SPAWN_COLLISION_MARGIN := 1.0 const SQUIRREL_SPAWN_LEVEL_OUTER_MARGIN := 256.0 const CAT_IS_CLOSE_DISTANCE_SQUARED_THRESHOLD := 512.0 * 512.0 const SQUIRREL_TRIGGER_NEW_NAVIGATION_INTERVAL_SEC := 3.0 -var jump_sfx_player: AudioStreamPlayer -var land_sfx_player: AudioStreamPlayer -var yell_sfx_player: AudioStreamPlayer - var was_cat_close_last_frame := false var previous_destination := \ MovementUtils.create_position_without_surface(Vector2.INF) func _init().("squirrel") -> void: - _init_sfx_players() - -func _init_sfx_players() -> void: - jump_sfx_player = AudioStreamPlayer.new() - jump_sfx_player.stream = JUMP_SFX_STREAM - add_child(jump_sfx_player) - - land_sfx_player = AudioStreamPlayer.new() - land_sfx_player.stream = LAND_SFX_STREAM - add_child(land_sfx_player) - - yell_sfx_player = AudioStreamPlayer.new() - yell_sfx_player.stream = YELL_SFX_STREAM - add_child(yell_sfx_player) + pass func _process_sfx() -> void: if just_triggered_jump: - jump_sfx_player.play() + Audio.play_sound("squirrel_jump") if surface_state.just_left_air: - land_sfx_player.play() + Audio.play_sound("squirrel_land") func _ready() -> void: if is_fake: @@ -66,7 +45,7 @@ func _update_navigator(delta_sec: float) -> void: if is_human_player: return - var cat_position: Vector2 = Global.current_player_for_clicks.position + var cat_position: Vector2 = SurfacerConfig.current_player_for_clicks.position var is_cat_close := \ self.position.distance_squared_to(cat_position) <= \ CAT_IS_CLOSE_DISTANCE_SQUARED_THRESHOLD @@ -84,7 +63,7 @@ func _start_new_navigation() -> void: Profiler.start(ProfilerMetric.START_NEW_SQUIRREL_NAVIGATION) var possible_destinations: Array = \ - Global.current_level.squirrel_destinations + ScaffoldConfig.level.squirrel_destinations var index: int var next_destination := previous_destination while next_destination.target_point == Vector2.INF or \ @@ -97,7 +76,7 @@ func _start_new_navigation() -> void: navigator.navigate_to_position(next_destination) previous_destination = next_destination - var duration := \ + var duration: float = \ Profiler.stop(ProfilerMetric.START_NEW_SQUIRREL_NAVIGATION) print_msg(("SQUIRREL NEW NAV ;" + \ "%8.3fs; " + \ diff --git a/src/squirrel_away_config.gd b/src/squirrel_away_config.gd index 9e2e1538..1d5d2251 100644 --- a/src/squirrel_away_config.gd +++ b/src/squirrel_away_config.gd @@ -1,5 +1,4 @@ extends Node -class_name SquirrelAwayConfig var debug := OS.is_debug_build() @@ -29,17 +28,98 @@ var third_party_license_text := \ var special_thanks_text := """ """ -const _LEVEL_RESOURCE_PATH := "res://src/levels/level_6.tscn" +var level_resource_path := "res://src/levels/level_6.tscn" -var _APP_MANIFEST := { +var test_runner_resource_path := "res://test/test_runner.tscn" + +var sounds_manifest := [ + { + name = "fall", + volume_db = 18.0, + path_prefix = "res://addons/scaffold/assets/sounds/", + }, + { + name = "cadence", + volume_db = 8.0, + path_prefix = "res://addons/scaffold/assets/sounds/", + }, + { + name = "jump", + volume_db = -6.0, + path_prefix = "res://addons/scaffold/assets/sounds/", + }, + { + name = "land", + volume_db = -0.0, + path_prefix = "res://addons/scaffold/assets/sounds/", + }, + { + name = "menu_select", + volume_db = -2.0, + path_prefix = "res://addons/scaffold/assets/sounds/", + }, + { + name = "menu_select_fancy", + volume_db = -6.0, + path_prefix = "res://addons/scaffold/assets/sounds/", + }, + { + name = "walk", + volume_db = 15.0, + path_prefix = "res://addons/scaffold/assets/sounds/", + }, + { + name = "achievement", + volume_db = 12.0, + path_prefix = "res://addons/scaffold/assets/sounds/", + }, + { + name = "single_cat_snore", + volume_db = 17.0, + path_prefix = "res://addons/scaffold/assets/sounds/", + }, + { + name = "cat_jump", + volume_db = 0.0, + }, + { + name = "cat_land", + volume_db = 0.0, + }, + { + name = "contact", + volume_db = 0.0, + }, + { + name = "squirrel_jump", + volume_db = 0.0, + }, + { + name = "squirrel_land", + volume_db = 0.0, + }, + { + name = "squirrel_yell", + volume_db = 0.0, + }, +] + +var music_manifest := [ + { + name = "on_a_quest", + volume_db = 0.0, + }, +] + +var app_manifest := { # TODO: Remember to reset these when creating releases. debug = debug, #debug = false playtest = false, debug_window_size = debug_window_size, - app_name = "TODO", - app_id = "games.snoringcat.TODO", + app_name = "Squirrel Away", + app_id = "games.snoringcat.squirrel_away", app_version = "0.0.1", #273149 @@ -63,10 +143,20 @@ var _APP_MANIFEST := { screen_exclusions = [ "rate_app_screen.tscn", + "data_agreement_screen.tscn", + "confirm_data_deletion_screen.tscn", ], screen_inclusions = [ ], + sounds_manifest = sounds_manifest, + default_sounds_path_prefix = "res://assets/sounds/", + default_sounds_file_suffix = ".wav", + default_sounds_bus_index = 1, + music_manifest = music_manifest, + default_music_path_prefix = "res://addons/scaffold/assets/music/", + default_music_file_suffix = ".ogg", + default_music_bus_index = 2, main_menu_music = "on_a_quest", third_party_license_text = third_party_license_text, @@ -105,12 +195,14 @@ var _APP_MANIFEST := { support_url_base = "", log_gestures_url = "", - main_font_normal = \ - preload("res://assets/fonts/main_font_normal.tres"), - main_font_large = \ - preload("res://assets/fonts/main_font_l.tres"), + main_font_m = \ + preload("res://addons/scaffold/assets/fonts/main_font_m.tres"), + main_font_xs = \ + preload("res://addons/scaffold/assets/fonts/main_font_xs.tres"), + main_font_l = \ + preload("res://addons/scaffold/assets/fonts/main_font_l.tres"), main_font_xl = \ - preload("res://assets/fonts/main_font_xl.tres"), + preload("res://addons/scaffold/assets/fonts/main_font_xl.tres"), cell_size = Vector2(32.0, 32.0), @@ -118,56 +210,5 @@ var _APP_MANIFEST := { aspect_ratio_min = 1.0 / 1.3, } -var _SOUNDS_MANIFEST := [ - { - name = "fall", - volume_db = 18.0, - }, - { - name = "cadence", - volume_db = 8.0, - }, - { - name = "jump", - volume_db = -6.0, - }, - { - name = "land", - volume_db = -0.0, - }, - { - name = "menu_select", - volume_db = -2.0, - }, - { - name = "menu_select_fancy", - volume_db = -6.0, - }, - { - name = "walk", - volume_db = 15.0, - }, - { - name = "achievement", - volume_db = 12.0, - }, - { - name = "single_cat_snore", - volume_db = 17.0, - }, -] - -var _MUSIC_MANIFEST := [ - { - name = "on_a_quest", - volume_db = 0.0, - }, -] - -func configure_scaffolding(main: Node) -> void: - ScaffoldConfig.register_app_config(_APP_MANIFEST) - ScaffoldConfig.next_level_resource_path = _LEVEL_RESOURCE_PATH - Audio.register_sounds(_SOUNDS_MANIFEST) - Audio.register_music(_MUSIC_MANIFEST) - var scaffold_bootstrap := ScaffoldBootstrap.new() - scaffold_bootstrap.on_app_ready(main) +func _init() -> void: + ScaffoldUtils.print("SquirrelAwayConfig._init") diff --git a/src/squirrel_away_level.gd b/src/squirrel_away_level.gd index 1b0bfe69..904516da 100644 --- a/src/squirrel_away_level.gd +++ b/src/squirrel_away_level.gd @@ -1,35 +1,23 @@ extends SurfacerLevel class_name SquirrelAwayLevel -const _UTILITY_PANEL_RESOURCE_PATH := \ - "res://addons/surfacer/gui/panels/utility_panel.tscn" const _WELCOME_PANEL_RESOURCE_PATH := \ - "res://addons/surfacer/gui/panels/welcome_panel.tscn" - -var annotators: Annotators + "res://addons/surfacer/src/gui/panels/welcome_panel.tscn" func start() -> void: - ScaffoldConfig.level = self - - annotators = Annotators.new() - add_child(annotators) - - var utility_panel: UtilityPanel = ScaffoldUtils.add_scene( \ - ScaffoldConfig.canvas_layers.layers.hud, \ - _UTILITY_PANEL_RESOURCE_PATH) - Global.utility_panel = utility_panel + .start() var welcome_panel: WelcomePanel = ScaffoldUtils.add_scene( \ ScaffoldConfig.canvas_layers.layers.hud, \ _WELCOME_PANEL_RESOURCE_PATH) - Global.welcome_panel = welcome_panel + SurfacerConfig.welcome_panel = welcome_panel # FIXME: Move this player creation (and readiness recording) back into # Level. # Add the player after removing the loading screen, since the camera # will track the player, which makes the loading screen look offset. add_player( \ - Global.player_params[SurfacerConfig.DEFAULT_PLAYER_NAME] \ + SurfacerConfig.player_params[SurfacerConfig.default_player_name] \ .movement_params.player_resource_path, \ Vector2.ZERO, \ true, \ @@ -40,12 +28,15 @@ func start() -> void: ] for squirrel_position in starting_squirrel_positions: add_player( \ - Global.player_params["squirrel"].movement_params \ + SurfacerConfig.player_params["squirrel"].movement_params \ .player_resource_path, \ squirrel_position, \ false, \ false) - annotators.on_level_ready() + + SurfacerConfig.annotators.on_level_ready() + + Audio.play_music("on_a_quest") func destroy() -> void: pass diff --git a/tier_tile_map.gd b/tier_tile_map.gd deleted file mode 100644 index bcf6846a..00000000 --- a/tier_tile_map.gd +++ /dev/null @@ -1,2 +0,0 @@ -extends TileMap -class_name TierTileMap diff --git a/tier_tile_map.tscn b/tier_tile_map.tscn deleted file mode 100644 index a9ef23d3..00000000 --- a/tier_tile_map.tscn +++ /dev/null @@ -1,16 +0,0 @@ -[gd_scene load_steps=3 format=2] - -[ext_resource path="res://src/level/tileset.tres" type="TileSet" id=1] -[ext_resource path="res://src/level/tier_tile_map.gd" type="Script" id=2] - -[node name="TierTileMap" type="TileMap" groups=[ -"tier_tilemaps", -]] -light_mask = 4 -tile_set = ExtResource( 1 ) -cell_size = Vector2( 32, 32 ) -cell_custom_transform = Transform2D( 32, 0, 0, 32, 0, 0 ) -collision_mask = 0 -occluder_light_mask = 4 -format = 1 -script = ExtResource( 2 ) diff --git a/tileset.tres b/tileset.tres deleted file mode 100644 index 31d723ba..00000000 --- a/tileset.tres +++ /dev/null @@ -1,1723 +0,0 @@ -[gd_resource type="TileSet" load_steps=157 format=2] - -[ext_resource path="res://assets/images/tiles/snow-platform-tile-template.png" type="Texture" id=1] -[ext_resource path="res://assets/images/tiles/wall-tile-template.png" type="Texture" id=2] -[ext_resource path="res://assets/images/tiles/wall-ice-tile-template.png" type="Texture" id=3] -[ext_resource path="res://assets/images/tiles/ice-platform-tile-template.png" type="Texture" id=4] -[ext_resource path="res://src/level/tileset_overrides.gd" type="Script" id=5] -[ext_resource path="res://assets/images/tiles/cairn.png" type="Texture" id=6] - -[sub_resource type="OccluderPolygon2D" id=1] -polygon = PoolVector2Array( 32, 32, 32, 32, 0, 32, 0, 1.80576, 2.11291, 0, 29.9277, 0, 32, 2.36654 ) - -[sub_resource type="OccluderPolygon2D" id=2] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=3] -polygon = PoolVector2Array( 32, 0, 32, 0, 32, 26.7166, 30.0399, 29.0719, 26.4509, 30.9786, 19.8337, 30.9786, 18.0391, 31.6515, 12.9921, 32, 11.4219, 30.0813, 8.05721, 30.9786, 4.13173, 30.9786, 2.00076, 28.9598, 0, 27.0531, 0, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0 ) - -[sub_resource type="OccluderPolygon2D" id=4] -polygon = PoolVector2Array( 29.8156, 0.129463, 29.8156, 0.129463, 32, 2.37258, 32, 24.0188, 29.1426, 29.178, 21.9646, 32, 10.076, 32, 5.81408, 30.9725, 0.991341, 24.6917, 0, 18.7475, 0, 2.03613, 2.11291, 0 ) - -[sub_resource type="OccluderPolygon2D" id=5] -polygon = PoolVector2Array( 32, 0, 32, 0, 32, 32, 0, 32, 0, 2.03007, 1.96539, 0 ) - -[sub_resource type="OccluderPolygon2D" id=6] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=7] -polygon = PoolVector2Array( 0, 0, 0, 0, 32, 0, 32, 32, 9.9285, 32, 6.00303, 30.8664, 3.08695, 27.9504, 1.06814, 24.81, 0, 18.7535 ) - -[sub_resource type="OccluderPolygon2D" id=8] -polygon = PoolVector2Array( 32, 0, 32, 0, 32, 32, 9.9285, 32, 6.00303, 31.0847, 1.06814, 24.5796, 0, 18.6353, 0, 1.92396, 2.18969, 0, 32, 0, 32, 0 ) - -[sub_resource type="OccluderPolygon2D" id=9] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=10] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=11] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=12] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=13] -polygon = PoolVector2Array( 32, 32, 32, 32, 0, 32, 0, 0, 29.8216, 0, 32, 2.36654 ) - -[sub_resource type="OccluderPolygon2D" id=14] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=15] -polygon = PoolVector2Array( 0, 0, 0, 0, 32, 0, 32, 24.0249, 29.0365, 29.0719, 21.9707, 31.7637, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=16] -polygon = PoolVector2Array( 29.8216, 0, 29.8216, 0, 32, 2.37258, 32, 23.9066, 28.9244, 28.8416, 21.8585, 32, 0, 32, 0, 0 ) - -[sub_resource type="OccluderPolygon2D" id=17] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=18] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=19] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=20] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=21] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=22] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=23] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=24] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=25] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=26] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=27] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=28] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=29] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=30] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=31] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=32] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=33] -polygon = PoolVector2Array( 32, 32, 32, 32, 0, 32, 0, 2.25438, 2.0654, 0, 32, 0 ) - -[sub_resource type="OccluderPolygon2D" id=34] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=35] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=36] -polygon = PoolVector2Array( 0, 0, 0, 0, 32, 0, 32, 32, 10.0285, 32, 6.10306, 30.9725, 0.943848, 24.8039, 0, 18.8596 ) - -[sub_resource type="OccluderPolygon2D" id=37] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=38] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=39] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=40] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=41] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=42] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=43] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=44] -polygon = PoolVector2Array( 32, 32, 32, 32, 0, 32, 0, 0, 29.9984, 0, 32, 2.4787 ) - -[sub_resource type="OccluderPolygon2D" id=45] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=46] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=47] -polygon = PoolVector2Array( 0, 32, 0, 32, 0, 0, 32, 0, 32, 23.9066, 28.8769, 29.2902, 21.6989, 32 ) - -[sub_resource type="OccluderPolygon2D" id=48] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=49] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=50] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=51] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=52] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=53] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=54] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=55] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=56] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=57] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=58] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=59] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=60] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=61] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=62] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=63] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=64] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=65] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=66] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=67] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=68] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=69] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=70] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=71] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=72] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=73] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=74] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=75] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=76] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=77] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=78] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=79] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=80] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=81] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=82] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=83] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=84] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=85] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=86] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=87] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=88] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=89] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=90] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=91] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=92] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=93] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=94] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=95] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=96] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=97] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=98] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=99] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=100] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=101] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=102] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=103] -polygon = PoolVector2Array( 0, 1.91792, 0, 1.91792, 2.11292, 0, 30.0399, 0, 32, 2.4787, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=104] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=105] -polygon = PoolVector2Array( 32, 0, 32, 0, 32, 26.6338, 30.0399, 28.7648, 27.9089, 30.8957, 19.7215, 31.0079, 17.927, 31.6808, 12.88, 32, 10.076, 29.8863, 8.05721, 31.2322, 3.90742, 31.0079, 2.00076, 28.8769, 0, 26.9703, 0, 0 ) - -[sub_resource type="OccluderPolygon2D" id=106] -polygon = PoolVector2Array( 29.8156, 0, 29.8156, 0, 32, 2.26043, 32, 23.9066, 29.2548, 28.8416, 21.9646, 32, 9.96387, 32, 6.0384, 30.9725, 1.10351, 24.9161, 0, 18.9718, 0, 2.14828, 2.00076, 0 ) - -[sub_resource type="OccluderPolygon2D" id=107] -polygon = PoolVector2Array( 0, 1.80576, 0, 1.80576, 1.96539, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=108] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=109] -polygon = PoolVector2Array( 32, 0, 32, 0, 32, 32, 9.9285, 32, 6.11518, 30.8957, 1.06814, 24.9514, 0, 18.7828, 0, 0 ) - -[sub_resource type="OccluderPolygon2D" id=110] -polygon = PoolVector2Array( 32, 32, 32, 32, 9.9285, 32, 6.11518, 30.9725, 0.955986, 24.9161, 0, 18.8596, 0, 1.92396, 2.07755, 0, 32, 0 ) - -[sub_resource type="OccluderPolygon2D" id=111] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=112] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=113] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=114] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=115] -polygon = PoolVector2Array( 0, 0, 0, 0, 29.9338, 0, 32, 2.36654, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=116] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=117] -polygon = PoolVector2Array( 0, 0, 0, 0, 32, 0, 32, 24.1663, 29.1487, 28.8769, 21.8585, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=118] -polygon = PoolVector2Array( 29.8217, 0, 29.8217, 0, 32, 2.14828, 32, 23.7945, 29.1487, 28.5051, 21.9707, 32, 0, 32, 0, 0 ) - -[sub_resource type="OccluderPolygon2D" id=119] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=120] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=121] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=122] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=123] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=124] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=125] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=126] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=127] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=128] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=129] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=130] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=131] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=132] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=133] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=134] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=135] -polygon = PoolVector2Array( 0, 1.6936, 0, 1.6936, 1.84186, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=136] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=137] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=138] -polygon = PoolVector2Array( 0, 0, 0, 0, 32, 0, 32, 32, 10.3658, 32, 6.10382, 31.0847, 1.05676, 25.1404, 0, 18.8596 ) - -[sub_resource type="OccluderPolygon2D" id=139] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=140] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=141] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=142] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=143] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=144] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=145] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=146] -polygon = PoolVector2Array( 0, 0, 0, 0, 29.9992, 0, 32, 2.14223, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=147] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=148] -polygon = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="OccluderPolygon2D" id=149] -polygon = PoolVector2Array( 0, 0, 0, 0, 32, 0, 32, 23.7945, 29.2141, 29.0659, 22.1483, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=150] -points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[resource] -0/name = "wall_tile" -0/texture = ExtResource( 2 ) -0/tex_offset = Vector2( 0, 0 ) -0/modulate = Color( 1, 1, 1, 1 ) -0/region = Rect2( 0, 0, 416, 128 ) -0/tile_mode = 1 -0/autotile/bitmask_mode = 1 -0/autotile/bitmask_flags = [ Vector2( 0, 0 ), 144, Vector2( 0, 1 ), 146, Vector2( 0, 2 ), 18, Vector2( 0, 3 ), 16, Vector2( 1, 0 ), 176, Vector2( 1, 1 ), 178, Vector2( 1, 2 ), 50, Vector2( 1, 3 ), 48, Vector2( 2, 0 ), 184, Vector2( 2, 1 ), 186, Vector2( 2, 2 ), 58, Vector2( 2, 3 ), 56, Vector2( 3, 0 ), 152, Vector2( 3, 1 ), 154, Vector2( 3, 2 ), 26, Vector2( 3, 3 ), 24, Vector2( 4, 0 ), 187, Vector2( 4, 1 ), 434, Vector2( 4, 2 ), 182, Vector2( 4, 3 ), 250, Vector2( 5, 0 ), 440, Vector2( 5, 1 ), 510, Vector2( 5, 2 ), 447, Vector2( 5, 3 ), 62, Vector2( 6, 0 ), 248, Vector2( 6, 1 ), 507, Vector2( 6, 2 ), 255, Vector2( 6, 3 ), 59, Vector2( 7, 0 ), 190, Vector2( 7, 1 ), 218, Vector2( 7, 2 ), 155, Vector2( 7, 3 ), 442, Vector2( 8, 0 ), 432, Vector2( 8, 1 ), 438, Vector2( 8, 2 ), 446, Vector2( 8, 3 ), 54, Vector2( 9, 0 ), 506, Vector2( 9, 1 ), 254, Vector2( 9, 2 ), 511, Vector2( 9, 3 ), 63, Vector2( 10, 0 ), 504, Vector2( 10, 2 ), 443, Vector2( 10, 3 ), 191, Vector2( 11, 0 ), 216, Vector2( 11, 1 ), 251, Vector2( 11, 2 ), 219, Vector2( 11, 3 ), 27, Vector2( 12, 0 ), 504, Vector2( 12, 1 ), 438, Vector2( 12, 2 ), 219, Vector2( 12, 3 ), 511 ] -0/autotile/icon_coordinate = Vector2( 0, 3 ) -0/autotile/tile_size = Vector2( 32, 32 ) -0/autotile/spacing = 0 -0/autotile/occluder_map = [ Vector2( 0, 0 ), SubResource( 1 ), Vector2( 0, 1 ), SubResource( 2 ), Vector2( 0, 2 ), SubResource( 3 ), Vector2( 0, 3 ), SubResource( 4 ), Vector2( 1, 0 ), SubResource( 5 ), Vector2( 1, 1 ), SubResource( 6 ), Vector2( 1, 2 ), SubResource( 7 ), Vector2( 1, 3 ), SubResource( 8 ), Vector2( 2, 0 ), SubResource( 9 ), Vector2( 2, 1 ), SubResource( 10 ), Vector2( 2, 2 ), SubResource( 11 ), Vector2( 2, 3 ), SubResource( 12 ), Vector2( 3, 0 ), SubResource( 13 ), Vector2( 3, 1 ), SubResource( 14 ), Vector2( 3, 2 ), SubResource( 15 ), Vector2( 3, 3 ), SubResource( 16 ), Vector2( 4, 0 ), SubResource( 17 ), Vector2( 4, 1 ), SubResource( 18 ), Vector2( 4, 2 ), SubResource( 19 ), Vector2( 4, 3 ), SubResource( 20 ), Vector2( 5, 0 ), SubResource( 21 ), Vector2( 5, 1 ), SubResource( 22 ), Vector2( 5, 2 ), SubResource( 23 ), Vector2( 5, 3 ), SubResource( 24 ), Vector2( 6, 0 ), SubResource( 25 ), Vector2( 6, 1 ), SubResource( 26 ), Vector2( 6, 2 ), SubResource( 27 ), Vector2( 6, 3 ), SubResource( 28 ), Vector2( 7, 0 ), SubResource( 29 ), Vector2( 7, 1 ), SubResource( 30 ), Vector2( 7, 2 ), SubResource( 31 ), Vector2( 7, 3 ), SubResource( 32 ), Vector2( 8, 0 ), SubResource( 33 ), Vector2( 8, 1 ), SubResource( 34 ), Vector2( 8, 2 ), SubResource( 35 ), Vector2( 8, 3 ), SubResource( 36 ), Vector2( 9, 0 ), SubResource( 37 ), Vector2( 9, 1 ), SubResource( 38 ), Vector2( 9, 2 ), SubResource( 39 ), Vector2( 9, 3 ), SubResource( 40 ), Vector2( 10, 0 ), SubResource( 41 ), Vector2( 10, 2 ), SubResource( 42 ), Vector2( 10, 3 ), SubResource( 43 ), Vector2( 11, 0 ), SubResource( 44 ), Vector2( 11, 1 ), SubResource( 45 ), Vector2( 11, 2 ), SubResource( 46 ), Vector2( 11, 3 ), SubResource( 47 ), Vector2( 12, 0 ), SubResource( 48 ), Vector2( 12, 1 ), SubResource( 49 ), Vector2( 12, 2 ), SubResource( 50 ), Vector2( 12, 3 ), SubResource( 51 ) ] -0/autotile/navpoly_map = [ ] -0/autotile/priority_map = [ Vector3( 8, 1, 4 ), Vector3( 9, 2, 6 ), Vector3( 10, 0, 3 ), Vector3( 11, 2, 4 ) ] -0/autotile/z_index_map = [ ] -0/occluder_offset = Vector2( 0, 0 ) -0/navigation_offset = Vector2( 0, 0 ) -0/shape_offset = Vector2( 0, 0 ) -0/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -0/shape = SubResource( 52 ) -0/shape_one_way = false -0/shape_one_way_margin = 1.0 -0/shapes = [ { -"autotile_coord": Vector2( 0, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 52 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 1, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 53 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 2, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 54 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 3, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 55 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 4, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 56 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 5, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 57 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 6, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 58 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 7, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 59 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 8, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 60 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 9, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 61 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 10, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 62 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 11, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 63 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 0, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 64 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 1, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 65 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 2, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 66 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 3, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 67 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 4, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 68 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 5, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 69 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 6, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 70 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 7, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 71 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 8, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 72 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 9, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 73 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 11, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 74 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 0, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 75 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 1, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 76 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 2, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 77 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 3, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 78 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 4, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 79 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 5, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 80 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 6, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 81 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 7, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 82 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 8, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 83 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 9, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 84 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 10, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 85 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 11, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 86 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 0, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 87 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 1, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 88 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 2, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 89 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 3, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 90 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 4, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 91 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 5, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 92 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 6, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 93 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 7, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 94 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 8, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 95 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 9, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 96 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 10, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 97 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 11, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 98 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 12, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 99 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 12, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 100 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 12, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 101 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 12, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 102 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -} ] -0/z_index = 0 -1/name = "ice_wall_tile" -1/texture = ExtResource( 3 ) -1/tex_offset = Vector2( 0, 0 ) -1/modulate = Color( 1, 1, 1, 1 ) -1/region = Rect2( 0, 0, 384, 128 ) -1/tile_mode = 1 -1/autotile/bitmask_mode = 1 -1/autotile/bitmask_flags = [ Vector2( 0, 0 ), 144, Vector2( 0, 1 ), 146, Vector2( 0, 2 ), 18, Vector2( 0, 3 ), 16, Vector2( 1, 0 ), 176, Vector2( 1, 1 ), 178, Vector2( 1, 2 ), 50, Vector2( 1, 3 ), 48, Vector2( 2, 0 ), 184, Vector2( 2, 1 ), 186, Vector2( 2, 2 ), 58, Vector2( 2, 3 ), 56, Vector2( 3, 0 ), 152, Vector2( 3, 1 ), 154, Vector2( 3, 2 ), 26, Vector2( 3, 3 ), 24, Vector2( 4, 0 ), 187, Vector2( 4, 1 ), 434, Vector2( 4, 2 ), 182, Vector2( 4, 3 ), 250, Vector2( 5, 0 ), 440, Vector2( 5, 1 ), 510, Vector2( 5, 2 ), 447, Vector2( 5, 3 ), 62, Vector2( 6, 0 ), 248, Vector2( 6, 1 ), 507, Vector2( 6, 2 ), 255, Vector2( 6, 3 ), 59, Vector2( 7, 0 ), 190, Vector2( 7, 1 ), 218, Vector2( 7, 2 ), 155, Vector2( 7, 3 ), 442, Vector2( 8, 0 ), 432, Vector2( 8, 1 ), 438, Vector2( 8, 2 ), 446, Vector2( 8, 3 ), 54, Vector2( 9, 0 ), 506, Vector2( 9, 1 ), 254, Vector2( 9, 2 ), 511, Vector2( 9, 3 ), 63, Vector2( 10, 0 ), 504, Vector2( 10, 2 ), 443, Vector2( 10, 3 ), 191, Vector2( 11, 0 ), 216, Vector2( 11, 1 ), 251, Vector2( 11, 2 ), 219, Vector2( 11, 3 ), 27 ] -1/autotile/icon_coordinate = Vector2( 0, 3 ) -1/autotile/tile_size = Vector2( 32, 32 ) -1/autotile/spacing = 0 -1/autotile/occluder_map = [ Vector2( 0, 0 ), SubResource( 103 ), Vector2( 0, 1 ), SubResource( 104 ), Vector2( 0, 2 ), SubResource( 105 ), Vector2( 0, 3 ), SubResource( 106 ), Vector2( 1, 0 ), SubResource( 107 ), Vector2( 1, 1 ), SubResource( 108 ), Vector2( 1, 2 ), SubResource( 109 ), Vector2( 1, 3 ), SubResource( 110 ), Vector2( 2, 0 ), SubResource( 111 ), Vector2( 2, 1 ), SubResource( 112 ), Vector2( 2, 2 ), SubResource( 113 ), Vector2( 2, 3 ), SubResource( 114 ), Vector2( 3, 0 ), SubResource( 115 ), Vector2( 3, 1 ), SubResource( 116 ), Vector2( 3, 2 ), SubResource( 117 ), Vector2( 3, 3 ), SubResource( 118 ), Vector2( 4, 0 ), SubResource( 119 ), Vector2( 4, 1 ), SubResource( 120 ), Vector2( 4, 2 ), SubResource( 121 ), Vector2( 4, 3 ), SubResource( 122 ), Vector2( 5, 0 ), SubResource( 123 ), Vector2( 5, 1 ), SubResource( 124 ), Vector2( 5, 2 ), SubResource( 125 ), Vector2( 5, 3 ), SubResource( 126 ), Vector2( 6, 0 ), SubResource( 127 ), Vector2( 6, 1 ), SubResource( 128 ), Vector2( 6, 2 ), SubResource( 129 ), Vector2( 6, 3 ), SubResource( 130 ), Vector2( 7, 0 ), SubResource( 131 ), Vector2( 7, 1 ), SubResource( 132 ), Vector2( 7, 2 ), SubResource( 133 ), Vector2( 7, 3 ), SubResource( 134 ), Vector2( 8, 0 ), SubResource( 135 ), Vector2( 8, 1 ), SubResource( 136 ), Vector2( 8, 2 ), SubResource( 137 ), Vector2( 8, 3 ), SubResource( 138 ), Vector2( 9, 0 ), SubResource( 139 ), Vector2( 9, 1 ), SubResource( 140 ), Vector2( 9, 2 ), SubResource( 141 ), Vector2( 9, 3 ), SubResource( 142 ), Vector2( 10, 0 ), SubResource( 143 ), Vector2( 10, 2 ), SubResource( 144 ), Vector2( 10, 3 ), SubResource( 145 ), Vector2( 11, 0 ), SubResource( 146 ), Vector2( 11, 1 ), SubResource( 147 ), Vector2( 11, 2 ), SubResource( 148 ), Vector2( 11, 3 ), SubResource( 149 ) ] -1/autotile/navpoly_map = [ ] -1/autotile/priority_map = [ ] -1/autotile/z_index_map = [ ] -1/occluder_offset = Vector2( 0, 0 ) -1/navigation_offset = Vector2( 0, 0 ) -1/shape_offset = Vector2( 0, 0 ) -1/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -1/shape = SubResource( 52 ) -1/shape_one_way = false -1/shape_one_way_margin = 1.0 -1/shapes = [ { -"autotile_coord": Vector2( 0, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 52 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 1, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 53 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 2, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 54 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 3, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 55 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 0, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 56 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 1, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 57 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 2, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 58 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 3, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 59 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 4, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 60 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 5, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 61 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 6, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 62 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 7, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 63 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 8, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 64 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 9, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 65 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 10, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 66 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 11, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 67 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 0, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 68 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 1, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 69 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 2, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 70 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 3, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 71 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 4, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 72 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 5, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 73 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 6, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 150 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 7, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 74 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 8, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 75 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 9, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 76 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 11, 1 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 77 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 0, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 78 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 1, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 79 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 2, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 80 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 3, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 81 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 4, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 82 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 5, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 83 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 6, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 84 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 7, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 85 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 8, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 86 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 9, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 87 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 10, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 88 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 11, 2 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 89 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 4, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 90 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 5, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 91 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 6, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 92 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 7, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 93 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 8, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 94 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 9, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 95 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 10, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 96 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 11, 3 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 97 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -} ] -1/z_index = 0 -2/name = "snow_platform_tile" -2/texture = ExtResource( 1 ) -2/tex_offset = Vector2( 0, 0 ) -2/modulate = Color( 1, 1, 1, 1 ) -2/region = Rect2( 0, 0, 384, 128 ) -2/tile_mode = 1 -2/autotile/bitmask_mode = 1 -2/autotile/bitmask_flags = [ Vector2( 0, 0 ), 144, Vector2( 0, 1 ), 146, Vector2( 0, 2 ), 18, Vector2( 0, 3 ), 16, Vector2( 1, 0 ), 176, Vector2( 1, 1 ), 178, Vector2( 1, 2 ), 50, Vector2( 1, 3 ), 48, Vector2( 2, 0 ), 184, Vector2( 2, 1 ), 186, Vector2( 2, 2 ), 58, Vector2( 2, 3 ), 56, Vector2( 3, 0 ), 152, Vector2( 3, 1 ), 154, Vector2( 3, 2 ), 26, Vector2( 3, 3 ), 24, Vector2( 4, 0 ), 187, Vector2( 4, 1 ), 434, Vector2( 4, 2 ), 182, Vector2( 4, 3 ), 250, Vector2( 5, 0 ), 440, Vector2( 5, 1 ), 510, Vector2( 5, 2 ), 447, Vector2( 5, 3 ), 62, Vector2( 6, 0 ), 248, Vector2( 6, 1 ), 507, Vector2( 6, 2 ), 255, Vector2( 6, 3 ), 59, Vector2( 7, 0 ), 190, Vector2( 7, 1 ), 218, Vector2( 7, 2 ), 155, Vector2( 7, 3 ), 442, Vector2( 8, 0 ), 432, Vector2( 8, 1 ), 438, Vector2( 8, 2 ), 446, Vector2( 8, 3 ), 54, Vector2( 9, 0 ), 506, Vector2( 9, 1 ), 254, Vector2( 9, 2 ), 511, Vector2( 9, 3 ), 63, Vector2( 10, 0 ), 504, Vector2( 10, 2 ), 443, Vector2( 10, 3 ), 191, Vector2( 11, 0 ), 216, Vector2( 11, 1 ), 251, Vector2( 11, 2 ), 219, Vector2( 11, 3 ), 27 ] -2/autotile/icon_coordinate = Vector2( 0, 3 ) -2/autotile/tile_size = Vector2( 32, 32 ) -2/autotile/spacing = 0 -2/autotile/occluder_map = [ ] -2/autotile/navpoly_map = [ ] -2/autotile/priority_map = [ ] -2/autotile/z_index_map = [ ] -2/occluder_offset = Vector2( 0, 0 ) -2/navigation_offset = Vector2( 0, 0 ) -2/shape_offset = Vector2( 0, 0 ) -2/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -2/shape = SubResource( 52 ) -2/shape_one_way = true -2/shape_one_way_margin = 1.0 -2/shapes = [ { -"autotile_coord": Vector2( 0, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 52 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 1, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 53 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 2, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 54 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 3, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 55 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 0, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 56 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 1, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 57 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 2, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 58 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 3, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 59 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 4, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 60 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 5, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 61 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 6, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 62 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 7, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 63 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 8, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 64 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 9, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 65 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 10, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 66 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 11, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 67 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 0, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 68 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 1, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 69 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 2, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 70 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 3, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 71 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 4, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 72 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 5, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 73 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 6, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 150 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 7, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 74 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 8, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 75 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 9, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 76 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 11, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 77 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 0, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 78 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 1, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 79 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 2, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 80 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 3, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 81 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 4, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 82 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 5, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 83 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 6, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 84 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 7, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 85 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 8, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 86 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 9, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 87 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 10, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 88 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 11, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 89 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 4, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 90 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 5, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 91 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 6, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 92 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 7, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 93 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 8, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 94 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 9, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 95 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 10, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 96 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 11, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 97 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -} ] -2/z_index = 0 -3/name = "ice_platform_tile" -3/texture = ExtResource( 4 ) -3/tex_offset = Vector2( 0, 0 ) -3/modulate = Color( 1, 1, 1, 1 ) -3/region = Rect2( 0, 0, 384, 128 ) -3/tile_mode = 1 -3/autotile/bitmask_mode = 1 -3/autotile/bitmask_flags = [ Vector2( 0, 0 ), 144, Vector2( 0, 1 ), 146, Vector2( 0, 2 ), 18, Vector2( 0, 3 ), 16, Vector2( 1, 0 ), 176, Vector2( 1, 1 ), 178, Vector2( 1, 2 ), 50, Vector2( 1, 3 ), 48, Vector2( 2, 0 ), 184, Vector2( 2, 1 ), 186, Vector2( 2, 2 ), 58, Vector2( 2, 3 ), 56, Vector2( 3, 0 ), 152, Vector2( 3, 1 ), 154, Vector2( 3, 2 ), 26, Vector2( 3, 3 ), 24, Vector2( 4, 0 ), 187, Vector2( 4, 1 ), 434, Vector2( 4, 2 ), 182, Vector2( 4, 3 ), 250, Vector2( 5, 0 ), 440, Vector2( 5, 1 ), 510, Vector2( 5, 2 ), 447, Vector2( 5, 3 ), 62, Vector2( 6, 0 ), 248, Vector2( 6, 1 ), 507, Vector2( 6, 2 ), 255, Vector2( 6, 3 ), 59, Vector2( 7, 0 ), 190, Vector2( 7, 1 ), 218, Vector2( 7, 2 ), 155, Vector2( 7, 3 ), 442, Vector2( 8, 0 ), 432, Vector2( 8, 1 ), 438, Vector2( 8, 2 ), 446, Vector2( 8, 3 ), 54, Vector2( 9, 0 ), 506, Vector2( 9, 1 ), 254, Vector2( 9, 2 ), 511, Vector2( 9, 3 ), 63, Vector2( 10, 0 ), 504, Vector2( 10, 2 ), 443, Vector2( 10, 3 ), 191, Vector2( 11, 0 ), 216, Vector2( 11, 1 ), 251, Vector2( 11, 2 ), 219, Vector2( 11, 3 ), 27 ] -3/autotile/icon_coordinate = Vector2( 0, 3 ) -3/autotile/tile_size = Vector2( 32, 32 ) -3/autotile/spacing = 0 -3/autotile/occluder_map = [ ] -3/autotile/navpoly_map = [ ] -3/autotile/priority_map = [ ] -3/autotile/z_index_map = [ ] -3/occluder_offset = Vector2( 0, 0 ) -3/navigation_offset = Vector2( 0, 0 ) -3/shape_offset = Vector2( 0, 0 ) -3/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -3/shape = SubResource( 52 ) -3/shape_one_way = true -3/shape_one_way_margin = 1.0 -3/shapes = [ { -"autotile_coord": Vector2( 0, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 52 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 1, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 53 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 2, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 54 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 3, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 55 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 0, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 56 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 1, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 57 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 2, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 58 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 3, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 59 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 4, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 60 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 5, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 61 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 6, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 62 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 7, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 63 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 8, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 64 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 9, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 65 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 10, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 66 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 11, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 67 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 0, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 68 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 1, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 69 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 2, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 70 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 3, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 71 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 4, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 72 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 5, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 73 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 6, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 150 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 7, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 74 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 8, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 75 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 9, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 76 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 11, 1 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 77 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 0, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 78 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 1, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 79 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 2, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 80 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 3, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 81 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 4, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 82 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 5, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 83 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 6, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 84 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 7, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 85 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 8, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 86 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 9, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 87 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 10, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 88 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 11, 2 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 89 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 4, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 90 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 5, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 91 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 6, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 92 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 7, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 93 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 8, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 94 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 9, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 95 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 10, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 96 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -}, { -"autotile_coord": Vector2( 11, 3 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 97 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -} ] -3/z_index = 0 -4/name = "cairn" -4/texture = ExtResource( 6 ) -4/tex_offset = Vector2( 4, 0 ) -4/modulate = Color( 1, 1, 1, 1 ) -4/region = Rect2( 0, 0, 23, 32 ) -4/tile_mode = 0 -4/occluder_offset = Vector2( 0, 0 ) -4/navigation_offset = Vector2( 0, 0 ) -4/shape_offset = Vector2( 0, 0 ) -4/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -4/shape_one_way = false -4/shape_one_way_margin = 0.0 -4/shapes = [ ] -4/z_index = 0 -script = ExtResource( 5 )