├── .gitignore ├── LICENSE ├── README.md ├── library ├── ArrayHelper.gd ├── ConvertCoord.gd ├── CoordCalculator.gd ├── CrossShapedFOV.gd ├── DijkstraPathFinding.gd ├── DungeonPrefab.gd ├── DungeonSize.gd ├── FileIOHelper.gd ├── FileParser.gd ├── InitWorldData.gd ├── InputTag.gd ├── InputTemplate.gd ├── IntCoord.gd ├── MainTag.gd ├── PathFindingData.gd ├── RootNodeTemplate.gd ├── SaveTag.gd ├── ScreenTag.gd ├── ShadowCastFOV.gd ├── SidebarText.gd ├── SpriteTypeTag.gd ├── StateTag.gd ├── SubTag.gd ├── WorldGenerator.gd ├── WorldTag.gd ├── ZIndex.gd ├── game_progress │ ├── BalloonProgress.gd │ ├── BaronProgress.gd │ ├── DemoProgress.gd │ ├── DesertProgress.gd │ ├── FactoryProgress.gd │ ├── FrogProgress.gd │ ├── HoundProgress.gd │ ├── KnightProgress.gd │ ├── MirrorProgress.gd │ ├── NinjaProgress.gd │ ├── ProgressTemplate.gd │ ├── RailgunProgress.gd │ ├── SnowRunnerProgress.gd │ └── StyxProgress.gd ├── init │ ├── InitBalloon.gd │ ├── InitBaron.gd │ ├── InitDemo.gd │ ├── InitDesert.gd │ ├── InitFactory.gd │ ├── InitFrog.gd │ ├── InitHound.gd │ ├── InitKnight.gd │ ├── InitMirror.gd │ ├── InitNinja.gd │ ├── InitRailgun.gd │ ├── InitSnowRunner.gd │ ├── InitStyx.gd │ ├── SpriteBlueprint.gd │ └── WorldTemplate.gd ├── npc_ai │ ├── AITemplate.gd │ ├── BalloonAI.gd │ ├── BaronAI.gd │ ├── DemoAI.gd │ ├── DesertAI.gd │ ├── FactoryAI.gd │ ├── FrogAI.gd │ ├── HoundAI.gd │ ├── KnightAI.gd │ ├── MirrorAI.gd │ ├── NinjaAI.gd │ ├── RailgunAI.gd │ ├── SnowRunnerAI.gd │ └── StyxAI.gd ├── npc_data │ ├── BalloonData.gd │ ├── BaronData.gd │ ├── DemoData.gd │ ├── DesertData.gd │ ├── FactoryData.gd │ ├── FrogData.gd │ ├── HoundData.gd │ ├── KnightData.gd │ ├── MirrorData.gd │ ├── NinjaData.gd │ ├── RailgunData.gd │ ├── SnowRunnerData.gd │ └── StyxData.gd └── pc_action │ ├── BalloonPCAction.gd │ ├── BaronPCAction.gd │ ├── DemoPCAction.gd │ ├── DesertPCAction.gd │ ├── FactoryPCAction.gd │ ├── FrogPCAction.gd │ ├── HoundPCAction.gd │ ├── KnightPCAction.gd │ ├── MirrorPCAction.gd │ ├── NinjaPCAction.gd │ ├── PCActionTemplate.gd │ ├── RailgunPCAction.gd │ ├── SnowRunnerPCAction.gd │ └── StyxPCAction.gd ├── misc ├── customStyle.css └── export.md ├── project.godot ├── resource ├── FiraCode-Regular.ttf ├── REXPaint │ ├── baron │ │ ├── baron_00.xp │ │ ├── baron_A01.xp │ │ ├── baron_A02.xp │ │ ├── baron_A03.xp │ │ ├── baron_A04.xp │ │ ├── baron_A05.xp │ │ ├── baron_B01.xp │ │ ├── baron_B02.xp │ │ ├── baron_B03.xp │ │ ├── baron_B04.xp │ │ ├── baron_B05.xp │ │ ├── baron_C01.xp │ │ ├── baron_C02.xp │ │ ├── baron_C03.xp │ │ ├── baron_C04.xp │ │ ├── baron_C05.xp │ │ ├── baron_D01.xp │ │ ├── baron_D02.xp │ │ ├── baron_D03.xp │ │ ├── baron_D04.xp │ │ ├── baron_D05.xp │ │ ├── baron_E01.xp │ │ ├── baron_E02.xp │ │ ├── baron_E03.xp │ │ ├── baron_E04.xp │ │ └── baron_E05.xp │ ├── factory │ │ ├── factory_00.xp │ │ ├── factory_01.xp │ │ ├── factory_02.xp │ │ ├── factory_03.xp │ │ ├── factory_04.xp │ │ ├── factory_05.xp │ │ ├── factory_06.xp │ │ ├── factory_07.xp │ │ ├── factory_08.xp │ │ ├── factory_09.xp │ │ ├── factory_10.xp │ │ ├── factory_11.xp │ │ ├── factory_12.xp │ │ ├── factory_13.xp │ │ ├── factory_14.xp │ │ ├── factory_15.xp │ │ ├── factory_16.xp │ │ ├── factory_17.xp │ │ ├── factory_18.xp │ │ ├── factory_19.xp │ │ ├── factory_20.xp │ │ ├── factory_21.xp │ │ ├── factory_22.xp │ │ ├── factory_23.xp │ │ ├── factory_24.xp │ │ └── factory_25.xp │ ├── mirror │ │ ├── left_side.xp │ │ ├── wall_1.xp │ │ ├── wall_2.xp │ │ ├── wall_3.xp │ │ └── wall_4.xp │ ├── ninja │ │ ├── ninja_00.xp │ │ └── ninja_01.xp │ └── snowrunner │ │ └── snowrunner.xp ├── curses_vector_24x36.png ├── curses_vector_24x36.png.import ├── dungeon_prefab │ ├── baron │ │ ├── baron_A01.txt │ │ ├── baron_A02.txt │ │ ├── baron_A03.txt │ │ ├── baron_A04.txt │ │ ├── baron_A05.txt │ │ ├── baron_B01.txt │ │ ├── baron_B02.txt │ │ ├── baron_B03.txt │ │ ├── baron_B04.txt │ │ ├── baron_B05.txt │ │ ├── baron_C01.txt │ │ ├── baron_C02.txt │ │ ├── baron_C03.txt │ │ ├── baron_C04.txt │ │ ├── baron_C05.txt │ │ ├── baron_D01.txt │ │ ├── baron_D02.txt │ │ ├── baron_D03.txt │ │ ├── baron_D04.txt │ │ ├── baron_D05.txt │ │ ├── baron_E01.txt │ │ ├── baron_E02.txt │ │ ├── baron_E03.txt │ │ ├── baron_E04.txt │ │ └── baron_E05.txt │ ├── factory │ │ ├── big_room │ │ │ ├── factory_06.txt │ │ │ ├── factory_07.txt │ │ │ ├── factory_08.txt │ │ │ ├── factory_09.txt │ │ │ ├── factory_10.txt │ │ │ ├── factory_11.txt │ │ │ ├── factory_12.txt │ │ │ ├── factory_13.txt │ │ │ ├── factory_14.txt │ │ │ ├── factory_15.txt │ │ │ ├── factory_16.txt │ │ │ ├── factory_17.txt │ │ │ ├── factory_18.txt │ │ │ ├── factory_19.txt │ │ │ ├── factory_20.txt │ │ │ ├── factory_21.txt │ │ │ ├── factory_22.txt │ │ │ ├── factory_23.txt │ │ │ ├── factory_24.txt │ │ │ └── factory_25.txt │ │ ├── small_room │ │ │ ├── factory_03.txt │ │ │ ├── factory_04.txt │ │ │ └── factory_05.txt │ │ └── start_point │ │ │ ├── factory_01.txt │ │ │ └── factory_02.txt │ ├── mirror │ │ ├── left_side.txt │ │ └── walls │ │ │ ├── wall_1.txt │ │ │ ├── wall_2.txt │ │ │ ├── wall_3.txt │ │ │ └── wall_4.txt │ ├── ninja │ │ └── ninja_01.txt │ └── snowrunner │ │ └── snowrunner.txt ├── icon.png └── icon.png.import ├── scene ├── gui │ ├── DebugGUI.tscn │ ├── DebugVBox.gd │ ├── GUIInputBox.tscn │ ├── GUIText.tscn │ ├── HelpGUI.tscn │ ├── HelpVScroll.gd │ ├── MainGUI.tscn │ ├── Modeline.gd │ └── SidebarVBox.gd ├── main │ ├── AutoStart.gd │ ├── BoolState.gd │ ├── CountDown.gd │ ├── CreateObject.gd │ ├── DangerZone.gd │ ├── DebugInput.gd │ ├── DungeonBoard.gd │ ├── EndGame.gd │ ├── EnemyAI.gd │ ├── GameProgress.gd │ ├── GameSetting.gd │ ├── HelpInput.gd │ ├── HitPoint.gd │ ├── InitWorld.gd │ ├── MainScene.gd │ ├── MainScene.tscn │ ├── ObjectData.gd │ ├── ObjectLayer.gd │ ├── ObjectState.gd │ ├── Palette.gd │ ├── PlayerInput.gd │ ├── RandomNumber.gd │ ├── ReloadGame.gd │ ├── RemoveObject.gd │ ├── Schedule.gd │ ├── SpriteType.gd │ ├── SwitchScreen.gd │ └── SwitchSprite.gd └── transfer_data │ ├── TransferData.gd │ └── TransferData.tscn ├── sprite ├── Arrow.tscn ├── Bandit.tscn ├── Bird.tscn ├── Counter.tscn ├── Crystal.tscn ├── CrystalBase.tscn ├── Devil.tscn ├── Door.tscn ├── DoorTruck.tscn ├── Dwarf.tscn ├── FactoryClock.tscn ├── Floor.tscn ├── FloorFactory.tscn ├── FloorHound.tscn ├── FloorNinja.tscn ├── FloorSnowRunner.tscn ├── Frog.tscn ├── FrogPrincess.tscn ├── HPBar.tscn ├── Harbor.tscn ├── Hound.tscn ├── HoundBoss.tscn ├── Knight.tscn ├── KnightBoss.tscn ├── KnightCaptain.tscn ├── Lighthouse.tscn ├── Ninja.tscn ├── NinjaShadow.tscn ├── OffloadGoods.tscn ├── OnloadGoods.tscn ├── PC.tscn ├── PCBalloon.tscn ├── PCBaron.tscn ├── PCDesert.tscn ├── PCFrog.tscn ├── PCHound.tscn ├── PCMirrorImage.tscn ├── PCNinja.tscn ├── PCRailgun.tscn ├── PCSnowRunner.tscn ├── Phantom.tscn ├── Portal.tscn ├── RareTreasure.tscn ├── SCP_173.tscn ├── SoulFragment.tscn ├── Treasure.tscn ├── TreeBranch.tscn ├── TreeTrunk.tscn ├── TriangleDown.tscn ├── TriangleRight.tscn ├── TriangleUp.tscn ├── TruckSlot.tscn ├── Wall.tscn ├── WallHound.tscn ├── WallNinja.tscn ├── WormBody.tscn ├── WormHead.tscn ├── WormSpice.tscn └── WormTail.tscn └── user ├── data ├── setting.json └── world_list.md ├── doc ├── balloon.md ├── baron.md ├── demo.md ├── desert.md ├── factory.md ├── frog.md ├── general.md ├── hint_dungeon.md ├── hint_general.md ├── hint_keybinding.md ├── hound.md ├── keybinding.md ├── knight.md ├── mirror.md ├── ninja.md ├── railgun.md ├── snowrunner.md └── styx.md └── palette ├── blue.json ├── default.json └── grey.json /.gitignore: -------------------------------------------------------------------------------- 1 | # User defined ignores 2 | bin/ 3 | 4 | # Godot-specific ignores 5 | .import/ 6 | export.cfg 7 | export_presets.cfg 8 | 9 | # Mono-specific ignores 10 | .mono/ 11 | data_*/ 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Bozar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /library/ArrayHelper.gd: -------------------------------------------------------------------------------- 1 | class_name Game_ArrayHelper 2 | 3 | 4 | const ELEMENT_WARNING := "rand_picker(): Pick too many elements." 5 | const RAND_WARNING := "rand_picker(): Rand is not of type Game_RandomNumber." 6 | 7 | 8 | static func rand_picker(source_array: Array, num_of_element: int, rand) -> void: 9 | var counter: int 10 | 11 | if num_of_element > source_array.size(): 12 | push_warning(ELEMENT_WARNING) 13 | elif not (rand is Game_RandomNumber): 14 | push_warning(RAND_WARNING) 15 | else: 16 | for i in range(num_of_element): 17 | counter = rand.get_int(i, source_array.size()) 18 | swap_element(source_array, i, counter) 19 | source_array.resize(num_of_element) 20 | 21 | 22 | static func shuffle(source_array: Array, rand) -> void: 23 | rand_picker(source_array, source_array.size(), rand) 24 | 25 | 26 | # filter_in_func(source_array: Array, current_index: int, 27 | #> optional_arg: Array) -> bool 28 | # Return true if we need an array element. 29 | static func filter_element(source_array: Array, func_host: Object, 30 | filter_in_func: String, optional_arg := []) -> void: 31 | var filter_in := funcref(func_host, filter_in_func) 32 | var counter: int = 0 33 | 34 | for i in range(source_array.size()): 35 | if filter_in.call_func(source_array, i, optional_arg): 36 | swap_element(source_array, counter, i) 37 | counter += 1 38 | source_array.resize(counter) 39 | 40 | 41 | # get_counter_func(source_array: Array, current_index: int, 42 | #> optional_arg: Array) -> int 43 | # Return how many times an element should appear in the new array. 44 | static func duplicate_element(source_array: Array, func_host: Object, 45 | get_counter_func: String, optional_arg := []) -> void: 46 | var get_counter := funcref(func_host, get_counter_func) 47 | var counter: int 48 | var tmp: Array = [] 49 | 50 | for i in range(source_array.size()): 51 | counter = get_counter.call_func(source_array, i, optional_arg) - 1 52 | for _j in range(counter): 53 | tmp.push_back(source_array[i]) 54 | merge(source_array, tmp) 55 | 56 | 57 | static func swap_element(source_array: Array, left_index: int, 58 | right_index: int) -> void: 59 | var tmp 60 | 61 | tmp = source_array[left_index] 62 | source_array[left_index] = source_array[right_index] 63 | source_array[right_index] = tmp 64 | 65 | 66 | static func merge(source_array: Array, merge_into_left: Array) -> void: 67 | var source_size: int = source_array.size() 68 | var merge_size: int = merge_into_left.size() 69 | 70 | source_array.resize(source_size + merge_size) 71 | for i in range(merge_size): 72 | source_array[i + source_size] = merge_into_left[i] 73 | 74 | 75 | static func remove_by_index(source_array: Array, remove_index: int) -> void: 76 | swap_element(source_array, remove_index, source_array.size() - 1) 77 | source_array.resize(source_array.size() - 1) 78 | 79 | 80 | static func reverse_key_value_in_dict(source_dict: Dictionary, 81 | reverse_dict: Dictionary) -> void: 82 | for i in source_dict.keys(): 83 | reverse_dict[source_dict[i]] = i 84 | -------------------------------------------------------------------------------- /library/ConvertCoord.gd: -------------------------------------------------------------------------------- 1 | class_name Game_ConvertCoord 2 | 3 | 4 | const START_X := 50 5 | const START_Y := 54 6 | const STEP_X := 26 7 | const STEP_Y := 34 8 | 9 | const MOUSE_START_X := START_X - 10 10 | const MOUSE_START_Y := START_Y - 10 11 | 12 | 13 | static func sprite_to_coord(this_sprite: Sprite) -> Game_IntCoord: 14 | return vector_to_coord(this_sprite.position) 15 | 16 | 17 | static func vector_to_coord(vector_coord: Vector2) -> Game_IntCoord: 18 | var x := int((vector_coord.x - START_X) / STEP_X) 19 | var y := int((vector_coord.y - START_Y) / STEP_Y) 20 | 21 | return Game_IntCoord.new(x, y) 22 | 23 | 24 | static func mouse_to_coord(mouse_event: InputEvent) -> Game_IntCoord: 25 | var x := int((mouse_event.position.x - MOUSE_START_X) / STEP_X) 26 | var y := int((mouse_event.position.y - MOUSE_START_Y) / STEP_Y) 27 | 28 | return Game_IntCoord.new(x, y) 29 | 30 | 31 | static func coord_to_vector(x: int, y: int, x_offset := 0, y_offset := 0) \ 32 | -> Vector2: 33 | var x_vector: int = START_X + STEP_X * x + x_offset 34 | var y_vector: int = START_Y + STEP_Y * y + y_offset 35 | 36 | return Vector2(x_vector, y_vector) 37 | -------------------------------------------------------------------------------- /library/DijkstraPathFinding.gd: -------------------------------------------------------------------------------- 1 | class_name Game_DijkstraPathFinding 2 | 3 | 4 | # Find the next step. 5 | # Call func_host.is_passable_func() to verify if a grid can be entered. 6 | # is_passable_func(source_array: Array, current_index: int, 7 | #> opt_arg: Array) -> bool 8 | static func get_path(dungeon: Dictionary, start_x: int, start_y: int, 9 | step_length: int, func_host: Object, is_passable_func: String, 10 | opt_arg: Array) -> Array: 11 | var neighbor := Game_CoordCalculator.get_neighbor_xy(start_x, start_y, 12 | step_length) 13 | var min_distance := Game_PathFindingData.OBSTACLE 14 | var x: int 15 | var y: int 16 | var current_index := 0 17 | 18 | Game_ArrayHelper.filter_element(neighbor, func_host, is_passable_func, 19 | opt_arg) 20 | 21 | for i in neighbor.size(): 22 | x = neighbor[i].x 23 | y = neighbor[i].y 24 | if _is_valid_distance(dungeon, x, y, Game_PathFindingData.OBSTACLE): 25 | if dungeon[x][y] < min_distance: 26 | min_distance = dungeon[x][y] 27 | Game_ArrayHelper.swap_element(neighbor, 0, i) 28 | current_index = 1 29 | elif dungeon[x][y] == min_distance: 30 | Game_ArrayHelper.swap_element(neighbor, current_index, i) 31 | current_index += 1 32 | 33 | neighbor.resize(current_index) 34 | return neighbor 35 | 36 | 37 | # Create a distance map. 38 | static func get_map(dungeon: Dictionary, end_point: Array) -> Dictionary: 39 | if end_point.size() < 1: 40 | return dungeon 41 | 42 | var check: Game_IntCoord = end_point.pop_front() 43 | var neighbor := Game_CoordCalculator.get_neighbor_xy(check.x, check.y, 1) 44 | var x: int 45 | var y: int 46 | 47 | for i in neighbor: 48 | x = i.x 49 | y = i.y 50 | if dungeon[x][y] == Game_PathFindingData.UNKNOWN: 51 | dungeon[x][y] = _get_distance(dungeon, x, y) 52 | end_point.push_back(i) 53 | return get_map(dungeon, end_point) 54 | 55 | 56 | static func _get_distance(dungeon: Dictionary, center_x: int, center_y: int) \ 57 | -> int: 58 | var neighbor := Game_CoordCalculator.get_neighbor_xy(center_x, center_y, 1) 59 | var min_distance: int = Game_PathFindingData.OBSTACLE 60 | var x: int 61 | var y: int 62 | 63 | for i in neighbor: 64 | x = i.x 65 | y = i.y 66 | if _is_valid_distance(dungeon, x, y, min_distance): 67 | min_distance = dungeon[x][y] 68 | min_distance = min(min_distance + 1, Game_PathFindingData.OBSTACLE) as int 69 | return min_distance 70 | 71 | 72 | static func _is_valid_distance(dungeon: Dictionary, x: int, y: int, 73 | max_distance: int) -> bool: 74 | return (dungeon[x][y] < max_distance) \ 75 | and (dungeon[x][y] > Game_PathFindingData.UNKNOWN) 76 | -------------------------------------------------------------------------------- /library/DungeonSize.gd: -------------------------------------------------------------------------------- 1 | class_name Game_DungeonSize 2 | 3 | 4 | const MAX_X := 21 5 | const MAX_Y := 15 6 | 7 | const CENTER_X := 10 8 | const CENTER_Y := 7 9 | 10 | const ARROW_MARGIN := 32 11 | 12 | 13 | static func init_dungeon_grids(dungeon: Dictionary, init_value = null, 14 | init_once := true) -> void: 15 | var is_empty := dungeon.size() < 1 16 | 17 | if (not is_empty) and init_once: 18 | return 19 | 20 | for x in range(0, MAX_X): 21 | if is_empty: 22 | dungeon[x] = [] 23 | dungeon[x].resize(MAX_Y) 24 | if init_value != null: 25 | for y in range(0, MAX_Y): 26 | dungeon[x][y] = init_value 27 | 28 | 29 | # get_init_value_func(x: int, y: int, optional_arg: Array) 30 | # Return an initial value for dungeon[x][y]. 31 | static func init_dungeon_grids_by_func(dungeon: Dictionary, func_host: Object, 32 | get_init_value_func: String, optional_arg := [], init_once := true) \ 33 | -> void: 34 | var is_empty := dungeon.size() < 1 35 | var get_init_value := funcref(func_host, get_init_value_func) 36 | 37 | if (not is_empty) and init_once: 38 | return 39 | 40 | for x in range(0, MAX_X): 41 | if is_empty: 42 | dungeon[x] = [] 43 | dungeon[x].resize(MAX_Y) 44 | for y in range(0, MAX_Y): 45 | dungeon[x][y] = get_init_value.call_func(x, y, optional_arg) 46 | 47 | 48 | static func init_all_coords(save_coords: Array) -> void: 49 | var row := 0 50 | 51 | save_coords.resize(MAX_X * MAX_Y) 52 | for x in range(0, MAX_X): 53 | for y in range(0, MAX_Y): 54 | save_coords[x + y + row] = Game_IntCoord.new(x, y) 55 | # Every row has (MAX_Y - 1) elements. 56 | row += MAX_Y - 1 57 | -------------------------------------------------------------------------------- /library/FileIOHelper.gd: -------------------------------------------------------------------------------- 1 | class_name Game_FileIOHelper 2 | 3 | 4 | static func read_as_text(path_to_file: String) -> Game_FileParser: 5 | var new_file: File = File.new() 6 | var file_parser := Game_FileParser.new() 7 | 8 | if new_file.open(path_to_file, File.READ) == OK: 9 | file_parser.parse_success = true 10 | file_parser.output_text = new_file.get_as_text() 11 | else: 12 | file_parser.parse_success = false 13 | new_file.close() 14 | return file_parser 15 | 16 | 17 | static func read_as_line(path_to_file: String) -> Game_FileParser: 18 | var new_file: File = File.new() 19 | var file_parser := Game_FileParser.new() 20 | var row: int = 0 21 | 22 | if new_file.open(path_to_file, File.READ) == OK: 23 | file_parser.parse_success = true 24 | file_parser.output_line = {} 25 | while not new_file.eof_reached(): 26 | file_parser.output_line[row] = new_file.get_line() 27 | row += 1 28 | else: 29 | file_parser.parse_success = false 30 | new_file.close() 31 | return file_parser 32 | 33 | 34 | static func read_as_json(path_to_file: String) -> Game_FileParser: 35 | var file_parser: Game_FileParser = read_as_text(path_to_file) 36 | var json_parser: JSONParseResult 37 | 38 | if file_parser.parse_success: 39 | json_parser = JSON.parse(file_parser.output_text) 40 | if json_parser.error == OK: 41 | file_parser.output_json = json_parser.get_result() 42 | else: 43 | file_parser.parse_success = false 44 | return file_parser 45 | 46 | 47 | # https://docs.godotengine.org/en/stable/classes/class_directory.html 48 | static func get_file_list(path_to_dir: String) -> Array: 49 | var dir := Directory.new() 50 | var __ 51 | var file_name: String 52 | var file_list: Array = [] 53 | 54 | if dir.open(path_to_dir) == OK: 55 | __ = dir.list_dir_begin(true, true) 56 | file_name = dir.get_next() 57 | while file_name != "": 58 | if not dir.current_is_dir(): 59 | file_list.push_back(dir.get_current_dir() + "/" + file_name) 60 | file_name = dir.get_next() 61 | return file_list 62 | 63 | 64 | static func has_file(path_to_file: String) -> bool: 65 | return File.new().file_exists(path_to_file) 66 | -------------------------------------------------------------------------------- /library/FileParser.gd: -------------------------------------------------------------------------------- 1 | class_name Game_FileParser 2 | 3 | 4 | var output_text: String setget set_output_text, get_output_text 5 | var output_json: Dictionary setget set_output_json, get_output_json 6 | var output_line: Dictionary setget set_output_line, get_output_line 7 | var parse_success: bool setget set_parse_success, get_parse_success 8 | 9 | 10 | func get_output_text() -> String: 11 | return output_text 12 | 13 | 14 | func set_output_text(file_content: String) -> void: 15 | output_text = file_content 16 | 17 | 18 | func get_output_json() -> Dictionary: 19 | return output_json 20 | 21 | 22 | func set_output_json(file_content: Dictionary) -> void: 23 | output_json = file_content 24 | 25 | 26 | func get_output_line() -> Dictionary: 27 | return output_line 28 | 29 | 30 | func set_output_line(file_content: Dictionary) -> void: 31 | output_line = file_content 32 | 33 | 34 | func get_parse_success() -> bool: 35 | return parse_success 36 | 37 | 38 | func set_parse_success(success: bool) -> void: 39 | parse_success = success 40 | -------------------------------------------------------------------------------- /library/InitWorldData.gd: -------------------------------------------------------------------------------- 1 | class_name Game_InitWorldData 2 | 3 | 4 | const WORLD_PLACEHOLDER := "%str%" 5 | const HINT_PLACEHOLDER := "[INPUT_HINT]\n" 6 | 7 | const INIT_PATH := "res://library/init/Init%str%.gd" 8 | const ACTION_PATH := "res://library/pc_action/%str%PCAction.gd" 9 | const AI_PATH := "res://library/npc_ai/%str%AI.gd" 10 | const PROGRESS_PATH := "res://library/game_progress/%str%Progress.gd" 11 | const HELP_PATH := "res://user/doc/%str%.md" 12 | 13 | const GENERAL_HELP := "res://user/doc/general.md" 14 | const KEY_BINDING_HELP := "res://user/doc/keybinding.md" 15 | 16 | const HINT_DUNGEON := "res://user/doc/hint_dungeon.md" 17 | const HINT_GENERAL := "res://user/doc/hint_general.md" 18 | const HINT_KEY_BINDING := "res://user/doc/hint_keybinding.md" 19 | 20 | 21 | static func get_world_template(world_tag: String) -> Game_WorldTemplate: 22 | return _load_data(INIT_PATH, world_tag) 23 | 24 | 25 | static func get_pc_action(world_tag: String) -> Game_PCActionTemplate: 26 | return _load_data(ACTION_PATH, world_tag) 27 | 28 | 29 | static func get_enemy_ai(world_tag: String) -> Game_AITemplate: 30 | return _load_data(AI_PATH, world_tag) 31 | 32 | 33 | static func get_progress(world_tag: String) -> Game_ProgressTemplate: 34 | return _load_data(PROGRESS_PATH, world_tag) 35 | 36 | 37 | static func get_help(world_tag: String) -> Array: 38 | var world_name: String = Game_WorldTag.get_world_name(world_tag).to_lower() 39 | var dungeon: String = HELP_PATH.replace(WORLD_PLACEHOLDER, world_name) 40 | var parse_help := [ 41 | Game_FileIOHelper.read_as_text(dungeon), 42 | Game_FileIOHelper.read_as_text(KEY_BINDING_HELP), 43 | Game_FileIOHelper.read_as_text(GENERAL_HELP), 44 | ] 45 | var parse_hint := [ 46 | Game_FileIOHelper.read_as_text(HINT_DUNGEON), 47 | Game_FileIOHelper.read_as_text(HINT_KEY_BINDING), 48 | Game_FileIOHelper.read_as_text(HINT_GENERAL), 49 | ] 50 | var help_text: String 51 | var hint_text: String 52 | var result := [] 53 | 54 | for i in parse_help.size(): 55 | if parse_help[i].parse_success and parse_hint[i].parse_success: 56 | hint_text = parse_hint[i].output_text 57 | help_text = parse_help[i].output_text 58 | help_text = help_text.replace(HINT_PLACEHOLDER, hint_text) 59 | result.push_back(help_text) 60 | else: 61 | result.push_back("") 62 | return result 63 | 64 | 65 | static func _load_data(file_path: String, world_tag: String): 66 | var world_name: String = Game_WorldTag.get_world_name(world_tag) 67 | var full_path: String = file_path.replace(WORLD_PLACEHOLDER, world_name) 68 | 69 | return load(full_path) 70 | -------------------------------------------------------------------------------- /library/InputTag.gd: -------------------------------------------------------------------------------- 1 | class_name Game_InputTag 2 | # InputTemplate._verify_input() requires a string tag. 3 | 4 | 5 | const MOVE_LEFT := "move_left" 6 | const MOVE_RIGHT := "move_right" 7 | const MOVE_UP := "move_up" 8 | const MOVE_DOWN := "move_down" 9 | const WAIT := "wait" 10 | 11 | const RELOAD := "reload" 12 | const REPLAY_DUNGEON := "replay_dungeon" 13 | const REPLAY_WORLD := "replay_world" 14 | const QUIT := "quit" 15 | const OPEN_HELP := "open_help" 16 | const COPY_SEED := "copy_seed" 17 | const COPY_WORLD := "copy_world" 18 | 19 | const INIT_WORLD := "init_world" 20 | const FORCE_RELOAD := "force_reload" 21 | const ADD_TURN := "add_turn" 22 | const FULLY_RESTORE_TURN := "fully_restore_turn" 23 | 24 | const PAGE_DOWN := "page_down" 25 | const PAGE_UP := "page_up" 26 | const SCROLL_TO_TOP := "scroll_to_top" 27 | const SCROLL_TO_BOTTOM := "scroll_to_bottom" 28 | const NEXT_HELP := "next_help" 29 | const PREVIOUS_HELP := "previous_help" 30 | 31 | const OPEN_DEBUG := "open_debug" 32 | const CLOSE_MENU := "close_menu" 33 | 34 | const MOVE_BY_MOUSE := "move_by_mouse" 35 | const WAIT_BY_MOUSE := "wait_by_mouse" 36 | const RELOAD_BY_MOUSE := "reload_by_mouse" 37 | const FORCE_RELOAD_BY_MOUSE := "force_reload_by_mouse" 38 | 39 | const DIRECTION_TO_COORD := { 40 | MOVE_UP: [0, -1], 41 | MOVE_DOWN: [0, 1], 42 | MOVE_LEFT: [-1, 0], 43 | MOVE_RIGHT: [1, 0], 44 | } 45 | 46 | const MOVE_INPUT := [ 47 | MOVE_LEFT, 48 | MOVE_RIGHT, 49 | MOVE_UP, 50 | MOVE_DOWN, 51 | ] 52 | 53 | const INPUT_TO_SPRITE := { 54 | MOVE_UP: Game_SpriteTypeTag.UP, 55 | MOVE_DOWN: Game_SpriteTypeTag.DOWN, 56 | MOVE_LEFT: Game_SpriteTypeTag.LEFT, 57 | MOVE_RIGHT: Game_SpriteTypeTag.RIGHT, 58 | } 59 | 60 | const INPUT_TO_STATE := { 61 | MOVE_UP: Game_StateTag.UP, 62 | MOVE_DOWN: Game_StateTag.DOWN, 63 | MOVE_LEFT: Game_StateTag.LEFT, 64 | MOVE_RIGHT: Game_StateTag.RIGHT, 65 | } 66 | -------------------------------------------------------------------------------- /library/InputTemplate.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_InputTemplate 3 | 4 | 5 | func _ready() -> void: 6 | set_process_unhandled_input(false) 7 | 8 | 9 | func _verify_input(event: InputEvent, input_tag: String) -> bool: 10 | return event.is_action_pressed(input_tag) 11 | -------------------------------------------------------------------------------- /library/IntCoord.gd: -------------------------------------------------------------------------------- 1 | class_name Game_IntCoord 2 | 3 | 4 | var x: int setget set_x, get_x 5 | var y: int setget set_y, get_y 6 | 7 | 8 | func _init(new_x: int, new_y: int) -> void: 9 | x = new_x 10 | y = new_y 11 | 12 | 13 | func get_x() -> int: 14 | return x 15 | 16 | 17 | func set_x(new_x) -> void: 18 | x = new_x 19 | 20 | 21 | func get_y() -> int: 22 | return y 23 | 24 | 25 | func set_y(new_y) -> void: 26 | y = new_y 27 | -------------------------------------------------------------------------------- /library/MainTag.gd: -------------------------------------------------------------------------------- 1 | class_name Game_MainTag 2 | # is_in_group() requires a string tag. 3 | 4 | 5 | const INVALID := "invalid" 6 | 7 | const GROUND := "ground" 8 | const TRAP := "trap" 9 | const BUILDING := "building" 10 | const ACTOR := "actor" 11 | const INDICATOR := "indicator" 12 | 13 | const DUNGEON_OBJECT := [GROUND, TRAP, BUILDING, ACTOR] 14 | const ABOVE_GROUND_OBJECT := [TRAP, BUILDING, ACTOR] 15 | -------------------------------------------------------------------------------- /library/PathFindingData.gd: -------------------------------------------------------------------------------- 1 | class_name Game_PathFindingData 2 | 3 | 4 | const DESTINATION := 0 5 | const OBSTACLE := 9999 6 | const UNKNOWN := -9999 7 | -------------------------------------------------------------------------------- /library/RootNodeTemplate.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_RootNodeTemplate 3 | 4 | 5 | # "/root/MainScene" 6 | var _path_to_self: String 7 | # [signal_name, func_name, source_node, target_node] 8 | var _signal_bind: Array 9 | # [target_var_name, source_node, target_node] 10 | var _node_ref: Array 11 | 12 | 13 | func _init(_signal: Array, _node: Array) -> void: 14 | _signal_bind = _signal 15 | _node_ref = _node 16 | 17 | 18 | func _ready() -> void: 19 | _set_path() 20 | _set_signal() 21 | _set_node_ref() 22 | 23 | 24 | func _set_path() -> void: 25 | _path_to_self = get_path() 26 | 27 | 28 | func _set_signal() -> void: 29 | var __ 30 | 31 | for s in _signal_bind: 32 | # [signal_name, func_name, source_node, target_node] 33 | for i in range(3, len(s)): 34 | __ = get_node(_get_path(s[2])).connect(s[0], 35 | get_node(_get_path(s[i])), s[1]) 36 | 37 | 38 | func _set_node_ref() -> void: 39 | for n in _node_ref: 40 | # [target_var_name, source_node, target_node] 41 | for i in range(2, len(n)): 42 | get_node(_get_path(n[i]))[n[0]] = get_node(_get_path(n[1])) 43 | 44 | 45 | func _get_path(path_to_node: String) -> String: 46 | return "{0}/{1}".format([_path_to_self, path_to_node]) 47 | -------------------------------------------------------------------------------- /library/SaveTag.gd: -------------------------------------------------------------------------------- 1 | class_name Game_SaveTag 2 | 3 | 4 | enum { 5 | REPLAY_DUNGEON, 6 | REPLAY_WORLD, 7 | } 8 | -------------------------------------------------------------------------------- /library/ScreenTag.gd: -------------------------------------------------------------------------------- 1 | class_name Game_ScreenTag 2 | 3 | 4 | enum { 5 | MAIN, 6 | HELP, 7 | DEBUG, 8 | } 9 | -------------------------------------------------------------------------------- /library/SidebarText.gd: -------------------------------------------------------------------------------- 1 | class_name Game_SidebarText 2 | 3 | 4 | const VERSION := "0.4.4" 5 | # const VERSION := "0.3.1-\nNightly-\n04-16-2021" 6 | const BOOL_TO_PREFIX := {true: "+", false: "-"} 7 | const VERSION_BAR := "\n--------" 8 | 9 | const TURN := "Turn: {0}" 10 | 11 | const WIN := "You win.\n[ Space ]" 12 | const LOSE := "You lose.\n[ Space ]" 13 | 14 | const MENU_KEY := "Menu: C|V\n" 15 | const PLAY_KEY := "Play: R|U|O\n" 16 | const HELP_BAR := "-----------" 17 | const HELP := MENU_KEY + PLAY_KEY + HELP_BAR 18 | 19 | const SEED := "{0}-{1}-{2}" 20 | -------------------------------------------------------------------------------- /library/SpriteTypeTag.gd: -------------------------------------------------------------------------------- 1 | class_name Game_SpriteTypeTag 2 | # SpriteType.set_sprite_type() requires a string tag. 3 | 4 | 5 | const DEFAULT := "default" 6 | const DEFAULT_1 := "default_1" 7 | const DEFAULT_2 := "default_2" 8 | const DEFAULT_3 := "default_3" 9 | 10 | const ACTIVE := "active" 11 | const ACTIVE_1 := "active_1" 12 | const ACTIVE_2 := "active_2" 13 | const ACTIVE_3 := "active_3" 14 | const ACTIVE_4 := "active_4" 15 | const PASSIVE := "passive" 16 | const PASSIVE_1 := "passive_1" 17 | 18 | const UP := "up" 19 | const DOWN := "down" 20 | const LEFT := "left" 21 | const RIGHT := "right" 22 | 23 | const ZERO := "zero" 24 | const ONE := "one" 25 | const TWO := "two" 26 | const THREE := "three" 27 | const FOUR := "four" 28 | const FIVE := "five" 29 | const SIX := "six" 30 | const SEVEN := "seven" 31 | const EIGHT := "eight" 32 | const NINE := "nine" 33 | 34 | const ORDERED_SPRITE_TYPE := [ 35 | ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, 36 | ] 37 | 38 | 39 | static func convert_digit_to_tag(digit: int) -> String: 40 | if (digit > -1) and (digit < ORDERED_SPRITE_TYPE.size()): 41 | return ORDERED_SPRITE_TYPE[digit] 42 | return ZERO 43 | -------------------------------------------------------------------------------- /library/StateTag.gd: -------------------------------------------------------------------------------- 1 | class_name Game_StateTag 2 | 3 | 4 | enum { 5 | DEFAULT, 6 | ACTIVE, 7 | PASSIVE, 8 | 9 | UP, 10 | DOWN, 11 | LEFT, 12 | RIGHT, 13 | } 14 | 15 | const DIRECTION_TO_COORD := { 16 | UP: [0, -1], 17 | DOWN: [0, 1], 18 | LEFT: [-1, 0], 19 | RIGHT: [1, 0], 20 | } 21 | 22 | const VALID_DIRECTION := [UP, DOWN, LEFT, RIGHT] 23 | 24 | const OPPOSITE_DIRECTION := { 25 | UP: DOWN, 26 | DOWN: UP, 27 | LEFT: RIGHT, 28 | RIGHT: LEFT, 29 | } 30 | 31 | const STATE_TO_SPRITE := { 32 | UP: Game_SpriteTypeTag.UP, 33 | DOWN: Game_SpriteTypeTag.DOWN, 34 | LEFT: Game_SpriteTypeTag.LEFT, 35 | RIGHT: Game_SpriteTypeTag.RIGHT, 36 | } 37 | 38 | const TURN_RIGHT := { 39 | UP: RIGHT, 40 | RIGHT: DOWN, 41 | DOWN: LEFT, 42 | LEFT: UP, 43 | } 44 | 45 | const TURN_LEFT := { 46 | UP: LEFT, 47 | RIGHT: UP, 48 | DOWN: RIGHT, 49 | LEFT: DOWN, 50 | } 51 | 52 | 53 | static func is_opposite_direction(this_dir: int, that_dir: int) -> bool: 54 | if OPPOSITE_DIRECTION.has(this_dir) and OPPOSITE_DIRECTION.has(that_dir): 55 | return this_dir == OPPOSITE_DIRECTION[that_dir] 56 | return false 57 | -------------------------------------------------------------------------------- /library/SubTag.gd: -------------------------------------------------------------------------------- 1 | class_name Game_SubTag 2 | # is_in_group() requires a string tag. 3 | 4 | 5 | const INVALID := "invalid" 6 | const DWARF := "dwarf" 7 | 8 | const PC := "pc" 9 | 10 | const KNIGHT := "knight" 11 | const KNIGHT_CAPTAIN := "knight_captain" 12 | const KNIGHT_BOSS := "knight_boss" 13 | 14 | const WORM_HEAD := "worm_head" 15 | const WORM_BODY := "worm_body" 16 | const WORM_SPICE := "worm_spice" 17 | 18 | const LIGHTHOUSE := "lighthouse" 19 | const HARBOR := "harbor" 20 | 21 | const CRYSTAL := "crystal" 22 | const CRYSTAL_BASE := "crystal_base" 23 | const PC_MIRROR_IMAGE := "pc_mirror_image" 24 | const PHANTOM := "phantom" 25 | 26 | const FLOOR := "floor" 27 | const WALL := "wall" 28 | const PILLAR := "pillar" 29 | const RESPAWN := "respawn" 30 | 31 | const TREASURE := "treasure" 32 | const RARE_TREASURE := "rare_treasure" 33 | const FAKE_RARE_TREASURE := "fake_rare_treasure" 34 | 35 | const ARROW := "arrow" 36 | const ARROW_LEFT := "arrow_left" 37 | const ARROW_RIGHT := "arrow_right" 38 | const ARROW_UP := "arrow_up" 39 | const ARROW_DOWN := "arrow_down" 40 | 41 | const COUNTER := "counter" 42 | const SEPARATOR := "separator" 43 | 44 | const FROG := "frog" 45 | const FROG_PRINCESS := "frog_princess" 46 | const LAND := "land" 47 | const SWAMP := "swamp" 48 | 49 | const DEVIL := "devil" 50 | 51 | const HOUND := "hound" 52 | const HOUND_BOSS := "hound_boss" 53 | 54 | const NINJA := "ninja" 55 | const NINJA_SHADOW := "ninja_shadow" 56 | 57 | const DOOR := "door" 58 | const SCP_173 := "scp_173" 59 | 60 | const CROSSROAD := "crossroad" 61 | const TRUCK_SLOT := "truck_slot" 62 | const ONLOAD_GOODS := "onload_goods" 63 | const OFFLOAD_GOODS := "offload_goods" 64 | const SNOW := "snow" 65 | 66 | const TREE_TRUNK := "tree_trunk" 67 | const TREE_BRANCH := "tree_branch" 68 | const BIRD := "bird" 69 | const BANDIT := "bandit" 70 | -------------------------------------------------------------------------------- /library/WorldGenerator.gd: -------------------------------------------------------------------------------- 1 | class_name Game_WorldGenerator 2 | 3 | 4 | const HARD_RETRY_LIMIT := 999 5 | const WARN_RETRY := "Too many retries." 6 | const WARN_RAND := "Rand is not of type Game_RandomNumber." 7 | 8 | 9 | # is_valid_coord_func(coord: Game_IntCoord, retry: int, 10 | #> is_valid_coord_opt_arg: Array) -> bool 11 | # create_here_func(coord: Game_IntCoord, create_here_opt_arg: Array) -> void 12 | static func create_by_coord(all_coords: Array, 13 | count_remaining: int, rand, func_host: Object, 14 | is_valid_coord_func: String, is_valid_coord_opt_arg: Array, 15 | create_here_func: String, create_here_opt_arg: Array, 16 | max_retry := HARD_RETRY_LIMIT, retry := 0) -> void: 17 | var is_valid_coord := funcref(func_host, is_valid_coord_func) 18 | var create_here := funcref(func_host, create_here_func) 19 | 20 | # print(retry) 21 | if not (rand is Game_RandomNumber): 22 | push_warning(WARN_RAND) 23 | if max_retry > HARD_RETRY_LIMIT: 24 | max_retry = HARD_RETRY_LIMIT 25 | 26 | if retry > max_retry: 27 | if max_retry == HARD_RETRY_LIMIT: 28 | push_warning(WARN_RETRY) 29 | return 30 | elif count_remaining < 1: 31 | return 32 | 33 | Game_ArrayHelper.shuffle(all_coords, rand) 34 | for i in all_coords: 35 | if is_valid_coord.call_func(i, retry, is_valid_coord_opt_arg): 36 | create_here.call_func(i, create_here_opt_arg) 37 | count_remaining -= 1 38 | if count_remaining < 1: 39 | return 40 | 41 | create_by_coord(all_coords, count_remaining, rand, func_host, 42 | is_valid_coord_func, is_valid_coord_opt_arg, 43 | create_here_func, create_here_opt_arg, 44 | max_retry, retry + 1) 45 | 46 | 47 | static func init_array(this_array: Array, init_size: int, init_value) -> void: 48 | this_array.resize(init_size) 49 | for i in range(0, init_size): 50 | this_array[i] = init_value 51 | -------------------------------------------------------------------------------- /library/WorldTag.gd: -------------------------------------------------------------------------------- 1 | class_name Game_WorldTag 2 | # setting.json requires a string tag. 3 | 4 | 5 | const INVALID := "INVALID" 6 | const DEMO := "demo" 7 | 8 | const KNIGHT := "knight" 9 | const DESERT := "desert" 10 | const STYX := "styx" 11 | const MIRROR := "mirror" 12 | const BALLOON := "balloon" 13 | const FROG := "frog" 14 | const RAILGUN := "railgun" 15 | const HOUND := "hound" 16 | const NINJA := "ninja" 17 | const FACTORY := "factory" 18 | const SNOWRUNNER := "snowrunner" 19 | const BARON := "baron" 20 | 21 | const TAG_TO_NAME := { 22 | DEMO: "Demo", 23 | KNIGHT: "Knight", 24 | DESERT: "Desert", 25 | STYX: "Styx", 26 | MIRROR: "Mirror", 27 | BALLOON: "Balloon", 28 | FROG: "Frog", 29 | RAILGUN: "Railgun", 30 | HOUND: "Hound", 31 | NINJA: "Ninja", 32 | FACTORY: "Factory", 33 | SNOWRUNNER: "SnowRunner", 34 | BARON: "Baron", 35 | } 36 | 37 | 38 | static func get_world_name(world_tag: String) -> String: 39 | if TAG_TO_NAME.has(world_tag): 40 | return TAG_TO_NAME[world_tag] 41 | return INVALID 42 | 43 | 44 | static func get_full_world_tag() -> Array: 45 | return TAG_TO_NAME.keys() 46 | 47 | 48 | static func is_valid_world_tag(world_tag: String) -> bool: 49 | return TAG_TO_NAME.has(world_tag) 50 | -------------------------------------------------------------------------------- /library/ZIndex.gd: -------------------------------------------------------------------------------- 1 | class_name Game_ZIndex 2 | 3 | 4 | const MAIN_TAG_TO_Z_INDEX := { 5 | Game_MainTag.INVALID: -100, 6 | Game_MainTag.GROUND: 0, 7 | Game_MainTag.TRAP: 1, 8 | Game_MainTag.BUILDING: 2, 9 | Game_MainTag.ACTOR: 3, 10 | Game_MainTag.INDICATOR: 4, 11 | } 12 | const LAYERED_MAIN_TAG := [ 13 | Game_MainTag.GROUND, 14 | Game_MainTag.TRAP, 15 | Game_MainTag.BUILDING, 16 | Game_MainTag.ACTOR, 17 | ] 18 | 19 | 20 | static func get_z_index(main_tag: String) -> int: 21 | if not MAIN_TAG_TO_Z_INDEX.has(main_tag): 22 | main_tag = Game_MainTag.INVALID 23 | return MAIN_TAG_TO_Z_INDEX[main_tag] 24 | -------------------------------------------------------------------------------- /library/game_progress/BalloonProgress.gd: -------------------------------------------------------------------------------- 1 | extends Game_ProgressTemplate 2 | 3 | 4 | const MAX_FORECAST_SLOT := 3 5 | 6 | var _wind_duration: int = 0 7 | var _wind_forecast: Array = [] 8 | 9 | 10 | func _init(parent_node: Node2D).(parent_node) -> void: 11 | _wind_forecast.resize(MAX_FORECAST_SLOT) 12 | 13 | 14 | func renew_world(_pc_coord: Game_IntCoord) -> void: 15 | var ground: Sprite 16 | 17 | if _wind_duration < 1: 18 | _set_wind_direction() 19 | _wind_duration = Game_BalloonData.WIND_DURATION 20 | else: 21 | ground = _ref_DungeonBoard.get_ground_xy(0, _wind_duration) 22 | _ref_SwitchSprite.set_sprite(ground, Game_SpriteTypeTag.DEFAULT) 23 | _wind_duration -= 1 24 | 25 | 26 | func _set_wind_direction() -> void: 27 | var last_index := MAX_FORECAST_SLOT - 1 28 | var pc: Sprite = _ref_DungeonBoard.get_pc() 29 | var ground: Sprite 30 | 31 | if _wind_forecast[0] == null: 32 | for i in range(0, _wind_forecast.size()): 33 | _set_direction_by_slot(i) 34 | else: 35 | for i in range(0, last_index): 36 | _wind_forecast[i] = _wind_forecast[i + 1] 37 | _set_direction_by_slot(last_index) 38 | 39 | _ref_ObjectData.set_state(pc, _wind_forecast[0]) 40 | _ref_SwitchSprite.set_sprite(pc, Game_StateTag.STATE_TO_SPRITE[ 41 | _wind_forecast[0]]) 42 | 43 | for x in range(0, 2): 44 | ground = _ref_DungeonBoard.get_ground_xy(x, 0) 45 | _ref_SwitchSprite.set_sprite(ground, Game_StateTag.STATE_TO_SPRITE[ 46 | _wind_forecast[x]]) 47 | for y in range(1, 3): 48 | ground = _ref_DungeonBoard.get_ground_xy(0, y) 49 | _ref_SwitchSprite.set_sprite(ground, Game_StateTag.STATE_TO_SPRITE[ 50 | _wind_forecast[0]]) 51 | 52 | 53 | func _set_direction_by_slot(slot: int) -> void: 54 | var valid_dirs := Game_StateTag.VALID_DIRECTION.duplicate() 55 | 56 | Game_ArrayHelper.filter_element(valid_dirs, self, "_filter_wind_direction", 57 | [slot]) 58 | Game_ArrayHelper.rand_picker(valid_dirs, 1, _ref_RandomNumber) 59 | _wind_forecast[slot] = valid_dirs[0] 60 | 61 | 62 | func _filter_wind_direction(source: Array, index: int, opt_arg: Array) -> bool: 63 | var forcast_slot: int = opt_arg[0] 64 | var is_opposite: bool 65 | var is_duplicated: bool 66 | var is_same: bool 67 | 68 | # No restriction for the first slot. 69 | if forcast_slot == 0: 70 | return true 71 | 72 | # The second slot cannot be opposite to the first one. 73 | is_opposite = Game_StateTag.is_opposite_direction(source[index], 74 | _wind_forecast[forcast_slot - 1]) 75 | if forcast_slot == 1: 76 | return not is_opposite 77 | 78 | # Check whether the previous two slot are the same. 79 | is_duplicated = _wind_forecast[forcast_slot - 2] \ 80 | == _wind_forecast[forcast_slot - 1] 81 | # Check whether the candidate and the previous slot are the same. 82 | is_same = source[index] == _wind_forecast[forcast_slot - 1] 83 | 84 | # Same as the second slot. 85 | if is_opposite: 86 | return false 87 | # There can be at most two slots of the same direction. 88 | elif is_duplicated: 89 | return not is_same 90 | # Two slots are less likely to be of the same direction. 91 | elif is_same: 92 | return _ref_RandomNumber.get_percent_chance( 93 | Game_BalloonData.CHANGE_DIRECTION) 94 | return true 95 | -------------------------------------------------------------------------------- /library/game_progress/DemoProgress.gd: -------------------------------------------------------------------------------- 1 | extends Game_ProgressTemplate 2 | 3 | 4 | func _init(parent_node: Node2D).(parent_node) -> void: 5 | pass 6 | 7 | 8 | func renew_world(_pc_coord: Game_IntCoord) -> void: 9 | pass 10 | 11 | 12 | func remove_actor(_actor: Sprite, _x: int, _y: int) -> void: 13 | print("remove actor") 14 | -------------------------------------------------------------------------------- /library/game_progress/FactoryProgress.gd: -------------------------------------------------------------------------------- 1 | extends Game_ProgressTemplate 2 | 3 | 4 | func _init(parent_node: Node2D).(parent_node) -> void: 5 | pass 6 | -------------------------------------------------------------------------------- /library/game_progress/KnightProgress.gd: -------------------------------------------------------------------------------- 1 | extends Game_ProgressTemplate 2 | 3 | 4 | const SWITCH_NUMBER := [ 5 | Game_SpriteTypeTag.ONE, 6 | Game_SpriteTypeTag.TWO, 7 | Game_SpriteTypeTag.THREE, 8 | ] 9 | 10 | var _spr_Knight := preload("res://sprite/Knight.tscn") 11 | var _spr_KnightCaptain := preload("res://sprite/KnightCaptain.tscn") 12 | var _spr_KnightBoss := preload("res://sprite/KnightBoss.tscn") 13 | 14 | var _dead_captain := 0 15 | var _count_new_captain := 0 16 | var _spawn_captain := false 17 | var _spawn_boss := false 18 | var _spawn_knight := false 19 | var _counter: Sprite 20 | var _ground_coords := [] 21 | 22 | 23 | func _init(parent_node: Node2D).(parent_node) -> void: 24 | pass 25 | 26 | 27 | func end_world(_pc_coord: Game_IntCoord) -> void: 28 | var count_knight := _ref_DungeonBoard.get_sprites_by_tag( 29 | Game_SubTag.KNIGHT).size() 30 | var __ 31 | 32 | if _ground_coords.size() < 1: 33 | for i in _ref_DungeonBoard.get_sprites_by_tag(Game_MainTag.GROUND): 34 | _ground_coords.push_back(Game_ConvertCoord.sprite_to_coord(i)) 35 | 36 | if _spawn_captain: 37 | if _count_new_captain == Game_KnightData.MAX_CAPTAIN - 1: 38 | _spawn_captain = false 39 | elif _spawn_npc(Game_SubTag.KNIGHT_CAPTAIN): 40 | _count_new_captain += 1 41 | elif _spawn_boss: 42 | _spawn_boss = not _spawn_npc(Game_SubTag.KNIGHT_BOSS) 43 | 44 | if count_knight == Game_KnightData.MAX_KNIGHT: 45 | _spawn_knight = false 46 | elif count_knight < Game_KnightData.START_RESPAWN: 47 | _spawn_knight = true 48 | if _spawn_knight: 49 | __ = _spawn_npc(Game_SubTag.KNIGHT) 50 | 51 | 52 | func remove_actor(actor: Sprite, _x: int, _y: int) -> void: 53 | if not actor.is_in_group(Game_SubTag.KNIGHT_CAPTAIN): 54 | return 55 | 56 | _dead_captain += 1 57 | if _dead_captain == 1: 58 | _spawn_captain = true 59 | elif _dead_captain == Game_KnightData.MAX_CAPTAIN: 60 | _spawn_boss = true 61 | 62 | if _counter == null: 63 | _counter = _ref_DungeonBoard.get_sprites_by_tag(Game_SubTag.COUNTER)[0] 64 | _ref_SwitchSprite.set_sprite(_counter, SWITCH_NUMBER[_dead_captain - 1]) 65 | 66 | 67 | func _spawn_npc(sub_tag: String) -> bool: 68 | var new_actor: PackedScene 69 | 70 | match sub_tag: 71 | Game_SubTag.KNIGHT: 72 | new_actor = _spr_Knight 73 | Game_SubTag.KNIGHT_CAPTAIN: 74 | new_actor = _spr_KnightCaptain 75 | Game_SubTag.KNIGHT_BOSS: 76 | new_actor = _spr_KnightBoss 77 | _: 78 | return false 79 | 80 | Game_ArrayHelper.shuffle(_ground_coords, _ref_RandomNumber) 81 | for i in _ground_coords: 82 | if _is_close_to_pc(i) or _is_close_to_knight(i): 83 | continue 84 | _ref_CreateObject.create_actor(new_actor, sub_tag, i) 85 | return true 86 | return false 87 | 88 | 89 | func _is_close_to_pc(coord: Game_IntCoord) -> bool: 90 | var pc_pos := Game_ConvertCoord.sprite_to_coord(_ref_DungeonBoard.get_pc()) 91 | return Game_CoordCalculator.is_in_range(coord, pc_pos, 92 | Game_KnightData.RENDER_RANGE) 93 | 94 | 95 | func _is_close_to_knight(coord: Game_IntCoord) -> bool: 96 | var pos: Game_IntCoord 97 | 98 | for i in _ref_DungeonBoard.get_npc(): 99 | pos = Game_ConvertCoord.sprite_to_coord(i) 100 | if Game_CoordCalculator.is_in_range(pos, coord, 101 | Game_KnightData.KNIGHT_GAP): 102 | return true 103 | return false 104 | -------------------------------------------------------------------------------- /library/game_progress/MirrorProgress.gd: -------------------------------------------------------------------------------- 1 | extends Game_ProgressTemplate 2 | 3 | 4 | const CRYSTAL_BASE_Y := [ 5 | Game_MirrorData.CENTER_Y_1, 6 | Game_MirrorData.CENTER_Y_2, 7 | Game_MirrorData.CENTER_Y_3, 8 | Game_MirrorData.CENTER_Y_4, 9 | Game_MirrorData.CENTER_Y_5, 10 | ] 11 | const MAX_REPLENISH := 1 12 | 13 | var _spr_Crystal := preload("res://sprite/Crystal.tscn") 14 | 15 | # If use a constant array, a seed may generate an invalid and irreproducible 16 | # world if keep pressing `O` enough times. 17 | var _ground_coords := [] 18 | 19 | 20 | func _init(parent_node: Node2D).(parent_node) -> void: 21 | pass 22 | 23 | 24 | func end_world(_pc_coord: Game_IntCoord) -> void: 25 | _try_end_game() 26 | 27 | 28 | func npc_end_world(_pc_coord: Game_IntCoord) -> void: 29 | _try_end_game() 30 | 31 | 32 | func remove_trap(_trap: Sprite, _x: int, _y: int) -> void: 33 | var pc := _ref_DungeonBoard.get_pc() 34 | var hp := _ref_ObjectData.get_hit_point(pc) 35 | var crystal_base := _ref_DungeonBoard.get_building_xy( 36 | Game_DungeonSize.CENTER_X, CRYSTAL_BASE_Y[hp]) 37 | 38 | _ref_SwitchSprite.set_sprite(crystal_base, Game_SpriteTypeTag.ACTIVE) 39 | _ref_ObjectData.add_hit_point(pc, 1) 40 | 41 | if _ref_ObjectData.get_hit_point(pc) < Game_MirrorData.MAX_CRYSTAL: 42 | _replenish_crystal() 43 | 44 | 45 | func _replenish_crystal() -> void: 46 | var pc_pos := _ref_DungeonBoard.get_pc_coord() 47 | var mirror_pos := Game_CoordCalculator.get_mirror_image_xy( 48 | pc_pos.x, pc_pos.y, Game_DungeonSize.CENTER_X, pc_pos.y) 49 | 50 | if _ground_coords.size() < 1: 51 | _init_ground_coords() 52 | Game_WorldGenerator.create_by_coord(_ground_coords, 53 | MAX_REPLENISH, _ref_RandomNumber, self, 54 | "_is_valid_ground_coord", [pc_pos, mirror_pos], 55 | "_create_crystal_here", []) 56 | 57 | 58 | func _init_ground_coords() -> void: 59 | var grounds := _ref_DungeonBoard.get_sprites_by_tag(Game_MainTag.GROUND) 60 | 61 | _ground_coords.resize(grounds.size()) 62 | for i in range(0, grounds.size()): 63 | _ground_coords[i] = Game_ConvertCoord.sprite_to_coord(grounds[i]) 64 | 65 | 66 | func _is_valid_ground_coord(coord: Game_IntCoord, retry: int, opt_arg: Array) \ 67 | -> bool: 68 | var pc_pos: Game_IntCoord = opt_arg[0] 69 | var mirror_pos: Game_IntCoord = opt_arg[1] 70 | 71 | if _ref_DungeonBoard.has_actor(coord): 72 | if (retry > 0) and (coord.x == pc_pos.x) and (coord.y == pc_pos.y): 73 | return true 74 | return false 75 | else: 76 | for i in [pc_pos, mirror_pos]: 77 | if Game_CoordCalculator.is_in_range(coord, i, 78 | Game_MirrorData.CRYSTAL_DISTANCE): 79 | return false 80 | return true 81 | 82 | 83 | func _create_crystal_here(coord: Game_IntCoord, _arg: Array) -> void: 84 | _ref_CreateObject.create_trap(_spr_Crystal, Game_SubTag.CRYSTAL, coord) 85 | 86 | 87 | func _try_end_game() -> void: 88 | var pc := _ref_DungeonBoard.get_pc() 89 | 90 | if _ref_ObjectData.get_hit_point(pc) >= Game_MirrorData.MAX_CRYSTAL: 91 | _ref_EndGame.player_win() 92 | -------------------------------------------------------------------------------- /library/game_progress/ProgressTemplate.gd: -------------------------------------------------------------------------------- 1 | class_name Game_ProgressTemplate 2 | 3 | 4 | const DUNGEON_GRIDS := {} 5 | 6 | var _ref_RandomNumber: Game_RandomNumber 7 | var _ref_Schedule: Game_Schedule 8 | var _ref_CreateObject: Game_CreateObject 9 | var _ref_RemoveObject: Game_RemoveObject 10 | var _ref_DungeonBoard: Game_DungeonBoard 11 | var _ref_SwitchSprite: Game_SwitchSprite 12 | var _ref_ObjectData: Game_ObjectData 13 | var _ref_DangerZone: Game_DangerZone 14 | var _ref_EndGame: Game_EndGame 15 | var _ref_Palette: Game_Palette 16 | var _ref_CountDown: Game_CountDown 17 | 18 | var _spr_Floor := preload("res://sprite/Floor.tscn") 19 | 20 | 21 | # Refer: GameProgress.gd. 22 | func _init(parent_node: Node2D) -> void: 23 | _ref_RandomNumber = parent_node._ref_RandomNumber 24 | _ref_Schedule = parent_node._ref_Schedule 25 | _ref_CreateObject = parent_node._ref_CreateObject 26 | _ref_RemoveObject = parent_node._ref_RemoveObject 27 | _ref_DungeonBoard = parent_node._ref_DungeonBoard 28 | _ref_SwitchSprite = parent_node._ref_SwitchSprite 29 | _ref_ObjectData = parent_node._ref_ObjectData 30 | _ref_DangerZone = parent_node._ref_DangerZone 31 | _ref_EndGame = parent_node._ref_EndGame 32 | _ref_Palette = parent_node._ref_Palette 33 | _ref_CountDown = parent_node._ref_CountDown 34 | 35 | 36 | func start_first_turn(_pc_coord: Game_IntCoord) -> void: 37 | pass 38 | 39 | 40 | func renew_world(_pc_coord: Game_IntCoord) -> void: 41 | pass 42 | 43 | 44 | # PC ends his turn. 45 | func end_world(_pc_coord: Game_IntCoord) -> void: 46 | pass 47 | 48 | 49 | # If an unspecified NPC changes PC's state, do something. 50 | func npc_end_world(_pc_coord: Game_IntCoord) -> void: 51 | pass 52 | 53 | 54 | func remove_actor(_actor: Sprite, _x: int, _y: int) -> void: 55 | pass 56 | 57 | 58 | func remove_building(_building: Sprite, _x: int, _y: int) -> void: 59 | pass 60 | 61 | 62 | func remove_trap(_trap: Sprite, _x: int, _y: int) -> void: 63 | pass 64 | 65 | 66 | func remove_ground(_ground: Sprite, _x: int, _y: int) -> void: 67 | pass 68 | 69 | 70 | func create_actor(_actor: Sprite, _sub_tag: String, _x: int, _y: int) -> void: 71 | pass 72 | 73 | 74 | func create_building(_building: Sprite, _sub_tag: String, _x: int, _y: int) \ 75 | -> void: 76 | pass 77 | 78 | 79 | func create_trap(_trap: Sprite, _sub_tag: String, _x: int, _y: int) -> void: 80 | pass 81 | 82 | 83 | func create_ground(_ground: Sprite, _sub_tag: String, _x: int, _y: int) -> void: 84 | pass 85 | 86 | 87 | func game_over(_win: bool) -> void: 88 | pass 89 | -------------------------------------------------------------------------------- /library/game_progress/RailgunProgress.gd: -------------------------------------------------------------------------------- 1 | extends Game_ProgressTemplate 2 | 3 | 4 | const MAX_RETRY := 1 5 | 6 | var _spr_Devil := preload("res://sprite/Devil.tscn") 7 | 8 | var _alive_npc := 0 9 | var _ground_coords := [] 10 | 11 | 12 | func _init(parent_node: Node2D).(parent_node) -> void: 13 | pass 14 | 15 | 16 | func start_first_turn(pc_coord: Game_IntCoord) -> void: 17 | _init_ground_coords() 18 | _respawn_npc(pc_coord) 19 | 20 | 21 | func end_world(pc_coord: Game_IntCoord) -> void: 22 | if Game_RailgunData.MAX_NPC - _alive_npc < Game_RailgunData.TRIGGER_RESPAWN: 23 | return 24 | _respawn_npc(pc_coord) 25 | 26 | 27 | func remove_actor(_actor: Sprite, _x: int, _y: int) -> void: 28 | _alive_npc -= 1 29 | _alive_npc = max(_alive_npc, 0) as int 30 | 31 | 32 | func _init_ground_coords() -> void: 33 | for x in range(0, Game_DungeonSize.MAX_X): 34 | for y in range(0, Game_DungeonSize.MAX_Y): 35 | if _ref_DungeonBoard.has_building_xy(x, y): 36 | continue 37 | _ground_coords.push_back(Game_IntCoord.new(x, y)) 38 | 39 | 40 | func _respawn_npc(pc_coord: Game_IntCoord) -> void: 41 | Game_WorldGenerator.create_by_coord(_ground_coords, 42 | Game_RailgunData.TRIGGER_RESPAWN, _ref_RandomNumber, self, 43 | "_is_valid_devil_coord", [pc_coord], 44 | "_create_devil_here", [], MAX_RETRY) 45 | 46 | 47 | func _is_valid_devil_coord(coord: Game_IntCoord, retry: int, opt_arg: Array) \ 48 | -> bool: 49 | var pc_coord: Game_IntCoord = opt_arg[0] 50 | var npc_coord: Game_IntCoord 51 | 52 | if Game_CoordCalculator.is_in_range(coord, pc_coord, 53 | Game_RailgunData.PC_FRONT_SIGHT): 54 | return false 55 | elif Game_CoordCalculator.is_out_of_range(coord, pc_coord, 56 | Game_RailgunData.MAX_DISTANCE_TO_PC): 57 | return false 58 | elif retry > 0: 59 | return not _ref_DungeonBoard.has_actor(coord) 60 | else: 61 | for i in _ref_DungeonBoard.get_npc(): 62 | npc_coord = Game_ConvertCoord.sprite_to_coord(i) 63 | if Game_CoordCalculator.is_in_range(coord, npc_coord, 64 | Game_RailgunData.NPC_GAP): 65 | return false 66 | return true 67 | 68 | 69 | func _create_devil_here(coord: Game_IntCoord, _opt: Array) -> void: 70 | _ref_RemoveObject.remove_trap(coord) 71 | _ref_CreateObject.create_actor(_spr_Devil, Game_SubTag.DEVIL, coord) 72 | _alive_npc += 1 73 | -------------------------------------------------------------------------------- /library/game_progress/StyxProgress.gd: -------------------------------------------------------------------------------- 1 | extends Game_ProgressTemplate 2 | 3 | 4 | func _init(parent_node: Node2D).(parent_node) -> void: 5 | pass 6 | 7 | 8 | func start_first_turn(_pc_coord: Game_IntCoord) -> void: 9 | _change_water_flow() 10 | 11 | 12 | func renew_world(_pc_coord: Game_IntCoord) -> void: 13 | var pc := _ref_DungeonBoard.get_pc() 14 | 15 | if _ref_ObjectData.verify_state(pc, Game_StateTag.ACTIVE): 16 | _ref_ObjectData.set_state(pc, Game_StateTag.DEFAULT) 17 | _change_water_flow() 18 | 19 | 20 | func _change_water_flow() -> void: 21 | var ground: Array = _ref_DungeonBoard.get_sprites_by_tag( 22 | Game_MainTag.GROUND) 23 | var valid_state: Array 24 | var direction: int 25 | var pos: Game_IntCoord 26 | var x: int 27 | var y: int 28 | var flow: Sprite 29 | 30 | Game_ArrayHelper.filter_element(ground, self, "_filter_change_flow", []) 31 | for i in ground: 32 | if not _ref_ObjectData.verify_state(i, Game_StateTag.DEFAULT): 33 | continue 34 | valid_state = Game_StateTag.DIRECTION_TO_COORD.keys() 35 | Game_ArrayHelper.rand_picker(valid_state, 1, _ref_RandomNumber) 36 | direction = valid_state[0] 37 | _rotate_sprite(i, direction) 38 | 39 | pos = Game_ConvertCoord.sprite_to_coord(i) 40 | x = pos.x 41 | y = pos.y 42 | for _j in range(Game_StyxData.FLOW_LENGTH): 43 | x += Game_StateTag.DIRECTION_TO_COORD[direction][0] 44 | y += Game_StateTag.DIRECTION_TO_COORD[direction][1] 45 | flow = _ref_DungeonBoard.get_ground_xy(x, y) 46 | if (flow != null) and _ref_ObjectData.verify_state(flow, 47 | Game_StateTag.DEFAULT): 48 | _rotate_sprite(flow, direction) 49 | else: 50 | break 51 | 52 | 53 | func _rotate_sprite(ground: Sprite, direction: int) -> void: 54 | _ref_ObjectData.set_state(ground, direction) 55 | _ref_SwitchSprite.set_sprite(ground, 56 | Game_StateTag.STATE_TO_SPRITE[direction]) 57 | 58 | 59 | func _filter_change_flow(source: Array, index: int, _opt_arg) -> bool: 60 | _ref_ObjectData.set_state(source[index], Game_StateTag.DEFAULT) 61 | return true 62 | -------------------------------------------------------------------------------- /library/init/InitDemo.gd: -------------------------------------------------------------------------------- 1 | extends Game_WorldTemplate 2 | # Initialize a simple map for testing. 3 | 4 | 5 | var _spr_Dwarf := preload("res://sprite/Dwarf.tscn") 6 | 7 | var _dungeon: Dictionary = {} 8 | 9 | 10 | func _init(parent_node: Node2D).(parent_node) -> void: 11 | pass 12 | 13 | 14 | func get_blueprint() -> Array: 15 | _init_wall() 16 | _init_floor() 17 | _init_pc() 18 | _init_dwarf() 19 | 20 | return _blueprint 21 | 22 | 23 | func _init_wall() -> void: 24 | var shift: int = 2 25 | var min_x: int = Game_DungeonSize.CENTER_X - shift 26 | var max_x: int = Game_DungeonSize.CENTER_X + shift + 1 27 | var min_y: int = Game_DungeonSize.CENTER_Y - shift 28 | var max_y: int = Game_DungeonSize.CENTER_Y + shift + 1 29 | 30 | for x in range(min_x, max_x): 31 | for y in range(min_y, max_y): 32 | _occupy_position(x, y) 33 | _add_building_to_blueprint(_spr_Wall, Game_SubTag.WALL, x, y) 34 | 35 | 36 | func _init_dwarf() -> void: 37 | var dwarf: int = _ref_RandomNumber.get_int(3, 6) 38 | var x: int 39 | var y: int 40 | 41 | while dwarf > 0: 42 | x = _ref_RandomNumber.get_x_coord() 43 | y = _ref_RandomNumber.get_y_coord() 44 | if _is_occupied(x, y): 45 | continue 46 | 47 | _occupy_position(x, y) 48 | _add_actor_to_blueprint(_spr_Dwarf, Game_SubTag.DWARF, x, y) 49 | dwarf -= 1 50 | -------------------------------------------------------------------------------- /library/init/InitDesert.gd: -------------------------------------------------------------------------------- 1 | extends Game_WorldTemplate 2 | 3 | 4 | var _spr_PCDesert := preload("res://sprite/PCDesert.tscn") 5 | var _spr_Treasure := preload("res://sprite/Treasure.tscn") 6 | 7 | 8 | func _init(parent_node: Node2D).(parent_node) -> void: 9 | pass 10 | 11 | 12 | func get_blueprint() -> Array: 13 | _init_floor() 14 | _init_wall() 15 | _init_pc(0, INVALID_COORD, INVALID_COORD, _spr_PCDesert) 16 | 17 | return _blueprint 18 | 19 | 20 | func _init_wall(count: int = 0) -> void: 21 | var max_repeat: int = 20 22 | if count > max_repeat: 23 | return 24 | 25 | var min_length: int = 3 26 | var max_length: int = 6 27 | var wall_length: int = _ref_RandomNumber.get_int(min_length, max_length) 28 | var treasure: int = _ref_RandomNumber.get_int(0, wall_length) 29 | var x: int = _ref_RandomNumber.get_int(0, Game_DungeonSize.MAX_X) 30 | var y: int = _ref_RandomNumber.get_int(0, Game_DungeonSize.MAX_Y) 31 | var direction: int = _ref_RandomNumber.get_int(0, 2) 32 | 33 | if direction == 0: 34 | for i in range(x, x + wall_length): 35 | _try_build_wall(i, y, i == x + treasure) 36 | elif direction == 1: 37 | for j in range(y, y + wall_length): 38 | _try_build_wall(x, j, j == y + treasure) 39 | 40 | count += 1 41 | _init_wall(count) 42 | 43 | 44 | func _try_build_wall(x: int, y: int, is_treasure: bool) -> void: 45 | if not Game_CoordCalculator.is_inside_dungeon(x, y): 46 | return 47 | if _is_occupied(x, y): 48 | return 49 | 50 | _occupy_position(x, y) 51 | if is_treasure: 52 | _add_trap_to_blueprint(_spr_Treasure, Game_SubTag.TREASURE, x, y) 53 | else: 54 | _add_building_to_blueprint(_spr_Wall, Game_SubTag.WALL, x, y) 55 | -------------------------------------------------------------------------------- /library/init/InitFrog.gd: -------------------------------------------------------------------------------- 1 | extends Game_WorldTemplate 2 | 3 | 4 | var _spr_PCFrog := preload("res://sprite/PCFrog.tscn") 5 | # var _spr_Frog := preload("res://sprite/Frog.tscn") 6 | var _spr_Counter := preload("res://sprite/Counter.tscn") 7 | 8 | 9 | func _init(parent_node: Node2D).(parent_node) -> void: 10 | pass 11 | 12 | 13 | func get_blueprint() -> Array: 14 | _init_swamp() 15 | _init_pc(Game_FrogData.MIN_DISTANCE, INVALID_COORD, INVALID_COORD, 16 | _spr_PCFrog) 17 | # _init_actor(0, INVALID_COORD, INVALID_COORD, 18 | # Game_FrogData.MAX_FROG, _spr_Frog, Game_SubTag.FROG) 19 | 20 | return _blueprint 21 | 22 | 23 | func _init_swamp() -> void: 24 | var counter := 0 25 | 26 | while counter < Game_FrogData.MAX_LAND: 27 | counter += _init_path() 28 | 29 | for i in range(Game_DungeonSize.MAX_X): 30 | for j in range(Game_DungeonSize.MAX_Y): 31 | if (i == Game_DungeonSize.MAX_X - 1) \ 32 | and (j == Game_DungeonSize.MAX_Y - 1): 33 | _add_ground_to_blueprint(_spr_Counter, Game_SubTag.COUNTER, 34 | i, j) 35 | elif _is_occupied(i, j): 36 | _add_ground_to_blueprint(_spr_Wall, Game_SubTag.LAND, i, j) 37 | else: 38 | _add_ground_to_blueprint(_spr_Floor, Game_SubTag.SWAMP, i, j) 39 | 40 | 41 | func _init_path() -> int: 42 | var current_length := 0 43 | var x: int 44 | var y: int 45 | var neighbor: Array 46 | var counter: int 47 | 48 | # There should be far more unoccupied grids than occupied ones. 49 | while true: 50 | x = _ref_RandomNumber.get_x_coord() 51 | y = _ref_RandomNumber.get_y_coord() 52 | if not _is_occupied(x, y): 53 | break 54 | 55 | for _i in range(Game_FrogData.PATH_LENGTH): 56 | _occupy_position(x, y) 57 | current_length += 1 58 | 59 | neighbor = Game_CoordCalculator.get_neighbor_xy(x, y, 1) 60 | counter = 0 61 | for j in range(neighbor.size()): 62 | if _is_occupied(neighbor[j].x, neighbor[j].y): 63 | continue 64 | neighbor[counter] = neighbor[j] 65 | counter += 1 66 | neighbor.resize(counter) 67 | if neighbor.size() < 1: 68 | return current_length 69 | 70 | counter = _ref_RandomNumber.get_int(0, neighbor.size()) 71 | x = neighbor[counter].x 72 | y = neighbor[counter].y 73 | 74 | return current_length 75 | -------------------------------------------------------------------------------- /library/init/InitHound.gd: -------------------------------------------------------------------------------- 1 | extends Game_WorldTemplate 2 | 3 | 4 | const ROOM_SIZE := 4 5 | const CORRIDOR_WIDTH := 1 6 | const PICK_ROOM := 11 7 | const MIN_X := 1 8 | const MIN_Y := 0 9 | const MIN_SHIFT := 1 10 | const MAX_SHIFT := 3 11 | 12 | var _spr_FloorHound := preload("res://sprite/FloorHound.tscn") 13 | var _spr_PCHound := preload("res://sprite/PCHound.tscn") 14 | var _spr_WallHound := preload("res://sprite/WallHound.tscn") 15 | var _spr_Hound := preload("res://sprite/Hound.tscn") 16 | # var _spr_HoundBoss := preload("res://sprite/HoundBoss.tscn") 17 | 18 | 19 | func _init(parent_node: Node2D).(parent_node) -> void: 20 | pass 21 | 22 | 23 | func get_blueprint() -> Array: 24 | _create_wall() 25 | _init_floor(_spr_FloorHound) 26 | _create_pc() 27 | _init_actor(Game_HoundData.MIN_HOUND_GAP, INVALID_COORD, INVALID_COORD, 28 | Game_HoundData.MAX_HOUND, _spr_Hound, Game_SubTag.HOUND) 29 | # _init_actor(1, INVALID_COORD, INVALID_COORD, 30 | # 1, _spr_HoundBoss, Game_SubTag.HOUND_BOSS) 31 | 32 | return _blueprint 33 | 34 | 35 | func _create_wall() -> void: 36 | var counter_index: int = _ref_RandomNumber.get_int(0, PICK_ROOM) 37 | var start_point: Array = _get_top_left_position() 38 | var x: int 39 | var y: int 40 | var neighbor: Array 41 | 42 | Game_ArrayHelper.rand_picker(start_point, PICK_ROOM, _ref_RandomNumber) 43 | for i in start_point: 44 | x = i[0] + _ref_RandomNumber.get_int(MIN_SHIFT, MAX_SHIFT) 45 | y = i[1] + _ref_RandomNumber.get_int(MIN_SHIFT, MAX_SHIFT) 46 | neighbor = Game_CoordCalculator.get_neighbor_xy(x, y, 1) 47 | for j in range(0, neighbor.size()): 48 | if (counter_index == 0) and (j == 0): 49 | continue 50 | x = neighbor[j].x 51 | y = neighbor[j].y 52 | _occupy_position(x, y) 53 | _add_building_to_blueprint(_spr_Wall, Game_SubTag.WALL, x, y) 54 | counter_index -= 1 55 | 56 | 57 | func _get_top_left_position() -> Array: 58 | var valid_position := [] 59 | var step := ROOM_SIZE + CORRIDOR_WIDTH 60 | 61 | # By setting MIN_X to 1, it is guarantted that every grid is reachable. 62 | for x in range(MIN_X, Game_DungeonSize.MAX_X, step): 63 | if x + ROOM_SIZE < Game_DungeonSize.MAX_X: 64 | for y in range(MIN_Y, Game_DungeonSize.MAX_Y, step): 65 | if y + ROOM_SIZE < Game_DungeonSize.MAX_Y: 66 | valid_position.push_back([x, y]) 67 | return valid_position 68 | 69 | 70 | func _create_pc() -> void: 71 | Game_WorldGenerator.create_by_coord(_all_coords, 1, _ref_RandomNumber, self, 72 | "_is_valid_pc_coord", [], "_create_pc_here", []) 73 | 74 | 75 | func _is_valid_pc_coord(coord: Game_IntCoord, _retry: int, _arg: Array) -> bool: 76 | if _is_occupied(coord.x, coord.y): 77 | return false 78 | for i in Game_CoordCalculator.get_neighbor(coord, 1): 79 | if _is_occupied(i.x, i.y): 80 | return false 81 | return true 82 | 83 | 84 | func _create_pc_here(coord: Game_IntCoord, _arg: Array) -> void: 85 | _add_actor_to_blueprint(_spr_PCHound, Game_SubTag.PC, coord.x, coord.y) 86 | for i in Game_CoordCalculator.get_neighbor(coord, Game_HoundData.PC_SIGHT, 87 | true): 88 | _occupy_position(i.x, i.y) 89 | -------------------------------------------------------------------------------- /library/init/InitNinja.gd: -------------------------------------------------------------------------------- 1 | extends Game_WorldTemplate 2 | 3 | 4 | const PATH_TO_PREFABS := "ninja" 5 | const HP_CHAR := "X" 6 | 7 | const RANGE_Y := [ 8 | [Game_NinjaData.LEVEL_2_Y, Game_NinjaData.LEVEL_3_Y], 9 | [Game_NinjaData.LEVEL_1_Y, Game_NinjaData.LEVEL_2_Y], 10 | [Game_NinjaData.MIN_Y, Game_NinjaData.LEVEL_1_Y], 11 | ] 12 | 13 | var _spr_FloorNinja := preload("res://sprite/FloorNinja.tscn") 14 | var _spr_HPBar := preload("res://sprite/HPBar.tscn") 15 | var _spr_PCNinja := preload("res://sprite/PCNinja.tscn") 16 | var _spr_Ninja := preload("res://sprite/Ninja.tscn") 17 | var _spr_WallNinja := preload("res://sprite/WallNinja.tscn") 18 | 19 | 20 | func _init(parent_node: Node2D).(parent_node) -> void: 21 | pass 22 | 23 | 24 | func get_blueprint() -> Array: 25 | _create_wall_floor() 26 | _init_floor(_spr_FloorNinja) 27 | _init_pc(1, Game_DungeonSize.CENTER_X, Game_NinjaData.MAX_Y - 1, 28 | _spr_PCNinja) 29 | _create_actor() 30 | 31 | return _blueprint 32 | 33 | 34 | func _create_wall_floor() -> void: 35 | var file_list: Array = Game_FileIOHelper.get_file_list( 36 | Game_DungeonPrefab.RESOURCE_PATH + PATH_TO_PREFABS) 37 | var packed_prefab: Game_DungeonPrefab.PackedPrefab \ 38 | = Game_DungeonPrefab.get_prefab(file_list[0], []) 39 | var new_scene: PackedScene 40 | var sub_tag: String 41 | 42 | for x in range(0, packed_prefab.max_x): 43 | for y in range(0, packed_prefab.max_y): 44 | _occupy_position(x, y) 45 | match packed_prefab.prefab[x][y]: 46 | Game_DungeonPrefab.WALL_CHAR: 47 | new_scene = _spr_WallNinja 48 | sub_tag = Game_SubTag.WALL 49 | _add_building_to_blueprint(new_scene, sub_tag, x, y) 50 | HP_CHAR: 51 | new_scene = _spr_HPBar 52 | sub_tag = Game_SubTag.FLOOR 53 | _add_ground_to_blueprint(new_scene, sub_tag, x, y) 54 | _: 55 | _reverse_occupy(x, y) 56 | 57 | 58 | func _create_actor() -> void: 59 | for i in RANGE_Y: 60 | _create_actor_in_one_region(i[0], i[1], 61 | Game_NinjaData.MAX_NINJA_PER_LEVEL) 62 | 63 | 64 | func _create_actor_in_one_region(min_y: int, max_y: int, count: int) -> void: 65 | if count < 1: 66 | return 67 | 68 | var x := _ref_RandomNumber.get_int(Game_NinjaData.MIN_X, 69 | Game_NinjaData.MAX_X) 70 | var y := _ref_RandomNumber.get_int(min_y, max_y) 71 | var neighbor: Array 72 | 73 | if _is_occupied(x, y): 74 | _create_actor_in_one_region(min_y, max_y, count) 75 | else: 76 | _add_actor_to_blueprint(_spr_Ninja, Game_SubTag.NINJA, x, y) 77 | neighbor = Game_CoordCalculator.get_neighbor_xy(x, y, 1, true) 78 | for i in neighbor: 79 | _occupy_position(i.x, i.y) 80 | _create_actor_in_one_region(min_y, max_y, count - 1) 81 | -------------------------------------------------------------------------------- /library/init/InitStyx.gd: -------------------------------------------------------------------------------- 1 | extends Game_WorldTemplate 2 | 3 | 4 | const HARBOR_MARKER := OCCUPIED_MARKER + 1 5 | const PC_COORD := [ 6 | [1, 1], 7 | [1, Game_DungeonSize.MAX_Y - 2], 8 | [Game_DungeonSize.MAX_X - 2, 1], 9 | [Game_DungeonSize.MAX_X - 2, Game_DungeonSize.MAX_Y - 2], 10 | ] 11 | 12 | var _spr_Lighthouse := preload("res://sprite/Lighthouse.tscn") 13 | var _spr_Harbor := preload("res://sprite/Harbor.tscn") 14 | var _spr_Arrow := preload("res://sprite/Arrow.tscn") 15 | 16 | 17 | func _init(parent_node: Node2D).(parent_node) -> void: 18 | pass 19 | 20 | 21 | func get_blueprint() -> Array: 22 | var coord_index := _ref_RandomNumber.get_int(0, PC_COORD.size()) 23 | var pc_pos: Array = PC_COORD[coord_index] 24 | var pc_x: int = pc_pos[0] 25 | var pc_y: int = pc_pos[1] 26 | 27 | _init_lighthouse() 28 | _init_harbor(pc_x, pc_y) 29 | _init_river() 30 | _init_pc(0, pc_x, pc_y) 31 | 32 | return _blueprint 33 | 34 | 35 | func _init_lighthouse() -> void: 36 | var neighbor := Game_CoordCalculator.get_neighbor_xy( 37 | Game_DungeonSize.CENTER_X, Game_DungeonSize.CENTER_Y, 38 | Game_StyxData.LIGHTHOUSE_GAP, true) 39 | 40 | _add_building_to_blueprint(_spr_Lighthouse, Game_SubTag.LIGHTHOUSE, 41 | Game_DungeonSize.CENTER_X, Game_DungeonSize.CENTER_Y) 42 | for i in neighbor: 43 | _occupy_position(i.x, i.y) 44 | 45 | 46 | func _init_harbor(pc_x: int, pc_y: int) -> void: 47 | for i in Game_CoordCalculator.get_neighbor_xy(pc_x, pc_y, 48 | Game_StyxData.HARBOR_GAP, true): 49 | _set_terrain_marker(i.x, i.y, HARBOR_MARKER) 50 | 51 | Game_WorldGenerator.create_by_coord(_all_coords, 52 | Game_StyxData.MAX_HARBOR, _ref_RandomNumber, self, 53 | "_is_valid_harbor_coord", [], 54 | "_create_harbor_here", []) 55 | 56 | 57 | func _init_river() -> void: 58 | for i in range(Game_DungeonSize.MAX_X): 59 | for j in range(Game_DungeonSize.MAX_Y): 60 | if _is_occupied(i, j): 61 | continue 62 | _add_ground_to_blueprint(_spr_Arrow, Game_SubTag.ARROW, i, j) 63 | 64 | 65 | func _is_valid_harbor_coord(coord: Game_IntCoord, _retry: int, _arg: Array) \ 66 | -> bool: 67 | if _is_terrain_marker(coord.x, coord.y, HARBOR_MARKER) \ 68 | or _is_occupied(coord.x, coord.y): 69 | return false 70 | return true 71 | 72 | 73 | func _create_harbor_here(coord: Game_IntCoord, _arg: Array) -> void: 74 | _add_building_to_blueprint(_spr_Harbor, Game_SubTag.HARBOR, 75 | coord.x, coord.y) 76 | _occupy_position(coord.x, coord.y) 77 | for i in Game_CoordCalculator.get_neighbor(coord, 78 | Game_StyxData.HARBOR_GAP, false): 79 | if _is_terrain_marker(i.x, i.y, DEFAULT_MARKER): 80 | _set_terrain_marker(i.x, i.y, HARBOR_MARKER) 81 | -------------------------------------------------------------------------------- /library/init/SpriteBlueprint.gd: -------------------------------------------------------------------------------- 1 | class_name Game_SpriteBlueprint 2 | 3 | 4 | var scene: PackedScene setget set_scene, get_scene 5 | var main_tag: String setget set_main_tag, get_main_tag 6 | var sub_tag: String setget set_sub_tag, get_sub_tag 7 | var x: int setget set_x, get_x 8 | var y: int setget set_y, get_y 9 | var sprite_layer: int setget set_sprite_layer, get_sprite_layer 10 | 11 | 12 | func _init(_scene: PackedScene, _main_tag: String, _sub_tag: String, 13 | _x: int, _y: int, _sprite_layer) -> void: 14 | scene = _scene 15 | main_tag = _main_tag 16 | sub_tag = _sub_tag 17 | x = _x 18 | y = _y 19 | sprite_layer = _sprite_layer 20 | 21 | 22 | func get_scene() -> PackedScene: 23 | return scene 24 | 25 | 26 | func set_scene(_scene: PackedScene) -> void: 27 | return 28 | 29 | 30 | func get_main_tag() -> String: 31 | return main_tag 32 | 33 | 34 | func set_main_tag(_main_tag: String) -> void: 35 | return 36 | 37 | 38 | func get_sub_tag() -> String: 39 | return sub_tag 40 | 41 | 42 | func set_sub_tag(_sub_tag: String) -> void: 43 | return 44 | 45 | 46 | func get_x() -> int: 47 | return x 48 | 49 | 50 | func set_x(_x: int) -> void: 51 | return 52 | 53 | 54 | func get_y() -> int: 55 | return y 56 | 57 | 58 | func set_y(_y: int) -> void: 59 | return 60 | 61 | 62 | func get_sprite_layer() -> int: 63 | return sprite_layer 64 | 65 | 66 | func set_sprite_layer(_sprite_layer: int) -> void: 67 | return 68 | -------------------------------------------------------------------------------- /library/npc_ai/BalloonAI.gd: -------------------------------------------------------------------------------- 1 | extends Game_AITemplate 2 | 3 | 4 | func _init(parent_node: Node2D).(parent_node) -> void: 5 | pass 6 | -------------------------------------------------------------------------------- /library/npc_ai/DemoAI.gd: -------------------------------------------------------------------------------- 1 | extends Game_AITemplate 2 | 3 | 4 | func _init(parent_node: Node2D).(parent_node) -> void: 5 | pass 6 | 7 | 8 | func take_action() -> void: 9 | print_text = "" 10 | 11 | if _pc_is_close(): 12 | print_text = "Urist McRogueliker is scared!" 13 | 14 | 15 | func _pc_is_close() -> bool: 16 | var delta_x: int = abs(_self_pos.x - _pc_pos.x) as int 17 | var delta_y: int = abs(_self_pos.y - _pc_pos.y) as int 18 | 19 | return delta_x + delta_y < 2 20 | -------------------------------------------------------------------------------- /library/npc_ai/MirrorAI.gd: -------------------------------------------------------------------------------- 1 | extends Game_AITemplate 2 | 3 | 4 | func _init(parent_node: Node2D).(parent_node) -> void: 5 | pass 6 | 7 | 8 | func take_action() -> void: 9 | var distance: int 10 | 11 | if _self.is_in_group(Game_SubTag.PC_MIRROR_IMAGE): 12 | return 13 | elif not _ref_ObjectData.verify_state(_self, Game_StateTag.PASSIVE): 14 | distance = Game_CoordCalculator.get_range(_self_pos, _pc_pos) 15 | if distance == Game_MirrorData.ATTACK_RANGE: 16 | _switch_pc_and_image() 17 | _set_npc_state() 18 | elif distance <= Game_MirrorData.PHANTOM_SIGHT: 19 | _approach_pc() 20 | 21 | 22 | func _switch_pc_and_image() -> void: 23 | var mirror_coord := Game_CoordCalculator.get_mirror_image_xy( 24 | _pc_pos.x, _pc_pos.y, Game_DungeonSize.CENTER_X, _pc_pos.y) 25 | _ref_DungeonBoard.swap_sprite(Game_MainTag.ACTOR, _pc_pos, mirror_coord) 26 | 27 | 28 | func _set_npc_state() -> void: 29 | var npc_pos: Game_IntCoord 30 | 31 | for i in _ref_DungeonBoard.get_npc(): 32 | if i.is_in_group(Game_SubTag.PC_MIRROR_IMAGE): 33 | continue 34 | elif _ref_ObjectData.verify_state(i, Game_StateTag.DEFAULT): 35 | _ref_ObjectData.set_state(i, Game_StateTag.PASSIVE) 36 | npc_pos = Game_ConvertCoord.sprite_to_coord(i) 37 | if _ref_DungeonBoard.has_trap(npc_pos): 38 | _ref_RemoveObject.remove_trap(npc_pos) 39 | else: 40 | _ref_ObjectData.set_state(i, Game_StateTag.DEFAULT) 41 | -------------------------------------------------------------------------------- /library/npc_ai/SnowRunnerAI.gd: -------------------------------------------------------------------------------- 1 | extends Game_AITemplate 2 | 3 | 4 | func _init(parent_node: Node2D).(parent_node) -> void: 5 | pass 6 | 7 | 8 | func take_action() -> void: 9 | print_text = "" 10 | 11 | if _pc_is_close(): 12 | print_text = "Urist McRogueliker is scared!" 13 | 14 | 15 | func _pc_is_close() -> bool: 16 | var delta_x: int = abs(_self_pos.x - _pc_pos.x) as int 17 | var delta_y: int = abs(_self_pos.y - _pc_pos.y) as int 18 | 19 | return delta_x + delta_y < 2 20 | -------------------------------------------------------------------------------- /library/npc_ai/StyxAI.gd: -------------------------------------------------------------------------------- 1 | extends Game_AITemplate 2 | 3 | 4 | func _init(parent_node: Node2D).(parent_node) -> void: 5 | pass 6 | -------------------------------------------------------------------------------- /library/npc_data/BalloonData.gd: -------------------------------------------------------------------------------- 1 | class_name Game_BalloonData 2 | 3 | 4 | const WIND_DURATION := 2 5 | const RENDER_RANGE := 3 6 | const CHANGE_DIRECTION := 40 7 | 8 | const MAX_TRAP := 5 9 | const MAX_REMAINING_TRAP := 3 10 | const MAX_WALL := 25 11 | 12 | const STAGE_1_BEACON := 2 13 | const STAGE_2_BEACON := 1 14 | 15 | const STAGE_1_RESTORE := 2 16 | const STAGE_2_RESTORE := 4 17 | const STAGE_3_RESTORE := 6 18 | 19 | -------------------------------------------------------------------------------- /library/npc_data/BaronData.gd: -------------------------------------------------------------------------------- 1 | class_name Game_BaronData 2 | 3 | 4 | const TREE_LAYER := 1 5 | const MAX_BIRD := 20 6 | const MIN_BIRD_GAP := 3 7 | 8 | const ALERT_RANGE := 3 9 | const BASE_ALERT := 10 10 | const BANDIT_ALERT := 80 11 | 12 | const MAX_BANDIT := 5 13 | const MIN_BANDIT := 2 14 | const MAX_HP := 9 15 | 16 | const BASE_SIGHT := 4 17 | const NEAR_SIGHT := 3 18 | const SIGHT_THRESHOLD := 0 19 | 20 | const FINAL_RESTORE := 11 21 | const BASE_RESTORE := 2 22 | -------------------------------------------------------------------------------- /library/npc_data/DemoData.gd: -------------------------------------------------------------------------------- 1 | class_name Game_DemoData 2 | -------------------------------------------------------------------------------- /library/npc_data/DesertData.gd: -------------------------------------------------------------------------------- 1 | class_name Game_DesertData 2 | 3 | 4 | const MAX_LENGTH := 23 5 | const MIN_LENGTH := 12 6 | const SPICE_START := 2 7 | const SPICE_END := 5 8 | 9 | const CREATE_SPICE := 5 10 | const BONUS_CREATE_SPICE := 5 11 | const CREATE_QUALITY_SPICE := 20 12 | 13 | const HP_TURN := 1 14 | const HP_WAIT := 5 15 | const HP_SPICE := 10 16 | const HP_BURY := 30 17 | 18 | const MAX_SPICE := 3 19 | const MAX_WORM := 2 20 | const MAX_COOLDOWN := 4 21 | const MIN_COOLDOWN := 0 22 | const WORM_DISTANCE := 5 23 | const MOVE_STRAIGHT := 60 24 | 25 | const RESTORE_TURN := 7 26 | const RENDER_RANGE := 8 27 | -------------------------------------------------------------------------------- /library/npc_data/FactoryData.gd: -------------------------------------------------------------------------------- 1 | class_name Game_FactoryData 2 | 3 | 4 | const MAX_TREASURE := 22 5 | const MAX_RARE_TREASURE := 3 6 | 7 | const TREASURE_GAP := 2 8 | const RARE_TREASURE_GAP := 10 9 | 10 | const MAX_SCP := 13 11 | const SCP_GAP := 2 12 | const SCP_STEP_COUNT := 2 13 | 14 | const PC_SIGHT := 5 15 | const PC_GAP := 2 16 | 17 | const RESTORE_TREASURE := 6 18 | const RESTORE_RARE_TREASURE := 24 19 | const MAX_TREASURE_SLOT := 9 20 | 21 | const MIN_WAIT := 5 22 | const MAX_WAIT := 11 23 | -------------------------------------------------------------------------------- /library/npc_data/FrogData.gd: -------------------------------------------------------------------------------- 1 | class_name Game_FrogData 2 | 3 | 4 | const MAX_LAND := 90 5 | const PATH_LENGTH := 5 6 | const SUBMERGE_LAND := 15 7 | const SUBMERGE_MORE_LAND := 20 8 | const RENDER_RANGE := 4 9 | const LIGHTED_RANGE := 1 10 | 11 | const MAX_FROG := 8 12 | const HALF_FROG := 4 13 | const MAX_PRINCESS := 1 14 | 15 | const MIN_DISTANCE := 4 16 | const MID_DISTANCE := 8 17 | const MAX_DISTANCE := 14 18 | 19 | const ATTACK_RANGE := 2 20 | const MIN_WAIT := 1 21 | const MAX_WAIT := 4 22 | 23 | const RESTORE_TURN := 9 24 | const SINK_IN_MUD := 3 25 | -------------------------------------------------------------------------------- /library/npc_data/HoundData.gd: -------------------------------------------------------------------------------- 1 | class_name Game_HoundData 2 | 3 | 4 | const PC_SIGHT := 5 5 | const SUBTRACT_HIT_POINT_IN_CAGE := 3 6 | const MAX_PC_HIT_POINT := 9 7 | const HIT_FROM_HOUND := 1 8 | const HIT_FROM_BOSS := 3 9 | const HIT_IN_FOG := 1 10 | 11 | const MIN_FOG_SIZE := 0 12 | const MAX_FOG_SIZE := 5 13 | const FOG_DURATION := 2 14 | 15 | const ABSORB_DURATION := 10 16 | const ABSORB_RANGE := 2 17 | 18 | const HOUND_SIGHT := 6 19 | const MIN_HOUND_GAP := 3 20 | const MAX_HOUND := 10 21 | const MAX_BOSS_HIT_POINT := 3 22 | 23 | const START_RESPAWN := 6 24 | const MIN_MINION_DISTANCE := 6 25 | const MAX_MINION_DISTANCE := 12 26 | const MIN_BOSS_DISTANCE := 10 27 | const MAX_BOSS_DISTANCE := 15 28 | 29 | const BOSS_RESTORE_COUNTDOWN := 7 30 | const BOSS_ADD_HIT_POINT := 1 31 | const PC_HIT_BOSS := 5 32 | -------------------------------------------------------------------------------- /library/npc_data/KnightData.gd: -------------------------------------------------------------------------------- 1 | class_name Game_KnightData 2 | 3 | 4 | const MAX_BOSS_HP := 2 5 | 6 | const ATTACK_RANGE := 1 7 | const GRUNT_SIGHT := 8 8 | const ELITE_SIGHT := 12 9 | const SNEAK_SIGHT := 1 10 | 11 | const MAX_KNIGHT := 10 12 | const MAX_CAPTAIN := 3 13 | const MIN_WAIT := 1 14 | const MAX_WAIT := 8 15 | 16 | const START_RESPAWN := 13 17 | const KNIGHT_GAP := 2 18 | 19 | const RESTORE_TURN := 7 20 | const RENDER_RANGE := 5 21 | -------------------------------------------------------------------------------- /library/npc_data/MirrorData.gd: -------------------------------------------------------------------------------- 1 | class_name Game_MirrorData 2 | 3 | 4 | const CENTER_Y_1 := 0 5 | const CENTER_Y_2 := 4 6 | const CENTER_Y_3 := 7 7 | const CENTER_Y_4 := 10 8 | const CENTER_Y_5 := 14 9 | 10 | const MAX_CRYSTAL := 5 11 | const MAX_MIRROR := 5 12 | const MAX_PHANTOM := 5 13 | 14 | const CRYSTAL_DISTANCE := 5 15 | const PHANTOM_SIGHT := 5 16 | const ATTACK_RANGE := 1 17 | const RESTORE_TURN := 3 18 | const RENDER_RANGE := 4 19 | 20 | const MAX_ACTOR_FOR_RESTORE := 2 21 | -------------------------------------------------------------------------------- /library/npc_data/NinjaData.gd: -------------------------------------------------------------------------------- 1 | class_name Game_NinjaData 2 | 3 | 4 | const MIN_X := 7 5 | const MAX_X := 14 6 | const MIN_Y := 0 7 | const MAX_Y := 13 8 | const GROUND_Y := 12 9 | 10 | const LEVEL_1_Y := 3 11 | const LEVEL_2_Y := 6 12 | const LEVEL_3_Y := 9 13 | 14 | const PC_SPEED := 2 15 | const PC_SIGHT := 6 16 | const MAX_TIME_STOP := 6 17 | const MAX_PC_HP := 2 18 | 19 | const NINJA_SPEED := 2 20 | const ATTACK_RANGE := 1 21 | const VERTICAL_NINJA_SIGHT := 3 22 | const MAX_NINJA_HP := 1 23 | 24 | # With 4 ninjas per level and 3 levels in all, we have 12 ninjas at the start of 25 | # the game. However, sometimes the formation is in such a coincidenct that all 26 | # the initial ninjas can be easily killed in one turn. In order to avoid this, 27 | # we set MAX_NINJA to 13. Therefore, a new ninja will be respawned at the end of 28 | # the first turn. He is probably away from his companions and he must be a 29 | # shadow ninja. Refer to NinjaProgress.end_world(). 30 | const MAX_NINJA_PER_LEVEL := 4 31 | const MAX_NINJA := 13 32 | # const MAX_NINJA := 12 33 | const MAX_SHADOW_NINJA := 3 34 | -------------------------------------------------------------------------------- /library/npc_data/RailgunData.gd: -------------------------------------------------------------------------------- 1 | class_name Game_RailgunData 2 | 3 | 4 | const PC_FRONT_SIGHT := 6 5 | const PC_SIDE_SIGHT := 4 6 | const CLOSE_RANGE := 1 7 | const TOUCH_PILLAR := 1 8 | const GUN_SHOT_HP := 1 9 | 10 | const NPC_SIGHT := 8 11 | const NPC_EAR_SHOT := 12 12 | const NPC_ATTACK := 4 13 | const NPC_GAP := 3 14 | const MAX_NPC := 6 15 | const TRIGGER_RESPAWN := 2 16 | const MAX_DISTANCE_TO_PC := 16 17 | 18 | const MAX_KILL_COUNT := 18 19 | const ONE_KILL := 1 20 | const COUNTER_DIGIT := 6 21 | const COUNTER_WIDTH := 3 22 | 23 | const MAX_AMMO := 5 24 | 25 | const RESTORE_AMMO := 1 26 | const RESTORE_TURN := 5 27 | -------------------------------------------------------------------------------- /library/npc_data/SnowRunnerData.gd: -------------------------------------------------------------------------------- 1 | class_name Game_SnowRunnerData 2 | 3 | 4 | const MAX_SLOT := 3 5 | const MAX_DELIVERY := 5 6 | 7 | const NO_PASSENGER := 0 8 | const PASSENGER_WAIT := 15 9 | const PASSENGER_ARRIVE := 20 10 | const PASSENGER_LEAVE := 40 11 | 12 | const NO_SNOW := 0 13 | const SNOW_FALL := 20 14 | const SNOW_MELT := 40 15 | 16 | const MAX_SNOW := 22 17 | const MAX_DOOR := 12 18 | const MAX_OFFLOAD := 2 19 | 20 | const SNOW_COST_TURN := 1 21 | 22 | const ONLOAD_GOODS := 5 23 | const OFFLOAD_GOODS := 17 24 | const DROP_OFF_PASSENGER := 9 25 | const PICK_UP_PASSENGER := 5 26 | -------------------------------------------------------------------------------- /library/npc_data/StyxData.gd: -------------------------------------------------------------------------------- 1 | class_name Game_StyxData 2 | 3 | 4 | const LIGHTHOUSE_GAP := 2 5 | 6 | const FLOW_LENGTH := 2 7 | 8 | const MIN_REACHED_HARBOR := 0 9 | const MAX_HARBOR := 3 10 | const HARBOR_GAP := 7 11 | 12 | const MIN_SIGHT := 2 13 | const NORMAL_SIGHT := 3 14 | const NORMAL_THRESHOLD := 4 15 | const DETECT_HARBOR := 6 16 | -------------------------------------------------------------------------------- /library/pc_action/DemoPCAction.gd: -------------------------------------------------------------------------------- 1 | extends Game_PCActionTemplate 2 | 3 | # This script is left blank intentionally. It inherits every behavior from its 4 | # parent, PCActionTemplate.gd. 5 | 6 | 7 | func _init(parent_node: Node2D).(parent_node) -> void: 8 | pass 9 | -------------------------------------------------------------------------------- /misc/customStyle.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #212529; 3 | } 4 | 5 | #canvas { 6 | display: inline; 7 | border-width: 2px; 8 | border-color: #6C757D; 9 | border-style: dashed; 10 | } 11 | -------------------------------------------------------------------------------- /misc/export.md: -------------------------------------------------------------------------------- 1 | # Export Settings 2 | 3 | * Godot engine: 3.4.4 4 | * Embed pck: True 5 | * Include filter: `user/doc/*`, `resource/dungeon_prefab/*` 6 | * Exclude filter: `bin/*`, `resource/REXPaint/*` 7 | 8 | `bin/*` is not tracked by Git. Therefore it does not exist in the GitHub repository. I use it locally to store binary files. 9 | 10 | The above settings are required for a Windows desktop project. If you want to export an HTML5 game, change following settings in addition to previous ones. 11 | 12 | Project settings - Display - Window: 13 | 14 | * Size - Resizable: On 15 | * Stretch - Mode: 2d 16 | * Stretch - Aspect: keep 17 | 18 | Export: 19 | 20 | * Head Include: `` 21 | * Canvas Resize Policy: Project 22 | 23 | In order to run the HTML5 game, deploy it on a server along with `misc/customStyle.css`. 24 | -------------------------------------------------------------------------------- /resource/FiraCode-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/FiraCode-Regular.ttf -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_00.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_00.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_A01.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_A01.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_A02.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_A02.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_A03.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_A03.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_A04.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_A04.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_A05.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_A05.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_B01.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_B01.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_B02.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_B02.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_B03.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_B03.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_B04.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_B04.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_B05.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_B05.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_C01.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_C01.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_C02.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_C02.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_C03.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_C03.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_C04.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_C04.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_C05.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_C05.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_D01.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_D01.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_D02.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_D02.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_D03.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_D03.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_D04.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_D04.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_D05.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_D05.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_E01.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_E01.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_E02.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_E02.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_E03.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_E03.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_E04.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_E04.xp -------------------------------------------------------------------------------- /resource/REXPaint/baron/baron_E05.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/baron/baron_E05.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_00.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_00.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_01.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_01.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_02.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_02.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_03.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_03.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_04.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_04.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_05.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_05.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_06.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_06.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_07.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_07.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_08.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_08.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_09.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_09.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_10.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_10.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_11.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_11.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_12.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_12.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_13.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_13.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_14.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_14.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_15.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_15.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_16.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_16.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_17.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_17.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_18.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_18.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_19.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_19.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_20.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_20.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_21.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_21.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_22.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_22.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_23.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_23.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_24.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_24.xp -------------------------------------------------------------------------------- /resource/REXPaint/factory/factory_25.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/factory/factory_25.xp -------------------------------------------------------------------------------- /resource/REXPaint/mirror/left_side.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/mirror/left_side.xp -------------------------------------------------------------------------------- /resource/REXPaint/mirror/wall_1.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/mirror/wall_1.xp -------------------------------------------------------------------------------- /resource/REXPaint/mirror/wall_2.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/mirror/wall_2.xp -------------------------------------------------------------------------------- /resource/REXPaint/mirror/wall_3.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/mirror/wall_3.xp -------------------------------------------------------------------------------- /resource/REXPaint/mirror/wall_4.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/mirror/wall_4.xp -------------------------------------------------------------------------------- /resource/REXPaint/ninja/ninja_00.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/ninja/ninja_00.xp -------------------------------------------------------------------------------- /resource/REXPaint/ninja/ninja_01.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/ninja/ninja_01.xp -------------------------------------------------------------------------------- /resource/REXPaint/snowrunner/snowrunner.xp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/REXPaint/snowrunner/snowrunner.xp -------------------------------------------------------------------------------- /resource/curses_vector_24x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/curses_vector_24x36.png -------------------------------------------------------------------------------- /resource/curses_vector_24x36.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/curses_vector_24x36.png-80c2c2165169b4817f9cc9fa8ece9db0.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://resource/curses_vector_24x36.png" 13 | dest_files=[ "res://.import/curses_vector_24x36.png-80c2c2165169b4817f9cc9fa8ece9db0.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_A01.txt: -------------------------------------------------------------------------------- 1 | .+O++.. 2 | +.+.O++ 3 | O...+.O 4 | ++..+.+ 5 | .O++O.. -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_A02.txt: -------------------------------------------------------------------------------- 1 | ++O+... 2 | O..+O++ 3 | +...+.O 4 | ..+.O.+ 5 | .+O++.. -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_A03.txt: -------------------------------------------------------------------------------- 1 | ++O+... 2 | O..++O+ 3 | +.+O..+ 4 | ..+..+O 5 | +OO+... -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_A04.txt: -------------------------------------------------------------------------------- 1 | ++O+... 2 | O..O+O+ 3 | +..+..+ 4 | ..+.++O 5 | .+O+O.. -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_A05.txt: -------------------------------------------------------------------------------- 1 | +O+O... 2 | +..++.. 3 | O+..O.+ 4 | ....+.O 5 | ...+O++ -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_B01.txt: -------------------------------------------------------------------------------- 1 | O+.+.+. 2 | ++.O+O+ 3 | .O++.+. 4 | +O...O+ 5 | .+..+O+ -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_B02.txt: -------------------------------------------------------------------------------- 1 | +...+O+ 2 | O+..+.. 3 | .+O+O.+ 4 | .+..++O 5 | +O.+O.. -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_B03.txt: -------------------------------------------------------------------------------- 1 | +O..+.+ 2 | .+..O+O 3 | .+O+O.. 4 | O+..+.. 5 | +...+O+ -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_B04.txt: -------------------------------------------------------------------------------- 1 | O++...+ 2 | +.O..+O 3 | .+O+.+. 4 | .+.++O+ 5 | +O.O+.. -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_B05.txt: -------------------------------------------------------------------------------- 1 | +.+..O+ 2 | O+O..+. 3 | .+O++O+ 4 | .+...+. 5 | +O...O+ -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_C01.txt: -------------------------------------------------------------------------------- 1 | O+O+... 2 | +..+..+ 3 | .+.O++O 4 | +O++... 5 | ...+OO+ -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_C02.txt: -------------------------------------------------------------------------------- 1 | O++O... 2 | +..++O+ 3 | .+.O.+. 4 | +O++..+ 5 | ...O++O -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_C03.txt: -------------------------------------------------------------------------------- 1 | +O++... 2 | .+.O+O+ 3 | O+.+.+. 4 | +..+..+ 5 | ...O++O -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_C04.txt: -------------------------------------------------------------------------------- 1 | +O++... 2 | .+.O+.+ 3 | +..+.+O 4 | O++O.+. 5 | ...++O+ -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_C05.txt: -------------------------------------------------------------------------------- 1 | O++O... 2 | +..+..+ 3 | .+.+.+O 4 | +O+O.+. 5 | ...++O+ -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_D01.txt: -------------------------------------------------------------------------------- 1 | .+O+.+. 2 | +.+.+O+ 3 | O++O..+ 4 | ++.+++O 5 | .O+.O+. -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_D02.txt: -------------------------------------------------------------------------------- 1 | O+..+O. 2 | +....++ 3 | +O+...O 4 | .+.++O+ 5 | .+O+.+. -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_D03.txt: -------------------------------------------------------------------------------- 1 | O+.+O.. 2 | +...+.. 3 | +O+.+.+ 4 | ..++O+O 5 | .+O.+.+ -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_D04.txt: -------------------------------------------------------------------------------- 1 | ++O.+.. 2 | O.++O++ 3 | +..O..O 4 | ..+++.+ 5 | .+O.O+. -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_D05.txt: -------------------------------------------------------------------------------- 1 | O+.+.+. 2 | +..O+O. 3 | +O++.++ 4 | .+.+..O 5 | ..+O+.+ -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_E01.txt: -------------------------------------------------------------------------------- 1 | .+.+O.+ 2 | +O.+++O 3 | O++O.+. 4 | +.+.+O+ 5 | .+O+.+. -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_E02.txt: -------------------------------------------------------------------------------- 1 | +O++... 2 | ...O+.+ 3 | +O+.O+O 4 | .+.++.+ 5 | +O+O... -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_E03.txt: -------------------------------------------------------------------------------- 1 | .++O+.. 2 | +O.+..+ 3 | .+.O++O 4 | +O+..+. 5 | O+...O+ -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_E04.txt: -------------------------------------------------------------------------------- 1 | +...O++ 2 | O...+.O 3 | ++.+O.+ 4 | .O.+... 5 | .++O+.. -------------------------------------------------------------------------------- /resource/dungeon_prefab/baron/baron_E05.txt: -------------------------------------------------------------------------------- 1 | .+O.+.+ 2 | +.++O+O 3 | O++...+ 4 | +.O.+.. 5 | ..++O+. -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_06.txt: -------------------------------------------------------------------------------- 1 | #+##### 2 | #.....+ 3 | #=##### 4 | #.#.#.# 5 | #.=.=.# 6 | #.#.#.# 7 | #+##### -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_07.txt: -------------------------------------------------------------------------------- 1 | ####+## 2 | #.....# 3 | #=##=## 4 | #.#...+ 5 | #.##### 6 | #.=...# 7 | ####+## -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_08.txt: -------------------------------------------------------------------------------- 1 | #+##### 2 | #..#..# 3 | #..#..# 4 | #=###=# 5 | #..#..# 6 | +..=..+ 7 | ####### -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_09.txt: -------------------------------------------------------------------------------- 1 | ##+#### 2 | #...=.# 3 | #...#.# 4 | #=##### 5 | #.#...# 6 | #.=...+ 7 | ####+## -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_10.txt: -------------------------------------------------------------------------------- 1 | #+##### 2 | #.=...# 3 | #.#...# 4 | #=##### 5 | #..#..# 6 | +..=..+ 7 | ####### -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_11.txt: -------------------------------------------------------------------------------- 1 | ####### 2 | +...=.+ 3 | #...#.# 4 | ##=##=# 5 | #...#.# 6 | #...#.# 7 | ##+#### -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_12.txt: -------------------------------------------------------------------------------- 1 | ###+#XX 2 | #...=XX 3 | ###=#=# 4 | #.#.#.# 5 | +.=.#.# 6 | #.#.#.# 7 | #####+# -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_13.txt: -------------------------------------------------------------------------------- 1 | ##+##XX 2 | #...#XX 3 | ##=##=# 4 | #...#.# 5 | #.#.#.# 6 | +...=.# 7 | ##+#### -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_14.txt: -------------------------------------------------------------------------------- 1 | ###+#XX 2 | #...#XX 3 | +...=XX 4 | ###=#=# 5 | #.=.#.# 6 | #.#.#.# 7 | ###+### -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_15.txt: -------------------------------------------------------------------------------- 1 | ##+##XX 2 | #...#XX 3 | +...=XX 4 | #####=# 5 | #.#...# 6 | #.=...# 7 | ####+## -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_16.txt: -------------------------------------------------------------------------------- 1 | #####XX 2 | #...=XX 3 | #...#XX 4 | ##=#### 5 | #...#.# 6 | +...=.+ 7 | ##+#### -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_17.txt: -------------------------------------------------------------------------------- 1 | #+##XXX 2 | +..=XXX 3 | #..#XXX 4 | #####=# 5 | #..#..# 6 | #..=..+ 7 | ####### -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_18.txt: -------------------------------------------------------------------------------- 1 | ####XXX 2 | #..=XXX 3 | #..#XXX 4 | #=##### 5 | #..#..# 6 | +..=..+ 7 | #+##### -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_19.txt: -------------------------------------------------------------------------------- 1 | #####XX 2 | #...=XX 3 | ##=##XX 4 | #...#XX 5 | #####=# 6 | +.....+ 7 | ##+#### -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_20.txt: -------------------------------------------------------------------------------- 1 | #+###XX 2 | #.#.#XX 3 | #.=.#XX 4 | #.#.#XX 5 | #=###=# 6 | #.....+ 7 | #+##### -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_21.txt: -------------------------------------------------------------------------------- 1 | #+###XX 2 | #.#.=XX 3 | #.#.#XX 4 | #.#.#XX 5 | #.#=### 6 | #.=...+ 7 | ###+### -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_22.txt: -------------------------------------------------------------------------------- 1 | ##+##XX 2 | #...#XX 3 | +.#.=XX 4 | #...#XX 5 | ##=#### 6 | #...=.+ 7 | ####### -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_23.txt: -------------------------------------------------------------------------------- 1 | #+###XX 2 | #...=XX 3 | #=###XX 4 | #.#.#XX 5 | #.#.### 6 | #.=...+ 7 | #+##### -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_24.txt: -------------------------------------------------------------------------------- 1 | ##+#XXX 2 | #..#XXX 3 | #..#XXX 4 | #..#XXX 5 | ##=#=## 6 | #.....+ 7 | ####+## -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/big_room/factory_25.txt: -------------------------------------------------------------------------------- 1 | #+##XXX 2 | #..#XXX 3 | +..=XXX 4 | #..#XXX 5 | #=###=# 6 | #..#..# 7 | #+##### -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/small_room/factory_03.txt: -------------------------------------------------------------------------------- 1 | #+# 2 | #.# 3 | #+# -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/small_room/factory_04.txt: -------------------------------------------------------------------------------- 1 | #+# 2 | #.+ 3 | ### -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/small_room/factory_05.txt: -------------------------------------------------------------------------------- 1 | # 2 | + 3 | # -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/start_point/factory_01.txt: -------------------------------------------------------------------------------- 1 | #+# 2 | #.# 3 | #-# -------------------------------------------------------------------------------- /resource/dungeon_prefab/factory/start_point/factory_02.txt: -------------------------------------------------------------------------------- 1 | #+# 2 | #.- 3 | ### -------------------------------------------------------------------------------- /resource/dungeon_prefab/mirror/left_side.txt: -------------------------------------------------------------------------------- 1 | ..........X 2 | ..........# 3 | ..+-..+-..# 4 | ..--..--..# 5 | ..........X 6 | ..........# 7 | ..+-..+-..# 8 | ..--..--..X 9 | ..........# 10 | ..........# 11 | ..+-..+-..X 12 | ..--..--..# 13 | ..........# 14 | ..........# 15 | ..........X -------------------------------------------------------------------------------- /resource/dungeon_prefab/mirror/walls/wall_1.txt: -------------------------------------------------------------------------------- 1 | ## 2 | .. -------------------------------------------------------------------------------- /resource/dungeon_prefab/mirror/walls/wall_2.txt: -------------------------------------------------------------------------------- 1 | .. 2 | ## -------------------------------------------------------------------------------- /resource/dungeon_prefab/mirror/walls/wall_3.txt: -------------------------------------------------------------------------------- 1 | #. 2 | #. -------------------------------------------------------------------------------- /resource/dungeon_prefab/mirror/walls/wall_4.txt: -------------------------------------------------------------------------------- 1 | .# 2 | .# -------------------------------------------------------------------------------- /resource/dungeon_prefab/ninja/ninja_01.txt: -------------------------------------------------------------------------------- 1 | #######∙∙∙∙∙∙∙####### 2 | #######∙∙∙∙∙∙∙####### 3 | #######∙∙∙∙∙∙∙####### 4 | #######∙∙∙∙∙∙∙####### 5 | #######∙∙∙∙∙∙∙####### 6 | #######∙∙∙∙∙∙∙####### 7 | #######∙∙∙∙∙∙∙####### 8 | #######∙∙∙∙∙∙∙####### 9 | #######∙∙∙∙∙∙∙####### 10 | #######∙∙∙∙∙∙∙####### 11 | #######∙∙∙∙∙∙∙####### 12 | #######∙∙∙∙∙∙∙####### 13 | #######∙∙∙∙∙∙∙####### 14 | ##################### 15 | #######XXX#XXX####### -------------------------------------------------------------------------------- /resource/dungeon_prefab/snowrunner/snowrunner.txt: -------------------------------------------------------------------------------- 1 | ####+######X#####X### 2 | #==∙∙==∙∙==∙∙∙==∙∙==# 3 | #==∙∙==∙∙==∙∙∙==∙∙==# 4 | #∙SG#∙∙+#∙∙#+#∙∙+#∙∙# 5 | +∙∙#+∙∙#X∙∙+#+∙∙#X∙∙+ 6 | #∙∙##∙∙##∙∙###∙∙##∙∙# 7 | #∙∙+#∙∙+#∙∙#X#∙∙+#∙∙# 8 | #==∙∙==∙∙==∙∙∙==∙∙==# 9 | #==∙∙==∙∙==∙∙∙==∙∙==# 10 | #∙∙#+∙∙#+∙∙#+#∙∙#X∙∙# 11 | +∙∙##∙∙##∙∙X#+∙∙##∙∙X 12 | #∙∙X#∙∙X#∙∙#+#∙∙+#∙∙# 13 | #==∙∙==∙∙==∙∙∙==∙∙==# 14 | #==∙∙==∙∙==∙∙∙==∙∙==# 15 | ####X######X#####+### -------------------------------------------------------------------------------- /resource/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bozar/OneMoreLevel/31df1b4f15f6aacab7836c505028146c997b5c34/resource/icon.png -------------------------------------------------------------------------------- /resource/icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/icon.png-bf61486c7aab7f975507bf829cf9e034.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://resource/icon.png" 13 | dest_files=[ "res://.import/icon.png-bf61486c7aab7f975507bf829cf9e034.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /scene/gui/GUIInputBox.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/FiraCode-Regular.ttf" type="DynamicFontData" id=1] 4 | 5 | [sub_resource type="DynamicFont" id=1] 6 | size = 24 7 | font_data = ExtResource( 1 ) 8 | 9 | [node name="GUIInputBox" type="LineEdit"] 10 | margin_bottom = 31.0 11 | custom_fonts/font = SubResource( 1 ) 12 | context_menu_enabled = false 13 | -------------------------------------------------------------------------------- /scene/gui/GUIText.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/FiraCode-Regular.ttf" type="DynamicFontData" id=1] 4 | 5 | [sub_resource type="DynamicFont" id=1] 6 | size = 24 7 | font_data = ExtResource( 1 ) 8 | 9 | [node name="GUIText" type="Label"] 10 | margin_bottom = 31.0 11 | size_flags_vertical = 1 12 | custom_fonts/font = SubResource( 1 ) 13 | __meta__ = { 14 | "_edit_use_anchors_": false 15 | } 16 | -------------------------------------------------------------------------------- /scene/gui/HelpGUI.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://scene/gui/GUIText.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://scene/gui/HelpVScroll.gd" type="Script" id=2] 5 | 6 | [node name="HelpGUI" type="MarginContainer"] 7 | margin_right = 800.0 8 | margin_bottom = 600.0 9 | 10 | [node name="HelpVScroll" type="ScrollContainer" parent="."] 11 | margin_right = 800.0 12 | margin_bottom = 600.0 13 | script = ExtResource( 2 ) 14 | 15 | [node name="Dungeon" parent="HelpVScroll" instance=ExtResource( 1 )] 16 | margin_right = 800.0 17 | margin_bottom = 600.0 18 | size_flags_horizontal = 3 19 | size_flags_vertical = 3 20 | autowrap = true 21 | -------------------------------------------------------------------------------- /scene/gui/HelpVScroll.gd: -------------------------------------------------------------------------------- 1 | extends ScrollContainer 2 | class_name Game_HelpVScroll 3 | 4 | 5 | const SCROLL_LINE := 20 6 | const SCROLL_PAGE := 300 7 | const DUNGEON := "Dungeon" 8 | 9 | var _ref_Palette: Game_Palette 10 | 11 | var _help_text: Array 12 | var _help_index: int 13 | 14 | 15 | func _ready() -> void: 16 | visible = false 17 | 18 | 19 | func slide_scroll_bar(scroll_line: bool, scroll_down: bool) -> void: 20 | var distance: int 21 | 22 | if scroll_line: 23 | if scroll_down: 24 | distance = SCROLL_LINE 25 | else: 26 | distance = -SCROLL_LINE 27 | else: 28 | if scroll_down: 29 | distance = SCROLL_PAGE 30 | else: 31 | distance = -SCROLL_PAGE 32 | 33 | scroll_vertical += distance 34 | 35 | 36 | func scroll_to_top_or_bottom(scroll_to_bottom: bool) -> void: 37 | if scroll_to_bottom: 38 | scroll_vertical = get_v_scrollbar().max_value as int 39 | else: 40 | scroll_vertical = 0 41 | 42 | 43 | func switch_help_text(switch_to_next: bool) -> void: 44 | if switch_to_next: 45 | _help_index += 1 46 | else: 47 | _help_index -= 1 48 | 49 | if _help_index < 0: 50 | _reset_index(false) 51 | elif _help_index > _help_text.size() - 1: 52 | _reset_index() 53 | 54 | get_node(DUNGEON).text = _help_text[_help_index] 55 | _reset_scroll_bar() 56 | 57 | 58 | func _on_InitWorld_world_selected(new_world: String) -> void: 59 | _help_text = Game_InitWorldData.get_help(new_world) 60 | _reset_index() 61 | 62 | get_node(DUNGEON).modulate = _ref_Palette.get_text_color(true) 63 | get_node(DUNGEON).text = _help_text[_help_index] 64 | 65 | 66 | func _on_SwitchScreen_screen_switched(_source: int, target: int) -> void: 67 | _reset_scroll_bar() 68 | _reset_index() 69 | visible = (target == Game_ScreenTag.HELP) 70 | get_node(DUNGEON).text = _help_text[_help_index] 71 | 72 | 73 | func _reset_scroll_bar() -> void: 74 | scroll_vertical = 0 75 | 76 | 77 | func _reset_index(reset_to_min: bool = true) -> void: 78 | if reset_to_min: 79 | _help_index = 0 80 | else: 81 | _help_index = _help_text.size() - 1 82 | -------------------------------------------------------------------------------- /scene/gui/MainGUI.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://scene/gui/GUIText.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://scene/gui/SidebarVBox.gd" type="Script" id=2] 5 | 6 | [node name="MainGUI" type="MarginContainer"] 7 | margin_right = 800.0 8 | margin_bottom = 600.0 9 | 10 | [node name="SidebarVBox" type="VBoxContainer" parent="."] 11 | margin_left = 590.0 12 | margin_right = 800.0 13 | margin_bottom = 600.0 14 | rect_min_size = Vector2( 180, 0 ) 15 | size_flags_horizontal = 8 16 | custom_constants/separation = 20 17 | script = ExtResource( 2 ) 18 | 19 | [node name="Upper" type="VBoxContainer" parent="SidebarVBox"] 20 | margin_right = 210.0 21 | margin_bottom = 444.0 22 | size_flags_vertical = 3 23 | custom_constants/separation = 20 24 | 25 | [node name="Turn" parent="SidebarVBox/Upper" instance=ExtResource( 1 )] 26 | margin_right = 210.0 27 | text = "Turn: 14" 28 | 29 | [node name="Message" parent="SidebarVBox/Upper" instance=ExtResource( 1 )] 30 | margin_top = 51.0 31 | margin_right = 210.0 32 | margin_bottom = 444.0 33 | size_flags_vertical = 3 34 | text = "Message" 35 | 36 | [node name="Lower" type="VBoxContainer" parent="SidebarVBox"] 37 | margin_top = 464.0 38 | margin_right = 210.0 39 | margin_bottom = 600.0 40 | 41 | [node name="Version" parent="SidebarVBox/Lower" instance=ExtResource( 1 )] 42 | margin_right = 210.0 43 | text = "Version: 1.2.3" 44 | align = 2 45 | 46 | [node name="Help" parent="SidebarVBox/Lower" instance=ExtResource( 1 )] 47 | margin_top = 35.0 48 | margin_right = 210.0 49 | margin_bottom = 66.0 50 | text = "Help" 51 | align = 2 52 | 53 | [node name="World" parent="SidebarVBox/Lower" instance=ExtResource( 1 )] 54 | margin_top = 70.0 55 | margin_right = 210.0 56 | margin_bottom = 101.0 57 | size_flags_vertical = 3 58 | text = "World Name" 59 | align = 2 60 | 61 | [node name="Seed" parent="SidebarVBox/Lower" instance=ExtResource( 1 )] 62 | margin_top = 105.0 63 | margin_right = 210.0 64 | margin_bottom = 136.0 65 | text = "123456" 66 | align = 2 67 | -------------------------------------------------------------------------------- /scene/gui/Modeline.gd: -------------------------------------------------------------------------------- 1 | extends Label 2 | 3 | 4 | func _ready() -> void: 5 | text = "Press Space to start game." 6 | 7 | 8 | func _on_Schedule_turn_ending(current_sprite: Sprite) -> void: 9 | if current_sprite.is_in_group(Game_SubTag.PC): 10 | text = "" 11 | 12 | 13 | func _on_EnemyAI_enemy_warned(message: String) -> void: 14 | text = message 15 | -------------------------------------------------------------------------------- /scene/gui/SidebarVBox.gd: -------------------------------------------------------------------------------- 1 | extends VBoxContainer 2 | class_name Game_SidebarVBox 3 | 4 | 5 | const TURN := "Upper/Turn" 6 | const MESSAGE := "Upper/Message" 7 | const WORLD := "Lower/World" 8 | const HELP := "Lower/Help" 9 | const VERSION := "Lower/Version" 10 | const SEED := "Lower/Seed" 11 | 12 | var _ref_RandomNumber: Game_RandomNumber 13 | var _ref_CountDown: Game_CountDown 14 | var _ref_DungeonBoard: Game_DungeonBoard 15 | var _ref_GameSetting: Game_GameSetting 16 | var _ref_Palette: Game_Palette 17 | 18 | var _node_to_color: Dictionary 19 | 20 | 21 | func _on_InitWorld_world_selected(new_world: String) -> void: 22 | _node_to_color = { 23 | TURN: _ref_Palette.get_text_color(true), 24 | MESSAGE: _ref_Palette.get_text_color(true), 25 | WORLD: _ref_Palette.get_text_color(false), 26 | HELP: _ref_Palette.get_text_color(false), 27 | VERSION: _ref_Palette.get_text_color(false), 28 | SEED: _ref_Palette.get_text_color(false), 29 | } 30 | _set_color() 31 | 32 | get_node(TURN).text = _get_turn() 33 | get_node(MESSAGE).text = "" 34 | 35 | get_node(WORLD).text = Game_WorldTag.get_world_name(new_world) 36 | get_node(HELP).text = Game_SidebarText.HELP 37 | get_node(VERSION).text = _get_version() 38 | get_node(SEED).text = _get_seed() 39 | 40 | 41 | func _on_Schedule_turn_started(current_sprite: Sprite) -> void: 42 | if not current_sprite.is_in_group(Game_SubTag.PC): 43 | return 44 | get_node(TURN).text = _get_turn() 45 | 46 | 47 | func _on_EndGame_game_over(win: bool) -> void: 48 | get_node(TURN).text = _get_turn() 49 | if win: 50 | get_node(MESSAGE).text = Game_SidebarText.WIN 51 | else: 52 | get_node(MESSAGE).text = Game_SidebarText.LOSE 53 | 54 | 55 | func _on_SwitchScreen_screen_switched(_source: int, target: int) -> void: 56 | visible = (target == Game_ScreenTag.MAIN) 57 | 58 | 59 | func _set_color() -> void: 60 | for i in _node_to_color.keys(): 61 | get_node(i).modulate = _node_to_color[i] 62 | 63 | 64 | func _get_turn() -> String: 65 | return Game_SidebarText.TURN.format([_ref_CountDown.get_count(true)]) 66 | 67 | 68 | func _get_seed() -> String: 69 | var _rng_seed: String = String(_ref_RandomNumber.rng_seed) 70 | var _head: String = _rng_seed.substr(0, 3) 71 | var _body: String = _rng_seed.substr(3, 3) 72 | var _tail: String = _rng_seed.substr(6) 73 | 74 | return Game_SidebarText.SEED.format([_head, _body, _tail]) 75 | 76 | 77 | func _get_version() -> String: 78 | var version := Game_SidebarText.VERSION 79 | var check_status := [ 80 | _ref_GameSetting.get_json_parse_error(), 81 | _ref_GameSetting.get_wizard_mode(), 82 | _ref_GameSetting.get_mouse_input(), 83 | ] 84 | var postfix := Game_SidebarText.VERSION_BAR 85 | 86 | for i in check_status: 87 | postfix += Game_SidebarText.BOOL_TO_PREFIX[i] 88 | return version + postfix 89 | -------------------------------------------------------------------------------- /scene/main/AutoStart.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_AutoStart 3 | 4 | 5 | const PATH_TO_INIT := "../InitWorld" 6 | 7 | var _started := false 8 | 9 | 10 | func _process(_delta) -> void: 11 | if _started: 12 | queue_free() 13 | return 14 | 15 | get_node(PATH_TO_INIT).init_world() 16 | _started = true 17 | -------------------------------------------------------------------------------- /scene/main/BoolState.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_BoolState 3 | 4 | 5 | var _id_to_bool: Dictionary = {} 6 | 7 | 8 | func get_bool(id: int) -> bool: 9 | if not _id_to_bool.has(id): 10 | _id_to_bool[id] = false 11 | return _id_to_bool[id] 12 | 13 | 14 | func set_bool(id: int, state: bool) -> void: 15 | _id_to_bool[id] = state 16 | 17 | 18 | func remove_data(id: int) -> void: 19 | var __ = _id_to_bool.erase(id) 20 | -------------------------------------------------------------------------------- /scene/main/CountDown.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_CountDown 3 | 4 | 5 | const MAX_TURN := 24 6 | const MIN_TURN := 1 7 | const ONE_TURN := 1 8 | const ZERO_TURN := 0 9 | 10 | var _ref_EndGame: Game_EndGame 11 | 12 | var _current_count: int = MAX_TURN 13 | 14 | 15 | func get_count(fix_overflow: bool) -> int: 16 | if fix_overflow: 17 | return _fix_overflow() 18 | return _current_count 19 | 20 | 21 | func add_count(add: int) -> void: 22 | _current_count += add 23 | 24 | 25 | func subtract_count(subtract: int) -> void: 26 | _current_count -= subtract 27 | 28 | 29 | func _on_Schedule_turn_started(current_sprite: Sprite) -> void: 30 | if not current_sprite.is_in_group(Game_SubTag.PC): 31 | return 32 | _current_count = _fix_overflow() 33 | 34 | 35 | func _on_Schedule_turn_ended(current_sprite: Sprite) -> void: 36 | if current_sprite.is_in_group(Game_SubTag.PC): 37 | subtract_count(ONE_TURN) 38 | if _current_count < MIN_TURN: 39 | _current_count = _fix_overflow() 40 | _ref_EndGame.player_lose() 41 | 42 | 43 | func _fix_overflow() -> int: 44 | if _current_count > MAX_TURN: 45 | _current_count = MAX_TURN 46 | elif _current_count < MIN_TURN: 47 | _current_count = ZERO_TURN 48 | return _current_count 49 | -------------------------------------------------------------------------------- /scene/main/DangerZone.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_DangerZone 3 | 4 | 5 | # > 6 | var _coord_to_state: Dictionary = {} 7 | 8 | 9 | func _ready() -> void: 10 | for x in range(Game_DungeonSize.MAX_X): 11 | _coord_to_state[x] = [] 12 | for _y in range(Game_DungeonSize.MAX_Y): 13 | _coord_to_state[x].push_back(0) 14 | 15 | 16 | func is_in_danger(x: int, y: int) -> bool: 17 | if not Game_CoordCalculator.is_inside_dungeon(x, y): 18 | return true 19 | return _coord_to_state[x][y] > 0 20 | 21 | 22 | func set_danger_zone(x: int, y: int, is_dangerous: bool) -> void: 23 | if not Game_CoordCalculator.is_inside_dungeon(x, y): 24 | return 25 | 26 | if is_dangerous: 27 | _coord_to_state[x][y] += 1 28 | else: 29 | if _coord_to_state[x][y] > 0: 30 | _coord_to_state[x][y] -= 1 31 | -------------------------------------------------------------------------------- /scene/main/DebugInput.gd: -------------------------------------------------------------------------------- 1 | extends Game_InputTemplate 2 | class_name Game_DebugInput 3 | 4 | 5 | var _ref_SwitchScreen: Game_SwitchScreen 6 | 7 | 8 | func _unhandled_input(event: InputEvent) -> void: 9 | if _verify_input(event, Game_InputTag.CLOSE_MENU): 10 | _ref_SwitchScreen.set_screen(Game_ScreenTag.DEBUG, Game_ScreenTag.MAIN) 11 | 12 | 13 | func _on_SwitchScreen_screen_switched(_source: int, target: int) -> void: 14 | set_process_unhandled_input(target == Game_ScreenTag.DEBUG) 15 | -------------------------------------------------------------------------------- /scene/main/EndGame.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_EndGame 3 | 4 | 5 | # 1. Emit this signal when PC's turn has already started, or when it is not PC's 6 | # turn. Otherwies it may conflict with another signal: Schedule.turn_started. 7 | # 2. On the other hand, since the signal could be emitted before a turn ends, 8 | # if a script receives both EndGame.game_over and Schedule.turn_ended, you might 9 | # want to specify that if the game is over, do not respond to 10 | # Schedule.turn_ended. 11 | signal game_over(win) 12 | 13 | 14 | func player_lose() -> void: 15 | emit_signal("game_over", false) 16 | 17 | 18 | func player_win() -> void: 19 | emit_signal("game_over", true) 20 | -------------------------------------------------------------------------------- /scene/main/EnemyAI.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_EnemyAI 3 | 4 | 5 | signal enemy_warned(message) 6 | 7 | var _ref_Schedule: Game_Schedule 8 | var _ref_ObjectData: Game_ObjectData 9 | var _ref_DungeonBoard: Game_DungeonBoard 10 | var _ref_SwitchSprite: Game_SwitchSprite 11 | var _ref_DangerZone: Game_DangerZone 12 | var _ref_EndGame: Game_EndGame 13 | var _ref_RandomNumber: Game_RandomNumber 14 | var _ref_RemoveObject: Game_RemoveObject 15 | var _ref_CountDown: Game_CountDown 16 | var _ref_CreateObject: Game_CreateObject 17 | var _ref_Palette: Game_Palette 18 | 19 | var _world_tag: String 20 | var _ai: Game_AITemplate 21 | 22 | 23 | func _on_Schedule_turn_started(current_sprite: Sprite) -> void: 24 | if current_sprite.is_in_group(Game_SubTag.PC): 25 | return 26 | 27 | _ai.set_local_var(current_sprite) 28 | _ai.take_action() 29 | if _ai.print_text != "": 30 | emit_signal("enemy_warned", _ai.print_text) 31 | _ref_Schedule.end_turn() 32 | 33 | 34 | func _on_InitWorld_world_selected(new_world: String) -> void: 35 | _world_tag = new_world 36 | 37 | 38 | func _on_CreateObject_sprite_created(_new_sprite: Sprite, _main_tag: String, 39 | sub_tag: String, _x: int, _y: int, _layer: int) -> void: 40 | if sub_tag != Game_SubTag.PC: 41 | return 42 | # Refer: AITemplate.gd. 43 | _ai = Game_InitWorldData.get_enemy_ai(_world_tag).new(self) 44 | 45 | 46 | func _on_RemoveObject_sprite_removed(remove_sprite: Sprite, 47 | _main_tag: String, _x: int, _y: int, _sprite_layer: int) -> void: 48 | _ai.remove_data(remove_sprite) 49 | -------------------------------------------------------------------------------- /scene/main/GameProgress.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_GameProgress 3 | 4 | 5 | var _ref_RandomNumber: Game_RandomNumber 6 | var _ref_Schedule: Game_Schedule 7 | var _ref_CreateObject: Game_CreateObject 8 | var _ref_RemoveObject: Game_RemoveObject 9 | var _ref_DungeonBoard: Game_DungeonBoard 10 | var _ref_SwitchSprite: Game_SwitchSprite 11 | var _ref_ObjectData: Game_ObjectData 12 | var _ref_DangerZone: Game_DangerZone 13 | var _ref_EndGame: Game_EndGame 14 | var _ref_Palette: Game_Palette 15 | var _ref_CountDown: Game_CountDown 16 | 17 | var _progress: Game_ProgressTemplate 18 | var _game_over: bool = false 19 | 20 | 21 | func _on_InitWorld_world_selected(new_world: String) -> void: 22 | _progress = Game_InitWorldData.get_progress(new_world).new(self) 23 | 24 | 25 | func _on_CreateObject_sprite_created(new_sprite: Sprite, main_tag: String, 26 | sub_tag: String, x: int, y: int, _layer: int) -> void: 27 | match main_tag: 28 | Game_MainTag.ACTOR: 29 | _progress.create_actor(new_sprite, sub_tag, x, y) 30 | Game_MainTag.BUILDING: 31 | _progress.create_building(new_sprite, sub_tag, x, y) 32 | Game_MainTag.TRAP: 33 | _progress.create_trap(new_sprite, sub_tag, x, y) 34 | Game_MainTag.GROUND: 35 | _progress.create_ground(new_sprite, sub_tag, x, y) 36 | 37 | 38 | func _on_Schedule_first_turn_starting() -> void: 39 | _progress.start_first_turn(_ref_DungeonBoard.get_pc_coord()) 40 | 41 | 42 | func _on_Schedule_turn_starting(current_sprite: Sprite) -> void: 43 | if current_sprite.is_in_group(Game_SubTag.PC): 44 | _progress.renew_world(_ref_DungeonBoard.get_pc_coord()) 45 | 46 | 47 | func _on_Schedule_turn_ending(current_sprite: Sprite) -> void: 48 | var pc_coord := _ref_DungeonBoard.get_pc_coord() 49 | 50 | # Do not change world (like adding new NPCs) when the game is over. 51 | if _game_over: 52 | return 53 | if current_sprite.is_in_group(Game_SubTag.PC): 54 | _progress.end_world(pc_coord) 55 | else: 56 | _progress.npc_end_world(pc_coord) 57 | 58 | 59 | func _on_RemoveObject_sprite_removed(remove_sprite: Sprite, 60 | main_tag: String, x: int, y: int, _sprite_layer: int) -> void: 61 | match main_tag: 62 | Game_MainTag.ACTOR: 63 | _progress.remove_actor(remove_sprite, x, y) 64 | Game_MainTag.BUILDING: 65 | _progress.remove_building(remove_sprite, x, y) 66 | Game_MainTag.TRAP: 67 | _progress.remove_trap(remove_sprite, x, y) 68 | Game_MainTag.GROUND: 69 | _progress.remove_ground(remove_sprite, x, y) 70 | 71 | 72 | func _on_EndGame_game_over(win: bool) -> void: 73 | _game_over = true 74 | _progress.game_over(win) 75 | -------------------------------------------------------------------------------- /scene/main/HelpInput.gd: -------------------------------------------------------------------------------- 1 | extends Game_InputTemplate 2 | class_name Game_HelpInput 3 | 4 | 5 | var _ref_SwitchScreen: Game_SwitchScreen 6 | var _ref_HelpVScroll: Game_HelpVScroll 7 | 8 | var _input_to_funcref: Dictionary 9 | 10 | 11 | func _on_InitWorld_world_selected(_new_world: String) -> void: 12 | if _input_to_funcref.size() > 0: 13 | return 14 | 15 | _input_to_funcref = { 16 | Game_InputTag.CLOSE_MENU: 17 | [_ref_SwitchScreen, "set_screen", [Game_ScreenTag.HELP, 18 | Game_ScreenTag.MAIN]], 19 | Game_InputTag.MOVE_DOWN: 20 | [_ref_HelpVScroll, "slide_scroll_bar", [true, true]], 21 | Game_InputTag.MOVE_UP: 22 | [_ref_HelpVScroll, "slide_scroll_bar", [true, false]], 23 | Game_InputTag.PAGE_DOWN: 24 | [_ref_HelpVScroll, "slide_scroll_bar", [false, true]], 25 | Game_InputTag.PAGE_UP: 26 | [_ref_HelpVScroll, "slide_scroll_bar", [false, false]], 27 | Game_InputTag.SCROLL_TO_BOTTOM: 28 | [_ref_HelpVScroll, "scroll_to_top_or_bottom", [true]], 29 | Game_InputTag.SCROLL_TO_TOP: 30 | [_ref_HelpVScroll, "scroll_to_top_or_bottom", [false]], 31 | Game_InputTag.NEXT_HELP: 32 | [_ref_HelpVScroll, "switch_help_text", [true]], 33 | Game_InputTag.PREVIOUS_HELP: 34 | [_ref_HelpVScroll, "switch_help_text", [false]], 35 | } 36 | 37 | 38 | func _unhandled_input(event: InputEvent) -> void: 39 | for i in _input_to_funcref.keys(): 40 | if _verify_input(event, i): 41 | funcref(_input_to_funcref[i][0], _input_to_funcref[i][1]) \ 42 | .call_funcv(_input_to_funcref[i][2]) 43 | break 44 | 45 | 46 | func _on_SwitchScreen_screen_switched(_source: int, target: int) -> void: 47 | set_process_unhandled_input(target == Game_ScreenTag.HELP) 48 | -------------------------------------------------------------------------------- /scene/main/HitPoint.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_HitPoint 3 | 4 | 5 | var _id_to_hit_point: Dictionary = {} 6 | 7 | 8 | func get_hit_point(id: int) -> int: 9 | if not _id_to_hit_point.has(id): 10 | _id_to_hit_point[id] = 0 11 | return _id_to_hit_point[id] 12 | 13 | 14 | func set_hit_point(id: int, hit_point: int) -> void: 15 | _id_to_hit_point[id] = hit_point 16 | 17 | 18 | func add_hit_point(id: int, hit_point: int) -> void: 19 | if _id_to_hit_point.has(id): 20 | _id_to_hit_point[id] += hit_point 21 | else: 22 | _id_to_hit_point[id] = hit_point 23 | 24 | 25 | func subtract_hit_point(id: int, hit_point: int) -> void: 26 | add_hit_point(id, -hit_point) 27 | 28 | 29 | func remove_data(id: int) -> void: 30 | var __ = _id_to_hit_point.erase(id) 31 | -------------------------------------------------------------------------------- /scene/main/ObjectData.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_ObjectData 3 | 4 | 5 | const OBJECT_STATE := "ObjectState" 6 | const OBJECT_LAYER := "ObjectLayer" 7 | const BOOL_STATE := "BoolState" 8 | const SPRITE_TYPE := "SpriteType" 9 | const HIT_POINT := "HitPoint" 10 | 11 | 12 | func _on_CreateObject_sprite_created(new_sprite: Sprite, _main_tag: String, 13 | _sub_tag: String, _x: int, _y: int, layer: int) -> void: 14 | if layer != 0: 15 | set_layer(new_sprite, layer) 16 | 17 | 18 | func _on_RemoveObject_sprite_removed(remove_sprite: Sprite, _main_tag: String, 19 | _x: int, _y: int, _sprite_layer: int) -> void: 20 | var child_node: Array = get_children() 21 | for i in child_node: 22 | i.remove_data(_get_id(remove_sprite)) 23 | 24 | 25 | func get_state(sprite: Sprite) -> int: 26 | return get_node(OBJECT_STATE).get_state(_get_id(sprite)) 27 | 28 | 29 | func set_state(sprite: Sprite, state: int) -> void: 30 | get_node(OBJECT_STATE).set_state(_get_id(sprite), state) 31 | 32 | 33 | func verify_state(sprite: Sprite, state: int) -> bool: 34 | return get_node(OBJECT_STATE).verify_state(_get_id(sprite), state) 35 | 36 | 37 | func get_layer(sprite: Sprite) -> int: 38 | return get_node(OBJECT_LAYER).get_layer(_get_id(sprite)) 39 | 40 | 41 | func set_layer(sprite: Sprite, layer: int) -> void: 42 | get_node(OBJECT_LAYER).set_layer(_get_id(sprite), layer) 43 | 44 | 45 | func get_bool(sprite: Sprite) -> bool: 46 | return get_node(BOOL_STATE).get_bool(_get_id(sprite)) 47 | 48 | 49 | func set_bool(sprite: Sprite, state: bool) -> void: 50 | get_node(BOOL_STATE).set_bool(_get_id(sprite), state) 51 | 52 | 53 | func get_sprite_type(sprite: Sprite) -> String: 54 | return get_node(SPRITE_TYPE).get_sprite_type(_get_id(sprite)) 55 | 56 | 57 | func set_sprite_type(sprite: Sprite, sprite_type: String) -> void: 58 | get_node(SPRITE_TYPE).set_sprite_type(_get_id(sprite), sprite_type) 59 | 60 | 61 | func get_hit_point(sprite: Sprite) -> int: 62 | return get_node(HIT_POINT).get_hit_point(_get_id(sprite)) 63 | 64 | 65 | func set_hit_point(sprite: Sprite, hit_point: int) -> void: 66 | get_node(HIT_POINT).set_hit_point(_get_id(sprite), hit_point) 67 | 68 | 69 | func add_hit_point(sprite: Sprite, hit_point: int) -> void: 70 | get_node(HIT_POINT).add_hit_point(_get_id(sprite), hit_point) 71 | 72 | 73 | func subtract_hit_point(sprite: Sprite, hit_point: int) -> void: 74 | get_node(HIT_POINT).subtract_hit_point(_get_id(sprite), hit_point) 75 | 76 | 77 | func _get_id(sprite: Sprite) -> int: 78 | return sprite.get_instance_id() 79 | -------------------------------------------------------------------------------- /scene/main/ObjectLayer.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_ObjectLayer 3 | # When two sprites of the same main tag appears at the same position, put them 4 | # into different layers. Refer to InitBaron.gd. 5 | 6 | 7 | var _id_to_layer: Dictionary = {} 8 | 9 | 10 | func get_layer(id: int) -> int: 11 | if not _id_to_layer.has(id): 12 | _id_to_layer[id] = 0 13 | return _id_to_layer[id] 14 | 15 | 16 | func set_layer(id: int, layer: int) -> void: 17 | _id_to_layer[id] = layer 18 | 19 | 20 | func remove_data(id: int) -> void: 21 | var __ = _id_to_layer.erase(id) 22 | -------------------------------------------------------------------------------- /scene/main/ObjectState.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_ObjectState 3 | 4 | 5 | var _id_to_state: Dictionary = {} 6 | 7 | 8 | func get_state(id: int) -> int: 9 | if not _id_to_state.has(id): 10 | _id_to_state[id] = Game_StateTag.DEFAULT 11 | return _id_to_state[id] 12 | 13 | 14 | func set_state(id: int, state: int) -> void: 15 | _id_to_state[id] = state 16 | 17 | 18 | func verify_state(id: int, state: int) -> bool: 19 | if _id_to_state.has(id): 20 | return _id_to_state[id] == state 21 | return state == Game_StateTag.DEFAULT 22 | 23 | 24 | func remove_data(id: int) -> void: 25 | var __ = _id_to_state.erase(id) 26 | -------------------------------------------------------------------------------- /scene/main/RandomNumber.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_RandomNumber 3 | 4 | 5 | var rng_seed: int setget set_rng_seed, get_rng_seed 6 | 7 | var _ref_GameSetting: Game_GameSetting 8 | 9 | var _init_seed: int 10 | var _rng := RandomNumberGenerator.new() 11 | 12 | 13 | # Get an integer from min_int (inclusive) to max_int (exclusive). 14 | func get_int(min_int: int, max_int: int) -> int: 15 | return _rng.randi_range(min_int, max_int - 1) 16 | 17 | 18 | func get_percent_chance(chance: int) -> bool: 19 | return chance > get_int(0, 100) 20 | 21 | 22 | func get_x_coord() -> int: 23 | return get_int(0, Game_DungeonSize.MAX_X) 24 | 25 | 26 | func get_y_coord() -> int: 27 | return get_int(0, Game_DungeonSize.MAX_Y) 28 | 29 | 30 | func get_dungeon_coord() -> Game_IntCoord: 31 | return Game_IntCoord.new(get_x_coord(), get_y_coord()) 32 | 33 | 34 | func shuffle(repeat: int) -> void: 35 | var __ 36 | for _i in range(repeat): 37 | __ = get_int(0, 10) 38 | 39 | 40 | func get_rng_seed() -> int: 41 | return _init_seed 42 | 43 | 44 | func set_rng_seed(_rng_seed: int) -> void: 45 | return 46 | 47 | 48 | func _on_GameSetting_setting_loaded() -> void: 49 | # _rng.seed = 123 50 | _init_seed = _ref_GameSetting.get_rng_seed() 51 | 52 | while _init_seed <= 0: 53 | _rng.randomize() 54 | _init_seed = _rng.randi() 55 | 56 | _rng.seed = _init_seed 57 | print("seed: {0}".format([_init_seed])) 58 | 59 | 60 | func _on_GameSetting_setting_saved(save_data: Game_TransferData, 61 | save_tag: int) -> void: 62 | if save_tag == Game_SaveTag.REPLAY_DUNGEON: 63 | save_data.overwrite_rng_seed = get_rng_seed() 64 | else: 65 | save_data.overwrite_rng_seed = 0 66 | -------------------------------------------------------------------------------- /scene/main/ReloadGame.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_ReloadGame 3 | 4 | 5 | const PATH_TO_MAIN := "res://scene/main/MainScene.tscn" 6 | 7 | 8 | func reload() -> void: 9 | var new_scene: Node2D = load(PATH_TO_MAIN).instance() 10 | var old_scene: Node2D = get_tree().current_scene 11 | 12 | get_tree().root.add_child(new_scene) 13 | get_tree().current_scene = new_scene 14 | 15 | get_tree().root.remove_child(old_scene) 16 | old_scene.queue_free() 17 | -------------------------------------------------------------------------------- /scene/main/RemoveObject.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_RemoveObject 3 | 4 | 5 | signal sprite_removed(remove_sprite, main_tag, x, y, sprite_layer) 6 | 7 | var _ref_DungeonBoard: Game_DungeonBoard 8 | 9 | 10 | func remove_xy(main_tag: String, x: int, y: int, sprite_layer := 0) -> void: 11 | var remove_this: Sprite = _ref_DungeonBoard.get_sprite_xy(main_tag, x, y, 12 | sprite_layer) 13 | if remove_this == null: 14 | return 15 | 16 | emit_signal("sprite_removed", remove_this, main_tag, x, y, sprite_layer) 17 | remove_this.queue_free() 18 | 19 | 20 | func remove(main_tag: String, coord: Game_IntCoord, sprite_layer := 0) -> void: 21 | remove_xy(main_tag, coord.x, coord.y, sprite_layer) 22 | 23 | 24 | func remove_actor_xy(x: int, y: int, sprite_layer := 0) -> void: 25 | remove_xy(Game_MainTag.ACTOR, x, y, sprite_layer) 26 | 27 | 28 | func remove_actor(coord: Game_IntCoord, sprite_layer := 0) -> void: 29 | remove_actor_xy(coord.x, coord.y, sprite_layer) 30 | 31 | 32 | func remove_building_xy(x: int, y: int) -> void: 33 | remove_xy(Game_MainTag.BUILDING, x, y) 34 | 35 | 36 | func remove_building(coord: Game_IntCoord) -> void: 37 | remove_building_xy(coord.x, coord.y) 38 | 39 | 40 | func remove_trap_xy(x: int, y: int) -> void: 41 | remove_xy(Game_MainTag.TRAP, x, y) 42 | 43 | 44 | func remove_trap(coord: Game_IntCoord) -> void: 45 | remove_trap_xy(coord.x, coord.y) 46 | 47 | 48 | func remove_ground_xy(x: int, y: int) -> void: 49 | remove_xy(Game_MainTag.GROUND, x, y) 50 | 51 | 52 | func remove_ground(coord: Game_IntCoord) -> void: 53 | remove_ground_xy(coord.x, coord.y) 54 | -------------------------------------------------------------------------------- /scene/main/Schedule.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_Schedule 3 | 4 | 5 | const FIRST_SIGNALS := ["first_turn_starting", "first_turn_started",] 6 | const START_SIGNALS := ["turn_starting", "turn_started",] 7 | const END_SIGNALS := ["turn_ending", "turn_ended",] 8 | 9 | # warning-ignore: UNUSED_SIGNAL 10 | signal first_turn_starting() 11 | # warning-ignore: UNUSED_SIGNAL 12 | signal first_turn_started() 13 | # warning-ignore: UNUSED_SIGNAL 14 | signal turn_starting(current_sprite) 15 | # warning-ignore: UNUSED_SIGNAL 16 | signal turn_started(current_sprite) 17 | # warning-ignore: UNUSED_SIGNAL 18 | signal turn_ending(current_sprite) 19 | # warning-ignore: UNUSED_SIGNAL 20 | signal turn_ended(current_sprite) 21 | 22 | var _actors: Array = [null] 23 | var _pointer: int = 0 24 | var _end_game: bool = false 25 | var _end_current_turn: bool = true 26 | var _start_first_turn: bool = true 27 | 28 | 29 | func end_turn() -> void: 30 | # The boolean variable _end_game could be set during an actor's turn, or 31 | # when a turn ends. 32 | if _end_game: 33 | return 34 | 35 | # Suppose NPC X is the currently active actor, and Y is the next one in row. 36 | # 1. EnemyAI calls remove(X). 37 | # 2. In Schedule, _goto_next() is called and _end_current_turn is set to 38 | # false. 39 | # 3. EnemyAI calls X.end_turn(). 40 | # 4. In Schedule, we should start Y's turn, rather than ends it. 41 | if _end_current_turn: 42 | # print("{0}: End turn.".format([_get_current().name])) 43 | for i in END_SIGNALS: 44 | emit_signal(i, _get_current()) 45 | if _end_game: 46 | return 47 | _goto_next() 48 | else: 49 | _end_current_turn = true 50 | 51 | if _end_game: 52 | return 53 | for i in START_SIGNALS: 54 | emit_signal(i, _get_current()) 55 | 56 | 57 | func init_schedule() -> void: 58 | if _start_first_turn: 59 | for i in FIRST_SIGNALS: 60 | emit_signal(i) 61 | for i in START_SIGNALS: 62 | emit_signal(i, _get_current()) 63 | _start_first_turn = false 64 | 65 | 66 | func _on_CreateObject_sprite_created(new_sprite: Sprite, main_tag: String, 67 | sub_tag: String, _x: int, _y: int, _layer: int) -> void: 68 | if main_tag == Game_MainTag.ACTOR: 69 | if sub_tag == Game_SubTag.PC: 70 | _actors[0] = new_sprite 71 | else: 72 | _actors.append(new_sprite) 73 | 74 | 75 | func _on_RemoveObject_sprite_removed(remove_sprite: Sprite, _main_tag: String, 76 | _x: int, _y: int, _sprite_layer: int) -> void: 77 | var current_sprite: Sprite 78 | 79 | if remove_sprite == _get_current(): 80 | _end_current_turn = false 81 | _goto_next() 82 | current_sprite = _get_current() 83 | 84 | _actors.erase(remove_sprite) 85 | _pointer = _actors.find(current_sprite) 86 | 87 | 88 | func _on_EndGame_game_over(_win: bool) -> void: 89 | _end_game = true 90 | 91 | 92 | func _get_current() -> Sprite: 93 | return _actors[_pointer] as Sprite 94 | 95 | 96 | func _goto_next() -> void: 97 | _pointer += 1 98 | if _pointer > _actors.size() - 1: 99 | _pointer = 0 100 | -------------------------------------------------------------------------------- /scene/main/SpriteType.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_SpriteType 3 | 4 | 5 | var _id_to_sprite_type: Dictionary = {} 6 | 7 | 8 | func get_sprite_type(id: int) -> String: 9 | if not _id_to_sprite_type.has(id): 10 | _id_to_sprite_type[id] = Game_SpriteTypeTag.DEFAULT 11 | return _id_to_sprite_type[id] 12 | 13 | 14 | func set_sprite_type(id: int, sprite_type: String) -> void: 15 | _id_to_sprite_type[id] = sprite_type 16 | 17 | 18 | func remove_data(id: int) -> void: 19 | var __ = _id_to_sprite_type.erase(id) 20 | -------------------------------------------------------------------------------- /scene/main/SwitchScreen.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_SwitchScreen 3 | 4 | 5 | signal screen_switched(source, target) 6 | 7 | 8 | func set_screen(source: int, target: int) -> void: 9 | emit_signal("screen_switched", source, target) 10 | -------------------------------------------------------------------------------- /scene/main/SwitchSprite.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_SwitchSprite 3 | 4 | 5 | var _ref_ObjectData: Game_ObjectData 6 | 7 | 8 | func set_sprite(sprite: Sprite, type_tag: String) -> void: 9 | var current_type: String 10 | 11 | if not sprite.has_node(type_tag): 12 | return 13 | 14 | current_type = _ref_ObjectData.get_sprite_type(sprite) 15 | 16 | sprite.get_node(current_type).visible = false 17 | sprite.get_node(type_tag).visible = true 18 | 19 | current_type = type_tag 20 | _ref_ObjectData.set_sprite_type(sprite, current_type) 21 | -------------------------------------------------------------------------------- /scene/transfer_data/TransferData.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | class_name Game_TransferData 3 | 4 | 5 | # Press R or U to replay a game. 6 | var overwrite_setting: bool 7 | var overwrite_include_world: Array 8 | var overwrite_rng_seed: float 9 | 10 | var wizard_mode: bool 11 | var rng_seed: float 12 | var include_world: Array 13 | var exclude_world: Array 14 | var show_full_map: bool 15 | var mouse_input: bool 16 | -------------------------------------------------------------------------------- /scene/transfer_data/TransferData.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://scene/transfer_data/TransferData.gd" type="Script" id=1] 4 | 5 | [node name="TransferData" type="Node2D"] 6 | script = ExtResource( 1 ) 7 | -------------------------------------------------------------------------------- /sprite/Arrow.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=7 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 240, 540, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 192, 36, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 216, 36, 24, 36 ) 19 | 20 | [sub_resource type="AtlasTexture" id=4] 21 | flags = 4 22 | atlas = ExtResource( 1 ) 23 | region = Rect2( 264, 36, 24, 36 ) 24 | 25 | [sub_resource type="AtlasTexture" id=5] 26 | flags = 4 27 | atlas = ExtResource( 1 ) 28 | region = Rect2( 240, 36, 24, 36 ) 29 | 30 | [node name="Arrow" type="Sprite"] 31 | 32 | [node name="default" type="Sprite" parent="."] 33 | texture = SubResource( 1 ) 34 | 35 | [node name="up" type="Sprite" parent="."] 36 | visible = false 37 | texture = SubResource( 2 ) 38 | 39 | [node name="down" type="Sprite" parent="."] 40 | visible = false 41 | texture = SubResource( 3 ) 42 | 43 | [node name="left" type="Sprite" parent="."] 44 | visible = false 45 | texture = SubResource( 4 ) 46 | 47 | [node name="right" type="Sprite" parent="."] 48 | visible = false 49 | texture = SubResource( 5 ) 50 | -------------------------------------------------------------------------------- /sprite/Bandit.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=11 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=11] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 216, 108, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=3] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 24, 108, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=4] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 48, 108, 24, 36 ) 19 | 20 | [sub_resource type="AtlasTexture" id=5] 21 | flags = 4 22 | atlas = ExtResource( 1 ) 23 | region = Rect2( 72, 108, 24, 36 ) 24 | 25 | [sub_resource type="AtlasTexture" id=6] 26 | flags = 4 27 | atlas = ExtResource( 1 ) 28 | region = Rect2( 96, 108, 24, 36 ) 29 | 30 | [sub_resource type="AtlasTexture" id=7] 31 | flags = 4 32 | atlas = ExtResource( 1 ) 33 | region = Rect2( 120, 108, 24, 36 ) 34 | 35 | [sub_resource type="AtlasTexture" id=8] 36 | flags = 4 37 | atlas = ExtResource( 1 ) 38 | region = Rect2( 144, 108, 24, 36 ) 39 | 40 | [sub_resource type="AtlasTexture" id=9] 41 | flags = 4 42 | atlas = ExtResource( 1 ) 43 | region = Rect2( 168, 108, 24, 36 ) 44 | 45 | [sub_resource type="AtlasTexture" id=10] 46 | flags = 4 47 | atlas = ExtResource( 1 ) 48 | region = Rect2( 192, 108, 24, 36 ) 49 | 50 | [node name="Bandit" type="Sprite"] 51 | 52 | [node name="default" type="Sprite" parent="."] 53 | texture = SubResource( 11 ) 54 | 55 | [node name="one" type="Sprite" parent="."] 56 | visible = false 57 | texture = SubResource( 3 ) 58 | 59 | [node name="two" type="Sprite" parent="."] 60 | visible = false 61 | texture = SubResource( 4 ) 62 | 63 | [node name="three" type="Sprite" parent="."] 64 | visible = false 65 | texture = SubResource( 5 ) 66 | 67 | [node name="four" type="Sprite" parent="."] 68 | visible = false 69 | texture = SubResource( 6 ) 70 | 71 | [node name="five" type="Sprite" parent="."] 72 | visible = false 73 | texture = SubResource( 7 ) 74 | 75 | [node name="six" type="Sprite" parent="."] 76 | visible = false 77 | texture = SubResource( 8 ) 78 | 79 | [node name="seven" type="Sprite" parent="."] 80 | visible = false 81 | texture = SubResource( 9 ) 82 | 83 | [node name="eight" type="Sprite" parent="."] 84 | visible = false 85 | texture = SubResource( 10 ) 86 | -------------------------------------------------------------------------------- /sprite/Bird.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 192, 252, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 216, 252, 24, 36 ) 14 | 15 | [node name="Bird" type="Sprite"] 16 | 17 | [node name="default" type="Sprite" parent="."] 18 | texture = SubResource( 1 ) 19 | 20 | [node name="active" type="Sprite" parent="."] 21 | visible = false 22 | texture = SubResource( 2 ) 23 | -------------------------------------------------------------------------------- /sprite/Counter.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=13 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 0, 108, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 0, 108, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 24, 108, 24, 36 ) 19 | 20 | [sub_resource type="AtlasTexture" id=4] 21 | flags = 4 22 | atlas = ExtResource( 1 ) 23 | region = Rect2( 48, 108, 24, 36 ) 24 | 25 | [sub_resource type="AtlasTexture" id=5] 26 | flags = 4 27 | atlas = ExtResource( 1 ) 28 | region = Rect2( 72, 108, 24, 36 ) 29 | 30 | [sub_resource type="AtlasTexture" id=6] 31 | flags = 4 32 | atlas = ExtResource( 1 ) 33 | region = Rect2( 96, 108, 24, 36 ) 34 | 35 | [sub_resource type="AtlasTexture" id=7] 36 | flags = 4 37 | atlas = ExtResource( 1 ) 38 | region = Rect2( 120, 108, 24, 36 ) 39 | 40 | [sub_resource type="AtlasTexture" id=8] 41 | flags = 4 42 | atlas = ExtResource( 1 ) 43 | region = Rect2( 144, 108, 24, 36 ) 44 | 45 | [sub_resource type="AtlasTexture" id=9] 46 | flags = 4 47 | atlas = ExtResource( 1 ) 48 | region = Rect2( 168, 108, 24, 36 ) 49 | 50 | [sub_resource type="AtlasTexture" id=10] 51 | flags = 4 52 | atlas = ExtResource( 1 ) 53 | region = Rect2( 192, 108, 24, 36 ) 54 | 55 | [sub_resource type="AtlasTexture" id=11] 56 | flags = 4 57 | atlas = ExtResource( 1 ) 58 | region = Rect2( 216, 108, 24, 36 ) 59 | 60 | [node name="Counter" type="Sprite"] 61 | 62 | [node name="default" type="Sprite" parent="."] 63 | texture = SubResource( 1 ) 64 | 65 | [node name="zero" type="Sprite" parent="."] 66 | visible = false 67 | texture = SubResource( 2 ) 68 | 69 | [node name="one" type="Sprite" parent="."] 70 | visible = false 71 | texture = SubResource( 3 ) 72 | 73 | [node name="two" type="Sprite" parent="."] 74 | visible = false 75 | texture = SubResource( 4 ) 76 | 77 | [node name="three" type="Sprite" parent="."] 78 | visible = false 79 | texture = SubResource( 5 ) 80 | 81 | [node name="four" type="Sprite" parent="."] 82 | visible = false 83 | texture = SubResource( 6 ) 84 | 85 | [node name="five" type="Sprite" parent="."] 86 | visible = false 87 | texture = SubResource( 7 ) 88 | 89 | [node name="six" type="Sprite" parent="."] 90 | visible = false 91 | texture = SubResource( 8 ) 92 | 93 | [node name="seven" type="Sprite" parent="."] 94 | visible = false 95 | texture = SubResource( 9 ) 96 | 97 | [node name="eight" type="Sprite" parent="."] 98 | visible = false 99 | texture = SubResource( 10 ) 100 | 101 | [node name="nine" type="Sprite" parent="."] 102 | visible = false 103 | texture = SubResource( 11 ) 104 | -------------------------------------------------------------------------------- /sprite/Crystal.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 360, 0, 24, 36 ) 9 | 10 | [node name="Crystal" type="Sprite"] 11 | texture = SubResource( 1 ) 12 | -------------------------------------------------------------------------------- /sprite/CrystalBase.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 216, 540, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 360, 0, 24, 36 ) 14 | 15 | [node name="CrystalBase" type="Sprite"] 16 | 17 | [node name="default" type="Sprite" parent="."] 18 | texture = SubResource( 1 ) 19 | 20 | [node name="active" type="Sprite" parent="."] 21 | visible = false 22 | texture = SubResource( 2 ) 23 | -------------------------------------------------------------------------------- /sprite/Devil.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 96, 216, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 96, 144, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 24, 144, 24, 36 ) 19 | 20 | [node name="Devil" type="Sprite"] 21 | 22 | [node name="default" type="Sprite" parent="."] 23 | texture = SubResource( 1 ) 24 | 25 | [node name="active" type="Sprite" parent="."] 26 | visible = false 27 | texture = SubResource( 2 ) 28 | 29 | [node name="active_1" type="Sprite" parent="."] 30 | visible = false 31 | texture = SubResource( 3 ) 32 | -------------------------------------------------------------------------------- /sprite/Door.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 264, 72, 24, 36 ) 9 | 10 | [node name="Door" type="Sprite"] 11 | texture = SubResource( 1 ) 12 | -------------------------------------------------------------------------------- /sprite/DoorTruck.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 264, 72, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 0, 180, 24, 36 ) 14 | 15 | [node name="DoorTruck" type="Sprite"] 16 | 17 | [node name="default" type="Sprite" parent="."] 18 | texture = SubResource( 1 ) 19 | 20 | [node name="active" type="Sprite" parent="."] 21 | visible = false 22 | texture = SubResource( 2 ) 23 | -------------------------------------------------------------------------------- /sprite/Dwarf.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 96, 216, 24, 36 ) 9 | 10 | [node name="Dwarf" type="Sprite"] 11 | modulate = Color( 0.678431, 0.709804, 0.741176, 1 ) 12 | 13 | [node name="default" type="Sprite" parent="."] 14 | texture = SubResource( 1 ) 15 | -------------------------------------------------------------------------------- /sprite/FactoryClock.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 216, 36, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 192, 36, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 264, 36, 24, 36 ) 19 | 20 | [sub_resource type="AtlasTexture" id=4] 21 | flags = 4 22 | atlas = ExtResource( 1 ) 23 | region = Rect2( 240, 36, 24, 36 ) 24 | 25 | [node name="FactoryClock" type="Sprite"] 26 | 27 | [node name="default" type="Sprite" parent="."] 28 | texture = SubResource( 1 ) 29 | 30 | [node name="up" type="Sprite" parent="."] 31 | visible = false 32 | texture = SubResource( 2 ) 33 | 34 | [node name="left" type="Sprite" parent="."] 35 | visible = false 36 | texture = SubResource( 3 ) 37 | 38 | [node name="right" type="Sprite" parent="."] 39 | visible = false 40 | texture = SubResource( 4 ) 41 | -------------------------------------------------------------------------------- /sprite/Floor.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 240, 540, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 72, 36, 24, 36 ) 14 | 15 | [node name="Floor" type="Sprite"] 16 | 17 | [node name="default" type="Sprite" parent="."] 18 | texture = SubResource( 1 ) 19 | 20 | [node name="active" type="Sprite" parent="."] 21 | visible = false 22 | texture = SubResource( 2 ) 23 | normal_map = ExtResource( 1 ) 24 | -------------------------------------------------------------------------------- /sprite/FloorFactory.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 312, 72, 24, 36 ) 9 | 10 | [node name="FloorFactory" type="Sprite"] 11 | 12 | [node name="default" type="Sprite" parent="."] 13 | texture = SubResource( 1 ) 14 | -------------------------------------------------------------------------------- /sprite/FloorHound.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 240, 540, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 216, 540, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 264, 72, 24, 36 ) 19 | 20 | [node name="FloorHound" type="Sprite"] 21 | 22 | [node name="default" type="Sprite" parent="."] 23 | texture = SubResource( 1 ) 24 | 25 | [node name="active" type="Sprite" parent="."] 26 | visible = false 27 | texture = SubResource( 2 ) 28 | 29 | [node name="active_1" type="Sprite" parent="."] 30 | visible = false 31 | texture = SubResource( 3 ) 32 | -------------------------------------------------------------------------------- /sprite/FloorNinja.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 240, 540, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 0, 540, 24, 36 ) 14 | 15 | [node name="FloorNinja" type="Sprite"] 16 | 17 | [node name="default" type="Sprite" parent="."] 18 | texture = SubResource( 1 ) 19 | 20 | [node name="active" type="Sprite" parent="."] 21 | visible = false 22 | texture = SubResource( 2 ) 23 | normal_map = ExtResource( 1 ) 24 | -------------------------------------------------------------------------------- /sprite/FloorSnowRunner.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 216, 540, 24, 36 ) 9 | 10 | [node name="FloorSnowRunner" type="Sprite"] 11 | 12 | [node name="default" type="Sprite" parent="."] 13 | texture = SubResource( 1 ) 14 | -------------------------------------------------------------------------------- /sprite/Frog.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 144, 216, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 24, 72, 24, 36 ) 14 | 15 | [node name="Frog" type="Sprite"] 16 | 17 | [node name="default" type="Sprite" parent="."] 18 | texture = SubResource( 1 ) 19 | 20 | [node name="active" type="Sprite" parent="."] 21 | visible = false 22 | texture = SubResource( 2 ) 23 | normal_map = ExtResource( 1 ) 24 | -------------------------------------------------------------------------------- /sprite/FrogPrincess.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 0, 180, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 312, 360, 24, 36 ) 14 | 15 | [node name="FrogPrincess" type="Sprite"] 16 | 17 | [node name="default" type="Sprite" parent="."] 18 | texture = SubResource( 1 ) 19 | 20 | [node name="active" type="Sprite" parent="."] 21 | visible = false 22 | texture = SubResource( 2 ) 23 | normal_map = ExtResource( 1 ) 24 | -------------------------------------------------------------------------------- /sprite/HPBar.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 264, 468, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 0, 0, 24, 36 ) 14 | 15 | [node name="HPBar" type="Sprite"] 16 | 17 | [node name="default" type="Sprite" parent="."] 18 | texture = SubResource( 1 ) 19 | 20 | [node name="passive" type="Sprite" parent="."] 21 | visible = false 22 | texture = SubResource( 2 ) 23 | normal_map = ExtResource( 1 ) 24 | -------------------------------------------------------------------------------- /sprite/Harbor.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 360, 108, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 24, 72, 24, 36 ) 14 | 15 | [node name="Harbor" type="Sprite"] 16 | 17 | [node name="default" type="Sprite" parent="."] 18 | texture = SubResource( 1 ) 19 | 20 | [node name="active" type="Sprite" parent="."] 21 | visible = false 22 | texture = SubResource( 2 ) 23 | -------------------------------------------------------------------------------- /sprite/Hound.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 240, 252, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 96, 252, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 192, 252, 24, 36 ) 19 | 20 | [node name="Hound" type="Sprite"] 21 | 22 | [node name="default" type="Sprite" parent="."] 23 | texture = SubResource( 1 ) 24 | 25 | [node name="active" type="Sprite" parent="."] 26 | visible = false 27 | texture = SubResource( 2 ) 28 | 29 | [node name="active_1" type="Sprite" parent="."] 30 | visible = false 31 | texture = SubResource( 3 ) 32 | -------------------------------------------------------------------------------- /sprite/HoundBoss.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 240, 180, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 96, 180, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 192, 180, 24, 36 ) 19 | 20 | [node name="HoundBoss" type="Sprite"] 21 | 22 | [node name="default" type="Sprite" parent="."] 23 | texture = SubResource( 1 ) 24 | 25 | [node name="active" type="Sprite" parent="."] 26 | visible = false 27 | texture = SubResource( 2 ) 28 | 29 | [node name="active_1" type="Sprite" parent="."] 30 | visible = false 31 | texture = SubResource( 3 ) 32 | -------------------------------------------------------------------------------- /sprite/Knight.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 264, 216, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 24, 72, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 360, 108, 24, 36 ) 19 | 20 | [node name="Knight" type="Sprite"] 21 | 22 | [node name="default" type="Sprite" parent="."] 23 | texture = SubResource( 1 ) 24 | 25 | [node name="active" type="Sprite" parent="."] 26 | visible = false 27 | texture = SubResource( 2 ) 28 | 29 | [node name="passive" type="Sprite" parent="."] 30 | visible = false 31 | texture = SubResource( 3 ) 32 | -------------------------------------------------------------------------------- /sprite/KnightBoss.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=7 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 72, 180, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 0, 180, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 96, 144, 24, 36 ) 19 | 20 | [sub_resource type="AtlasTexture" id=4] 21 | flags = 4 22 | atlas = ExtResource( 1 ) 23 | region = Rect2( 312, 360, 24, 36 ) 24 | 25 | [sub_resource type="AtlasTexture" id=5] 26 | flags = 4 27 | atlas = ExtResource( 1 ) 28 | region = Rect2( 192, 360, 24, 36 ) 29 | 30 | [node name="KnightBoss" type="Sprite"] 31 | 32 | [node name="default" type="Sprite" parent="."] 33 | texture = SubResource( 1 ) 34 | 35 | [node name="default_2" type="Sprite" parent="."] 36 | visible = false 37 | texture = SubResource( 2 ) 38 | 39 | [node name="default_3" type="Sprite" parent="."] 40 | visible = false 41 | texture = SubResource( 3 ) 42 | 43 | [node name="active" type="Sprite" parent="."] 44 | visible = false 45 | texture = SubResource( 4 ) 46 | region_rect = Rect2( 96, 144, 24, 36 ) 47 | 48 | [node name="passive" type="Sprite" parent="."] 49 | visible = false 50 | texture = SubResource( 5 ) 51 | -------------------------------------------------------------------------------- /sprite/KnightCaptain.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 72, 144, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 312, 360, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 192, 360, 24, 36 ) 19 | 20 | [node name="KnightCaptain" type="Sprite"] 21 | 22 | [node name="default" type="Sprite" parent="."] 23 | texture = SubResource( 1 ) 24 | 25 | [node name="active" type="Sprite" parent="."] 26 | visible = false 27 | texture = SubResource( 2 ) 28 | 29 | [node name="passive" type="Sprite" parent="."] 30 | visible = false 31 | texture = SubResource( 3 ) 32 | -------------------------------------------------------------------------------- /sprite/Lighthouse.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=13 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 288, 144, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 288, 144, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 24, 108, 24, 36 ) 19 | 20 | [sub_resource type="AtlasTexture" id=4] 21 | flags = 4 22 | atlas = ExtResource( 1 ) 23 | region = Rect2( 48, 108, 24, 36 ) 24 | 25 | [sub_resource type="AtlasTexture" id=5] 26 | flags = 4 27 | atlas = ExtResource( 1 ) 28 | region = Rect2( 72, 108, 24, 36 ) 29 | 30 | [sub_resource type="AtlasTexture" id=6] 31 | flags = 4 32 | atlas = ExtResource( 1 ) 33 | region = Rect2( 96, 108, 24, 36 ) 34 | 35 | [sub_resource type="AtlasTexture" id=7] 36 | flags = 4 37 | atlas = ExtResource( 1 ) 38 | region = Rect2( 120, 108, 24, 36 ) 39 | 40 | [sub_resource type="AtlasTexture" id=8] 41 | flags = 4 42 | atlas = ExtResource( 1 ) 43 | region = Rect2( 144, 108, 24, 36 ) 44 | 45 | [sub_resource type="AtlasTexture" id=9] 46 | flags = 4 47 | atlas = ExtResource( 1 ) 48 | region = Rect2( 168, 108, 24, 36 ) 49 | 50 | [sub_resource type="AtlasTexture" id=10] 51 | flags = 4 52 | atlas = ExtResource( 1 ) 53 | region = Rect2( 192, 108, 24, 36 ) 54 | 55 | [sub_resource type="AtlasTexture" id=11] 56 | flags = 4 57 | atlas = ExtResource( 1 ) 58 | region = Rect2( 216, 108, 24, 36 ) 59 | 60 | [node name="Lighthouse" type="Sprite"] 61 | 62 | [node name="default" type="Sprite" parent="."] 63 | texture = SubResource( 1 ) 64 | 65 | [node name="zero" type="Sprite" parent="."] 66 | visible = false 67 | texture = SubResource( 2 ) 68 | 69 | [node name="one" type="Sprite" parent="."] 70 | visible = false 71 | texture = SubResource( 3 ) 72 | 73 | [node name="two" type="Sprite" parent="."] 74 | visible = false 75 | texture = SubResource( 4 ) 76 | 77 | [node name="three" type="Sprite" parent="."] 78 | visible = false 79 | texture = SubResource( 5 ) 80 | 81 | [node name="four" type="Sprite" parent="."] 82 | visible = false 83 | texture = SubResource( 6 ) 84 | 85 | [node name="five" type="Sprite" parent="."] 86 | visible = false 87 | texture = SubResource( 7 ) 88 | 89 | [node name="six" type="Sprite" parent="."] 90 | visible = false 91 | texture = SubResource( 8 ) 92 | 93 | [node name="seven" type="Sprite" parent="."] 94 | visible = false 95 | texture = SubResource( 9 ) 96 | 97 | [node name="eight" type="Sprite" parent="."] 98 | visible = false 99 | texture = SubResource( 10 ) 100 | 101 | [node name="nine" type="Sprite" parent="."] 102 | visible = false 103 | texture = SubResource( 11 ) 104 | -------------------------------------------------------------------------------- /sprite/Ninja.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 336, 216, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 336, 144, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 192, 252, 24, 36 ) 19 | 20 | [sub_resource type="AtlasTexture" id=4] 21 | flags = 4 22 | atlas = ExtResource( 1 ) 23 | region = Rect2( 192, 180, 24, 36 ) 24 | 25 | [node name="Ninja" type="Sprite"] 26 | 27 | [node name="default" type="Sprite" parent="."] 28 | texture = SubResource( 1 ) 29 | 30 | [node name="active" type="Sprite" parent="."] 31 | visible = false 32 | texture = SubResource( 2 ) 33 | 34 | [node name="default_1" type="Sprite" parent="."] 35 | visible = false 36 | texture = SubResource( 3 ) 37 | 38 | [node name="active_1" type="Sprite" parent="."] 39 | visible = false 40 | texture = SubResource( 4 ) 41 | -------------------------------------------------------------------------------- /sprite/NinjaShadow.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 72, 252, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 72, 180, 24, 36 ) 14 | 15 | [node name="NinjaShadow" type="Sprite"] 16 | 17 | [node name="default" type="Sprite" parent="."] 18 | texture = SubResource( 1 ) 19 | 20 | [node name="active" type="Sprite" parent="."] 21 | visible = false 22 | texture = SubResource( 2 ) 23 | -------------------------------------------------------------------------------- /sprite/OffloadGoods.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 264, 468, 24, 36 ) 9 | 10 | [node name="OffloadGoods" type="Sprite"] 11 | 12 | [node name="default" type="Sprite" parent="."] 13 | texture = SubResource( 1 ) 14 | -------------------------------------------------------------------------------- /sprite/OnloadGoods.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 168, 144, 24, 36 ) 9 | 10 | [node name="OnloadGoods" type="Sprite"] 11 | 12 | [node name="default" type="Sprite" parent="."] 13 | texture = SubResource( 1 ) 14 | -------------------------------------------------------------------------------- /sprite/PC.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 0, 144, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 264, 468, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 0, 396, 24, 36 ) 19 | 20 | [node name="PC" type="Sprite"] 21 | 22 | [node name="default" type="Sprite" parent="."] 23 | texture = SubResource( 1 ) 24 | 25 | [node name="active" type="Sprite" parent="."] 26 | visible = false 27 | texture = SubResource( 2 ) 28 | 29 | [node name="passive" type="Sprite" parent="."] 30 | visible = false 31 | texture = SubResource( 3 ) 32 | -------------------------------------------------------------------------------- /sprite/PCBalloon.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=7 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 0, 144, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 192, 36, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 216, 36, 24, 36 ) 19 | 20 | [sub_resource type="AtlasTexture" id=4] 21 | flags = 4 22 | atlas = ExtResource( 1 ) 23 | region = Rect2( 264, 36, 24, 36 ) 24 | 25 | [sub_resource type="AtlasTexture" id=5] 26 | flags = 4 27 | atlas = ExtResource( 1 ) 28 | region = Rect2( 240, 36, 24, 36 ) 29 | 30 | [node name="PCBalloon" type="Sprite"] 31 | 32 | [node name="default" type="Sprite" parent="."] 33 | texture = SubResource( 1 ) 34 | 35 | [node name="up" type="Sprite" parent="."] 36 | visible = false 37 | texture = SubResource( 2 ) 38 | 39 | [node name="down" type="Sprite" parent="."] 40 | visible = false 41 | texture = SubResource( 3 ) 42 | 43 | [node name="left" type="Sprite" parent="."] 44 | visible = false 45 | texture = SubResource( 4 ) 46 | 47 | [node name="right" type="Sprite" parent="."] 48 | visible = false 49 | texture = SubResource( 5 ) 50 | -------------------------------------------------------------------------------- /sprite/PCBaron.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 0, 144, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 72, 36, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 0, 540, 24, 36 ) 19 | 20 | [node name="PCBaron" type="Sprite"] 21 | 22 | [node name="default" type="Sprite" parent="."] 23 | texture = SubResource( 1 ) 24 | 25 | [node name="default_1" type="Sprite" parent="."] 26 | visible = false 27 | texture = SubResource( 2 ) 28 | 29 | [node name="active" type="Sprite" parent="."] 30 | visible = false 31 | texture = SubResource( 3 ) 32 | -------------------------------------------------------------------------------- /sprite/PCDesert.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=7 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 0, 144, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 264, 468, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 0, 108, 24, 36 ) 19 | 20 | [sub_resource type="AtlasTexture" id=4] 21 | flags = 4 22 | atlas = ExtResource( 1 ) 23 | region = Rect2( 24, 108, 24, 36 ) 24 | 25 | [sub_resource type="AtlasTexture" id=5] 26 | flags = 4 27 | atlas = ExtResource( 1 ) 28 | region = Rect2( 48, 108, 24, 36 ) 29 | 30 | [node name="PCDesert" type="Sprite"] 31 | 32 | [node name="default" type="Sprite" parent="."] 33 | texture = SubResource( 1 ) 34 | 35 | [node name="active" type="Sprite" parent="."] 36 | visible = false 37 | texture = SubResource( 2 ) 38 | 39 | [node name="zero" type="Sprite" parent="."] 40 | visible = false 41 | texture = SubResource( 3 ) 42 | 43 | [node name="one" type="Sprite" parent="."] 44 | visible = false 45 | texture = SubResource( 4 ) 46 | 47 | [node name="two" type="Sprite" parent="."] 48 | visible = false 49 | texture = SubResource( 5 ) 50 | -------------------------------------------------------------------------------- /sprite/PCFrog.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 0, 144, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 264, 468, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 0, 540, 24, 36 ) 19 | 20 | [sub_resource type="AtlasTexture" id=4] 21 | flags = 4 22 | atlas = ExtResource( 1 ) 23 | region = Rect2( 0, 396, 24, 36 ) 24 | 25 | [node name="PC" type="Sprite"] 26 | 27 | [node name="default" type="Sprite" parent="."] 28 | texture = SubResource( 1 ) 29 | 30 | [node name="active" type="Sprite" parent="."] 31 | visible = false 32 | texture = SubResource( 2 ) 33 | 34 | [node name="passive" type="Sprite" parent="."] 35 | visible = false 36 | texture = SubResource( 3 ) 37 | 38 | [node name="passive_1" type="Sprite" parent="."] 39 | visible = false 40 | texture = SubResource( 4 ) 41 | -------------------------------------------------------------------------------- /sprite/PCHound.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=9 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 0, 144, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 0, 540, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 0, 396, 24, 36 ) 19 | 20 | [sub_resource type="AtlasTexture" id=4] 21 | flags = 4 22 | atlas = ExtResource( 1 ) 23 | region = Rect2( 192, 36, 24, 36 ) 24 | 25 | [sub_resource type="AtlasTexture" id=5] 26 | flags = 4 27 | atlas = ExtResource( 1 ) 28 | region = Rect2( 216, 36, 24, 36 ) 29 | 30 | [sub_resource type="AtlasTexture" id=6] 31 | flags = 4 32 | atlas = ExtResource( 1 ) 33 | region = Rect2( 264, 36, 24, 36 ) 34 | 35 | [sub_resource type="AtlasTexture" id=7] 36 | flags = 4 37 | atlas = ExtResource( 1 ) 38 | region = Rect2( 240, 36, 24, 36 ) 39 | 40 | [node name="PCHound" type="Sprite"] 41 | 42 | [node name="default" type="Sprite" parent="."] 43 | texture = SubResource( 1 ) 44 | 45 | [node name="active" type="Sprite" parent="."] 46 | visible = false 47 | texture = SubResource( 2 ) 48 | 49 | [node name="active_1" type="Sprite" parent="."] 50 | visible = false 51 | texture = SubResource( 3 ) 52 | 53 | [node name="up" type="Sprite" parent="."] 54 | visible = false 55 | texture = SubResource( 4 ) 56 | 57 | [node name="down" type="Sprite" parent="."] 58 | visible = false 59 | texture = SubResource( 5 ) 60 | 61 | [node name="left" type="Sprite" parent="."] 62 | visible = false 63 | texture = SubResource( 6 ) 64 | 65 | [node name="right" type="Sprite" parent="."] 66 | visible = false 67 | texture = SubResource( 7 ) 68 | -------------------------------------------------------------------------------- /sprite/PCMirrorImage.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 0, 144, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 264, 468, 24, 36 ) 14 | 15 | [node name="PCMirrorImage" type="Sprite"] 16 | 17 | [node name="default" type="Sprite" parent="."] 18 | texture = SubResource( 1 ) 19 | 20 | [node name="active" type="Sprite" parent="."] 21 | visible = false 22 | texture = SubResource( 2 ) 23 | -------------------------------------------------------------------------------- /sprite/PCNinja.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=13 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 0, 144, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 0, 108, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 24, 108, 24, 36 ) 19 | 20 | [sub_resource type="AtlasTexture" id=4] 21 | flags = 4 22 | atlas = ExtResource( 1 ) 23 | region = Rect2( 48, 108, 24, 36 ) 24 | 25 | [sub_resource type="AtlasTexture" id=5] 26 | flags = 4 27 | atlas = ExtResource( 1 ) 28 | region = Rect2( 72, 108, 24, 36 ) 29 | 30 | [sub_resource type="AtlasTexture" id=6] 31 | flags = 4 32 | atlas = ExtResource( 1 ) 33 | region = Rect2( 96, 108, 24, 36 ) 34 | 35 | [sub_resource type="AtlasTexture" id=7] 36 | flags = 4 37 | atlas = ExtResource( 1 ) 38 | region = Rect2( 120, 108, 24, 36 ) 39 | 40 | [sub_resource type="AtlasTexture" id=8] 41 | flags = 4 42 | atlas = ExtResource( 1 ) 43 | region = Rect2( 144, 108, 24, 36 ) 44 | 45 | [sub_resource type="AtlasTexture" id=9] 46 | flags = 4 47 | atlas = ExtResource( 1 ) 48 | region = Rect2( 168, 108, 24, 36 ) 49 | 50 | [sub_resource type="AtlasTexture" id=10] 51 | flags = 4 52 | atlas = ExtResource( 1 ) 53 | region = Rect2( 192, 108, 24, 36 ) 54 | 55 | [sub_resource type="AtlasTexture" id=11] 56 | flags = 4 57 | atlas = ExtResource( 1 ) 58 | region = Rect2( 216, 108, 24, 36 ) 59 | 60 | [node name="PCNinja" type="Sprite"] 61 | 62 | [node name="default" type="Sprite" parent="."] 63 | texture = SubResource( 1 ) 64 | 65 | [node name="zero" type="Sprite" parent="."] 66 | visible = false 67 | texture = SubResource( 2 ) 68 | 69 | [node name="one" type="Sprite" parent="."] 70 | visible = false 71 | texture = SubResource( 3 ) 72 | 73 | [node name="two" type="Sprite" parent="."] 74 | visible = false 75 | texture = SubResource( 4 ) 76 | 77 | [node name="three" type="Sprite" parent="."] 78 | visible = false 79 | texture = SubResource( 5 ) 80 | 81 | [node name="four" type="Sprite" parent="."] 82 | visible = false 83 | texture = SubResource( 6 ) 84 | 85 | [node name="five" type="Sprite" parent="."] 86 | visible = false 87 | texture = SubResource( 7 ) 88 | 89 | [node name="six" type="Sprite" parent="."] 90 | visible = false 91 | texture = SubResource( 8 ) 92 | 93 | [node name="seven" type="Sprite" parent="."] 94 | visible = false 95 | texture = SubResource( 9 ) 96 | 97 | [node name="eight" type="Sprite" parent="."] 98 | visible = false 99 | texture = SubResource( 10 ) 100 | 101 | [node name="nine" type="Sprite" parent="."] 102 | visible = false 103 | texture = SubResource( 11 ) 104 | -------------------------------------------------------------------------------- /sprite/PCRailgun.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=9 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 0, 144, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 0, 108, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 24, 108, 24, 36 ) 19 | 20 | [sub_resource type="AtlasTexture" id=4] 21 | flags = 4 22 | atlas = ExtResource( 1 ) 23 | region = Rect2( 48, 108, 24, 36 ) 24 | 25 | [sub_resource type="AtlasTexture" id=5] 26 | flags = 4 27 | atlas = ExtResource( 1 ) 28 | region = Rect2( 72, 108, 24, 36 ) 29 | 30 | [sub_resource type="AtlasTexture" id=6] 31 | flags = 4 32 | atlas = ExtResource( 1 ) 33 | region = Rect2( 96, 108, 24, 36 ) 34 | 35 | [sub_resource type="AtlasTexture" id=7] 36 | flags = 4 37 | atlas = ExtResource( 1 ) 38 | region = Rect2( 120, 108, 24, 36 ) 39 | 40 | [node name="PCRailgun" type="Sprite"] 41 | 42 | [node name="default" type="Sprite" parent="."] 43 | texture = SubResource( 1 ) 44 | 45 | [node name="zero" type="Sprite" parent="."] 46 | visible = false 47 | texture = SubResource( 2 ) 48 | 49 | [node name="one" type="Sprite" parent="."] 50 | visible = false 51 | texture = SubResource( 3 ) 52 | 53 | [node name="two" type="Sprite" parent="."] 54 | visible = false 55 | texture = SubResource( 4 ) 56 | 57 | [node name="three" type="Sprite" parent="."] 58 | visible = false 59 | texture = SubResource( 5 ) 60 | 61 | [node name="four" type="Sprite" parent="."] 62 | visible = false 63 | texture = SubResource( 6 ) 64 | 65 | [node name="five" type="Sprite" parent="."] 66 | visible = false 67 | texture = SubResource( 7 ) 68 | -------------------------------------------------------------------------------- /sprite/Phantom.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 0, 252, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 48, 396, 24, 36 ) 14 | 15 | [node name="Phantom" type="Sprite"] 16 | 17 | [node name="default" type="Sprite" parent="."] 18 | texture = SubResource( 1 ) 19 | 20 | [node name="active" type="Sprite" parent="."] 21 | visible = false 22 | texture = SubResource( 2 ) 23 | -------------------------------------------------------------------------------- /sprite/Portal.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 192, 180, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 0, 180, 24, 36 ) 14 | 15 | [node name="Portal" type="Sprite"] 16 | 17 | [node name="default" type="Sprite" parent="."] 18 | texture = SubResource( 1 ) 19 | 20 | [node name="active" type="Sprite" parent="."] 21 | visible = false 22 | texture = SubResource( 2 ) 23 | -------------------------------------------------------------------------------- /sprite/RareTreasure.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 24, 72, 24, 36 ) 9 | 10 | [node name="RareTreasure" type="Sprite"] 11 | texture = SubResource( 1 ) 12 | -------------------------------------------------------------------------------- /sprite/SCP_173.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 72, 144, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 192, 360, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 312, 360, 24, 36 ) 19 | 20 | [node name="SCP_173" type="Sprite"] 21 | 22 | [node name="default" type="Sprite" parent="."] 23 | texture = SubResource( 1 ) 24 | 25 | [node name="active" type="Sprite" parent="."] 26 | visible = false 27 | texture = SubResource( 2 ) 28 | 29 | [node name="active_1" type="Sprite" parent="."] 30 | visible = false 31 | texture = SubResource( 3 ) 32 | -------------------------------------------------------------------------------- /sprite/SoulFragment.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 360, 108, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 24, 72, 24, 36 ) 14 | 15 | [node name="SoulFragment" type="Sprite"] 16 | 17 | [node name="default" type="Sprite" parent="."] 18 | texture = SubResource( 1 ) 19 | 20 | [node name="active" type="Sprite" parent="."] 21 | visible = false 22 | texture = SubResource( 2 ) 23 | -------------------------------------------------------------------------------- /sprite/Treasure.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 360, 108, 24, 36 ) 9 | 10 | [node name="Treasure" type="Sprite"] 11 | texture = SubResource( 1 ) 12 | -------------------------------------------------------------------------------- /sprite/TreeBranch.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 264, 72, 24, 36 ) 9 | 10 | [node name="TreeBranch" type="Sprite"] 11 | modulate = Color( 0.678431, 0.709804, 0.741176, 1 ) 12 | 13 | [node name="default" type="Sprite" parent="."] 14 | texture = SubResource( 1 ) 15 | -------------------------------------------------------------------------------- /sprite/TreeTrunk.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 360, 144, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 24, 72, 24, 36 ) 14 | 15 | [node name="TreeTrunk" type="Sprite"] 16 | modulate = Color( 0.678431, 0.709804, 0.741176, 1 ) 17 | 18 | [node name="default" type="Sprite" parent="."] 19 | texture = SubResource( 1 ) 20 | 21 | [node name="active" type="Sprite" parent="."] 22 | visible = false 23 | texture = SubResource( 2 ) 24 | -------------------------------------------------------------------------------- /sprite/TriangleDown.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 360, 36, 24, 36 ) 9 | 10 | [node name="TriangleDown" type="Sprite"] 11 | texture = SubResource( 1 ) 12 | -------------------------------------------------------------------------------- /sprite/TriangleRight.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 0, 36, 24, 36 ) 9 | 10 | [node name="TriangleRight" type="Sprite"] 11 | texture = SubResource( 1 ) 12 | -------------------------------------------------------------------------------- /sprite/TriangleUp.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 336, 36, 24, 36 ) 9 | 10 | [node name="TriangleUp" type="Sprite"] 11 | texture = SubResource( 1 ) 12 | -------------------------------------------------------------------------------- /sprite/TruckSlot.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 360, 180, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 0, 540, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=4] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 24, 0, 24, 36 ) 19 | 20 | [sub_resource type="AtlasTexture" id=5] 21 | flags = 4 22 | atlas = ExtResource( 1 ) 23 | region = Rect2( 48, 0, 24, 36 ) 24 | 25 | [node name="TruckSlot" type="Sprite"] 26 | 27 | [node name="default" type="Sprite" parent="."] 28 | texture = SubResource( 1 ) 29 | 30 | [node name="active" type="Sprite" parent="."] 31 | visible = false 32 | texture = SubResource( 2 ) 33 | 34 | [node name="active_1" type="Sprite" parent="."] 35 | visible = false 36 | texture = SubResource( 4 ) 37 | 38 | [node name="passive_1" type="Sprite" parent="."] 39 | visible = false 40 | texture = SubResource( 5 ) 41 | -------------------------------------------------------------------------------- /sprite/Wall.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 72, 72, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 72, 36, 24, 36 ) 14 | 15 | [node name="Wall" type="Sprite"] 16 | 17 | [node name="default" type="Sprite" parent="."] 18 | texture = SubResource( 1 ) 19 | 20 | [node name="active" type="Sprite" parent="."] 21 | visible = false 22 | texture = SubResource( 2 ) 23 | -------------------------------------------------------------------------------- /sprite/WallHound.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 360, 108, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 24, 72, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 72, 72, 24, 36 ) 19 | 20 | [node name="WallHound" type="Sprite"] 21 | 22 | [node name="default" type="Sprite" parent="."] 23 | texture = SubResource( 1 ) 24 | 25 | [node name="active" type="Sprite" parent="."] 26 | visible = false 27 | texture = SubResource( 2 ) 28 | 29 | [node name="passive" type="Sprite" parent="."] 30 | visible = false 31 | texture = SubResource( 3 ) 32 | -------------------------------------------------------------------------------- /sprite/WallNinja.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 72, 72, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 360, 108, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 0, 0, 24, 36 ) 19 | 20 | [node name="WallNinja" type="Sprite"] 21 | 22 | [node name="default" type="Sprite" parent="."] 23 | texture = SubResource( 1 ) 24 | 25 | [node name="active" type="Sprite" parent="."] 26 | visible = false 27 | texture = SubResource( 2 ) 28 | 29 | [node name="passive" type="Sprite" parent="."] 30 | visible = false 31 | texture = SubResource( 3 ) 32 | -------------------------------------------------------------------------------- /sprite/WormBody.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 264, 72, 24, 36 ) 9 | 10 | [node name="WormBody" type="Sprite"] 11 | texture = SubResource( 1 ) 12 | -------------------------------------------------------------------------------- /sprite/WormHead.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 96, 0, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 192, 0, 24, 36 ) 14 | 15 | [node name="WormHead" type="Sprite"] 16 | 17 | [node name="default" type="Sprite" parent="."] 18 | texture = SubResource( 1 ) 19 | 20 | [node name="active" type="Sprite" parent="."] 21 | visible = false 22 | texture = SubResource( 2 ) 23 | -------------------------------------------------------------------------------- /sprite/WormSpice.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 360, 108, 24, 36 ) 9 | 10 | [sub_resource type="AtlasTexture" id=2] 11 | flags = 4 12 | atlas = ExtResource( 1 ) 13 | region = Rect2( 360, 0, 24, 36 ) 14 | 15 | [sub_resource type="AtlasTexture" id=3] 16 | flags = 4 17 | atlas = ExtResource( 1 ) 18 | region = Rect2( 264, 72, 24, 36 ) 19 | 20 | [node name="WormSpice" type="Sprite"] 21 | 22 | [node name="default" type="Sprite" parent="."] 23 | texture = SubResource( 1 ) 24 | 25 | [node name="active" type="Sprite" parent="."] 26 | visible = false 27 | texture = SubResource( 2 ) 28 | 29 | [node name="passive" type="Sprite" parent="."] 30 | visible = false 31 | texture = SubResource( 3 ) 32 | -------------------------------------------------------------------------------- /sprite/WormTail.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://resource/curses_vector_24x36.png" type="Texture" id=1] 4 | 5 | [sub_resource type="AtlasTexture" id=1] 6 | flags = 4 7 | atlas = ExtResource( 1 ) 8 | region = Rect2( 312, 72, 24, 36 ) 9 | 10 | [node name="WormTail" type="Sprite"] 11 | texture = SubResource( 1 ) 12 | -------------------------------------------------------------------------------- /user/data/setting.json: -------------------------------------------------------------------------------- 1 | { 2 | "wizard_mode": false, 3 | "rng_seed": 0, 4 | "include_world": [], 5 | "show_full_map": false, 6 | "mouse_input": false, 7 | "palette": "", 8 | "exclude_world": [ 9 | "demo" 10 | ] 11 | } -------------------------------------------------------------------------------- /user/data/world_list.md: -------------------------------------------------------------------------------- 1 | # World List 2 | 3 | * balloon 4 | * baron 5 | * demo 6 | * desert 7 | * factory 8 | * frog 9 | * hound 10 | * knight 11 | * mirror 12 | * ninja 13 | * railgun 14 | * snowrunner 15 | * styx 16 | -------------------------------------------------------------------------------- /user/doc/balloon.md: -------------------------------------------------------------------------------- 1 | # Balloon Travellers 2 | 3 | [INPUT_HINT] 4 | 5 | > Sit in a hot balloon and fly across a power station in a speed race. Reach designated places to earn points. Do not bump into tower like chimneys when possible. 6 | 7 | During the balloon race, you need to earn at least 3 points by ending your turn at a beacon marked with a question mark (?). You have at most 24 turns. You lose the game when running out of turns. 8 | 9 | A beacon has three states: 10 | 11 | * Unexplored: A light colored question mark (?). 12 | * Active: A light colored plus sign (+). 13 | * Inactive: A dark colored plus sign (+). 14 | 15 | Reaching an unexplored beacon restores one or more turns and grants you 1 point. Then it becomes inactive. Visit an active beacon restores the same amount of turns as above, but it grants you no point. All inactive beacons become active when an unexplored or active beacon is reached. 16 | 17 | The amount of turn restoration depends on the number of unexplored beacons: 18 | 19 | * 3+ beacons: Restore 1 turn. 20 | * 2 beacons: Restore 3 turns. 21 | * 1 beacon: Restore 5 turns. 22 | 23 | You can move over the border of the dungeon and reappear on the opposite side. When there is a chimney (#) in the way, the balloon will try to step back one grid if possible. 24 | 25 | Every turn the balloon moves two steps. Firstly, it goes with the wind. The wind direction is indicated by an arrow and it changes every 3 turns. [1] Secondly, the balloon responds to your key input, which could be one of four directions (arrow keys) or waiting (Space). 26 | 27 | Indicators on the top left corner show the direction and duration of the current wind wave, and the direction of the next wave. 28 | 29 | [1] The wind direction is more likely to change into its vertical counterparts: from left/right to up/down, or vice versa. And it is less likely to remain unchanged for another three turns. It never changes to the opposite direction: between left and right, or up and down. 30 | -------------------------------------------------------------------------------- /user/doc/demo.md: -------------------------------------------------------------------------------- 1 | # Demo 2 | 3 | [INPUT_HINT] 4 | 5 | Demo help. 6 | -------------------------------------------------------------------------------- /user/doc/desert.md: -------------------------------------------------------------------------------- 1 | # Desert 2 | 3 | [INPUT_HINT] 4 | 5 | You need to bump and collect 3 quality spices (*) from a living sandworm. Press Space to show how many spices you have so far, but you cannot wait in desert, which makes the job a little bit harder. 6 | 7 | A sandworm has a head (diamond), a tail (-) and body segments (+). The third, fourth and fifth segment contains a common spice (?) or a quality spice (*). Every sandworm has at most one quality spice. You can only bump segments that have spices. Other sandworm parts (head, body and tail) act like indestructible walls. 8 | 9 | There are at most 2 sandworms in the desert. A new sandworm always appears in a grid that is at least 5 steps away from PC or another sandworm. It is more likely to appear in a grid surrounded by fewer dunes. 10 | 11 | Every turn a sandworm moves one step in a random direction. It has a higher chance to move in a straight line. Eventually it will tunnel into ground and leave a wall of dunes behind. A sandworm spends fewer time on the surface if: (1) It is immobilized; (2) It has spices, the more the better. 12 | 13 | Dunes are composed of sand walls (#) and spices (?). They are created by a living sandworm. The more spices a sandworm has, the more spices will be left behind. You can bump and destroy a wall or bump and collect a spice just as from a sandworm. You do not move when bumping. It can be used as a poor man's waiting key. 14 | 15 | You might lose the game due to one of three reasons. 16 | 17 | Firstly, you can survive in desert for at most 24 turns. Moving and bumping costs 1 turn. Starting your turn beside a sandworm costs an extra `2N - 1` turns, where `N` is the number of adjacent sandworm segments. Bumping a common or quality spice restores 6 turns. You lose if you have not collected 3 spices when your last turn ends. 18 | 19 | Secondly, PC's symbol turns into a rectangle when being adjacent to a sandworm's head. The game ends if the sandworm intends to move into PC's position the next turn. 20 | 21 | Lastly, if you are surrounded by four solid blocks when your turn starts, you fail automatically. A solid block refers to a sandworm segment or an edge of the dungeon. See digraph below. 22 | 23 | . # . North (O): Sand wall. 24 | . @ + East (X): Sandworm segment. 25 | + + + South (X): Sandworm segment. 26 | [Alive] West (O): Floor. 27 | 28 | % ? . North (O): Common spice, dune. 29 | % @ * East (X): Quality spice, sandworm. 30 | % - + South (X): Sandworm tail. 31 | [Alive] West (X): Edge of the dungeon. 32 | 33 | % s + North (X): Sandworm head. 34 | % @ + East (X): Sandworm segment. 35 | % - + South (X): Sandworm tail. 36 | [Dead] West (X): Edge of the dungeon. 37 | -------------------------------------------------------------------------------- /user/doc/general.md: -------------------------------------------------------------------------------- 1 | # General Help 2 | 3 | [INPUT_HINT] 4 | 5 | ## About This Game 6 | 7 | One More Level is a turn-based Roguelike game made with Godot engine. It is available on GitHub. The GUI font, Fira Code, is created by Nikita Prokopov. The tileset, curses_vector, is created by DragonDePlatino for Dwarf Fortress. 8 | 9 | You can play One More Level either locally (which is an executable file) or as a HTML5 game on itch.io. You can change most settings (except `palette`, see below) when playing online. 10 | 11 | Every time you start the game, One More Level presents you with a theme dungeon of unique mechanics and goals. This idea comes from HyperRogue, one of the most bizarre and fascinating games I have ever played. You can beat the game in five minutes, so it never hurts to go down just one level deeper. 12 | 13 | ## Game Mechanics 14 | 15 | There is a count down timer at the top right corner of the main screen. You have 24 turns at most. When it reduces to zero, you lose the game. Sometimes enemies and environment are able to consume your remaining turns. They might also kill you in other ways. On the other hand, every theme dungeon has a unique winning condition. 16 | 17 | Press `C` to read these mechanics. The help text is also available in `doc/`. 18 | 19 | ## Change Game Settings 20 | 21 | Edit `data/setting.json` for play testing. You can also change settings in debug menu by pressing `V`. Debug settings overwrite their counterparts in `data/setting.json`. All settings take effect when starting a new game. 22 | 23 | When in debug menu, if a text field requires a boolean value, strings match this pattern are `true`: `^(true|t|yes|y|[1-9]\d*)$`. 24 | 25 | Set `rng_seed` to a positive integer as a random number generator seed. When in debug menu, seed digits can be separated by characters: `[-,.\s]`. For example: `12-3,4.56` is the same as `123456`. 26 | 27 | Add world names from `data/world_list.md` to `include_world` or `exclude_world` to customize your world rotation list. 28 | 29 | Set `wizard_mode` to `true` to enable wizard keys. Set `show_full_map` to `true` to disable fog of war. Set `mouse_input` to `true` to move, wait and reload game by mouse. 30 | 31 | Leave `palette` blank to use the default color theme. If you want to use another theme, copy a json file (for example, `blue.json`) from `palette/` to `data/`, and then feed `palette` with a file name with or without the json file extension (both `blue` and `blue.json` works). You can also create your own theme based on `default.json`. 32 | 33 | ## Status Indicators 34 | 35 | In the lower right corner of the main screen, there is a bar under the version number. Three of the right most segments are indicators. A minus sign (-) means `false` and a plus sign (+) means `true`. From left to right, these indicators show that: 36 | 37 | * Whether `setting.json` is broken; 38 | * Whether `wizard_mode` is `true`; 39 | * Whether `mouse_input` is `true`. 40 | 41 | ## Export the Game 42 | 43 | If you want to export One More Level using Godot engine by yourself, first you need to download the project from GitHub (see above, About This Game). You also have to tweak export settings to filter certain files. In the GitHub repository, refer to `misc/export.md` for more information. 44 | -------------------------------------------------------------------------------- /user/doc/hint_dungeon.md: -------------------------------------------------------------------------------- 1 | [→: Key bindings | ←: General help] 2 | [↑, PgUp: Scroll up | ↓, PgDn: Scroll down] 3 | [Esc: Exit help] 4 | -------------------------------------------------------------------------------- /user/doc/hint_general.md: -------------------------------------------------------------------------------- 1 | [→: Dungeon help | ←: Key bindings] 2 | [↑, PgUp: Scroll up | ↓, PgDn: Scroll down] 3 | [Esc: Exit help] 4 | -------------------------------------------------------------------------------- /user/doc/hint_keybinding.md: -------------------------------------------------------------------------------- 1 | [→: General help | ←: Dungeon help] 2 | [↑, PgUp: Scroll up | ↓, PgDn: Scroll down] 3 | [Esc: Exit help] 4 | -------------------------------------------------------------------------------- /user/doc/keybinding.md: -------------------------------------------------------------------------------- 1 | # Key Bindings 2 | 3 | [INPUT_HINT] 4 | 5 | One More Level is made with Godot engine, which natively supports keyboards and gamepads (Xbox, DualShock and Nintendo). Xbox buttons are shown in square brackets below. If you need mouse support, press `V` to open debug menu, then set `mouse_input` to `true`. 6 | 7 | General gameplay: 8 | 9 | * Move: Arrow keys, Vi keys, ASDW, Left-click, [Direction pad]. 10 | * Wait: Space, Enter, Z, Period (.), Right-click, [A]. 11 | * Reload after win/lose: Space, Right-click, [A]. 12 | * Quit: Ctrl + W, [Select]. 13 | 14 | Menu keys: 15 | 16 | * Open Help menu: C, [B]. 17 | * Open Debug menu: V. 18 | * Exit menu: Esc, Ctrl + [, [B]. 19 | 20 | Function keys: 21 | 22 | * Force reload: O, Left-click[!], [Y]. 23 | * Replay dungeon: R, [X]. 24 | * Replay world: U, [Start]. 25 | * Copy RNG seed to clipboard: Ctrl + C. 26 | * Copy world name to clipboard: Ctrl + D. 27 | 28 | Force reload and two replay keys start a new game in different ways. 29 | 30 | * Force reload: A random seed and world tag. 31 | * Replay dungeon: The same seed and world tag. 32 | * Replay world: A random seed and the same world tag. 33 | 34 | [!] In order to force reload by mouse, left-click the grid that is just outside the bottom right corner of the dungeon, or, put it in another way, the grid that is on the left end of the RNG seed. 35 | 36 | Following keys are available in Help menu. 37 | 38 | * Move down: Down, J, S, [Direction pad down]. 39 | * Move up: Up, K, W, [Direction pad up]. 40 | * Page down: PgDn, Space, F, N, [RB]. 41 | * Page up: PgUp, B, P, [LB]. 42 | * Scroll to bottom: End, Shift + G, [RT]. 43 | * Scroll to top: Home, G, [LT]. 44 | * Switch to next help: Enter, Right, L, D, [A], [Direction pad right]. 45 | * Switch to previous help: Left, H, A, [Direction pad left]. 46 | 47 | Following keys are available in Debug menu. Quote from `Godot Docs` with slight modification. 48 | 49 | * Copy: Ctrl + C. 50 | * Cut: Ctrl + X. 51 | * Paste/"yank": Ctrl + V, Ctrl + Y. 52 | * Undo: Ctrl + Z. 53 | * Redo: Ctrl + Shift + Z. 54 | * Delete text from the cursor position to the beginning of the line: Ctrl + U. 55 | * Delete text from the cursor position to the end of the line: Ctrl + K. 56 | * Select all text: Ctrl + A. 57 | * Move the cursor to the beginning/end of the line: Up/Down arrow. 58 | 59 | These keys are available in wizard mode (see General Help). 60 | 61 | * Add 1 turn: T. 62 | * Fully restore turns: F. 63 | -------------------------------------------------------------------------------- /user/doc/knight.md: -------------------------------------------------------------------------------- 1 | # Silent Knight Hall 2 | 3 | [INPUT_HINT] 4 | 5 | Your mission is to sneak into the Silent Knight Hall and assassinate the knight boss. However, the boss will not show up until you have killed three captains (C). There is a counter that behaves like a wall (#) and shows the number of dead captains. Whether or not to kill knights (k) is your own choice. 6 | 7 | Press arrow keys to move, roll over or attack. Press Space to wait. Every action (move, roll over, attack and wait) costs exactly 1 turn. When an enemy dies, you gain 6 turns. You have at most 24 turns. You lose the game either because of running out of time or being killed by an enemy. 8 | 9 | An enemy has three states: normal, alert and fatigued. In normal state, his symbol is an alphabet. Such an enemy acts like a wall. You cannot bump attack or pass through him. He might take one of three actions. 10 | 11 | * Approach you if he can see you. 12 | * High chance: Wait one turn. 13 | * Low chance: Approach a knight captain or boss. 14 | 15 | If an enemy starts his turn being adjacent to you, he becomes alert (!) and waits one turn. An upside-down exclamation mark means an alert elite (captains or the boss). Such an enemy will attack grids marked by double excmamation marks (danger zone) the next turn and kills everyone in the zone. Your symbol turns into a solid rectangle if you are in danger. The game prevents you from staying inside if possible, otherwise it ends automatically. Bump an alert enemy and roll over to the other side if the destination is not occupied. 16 | 17 | @ ! . <-- Roll over. 18 | @ ! # <-- Cannot roll over. The grid is blocked by wall. 19 | @ ! K <-- Cannot roll over. The grid is blocked by knight. 20 | 21 | An enemy becomes fatigued (?) and waits one turn after attacking. Similarly, an upside-down question mark means an elite. Bump attack a fatigued enemy to kill him. Kill knights (K) and captains (C) with 1 hit. The boss requires 3 hits to kill. He has three symbols (S, P, D) to show how many hits he has taken (S: 0 hit, P: 1 hit, D: 2 hits). 22 | 23 | A knight can see you from 8 grids away. The sight range of an elite (captain or boss) is 12 grids. An elite attacks more than one grids. The boss attacks twice before cooling down in his final form (D). 24 | 25 | After rolling over an enemy, your symbol turns into a dotted rectangle. It means you are sneaking and an enemy cannot see you unless you are adjacent to him. You reveal yourself right after killing an enemy. 26 | -------------------------------------------------------------------------------- /user/doc/styx.md: -------------------------------------------------------------------------------- 1 | # Styx Ferryman 2 | 3 | [INPUT_HINT] 4 | 5 | ## Winning and Losing 6 | 7 | There are 3 lost harbors in the mist of Styx. In order to beat the game, you need to reach at least one of them in 24 turns. You lose the game if you have not reached any harbor when the last turn ends. 8 | 9 | ## Moving and Waiting 10 | 11 | Press arrow keys to sail a boat in Styx, which is composed of arrows. You cannot enter a grid with an arrow that is opposing to your input direction. This is an invalid input. All other arrow key inputs are valid. Such a valid input, no matter how long distance it covers, costs 1 turn. 12 | 13 | You move 1 step if the destination has a perpendicular arrow. If you move along the water flow, it may carry you to a far away place. 14 | 15 | 1 2 3 4 5 6 16 | → → → → → ↑ 17 | 18 | Suppose you start from grid 2. You cannot press left arrow key to enter grid 1, because it has a right arrow which is opposing to left arrow key. If you press right arrow key, the water flow pushs you all the way to grid 5. When in grid 5, press right arrow key again to enter grid 6. 19 | 20 | Press Space to wait 1 turn. Waiting also randomize the directions of all arrows in the dungeon. 21 | 22 | ## Field of View and Lighthouse 23 | 24 | Your field of view is a rhombus area. Grids outside this area are invisible. Grids on the edge are dark grey. Grids inside are grey. Initially, you can see 3 grids around you. Whenever you press Space, your sight range reduces to 2, and it will increase to 3 grids after 3 turns. 25 | 26 | There is a lighthouse in the center of the map, which is shown as a digit. The digit is a countdown timer. When it reduces to 0, your sight range restores to normal. The lighthouse is always visible. It blocks movement. There is no water flow around it. Its color is dark grey by default. However, if you are within 6 or fewer grids to a harbor, the lighthouse turns to grey. 27 | 28 | The field of view is updated once at the start of a turn. You cannot examine surroundings when being carried away by water flow. 29 | 30 | 1 2 3 4 5 6 7 8 9 31 | → → → → → → → → ↑ 32 | 33 | Suppose you start from grid 1, press right arrow key to move to grid 8. You can only see things around grid 1 and 8, but nothing in between. 34 | 35 | ## Reaching a Harbor 36 | 37 | A harbor is an impassable building similar to the lighthouse. There are 3 harbors in Styx. They are all invisible initially. Harbors are 7+ grids away from each other and PC's start point. 38 | 39 | If a harbor shows up at the edge of your field of view, it is a dark grey question mark (?). You cannot remember the position of such a harbor. If you move away, the harbor becomes invisible again. 40 | 41 | If a harbor appears inside your field of view, it turns into a grey question mark (?). It remains visible no matter where you go from now on. 42 | 43 | In order to reach a harbor, you need to end your turn in an adjacent grid. The harbor becomes a grey exclamation mark (!) and remains visible. Beating the game requires reaching one harbor. Try to discover more of them before your time runs out as a bonus quest. 44 | -------------------------------------------------------------------------------- /user/palette/blue.json: -------------------------------------------------------------------------------- 1 | { 2 | "actor": "56add8", 3 | "dark_actor": "0e628c" 4 | } -------------------------------------------------------------------------------- /user/palette/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "background": "black", 3 | "indicator": "grey", 4 | "ground": "grey", 5 | "trap": "orange", 6 | "building": "grey", 7 | "actor": "green", 8 | "gui_text": "white", 9 | "dark_ground": "dark_grey", 10 | "dark_trap": "dark_orange", 11 | "dark_building": "dark_grey", 12 | "dark_actor": "dark_green", 13 | "dark_gui_text": "grey", 14 | "color_value": { 15 | "black": "#212529", 16 | "grey": "#6C757D", 17 | "dark_grey": "#343A40", 18 | "white": "#ADB5BD", 19 | "green": "#52B788", 20 | "dark_green": "#2D6A4F", 21 | "orange": "#F8B945", 22 | "dark_orange": "#854E19" 23 | } 24 | } -------------------------------------------------------------------------------- /user/palette/grey.json: -------------------------------------------------------------------------------- 1 | { 2 | "background": "black", 3 | "indicator": "grey", 4 | "ground": "grey", 5 | "trap": "grey", 6 | "building": "grey", 7 | "actor": "white", 8 | "gui_text": "white", 9 | "dark_ground": "dark_grey", 10 | "dark_trap": "dark_grey", 11 | "dark_building": "dark_grey", 12 | "dark_actor": "grey", 13 | "dark_gui_text": "grey", 14 | "color_value": { 15 | "black": "#212529", 16 | "grey": "#6C757D", 17 | "dark_grey": "#343A40", 18 | "white": "#ADB5BD" 19 | } 20 | } --------------------------------------------------------------------------------