diff --git a/DungeonShooting_Godot/prefab/ui/MapEditorCreateGroup.tscn b/DungeonShooting_Godot/prefab/ui/MapEditorCreateGroup.tscn new file mode 100644 index 0000000..7f5a455 --- /dev/null +++ b/DungeonShooting_Godot/prefab/ui/MapEditorCreateGroup.tscn @@ -0,0 +1,63 @@ +[gd_scene load_steps=2 format=3 uid="uid://45krchsjrluh"] + +[ext_resource type="Script" path="res://src/game/ui/mapEditorCreateGroup/MapEditorCreateGroupPanel.cs" id="1_qoujx"] + +[node name="MapEditorCreateGroup" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource("1_qoujx") + +[node name="MarginContainer" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_left = 20 +theme_override_constants/margin_top = 50 +theme_override_constants/margin_right = 20 +theme_override_constants/margin_bottom = 20 + +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"] +layout_mode = 2 +theme_override_constants/separation = 20 + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="GroupNameLabel" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 20.0 +text = "组名称:" +horizontal_alignment = 2 +vertical_alignment = 1 + +[node name="GroupNameInput" type="LineEdit" parent="MarginContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 80.0 +placeholder_text = "请输入组名称" + +[node name="HBoxContainer5" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="RemarkNameLabel" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer5"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 0 +size_flags_stretch_ratio = 20.0 +text = "组备注:" +horizontal_alignment = 2 +vertical_alignment = 1 + +[node name="RemarkInput" type="TextEdit" parent="MarginContainer/VBoxContainer/HBoxContainer5"] +custom_minimum_size = Vector2(0, 150) +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 80.0 +placeholder_text = "选填" +wrap_mode = 1 diff --git a/DungeonShooting_Godot/prefab/ui/MapEditorCreateRoom.tscn b/DungeonShooting_Godot/prefab/ui/MapEditorCreateRoom.tscn index fc9cc5c..84738ec 100644 --- a/DungeonShooting_Godot/prefab/ui/MapEditorCreateRoom.tscn +++ b/DungeonShooting_Godot/prefab/ui/MapEditorCreateRoom.tscn @@ -43,6 +43,7 @@ layout_mode = 2 size_flags_horizontal = 3 size_flags_stretch_ratio = 80.0 +placeholder_text = "请输入房间名称" [node name="HBoxContainer2" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] layout_mode = 2 @@ -94,3 +95,23 @@ min_value = 1.0 max_value = 1000.0 value = 100.0 + +[node name="HBoxContainer5" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="RemarkNameLabel" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer5"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 0 +size_flags_stretch_ratio = 20.0 +text = "房间备注:" +horizontal_alignment = 2 +vertical_alignment = 1 + +[node name="RemarkInput" type="TextEdit" parent="MarginContainer/VBoxContainer/HBoxContainer5"] +custom_minimum_size = Vector2(0, 150) +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 80.0 +placeholder_text = "选填" +wrap_mode = 1 diff --git a/DungeonShooting_Godot/resource/map/RoomConfig.json b/DungeonShooting_Godot/resource/map/RoomConfig.json deleted file mode 100644 index d3c7171..0000000 --- a/DungeonShooting_Godot/resource/map/RoomConfig.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "testGroup": { - "GroupName": "testGroup", - "BattleList": [ - { - "ScenePath": "res://resource/map/tileMaps/testGroup/battle/Room1.tscn", - "RoomPath": "res://resource/map/tiledata/testGroup/battle/Room1.json" - }, - { - "ScenePath": "res://resource/map/tileMaps/testGroup/battle/Room2.tscn", - "RoomPath": "res://resource/map/tiledata/testGroup/battle/Room2.json" - }, - { - "ScenePath": "res://resource/map/tileMaps/testGroup/battle/Room3.tscn", - "RoomPath": "res://resource/map/tiledata/testGroup/battle/Room3.json" - }, - { - "ScenePath": "res://resource/map/tileMaps/testGroup/battle/Room4.tscn", - "RoomPath": "res://resource/map/tiledata/testGroup/battle/Room4.json" - }, - { - "ScenePath": "res://resource/map/tileMaps/testGroup/battle/Room5.tscn", - "RoomPath": "res://resource/map/tiledata/testGroup/battle/Room5.json" - }, - { - "ScenePath": "res://resource/map/tileMaps/testGroup/battle/Room6.tscn", - "RoomPath": "res://resource/map/tiledata/testGroup/battle/Room6.json" - }, - { - "ScenePath": "res://resource/map/tileMaps/testGroup/battle/Room8.tscn", - "RoomPath": "res://resource/map/tiledata/testGroup/battle/Room8.json" - } - ], - "InletList": [ - { - "ScenePath": "res://resource/map/tileMaps/testGroup/inlet/Room1.tscn", - "RoomPath": "res://resource/map/tiledata/testGroup/inlet/Room1.json" - } - ], - "OutletList": [ - { - "ScenePath": "res://resource/map/tileMaps/testGroup/outlet/Room1.tscn", - "RoomPath": "res://resource/map/tiledata/testGroup/outlet/Room1.json" - } - ], - "BossList": [ - { - "ScenePath": "res://resource/map/tileMaps/testGroup/boss/Room1.tscn", - "RoomPath": "res://resource/map/tiledata/testGroup/boss/Room1.json" - } - ], - "RewardList": [], - "ShopList": [], - "EventList": [] - } -} diff --git a/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json b/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json new file mode 100644 index 0000000..cab1a6a --- /dev/null +++ b/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json @@ -0,0 +1,30 @@ +{ + "TestGroup1": { + "GroupName": "TestGroup1", + "BattleList": [ + { + "Ready": false, + "RoomPath": "resource/map/tileMaps/TestGroup1/battle/Room1/Room1_roomInfo.json", + "TilePath": "resource/map/tileMaps/TestGroup1/battle/Room1/Room1_tileInfo.json" + } + ], + "InletList": [], + "OutletList": [], + "BossList": [], + "RewardList": [], + "ShopList": [], + "EventList": [], + "Remark": "\u6D4B\u8BD5\u7EC4" + }, + "TestGroup2": { + "GroupName": "TestGroup2", + "BattleList": [], + "InletList": [], + "OutletList": [], + "BossList": [], + "RewardList": [], + "ShopList": [], + "EventList": [], + "Remark": "\u6D4B\u8BD5\u7EC4" + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room1/Room1_roomInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room1/Room1_roomInfo.json new file mode 100644 index 0000000..417c1c2 --- /dev/null +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room1/Room1_roomInfo.json @@ -0,0 +1 @@ +{"Position":{"X":-7,"Y":-4},"Size":{"X":20,"Y":18},"DoorAreaInfos":[{"Direction":3,"Start":16,"End":-16},{"Direction":2,"Start":16,"End":-16},{"Direction":1,"Start":16,"End":-16},{"Direction":0,"Start":16,"End":-16}],"GroupName":"TestGroup1","RoomType":0,"RoomName":"Room1","Weight":100,"Remark":""} \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room1/Room1_tileInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room1/Room1_tileInfo.json new file mode 100644 index 0000000..8cf87af --- /dev/null +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room1/Room1_tileInfo.json @@ -0,0 +1 @@ +{"NavigationList":[{"Type":0,"Points":[-72,-56,120,-56,120,8,200,8,200,224,88,224,88,112,-40,112,-40,208,-104,208,-104,-24,-72,-24]},{"Type":1,"Points":[-40,-32,56,-32,56,72,-8,72,-8,40,-40,40]}],"Floor":[-6,12,0,0,8,-6,11,0,0,8,-6,10,0,0,8,-6,9,0,0,8,-6,8,0,0,8,-6,7,0,0,8,-6,6,0,0,8,-6,5,0,0,8,-6,4,0,0,8,-6,3,0,0,8,-6,2,0,0,8,-6,1,0,0,8,-6,0,0,0,8,-6,-1,0,0,8,-6,-2,0,0,8,-7,12,0,0,8,-7,11,0,0,8,-7,10,0,0,8,-7,9,0,0,8,-7,8,0,0,8,-7,7,0,0,8,-7,6,0,0,8,-7,5,0,0,8,-7,4,0,0,8,-7,3,0,0,8,-7,2,0,0,8,-7,1,0,0,8,-7,0,0,0,8,-7,-1,0,0,8,-7,-2,0,0,8,12,13,0,0,8,12,12,0,0,8,12,11,0,0,8,12,10,0,0,8,12,9,0,0,8,12,8,0,0,8,12,7,0,0,8,12,6,0,0,8,12,5,0,0,8,12,4,0,0,8,12,3,0,0,8,12,2,0,0,8,12,1,0,0,8,12,0,0,0,8,11,13,0,0,8,11,12,0,0,8,11,11,0,0,8,11,10,0,0,8,11,9,0,0,8,11,8,0,0,8,11,7,0,0,8,11,6,0,0,8,11,5,0,0,8,11,4,0,0,8,11,3,0,0,8,11,2,0,0,8,11,1,0,0,8,11,0,0,0,8,10,13,0,0,8,10,12,0,0,8,10,11,0,0,8,10,10,0,0,8,10,9,0,0,8,10,8,0,0,8,10,7,0,0,8,10,6,0,0,8,10,5,0,0,8,10,4,0,0,8,10,3,0,0,8,10,2,0,0,8,10,1,0,0,8,10,0,0,0,8,9,13,0,0,8,9,12,0,0,8,9,11,0,0,8,9,10,0,0,8,9,9,0,0,8,9,8,0,0,8,9,7,0,0,8,9,6,0,0,8,9,5,0,0,8,9,4,0,0,8,9,3,0,0,8,9,2,0,0,8,9,1,0,0,8,9,0,0,0,8,8,13,0,0,8,8,12,0,0,8,8,11,0,0,8,8,10,0,0,8,8,9,0,0,8,8,8,0,0,8,8,7,0,0,8,8,6,0,0,8,8,5,0,0,8,8,4,0,0,8,8,3,0,0,8,8,2,0,0,8,8,1,0,0,8,8,0,0,0,8,7,13,0,0,8,7,12,0,0,8,7,11,0,0,8,7,10,0,0,8,7,9,0,0,8,7,8,0,0,8,7,7,0,0,8,7,6,0,0,8,7,5,0,0,8,7,4,0,0,8,7,3,0,0,8,7,2,0,0,8,7,1,0,0,8,7,0,0,0,8,7,-1,0,0,8,7,-2,0,0,8,7,-3,0,0,8,7,-4,0,0,8,6,13,0,0,8,6,12,0,0,8,6,11,0,0,8,6,10,0,0,8,6,9,0,0,8,6,8,0,0,8,6,7,0,0,8,6,6,0,0,8,6,5,0,0,8,6,4,0,0,8,6,3,0,0,8,6,2,0,0,8,6,1,0,0,8,6,0,0,0,8,6,-1,0,0,8,6,-2,0,0,8,6,-3,0,0,8,6,-4,0,0,8,5,13,0,0,8,5,12,0,0,8,5,11,0,0,8,5,10,0,0,8,5,9,0,0,8,5,8,0,0,8,5,7,0,0,8,5,6,0,0,8,5,5,0,0,8,5,4,0,0,8,5,3,0,0,8,5,2,0,0,8,5,1,0,0,8,5,0,0,0,8,5,-1,0,0,8,5,-2,0,0,8,5,-3,0,0,8,5,-4,0,0,8,4,6,0,0,8,4,5,0,0,8,4,4,0,0,8,4,3,0,0,8,4,2,0,0,8,4,1,0,0,8,4,0,0,0,8,4,-1,0,0,8,4,-2,0,0,8,4,-3,0,0,8,4,-4,0,0,8,3,6,0,0,8,3,5,0,0,8,3,4,0,0,8,3,3,0,0,8,3,2,0,0,8,3,1,0,0,8,3,0,0,0,8,3,-1,0,0,8,3,-2,0,0,8,3,-3,0,0,8,3,-4,0,0,8,2,6,0,0,8,2,5,0,0,8,2,4,0,0,8,2,-3,0,0,8,2,-4,0,0,8,1,6,0,0,8,1,5,0,0,8,1,4,0,0,8,1,-3,0,0,8,1,-4,0,0,8,0,6,0,0,8,0,5,0,0,8,0,4,0,0,8,0,-3,0,0,8,0,-4,0,0,8,-1,6,0,0,8,-1,5,0,0,8,-1,4,0,0,8,-1,2,0,0,8,-1,3,0,0,8,-1,-3,0,0,8,-1,-4,0,0,8,-2,6,0,0,8,-2,2,0,0,8,-2,3,0,0,8,-2,4,0,0,8,-2,5,0,0,8,-2,-3,0,0,8,-2,-4,0,0,8,-3,12,0,0,8,-3,11,0,0,8,-3,10,0,0,8,-3,9,0,0,8,-3,8,0,0,8,-3,7,0,0,8,-3,6,0,0,8,-3,2,0,0,8,-3,3,0,0,8,-3,-2,0,0,8,-3,-1,0,0,8,-3,0,0,0,8,-3,1,0,0,8,-3,5,0,0,8,-3,4,0,0,8,-3,-3,0,0,8,-3,-4,0,0,8,-4,12,0,0,8,-4,11,0,0,8,-4,10,0,0,8,-4,9,0,0,8,-4,8,0,0,8,-4,7,0,0,8,-4,6,0,0,8,-4,2,0,0,8,-4,3,0,0,8,-4,4,0,0,8,-4,5,0,0,8,-4,1,0,0,8,-4,0,0,0,8,-4,-1,0,0,8,-4,-2,0,0,8,-4,-3,0,0,8,-4,-4,0,0,8,-5,12,0,0,8,-5,11,0,0,8,-5,10,0,0,8,-5,9,0,0,8,-5,8,0,0,8,-5,7,0,0,8,-5,6,0,0,8,-5,5,0,0,8,-5,4,0,0,8,-5,3,0,0,8,-5,2,0,0,8,-5,1,0,0,8,-5,0,0,0,8,-5,-1,0,0,8,-5,-2,0,0,8,-5,-3,0,0,8,-5,-4,0,0,8,-6,-5,0,3,4,-5,-5,0,2,7,-4,-5,0,2,7,-3,-5,0,2,7,-2,-5,0,2,7,-1,-5,0,2,7,0,-5,0,2,7,1,-5,0,2,7,2,-5,0,2,7,3,-5,0,2,7,4,-5,0,2,7,5,-5,0,2,7,6,-5,0,2,7,6,14,0,2,2,5,14,0,2,2,4,14,0,11,2,7,-5,0,2,7,7,14,0,2,2,8,-5,0,1,4,8,14,0,2,2,9,14,0,2,2,10,14,0,2,2,11,14,0,2,2,12,14,0,2,2,13,0,0,1,3,13,1,0,1,3,13,-1,0,1,4,13,2,0,1,3,13,3,0,1,3,13,4,0,1,3,13,5,0,1,3,13,6,0,1,3,13,7,0,1,3,13,8,0,1,3,13,9,0,1,3,13,10,0,1,3,13,11,0,1,3,13,12,0,1,3,13,13,0,1,3,13,14,0,13,2,-8,-1,0,3,3,-8,-2,0,3,3,-8,-3,0,3,4,-8,0,0,3,3,-8,1,0,3,3,-8,2,0,3,3,-8,3,0,3,3,-8,4,0,3,3,-8,5,0,3,3,-8,6,0,3,3,-8,7,0,3,3,-8,8,0,3,3,-8,9,0,3,3,-8,10,0,3,3,-8,11,0,3,3,-8,12,0,3,3,-8,13,0,11,2],"Middle":[-7,-3,0,2,7,-6,-3,0,3,7,-2,1,0,1,7,-1,1,0,2,7,0,3,0,1,7,1,3,0,2,7,2,3,0,3,7,8,-1,0,1,7,9,-1,0,2,7,10,-1,0,2,7,11,-1,0,2,7,12,-1,0,2,7],"Top":[-7,13,0,2,2,-6,-4,0,3,3,-6,13,0,2,2,-5,13,0,2,2,-4,13,0,2,2,-3,13,0,2,2,-2,-2,0,1,2,-2,-1,0,1,3,-2,0,0,1,3,-2,7,0,1,2,-2,8,0,1,3,-2,9,0,1,3,-2,10,0,1,3,-2,11,0,1,3,-2,12,0,1,3,-2,13,0,13,2,-1,-2,0,2,2,-1,7,0,2,2,0,-2,0,2,2,0,1,0,1,4,0,2,0,1,3,0,7,0,2,2,1,-2,0,2,2,1,7,0,2,2,2,-2,0,3,2,2,-1,0,3,3,2,0,0,3,3,2,1,0,3,3,2,2,0,3,3,2,7,0,2,2,3,7,0,2,2,4,7,0,3,2,4,8,0,3,3,4,9,0,3,3,4,10,0,3,3,4,11,0,3,3,4,12,0,3,3,4,13,0,3,3,8,-4,0,1,3,8,-3,0,1,3,8,-2,0,1,3]} \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/testGroup1/battle/Room2/Room2_roomInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/testGroup1/battle/Room2/Room2_roomInfo.json deleted file mode 100644 index ebc9d7b..0000000 --- a/DungeonShooting_Godot/resource/map/tileMaps/testGroup1/battle/Room2/Room2_roomInfo.json +++ /dev/null @@ -1 +0,0 @@ -{"Position":{"X":-11,"Y":-2},"Size":{"X":42,"Y":42},"DoorAreaInfos":[],"GroupName":"testGroup1","RoomType":0,"FileName":"Room2","Weight":100} \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/testGroup1/battle/Room2/Room2_tileInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/testGroup1/battle/Room2/Room2_tileInfo.json deleted file mode 100644 index edfbaac..0000000 --- a/DungeonShooting_Godot/resource/map/tileMaps/testGroup1/battle/Room2/Room2_tileInfo.json +++ /dev/null @@ -1 +0,0 @@ -{"NavigationList":[{"Type":0,"Points":[-152,-8,-104,-8,-104,184,-8,184,-8,152,40,152,40,40,216,40,216,72,392,72,392,192,360,192,360,328,424,328,424,368,408,368,408,488,472,488,472,624,-88,624,-88,568,-72,568,-72,336,-104,336,-104,240,-120,240,-120,32,-136,32,-136,16,-152,16]},{"Type":1,"Points":[56,64,120,64,120,96,200,96,200,136,120,136,120,152,56,152]},{"Type":1,"Points":[248,112,344,112,344,152,248,152]},{"Type":1,"Points":[216,176,296,176,296,248,216,248]},{"Type":1,"Points":[72,224,152,224,152,312,104,312,104,464,136,464,136,496,184,496,184,568,-40,568,-40,336,24,336,24,240,72,240]},{"Type":1,"Points":[-72,240,-24,240,-24,296,-72,296]},{"Type":1,"Points":[264,288,312,288,312,352,328,352,328,368,360,368,360,440,232,440,232,424,152,424,152,336,264,336]},{"Type":0,"Points":[24,424,40,424,40,496,24,496]}],"Floor":[-10,-1,0,0,8,-10,0,0,0,8,-9,-1,0,0,8,-9,0,0,0,8,-9,1,0,0,8,-8,14,0,0,8,-8,13,0,0,8,-8,12,0,0,8,-8,11,0,0,8,-8,10,0,0,8,-8,9,0,0,8,-8,8,0,0,8,-8,7,0,0,8,-8,6,0,0,8,-8,5,0,0,8,-8,4,0,0,8,-8,3,0,0,8,-8,2,0,0,8,-8,0,0,0,8,-8,-1,0,0,8,-8,1,0,0,8,29,38,0,0,8,29,37,0,0,8,29,36,0,0,8,29,35,0,0,8,29,34,0,0,8,29,33,0,0,8,29,32,0,0,8,29,31,0,0,8,29,30,0,0,8,28,38,0,0,8,28,37,0,0,8,28,36,0,0,8,28,35,0,0,8,28,34,0,0,8,28,33,0,0,8,28,32,0,0,8,28,31,0,0,8,28,30,0,0,8,27,38,0,0,8,27,37,0,0,8,27,36,0,0,8,27,35,0,0,8,27,34,0,0,8,27,33,0,0,8,27,32,0,0,8,27,31,0,0,8,27,30,0,0,8,26,38,0,0,8,26,37,0,0,8,26,36,0,0,8,26,35,0,0,8,26,34,0,0,8,26,33,0,0,8,26,32,0,0,8,26,31,0,0,8,26,30,0,0,8,26,20,0,0,8,26,21,0,0,8,26,22,0,0,8,25,29,0,0,8,25,28,0,0,8,25,27,0,0,8,25,26,0,0,8,25,25,0,0,8,25,24,0,0,8,25,23,0,0,8,25,38,0,0,8,25,37,0,0,8,25,36,0,0,8,25,35,0,0,8,25,34,0,0,8,25,33,0,0,8,25,32,0,0,8,25,31,0,0,8,25,30,0,0,8,25,20,0,0,8,25,21,0,0,8,25,22,0,0,8,1,26,0,0,8,1,28,0,0,8,1,27,0,0,8,1,30,0,0,8,1,29,0,0,8,1,38,0,0,8,1,37,0,0,8,1,36,0,0,8,1,35,0,0,8,1,10,0,0,8,1,9,0,0,8,1,20,0,0,8,1,19,0,0,8,1,18,0,0,8,1,17,0,0,8,1,16,0,0,8,1,15,0,0,8,1,14,0,0,8,1,13,0,0,8,1,12,0,0,8,1,11,0,0,8,0,38,0,0,8,0,37,0,0,8,0,36,0,0,8,0,35,0,0,8,0,9,0,0,8,0,10,0,0,8,0,20,0,0,8,0,19,0,0,8,0,18,0,0,8,0,17,0,0,8,0,16,0,0,8,0,15,0,0,8,0,14,0,0,8,0,13,0,0,8,0,12,0,0,8,0,11,0,0,8,-1,38,0,0,8,-1,37,0,0,8,-1,36,0,0,8,-1,35,0,0,8,-1,10,0,0,8,-1,9,0,0,8,-1,20,0,0,8,-1,19,0,0,8,-1,18,0,0,8,-1,17,0,0,8,-1,16,0,0,8,-1,15,0,0,8,-1,14,0,0,8,-1,13,0,0,8,-1,12,0,0,8,-1,11,0,0,8,-2,38,0,0,8,-2,37,0,0,8,-2,36,0,0,8,-2,35,0,0,8,-2,20,0,0,8,-2,19,0,0,8,-2,18,0,0,8,-2,17,0,0,8,-2,16,0,0,8,-2,15,0,0,8,-2,14,0,0,8,-2,13,0,0,8,-2,12,0,0,8,-2,11,0,0,8,-3,38,0,0,8,-3,37,0,0,8,-3,36,0,0,8,-3,35,0,0,8,-3,34,0,0,8,-3,33,0,0,8,-3,32,0,0,8,-3,31,0,0,8,-3,30,0,0,8,-3,29,0,0,8,-3,28,0,0,8,-3,27,0,0,8,-3,26,0,0,8,-3,25,0,0,8,-3,24,0,0,8,-3,20,0,0,8,-3,19,0,0,8,-3,18,0,0,8,-3,21,0,0,8,-3,22,0,0,8,-3,23,0,0,8,-3,14,0,0,8,-3,13,0,0,8,-3,12,0,0,8,-3,11,0,0,8,-4,38,0,0,8,-4,37,0,0,8,-4,36,0,0,8,-4,35,0,0,8,-4,34,0,0,8,-4,33,0,0,8,-4,32,0,0,8,-4,31,0,0,8,-4,30,0,0,8,-4,29,0,0,8,-4,28,0,0,8,-4,27,0,0,8,-4,26,0,0,8,-4,25,0,0,8,-4,24,0,0,8,-4,20,0,0,8,-4,19,0,0,8,-4,18,0,0,8,-4,21,0,0,8,-4,22,0,0,8,-4,23,0,0,8,-4,14,0,0,8,-4,13,0,0,8,-4,12,0,0,8,-4,11,0,0,8,-5,38,0,0,8,-5,37,0,0,8,-5,36,0,0,8,-5,35,0,0,8,-5,34,0,0,8,-5,33,0,0,8,-5,32,0,0,8,-5,31,0,0,8,-5,30,0,0,8,-5,29,0,0,8,-5,28,0,0,8,-5,27,0,0,8,-5,26,0,0,8,-5,25,0,0,8,-5,24,0,0,8,-5,23,0,0,8,-5,22,0,0,8,-5,21,0,0,8,-5,20,0,0,8,-5,19,0,0,8,-5,18,0,0,8,-5,17,0,0,8,-5,16,0,0,8,-5,15,0,0,8,-5,14,0,0,8,-5,13,0,0,8,-5,12,0,0,8,-5,11,0,0,8,-6,38,0,0,8,-6,37,0,0,8,-6,36,0,0,8,-6,35,0,0,8,-6,20,0,0,8,-6,19,0,0,8,-6,18,0,0,8,-6,17,0,0,8,-6,16,0,0,8,-6,15,0,0,8,-6,14,0,0,8,-6,13,0,0,8,-6,12,0,0,8,-6,11,0,0,8,-7,10,0,0,8,-7,9,0,0,8,-7,8,0,0,8,-7,7,0,0,8,-7,6,0,0,8,-7,5,0,0,8,-7,4,0,0,8,-7,3,0,0,8,-7,2,0,0,8,-7,0,0,0,8,-7,-1,0,0,8,-7,1,0,0,8,-7,20,0,0,8,-7,19,0,0,8,-7,18,0,0,8,-7,17,0,0,8,-7,16,0,0,8,-7,15,0,0,8,-7,14,0,0,8,-7,13,0,0,8,-7,12,0,0,8,-7,11,0,0,8,24,29,0,0,8,24,28,0,0,8,24,27,0,0,8,24,26,0,0,8,24,25,0,0,8,24,24,0,0,8,24,23,0,0,8,24,38,0,0,8,24,37,0,0,8,24,36,0,0,8,24,35,0,0,8,24,34,0,0,8,24,33,0,0,8,24,32,0,0,8,24,31,0,0,8,24,30,0,0,8,24,20,0,0,8,24,21,0,0,8,24,22,0,0,8,24,11,0,0,8,24,10,0,0,8,24,9,0,0,8,24,8,0,0,8,24,7,0,0,8,24,6,0,0,8,24,5,0,0,8,24,4,0,0,8,23,29,0,0,8,23,28,0,0,8,23,27,0,0,8,23,26,0,0,8,23,25,0,0,8,23,24,0,0,8,23,23,0,0,8,23,38,0,0,8,23,37,0,0,8,23,36,0,0,8,23,35,0,0,8,23,34,0,0,8,23,33,0,0,8,23,32,0,0,8,23,31,0,0,8,23,30,0,0,8,23,22,0,0,8,23,20,0,0,8,23,21,0,0,8,23,11,0,0,8,23,10,0,0,8,23,9,0,0,8,23,8,0,0,8,23,7,0,0,8,23,6,0,0,8,23,5,0,0,8,23,4,0,0,8,22,26,0,0,8,22,25,0,0,8,22,24,0,0,8,22,23,0,0,8,22,29,0,0,8,22,28,0,0,8,22,27,0,0,8,22,38,0,0,8,22,37,0,0,8,22,36,0,0,8,22,35,0,0,8,22,34,0,0,8,22,33,0,0,8,22,32,0,0,8,22,31,0,0,8,22,30,0,0,8,22,19,0,0,8,22,18,0,0,8,22,17,0,0,8,22,16,0,0,8,22,15,0,0,8,22,14,0,0,8,22,13,0,0,8,22,12,0,0,8,22,22,0,0,8,22,21,0,0,8,22,20,0,0,8,22,11,0,0,8,22,10,0,0,8,22,9,0,0,8,22,8,0,0,8,22,7,0,0,8,22,6,0,0,8,22,5,0,0,8,22,4,0,0,8,21,29,0,0,8,21,28,0,0,8,21,27,0,0,8,21,38,0,0,8,21,37,0,0,8,21,36,0,0,8,21,35,0,0,8,21,34,0,0,8,21,33,0,0,8,21,32,0,0,8,21,31,0,0,8,21,30,0,0,8,21,19,0,0,8,21,18,0,0,8,21,22,0,0,8,21,21,0,0,8,21,20,0,0,8,21,17,0,0,8,21,16,0,0,8,21,15,0,0,8,21,14,0,0,8,21,13,0,0,8,21,12,0,0,8,21,11,0,0,8,21,10,0,0,8,21,9,0,0,8,21,8,0,0,8,21,7,0,0,8,21,6,0,0,8,21,5,0,0,8,21,4,0,0,8,20,29,0,0,8,20,28,0,0,8,20,27,0,0,8,20,38,0,0,8,20,37,0,0,8,20,36,0,0,8,20,35,0,0,8,20,34,0,0,8,20,33,0,0,8,20,32,0,0,8,20,21,0,0,8,20,20,0,0,8,20,19,0,0,8,20,18,0,0,8,20,22,0,0,8,20,17,0,0,8,20,16,0,0,8,20,15,0,0,8,20,14,0,0,8,20,13,0,0,8,20,12,0,0,8,20,11,0,0,8,20,10,0,0,8,20,9,0,0,8,20,30,0,0,8,20,31,0,0,8,20,6,0,0,8,20,5,0,0,8,20,4,0,0,8,19,29,0,0,8,19,28,0,0,8,19,27,0,0,8,19,38,0,0,8,19,37,0,0,8,19,36,0,0,8,19,35,0,0,8,19,34,0,0,8,19,33,0,0,8,19,32,0,0,8,19,21,0,0,8,19,20,0,0,8,19,19,0,0,8,19,18,0,0,8,19,17,0,0,8,19,16,0,0,8,19,15,0,0,8,19,14,0,0,8,19,13,0,0,8,19,12,0,0,8,19,11,0,0,8,19,10,0,0,8,19,9,0,0,8,19,30,0,0,8,19,31,0,0,8,19,6,0,0,8,19,5,0,0,8,19,4,0,0,8,18,29,0,0,8,18,28,0,0,8,18,27,0,0,8,18,38,0,0,8,18,37,0,0,8,18,36,0,0,8,18,35,0,0,8,18,34,0,0,8,18,33,0,0,8,18,32,0,0,8,18,17,0,0,8,18,16,0,0,8,18,15,0,0,8,18,14,0,0,8,18,13,0,0,8,18,12,0,0,8,18,11,0,0,8,18,10,0,0,8,18,9,0,0,8,18,30,0,0,8,18,31,0,0,8,18,6,0,0,8,18,5,0,0,8,18,4,0,0,8,17,29,0,0,8,17,28,0,0,8,17,27,0,0,8,17,38,0,0,8,17,37,0,0,8,17,36,0,0,8,17,17,0,0,8,17,16,0,0,8,17,15,0,0,8,17,32,0,0,8,17,33,0,0,8,17,34,0,0,8,17,35,0,0,8,17,10,0,0,8,17,9,0,0,8,17,30,0,0,8,17,31,0,0,8,17,6,0,0,8,17,5,0,0,8,17,4,0,0,8,16,29,0,0,8,16,28,0,0,8,16,27,0,0,8,16,38,0,0,8,16,37,0,0,8,16,36,0,0,8,16,9,0,0,8,16,30,0,0,8,16,31,0,0,8,16,6,0,0,8,16,5,0,0,8,16,4,0,0,8,16,20,0,0,8,16,19,0,0,8,16,18,0,0,8,16,17,0,0,8,16,16,0,0,8,16,15,0,0,8,16,32,0,0,8,16,33,0,0,8,16,34,0,0,8,16,35,0,0,8,16,10,0,0,8,15,29,0,0,8,15,28,0,0,8,15,27,0,0,8,15,38,0,0,8,15,37,0,0,8,15,36,0,0,8,15,35,0,0,8,15,34,0,0,8,15,9,0,0,8,15,8,0,0,8,15,7,0,0,8,15,6,0,0,8,15,5,0,0,8,15,4,0,0,8,15,20,0,0,8,15,19,0,0,8,15,18,0,0,8,15,17,0,0,8,15,16,0,0,8,15,15,0,0,8,15,30,0,0,8,15,31,0,0,8,15,32,0,0,8,15,33,0,0,8,15,10,0,0,8,14,38,0,0,8,14,37,0,0,8,14,36,0,0,8,14,26,0,0,8,14,35,0,0,8,14,34,0,0,8,14,33,0,0,8,14,32,0,0,8,14,31,0,0,8,14,9,0,0,8,14,8,0,0,8,14,7,0,0,8,14,6,0,0,8,14,5,0,0,8,14,4,0,0,8,14,20,0,0,8,14,19,0,0,8,14,18,0,0,8,14,17,0,0,8,14,16,0,0,8,14,15,0,0,8,14,27,0,0,8,14,28,0,0,8,14,29,0,0,8,14,30,0,0,8,14,10,0,0,8,13,38,0,0,8,13,37,0,0,8,13,36,0,0,8,13,26,0,0,8,13,35,0,0,8,13,34,0,0,8,13,33,0,0,8,13,32,0,0,8,13,31,0,0,8,13,30,0,0,8,13,29,0,0,8,13,28,0,0,8,13,27,0,0,8,13,20,0,0,8,13,19,0,0,8,13,18,0,0,8,13,17,0,0,8,13,16,0,0,8,13,15,0,0,8,13,14,0,0,8,13,13,0,0,8,13,12,0,0,8,13,11,0,0,8,13,10,0,0,8,13,9,0,0,8,13,8,0,0,8,13,7,0,0,8,13,6,0,0,8,13,5,0,0,8,13,4,0,0,8,13,3,0,0,8,13,2,0,0,8,12,38,0,0,8,12,37,0,0,8,12,36,0,0,8,12,26,0,0,8,12,35,0,0,8,12,34,0,0,8,12,33,0,0,8,12,32,0,0,8,12,31,0,0,8,12,30,0,0,8,12,29,0,0,8,12,28,0,0,8,12,27,0,0,8,12,20,0,0,8,12,19,0,0,8,12,18,0,0,8,12,17,0,0,8,12,16,0,0,8,12,15,0,0,8,12,14,0,0,8,12,13,0,0,8,12,12,0,0,8,12,11,0,0,8,12,10,0,0,8,12,9,0,0,8,12,8,0,0,8,12,7,0,0,8,12,6,0,0,8,12,5,0,0,8,12,4,0,0,8,12,3,0,0,8,12,2,0,0,8,11,38,0,0,8,11,37,0,0,8,11,36,0,0,8,11,26,0,0,8,11,35,0,0,8,11,34,0,0,8,11,33,0,0,8,11,32,0,0,8,11,31,0,0,8,11,30,0,0,8,11,29,0,0,8,11,28,0,0,8,11,27,0,0,8,11,20,0,0,8,11,19,0,0,8,11,18,0,0,8,11,17,0,0,8,11,16,0,0,8,11,15,0,0,8,11,14,0,0,8,11,11,0,0,8,11,10,0,0,8,11,9,0,0,8,11,8,0,0,8,11,12,0,0,8,11,13,0,0,8,11,5,0,0,8,11,4,0,0,8,11,3,0,0,8,11,2,0,0,8,10,38,0,0,8,10,37,0,0,8,10,36,0,0,8,10,35,0,0,8,10,30,0,0,8,10,29,0,0,8,10,28,0,0,8,10,27,0,0,8,10,26,0,0,8,10,20,0,0,8,10,19,0,0,8,10,18,0,0,8,10,17,0,0,8,10,16,0,0,8,10,15,0,0,8,10,14,0,0,8,10,11,0,0,8,10,10,0,0,8,10,9,0,0,8,10,8,0,0,8,10,12,0,0,8,10,13,0,0,8,10,5,0,0,8,10,4,0,0,8,10,3,0,0,8,10,2,0,0,8,9,38,0,0,8,9,37,0,0,8,9,36,0,0,8,9,35,0,0,8,9,25,0,0,8,9,24,0,0,8,9,23,0,0,8,9,22,0,0,8,9,21,0,0,8,9,30,0,0,8,9,29,0,0,8,9,28,0,0,8,9,27,0,0,8,9,26,0,0,8,9,20,0,0,8,9,19,0,0,8,9,18,0,0,8,9,17,0,0,8,9,16,0,0,8,9,15,0,0,8,9,14,0,0,8,9,11,0,0,8,9,10,0,0,8,9,9,0,0,8,9,8,0,0,8,9,12,0,0,8,9,13,0,0,8,9,5,0,0,8,9,4,0,0,8,9,3,0,0,8,9,2,0,0,8,8,38,0,0,8,8,37,0,0,8,8,36,0,0,8,8,35,0,0,8,8,25,0,0,8,8,24,0,0,8,8,23,0,0,8,8,22,0,0,8,8,21,0,0,8,8,20,0,0,8,8,19,0,0,8,8,30,0,0,8,8,29,0,0,8,8,28,0,0,8,8,27,0,0,8,8,26,0,0,8,8,11,0,0,8,8,10,0,0,8,8,9,0,0,8,8,8,0,0,8,8,12,0,0,8,8,13,0,0,8,8,5,0,0,8,8,4,0,0,8,8,3,0,0,8,8,2,0,0,8,7,38,0,0,8,7,37,0,0,8,7,36,0,0,8,7,35,0,0,8,7,28,0,0,8,7,27,0,0,8,7,26,0,0,8,7,25,0,0,8,7,24,0,0,8,7,23,0,0,8,7,22,0,0,8,7,21,0,0,8,7,20,0,0,8,7,19,0,0,8,7,11,0,0,8,7,10,0,0,8,7,9,0,0,8,7,8,0,0,8,7,12,0,0,8,7,13,0,0,8,7,5,0,0,8,7,4,0,0,8,7,3,0,0,8,7,2,0,0,8,6,38,0,0,8,6,37,0,0,8,6,36,0,0,8,6,35,0,0,8,6,28,0,0,8,6,27,0,0,8,6,26,0,0,8,6,25,0,0,8,6,24,0,0,8,6,23,0,0,8,6,22,0,0,8,6,11,0,0,8,6,10,0,0,8,6,9,0,0,8,6,12,0,0,8,6,13,0,0,8,6,19,0,0,8,6,20,0,0,8,6,21,0,0,8,6,3,0,0,8,6,2,0,0,8,5,38,0,0,8,5,11,0,0,8,5,10,0,0,8,5,9,0,0,8,5,12,0,0,8,5,13,0,0,8,5,35,0,0,8,5,36,0,0,8,5,37,0,0,8,5,3,0,0,8,5,2,0,0,8,4,38,0,0,8,4,37,0,0,8,4,11,0,0,8,4,10,0,0,8,4,9,0,0,8,4,13,0,0,8,4,14,0,0,8,4,12,0,0,8,4,35,0,0,8,4,36,0,0,8,4,3,0,0,8,4,2,0,0,8,3,38,0,0,8,3,37,0,0,8,3,36,0,0,8,3,35,0,0,8,3,14,0,0,8,3,12,0,0,8,3,13,0,0,8,3,11,0,0,8,3,10,0,0,8,3,9,0,0,8,3,8,0,0,8,3,7,0,0,8,3,6,0,0,8,3,5,0,0,8,3,4,0,0,8,3,3,0,0,8,3,2,0,0,8,2,26,0,0,8,2,27,0,0,8,2,28,0,0,8,2,29,0,0,8,2,30,0,0,8,2,38,0,0,8,2,37,0,0,8,2,36,0,0,8,2,35,0,0,8,2,14,0,0,8,2,13,0,0,8,2,12,0,0,8,2,11,0,0,8,2,10,0,0,8,2,9,0,0,8,2,8,0,0,8,2,7,0,0,8,2,6,0,0,8,2,5,0,0,8,2,4,0,0,8,2,3,0,0,8,2,2,0,0,8],"Middle":[-10,-2,0,2,7,-9,-2,0,2,7,-8,-2,0,2,7,-7,-2,0,2,7,-6,10,0,1,7,-6,34,0,3,7,-5,10,0,2,7,-4,10,0,2,7,-4,17,0,1,7,-3,10,0,2,7,-3,17,0,3,7,-2,10,0,3,7,-2,34,0,1,7,-1,8,0,2,7,-1,34,0,2,7,0,8,0,2,7,0,34,0,2,7,1,8,0,3,7,1,25,0,2,7,1,34,0,2,7,2,1,0,2,7,2,25,0,2,7,2,34,0,2,7,3,1,0,2,7,3,34,0,2,7,4,1,0,2,7,4,8,0,1,7,4,34,0,2,7,5,1,0,2,7,5,8,0,2,7,5,34,0,2,7,6,1,0,2,7,6,8,0,3,7,6,18,0,2,7,6,34,0,2,7,7,1,0,2,7,7,7,0,2,7,7,18,0,2,7,7,34,0,2,7,8,1,0,2,7,8,7,0,2,7,8,18,0,3,7,8,34,0,2,7,9,1,0,2,7,9,7,0,2,7,9,34,0,2,7,10,1,0,2,7,10,7,0,2,7,10,25,0,1,7,10,34,0,3,7,11,1,0,2,7,11,7,0,3,7,11,25,0,2,7,12,1,0,2,7,12,25,0,2,7,13,1,0,2,7,13,25,0,2,7,14,3,0,1,7,14,14,0,1,7,14,25,0,2,7,15,3,0,2,7,15,14,0,2,7,15,26,0,1,7,16,3,0,2,7,16,8,0,1,7,16,14,0,2,7,16,26,0,2,7,17,3,0,2,7,17,8,0,2,7,17,14,0,3,7,17,26,0,2,7,18,3,0,2,7,18,8,0,2,7,18,26,0,2,7,19,3,0,2,7,19,8,0,2,7,19,26,0,2,7,20,3,0,2,7,20,8,0,3,7,20,26,0,2,7,21,3,0,2,7,21,26,0,3,7,22,3,0,2,7,23,3,0,2,7,23,19,0,1,7,24,3,0,2,7,24,19,0,2,7,25,19,0,2,7,26,19,0,2,7,26,29,0,1,7,27,29,0,2,7,28,29,0,2,7,29,29,0,2,7],"Top":[-11,-2,0,3,4,-11,-1,0,3,3,-11,0,0,3,3,-11,1,0,11,2,-10,1,0,3,2,-10,2,0,11,2,-9,2,0,3,2,-9,3,0,3,3,-9,4,0,3,3,-9,5,0,3,3,-9,6,0,3,3,-9,7,0,3,3,-9,8,0,3,3,-9,9,0,3,3,-9,10,0,3,3,-9,11,0,3,3,-9,12,0,3,3,-9,13,0,3,3,-9,14,0,3,3,-9,15,0,11,2,-8,15,0,3,2,-8,16,0,3,3,-8,17,0,3,3,-8,18,0,3,3,-8,19,0,3,3,-8,20,0,3,3,-8,21,0,11,2,-7,21,0,2,2,-7,34,0,3,4,-7,35,0,3,3,-7,36,0,3,3,-7,37,0,3,3,-7,38,0,3,3,-7,39,0,11,2,-6,-2,0,1,4,-6,-1,0,1,3,-6,0,0,1,3,-6,1,0,1,3,-6,2,0,1,3,-6,3,0,1,3,-6,4,0,1,3,-6,5,0,1,3,-6,6,0,1,3,-6,7,0,1,3,-6,8,0,1,3,-6,9,0,1,3,-6,21,0,3,2,-6,22,0,3,3,-6,23,0,3,3,-6,24,0,3,3,-6,25,0,3,3,-6,26,0,3,3,-6,27,0,3,3,-6,28,0,3,3,-6,29,0,3,3,-6,30,0,3,3,-6,31,0,3,3,-6,32,0,3,3,-6,33,0,3,3,-6,39,0,2,2,-5,39,0,2,2,-4,15,0,1,2,-4,16,0,1,3,-4,39,0,2,2,-3,15,0,3,2,-3,16,0,3,3,-3,39,0,2,2,-2,8,0,3,4,-2,9,0,3,3,-2,21,0,1,2,-2,22,0,1,3,-2,23,0,1,3,-2,24,0,1,3,-2,25,0,1,3,-2,26,0,1,3,-2,27,0,1,3,-2,28,0,1,3,-2,29,0,1,3,-2,30,0,1,3,-2,31,0,1,3,-2,32,0,1,3,-2,33,0,1,3,-2,39,0,2,2,-1,21,0,2,2,-1,39,0,2,2,0,21,0,2,2,0,25,0,3,4,0,26,0,3,3,0,27,0,3,3,0,28,0,3,3,0,29,0,3,3,0,30,0,3,3,0,31,0,11,2,0,39,0,2,2,1,1,0,3,4,1,2,0,3,3,1,3,0,3,3,1,4,0,3,3,1,5,0,3,3,1,6,0,3,3,1,7,0,3,3,1,21,0,2,2,1,31,0,2,2,1,39,0,2,2,2,15,0,1,2,2,16,0,1,3,2,17,0,1,3,2,18,0,1,3,2,19,0,1,3,2,20,0,1,3,2,21,0,13,2,2,31,0,2,2,2,39,0,2,2,3,15,0,2,2,3,25,0,1,4,3,26,0,1,3,3,27,0,1,3,3,28,0,1,3,3,29,0,1,3,3,30,0,1,3,3,31,0,13,2,3,39,0,2,2,4,4,0,1,2,4,5,0,1,3,4,6,0,1,3,4,7,0,1,3,4,15,0,2,2,4,39,0,2,2,5,4,0,2,2,5,14,0,1,2,5,15,0,13,2,5,18,0,3,4,5,19,0,3,3,5,20,0,3,3,5,21,0,3,3,5,22,0,3,3,5,23,0,3,3,5,24,0,3,3,5,25,0,3,3,5,26,0,3,3,5,27,0,3,3,5,28,0,3,3,5,29,0,11,2,5,39,0,2,2,6,4,0,3,2,6,5,0,3,3,6,6,0,11,2,6,7,0,3,4,6,14,0,2,2,6,29,0,2,2,6,39,0,2,2,7,6,0,2,2,7,14,0,2,2,7,29,0,3,2,7,30,0,3,3,7,31,0,11,2,7,39,0,2,2,8,6,0,2,2,8,14,0,3,2,8,15,0,3,3,8,16,0,3,3,8,17,0,3,3,8,31,0,2,2,8,39,0,2,2,9,6,0,2,2,9,31,0,2,2,9,39,0,2,2,10,6,0,2,2,10,21,0,1,2,10,22,0,1,3,10,23,0,1,3,10,24,0,1,3,10,31,0,3,2,10,32,0,3,3,10,33,0,3,3,10,39,0,2,2,11,6,0,3,2,11,21,0,2,2,11,39,0,2,2,12,21,0,2,2,12,39,0,2,2,13,21,0,2,2,13,39,0,2,2,14,1,0,1,4,14,2,0,1,3,14,11,0,1,2,14,12,0,1,3,14,13,0,1,3,14,21,0,2,2,14,39,0,2,2,15,11,0,2,2,15,21,0,2,2,15,25,0,1,4,15,39,0,2,2,16,7,0,1,2,16,11,0,2,2,16,21,0,2,2,16,39,0,2,2,17,7,0,2,2,17,11,0,3,2,17,12,0,3,3,17,13,0,3,3,17,18,0,1,2,17,19,0,1,3,17,20,0,1,3,17,21,0,13,2,17,39,0,2,2,18,7,0,2,2,18,18,0,3,2,18,19,0,3,3,18,20,0,3,3,18,21,0,3,3,18,22,0,11,2,18,39,0,2,2,19,7,0,2,2,19,22,0,3,2,19,23,0,11,2,19,39,0,2,2,20,7,0,3,2,20,23,0,2,2,20,39,0,2,2,21,23,0,3,2,21,24,0,3,3,21,25,0,3,3,21,39,0,2,2,22,39,0,2,2,23,12,0,1,2,23,13,0,1,3,23,14,0,1,3,23,15,0,1,3,23,16,0,1,3,23,17,0,1,3,23,18,0,1,3,23,39,0,2,2,24,12,0,2,2,24,39,0,2,2,25,3,0,1,4,25,4,0,1,3,25,5,0,1,3,25,6,0,1,3,25,7,0,1,3,25,8,0,1,3,25,9,0,1,3,25,10,0,1,3,25,11,0,1,3,25,12,0,13,2,25,39,0,2,2,26,23,0,1,2,26,24,0,1,3,26,25,0,1,3,26,26,0,1,3,26,27,0,1,3,26,28,0,1,3,26,39,0,2,2,27,19,0,1,4,27,20,0,1,3,27,21,0,1,3,27,22,0,1,3,27,23,0,13,2,27,39,0,2,2,28,39,0,2,2,29,39,0,2,2,30,29,0,1,4,30,30,0,1,3,30,31,0,1,3,30,32,0,1,3,30,33,0,1,3,30,34,0,1,3,30,35,0,1,3,30,36,0,1,3,30,37,0,1,3,30,38,0,1,3,30,39,0,13,2]} \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/testGroup2/battle/Room1/Room1_roomInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/testGroup2/battle/Room1/Room1_roomInfo.json deleted file mode 100644 index 3ad1530..0000000 --- a/DungeonShooting_Godot/resource/map/tileMaps/testGroup2/battle/Room1/Room1_roomInfo.json +++ /dev/null @@ -1 +0,0 @@ -{"Position":{"X":-7,"Y":-5},"Size":{"X":16,"Y":14},"DoorAreaInfos":[],"GroupName":"testGroup2","RoomType":0,"FileName":"Room1","Weight":100} \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/testGroup2/battle/Room1/Room1_tileInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/testGroup2/battle/Room1/Room1_tileInfo.json deleted file mode 100644 index dc5674d..0000000 --- a/DungeonShooting_Godot/resource/map/tileMaps/testGroup2/battle/Room1/Room1_tileInfo.json +++ /dev/null @@ -1 +0,0 @@ -{"NavigationList":[{"Type":0,"Points":[-72,-72,104,-72,104,-56,120,-56,120,-40,136,-40,136,112,120,112,120,128,104,128,104,144,-72,144,-72,128,-88,128,-88,112,-104,112,-104,-40,-88,-40,-88,-56,-72,-56]},{"Type":1,"Points":[-72,-32,-8,-32,-8,24,-72,24]},{"Type":1,"Points":[40,-32,104,-32,104,24,40,24]},{"Type":1,"Points":[-72,48,-8,48,-8,104,-72,104]},{"Type":1,"Points":[40,48,104,48,104,104,40,104]}],"Floor":[7,6,0,0,8,7,5,0,0,8,7,4,0,0,8,7,3,0,0,8,7,2,0,0,8,7,1,0,0,8,7,0,0,0,8,7,-1,0,0,8,7,-2,0,0,8,7,-3,0,0,8,7,7,0,0,8,7,-4,0,0,8,6,8,0,0,8,6,7,0,0,8,6,6,0,0,8,6,5,0,0,8,6,4,0,0,8,6,3,0,0,8,6,2,0,0,8,6,1,0,0,8,6,0,0,0,8,6,-1,0,0,8,6,-2,0,0,8,6,-3,0,0,8,6,-4,0,0,8,6,-5,0,0,8,-6,-4,0,0,8,-6,6,0,0,8,-6,5,0,0,8,-6,4,0,0,8,-6,3,0,0,8,-6,2,0,0,8,-6,1,0,0,8,-6,0,0,0,8,-6,-1,0,0,8,-6,-2,0,0,8,-6,-3,0,0,8,-6,7,0,0,8,5,8,0,0,8,5,6,0,0,8,5,7,0,0,8,5,-4,0,0,8,5,2,0,0,8,5,1,0,0,8,5,-3,0,0,8,5,-5,0,0,8,4,8,0,0,8,4,6,0,0,8,4,7,0,0,8,4,-4,0,0,8,4,2,0,0,8,4,1,0,0,8,4,-3,0,0,8,4,-5,0,0,8,3,8,0,0,8,3,6,0,0,8,3,7,0,0,8,3,-4,0,0,8,3,2,0,0,8,3,1,0,0,8,3,-3,0,0,8,3,-5,0,0,8,2,8,0,0,8,2,7,0,0,8,2,6,0,0,8,2,5,0,0,8,2,-4,0,0,8,2,4,0,0,8,2,3,0,0,8,2,2,0,0,8,2,1,0,0,8,2,-1,0,0,8,2,0,0,0,8,2,-2,0,0,8,2,-3,0,0,8,2,-5,0,0,8,1,8,0,0,8,1,7,0,0,8,1,6,0,0,8,1,5,0,0,8,1,-4,0,0,8,1,4,0,0,8,1,3,0,0,8,1,2,0,0,8,1,1,0,0,8,1,-2,0,0,8,1,-1,0,0,8,1,0,0,0,8,1,-3,0,0,8,1,-5,0,0,8,0,7,0,0,8,0,6,0,0,8,0,5,0,0,8,0,-4,0,0,8,0,4,0,0,8,0,3,0,0,8,0,2,0,0,8,0,1,0,0,8,0,0,0,0,8,0,-1,0,0,8,0,-2,0,0,8,0,-3,0,0,8,0,-5,0,0,8,0,8,0,0,8,-1,7,0,0,8,-1,6,0,0,8,-1,5,0,0,8,-1,-4,0,0,8,-1,4,0,0,8,-1,3,0,0,8,-1,2,0,0,8,-1,1,0,0,8,-1,0,0,0,8,-1,-1,0,0,8,-1,-2,0,0,8,-1,-3,0,0,8,-1,-5,0,0,8,-1,8,0,0,8,-2,6,0,0,8,-2,7,0,0,8,-2,-4,0,0,8,-2,2,0,0,8,-2,1,0,0,8,-2,-3,0,0,8,-2,-5,0,0,8,-2,8,0,0,8,-3,6,0,0,8,-3,7,0,0,8,-3,-4,0,0,8,-3,2,0,0,8,-3,1,0,0,8,-3,-3,0,0,8,-3,-5,0,0,8,-3,8,0,0,8,-4,6,0,0,8,-4,7,0,0,8,-4,-4,0,0,8,-4,2,0,0,8,-4,1,0,0,8,-4,-3,0,0,8,-4,-5,0,0,8,-4,8,0,0,8,-5,7,0,0,8,-5,6,0,0,8,-5,5,0,0,8,-5,-4,0,0,8,-5,4,0,0,8,-5,3,0,0,8,-5,2,0,0,8,-5,1,0,0,8,-5,0,0,0,8,-5,-1,0,0,8,-5,-2,0,0,8,-5,-3,0,0,8,-5,-5,0,0,8,-5,8,0,0,8,8,-3,0,0,8,8,-2,0,0,8,8,-1,0,0,8,8,0,0,0,8,8,1,0,0,8,8,2,0,0,8,8,3,0,0,8,8,4,0,0,8,8,5,0,0,8,8,6,0,0,8,-7,6,0,0,8,-7,5,0,0,8,-7,4,0,0,8,-7,3,0,0,8,-7,2,0,0,8,-7,1,0,0,8,-7,0,0,0,8,-7,-1,0,0,8,-7,-2,0,0,8,-7,-3,0,0,8,-8,-2,0,3,3,-8,-3,0,3,3,-8,-4,0,3,4,-8,-1,0,3,3,-8,0,0,3,3,-8,1,0,3,3,-8,2,0,3,3,-8,3,0,3,3,-8,4,0,3,3,-8,5,0,3,3,-8,6,0,3,3,-8,7,0,11,2,9,6,0,1,3,9,7,0,13,2,9,5,0,1,3,9,4,0,1,3,9,3,0,1,3,9,2,0,1,3,9,1,0,1,3,9,0,0,1,3,9,-1,0,1,3,9,-2,0,1,3,9,-3,0,1,3,9,-4,0,1,4,-4,9,0,2,2,-5,9,0,2,2,-6,9,0,11,2,-6,-6,0,3,4,-5,-6,0,2,7,-4,-6,0,2,7,-3,9,0,2,2,-3,-6,0,2,7,-2,9,0,2,2,-2,-6,0,2,7,-1,9,0,2,2,-1,-6,0,2,7,0,9,0,2,2,0,-6,0,2,7,1,9,0,2,2,1,-6,0,2,7,2,-6,0,2,7,2,9,0,2,2,3,-6,0,2,7,3,9,0,2,2,4,-6,0,2,7,4,9,0,2,2,5,-6,0,2,7,5,9,0,2,2,6,-6,0,2,7,6,9,0,2,2,7,-6,0,1,4,7,9,0,13,2],"Middle":[-7,-4,0,3,7,-6,-5,0,3,7,-4,0,0,1,7,-4,5,0,1,7,-3,0,0,2,7,-3,5,0,2,7,-2,0,0,3,7,-2,5,0,3,7,3,0,0,1,7,3,5,0,1,7,4,0,0,2,7,4,5,0,2,7,5,0,0,3,7,5,5,0,3,7,7,-5,0,1,7,8,-4,0,1,7],"Top":[-7,-5,0,3,4,-7,7,0,3,2,-7,8,0,11,2,-6,8,0,3,2,-4,-2,0,1,2,-4,-1,0,1,3,-4,3,0,1,2,-4,4,0,1,3,-3,-2,0,2,2,-3,3,0,2,2,-2,-2,0,3,2,-2,-1,0,3,3,-2,3,0,3,2,-2,4,0,3,3,3,-2,0,1,2,3,-1,0,1,3,3,3,0,1,2,3,4,0,1,3,4,-2,0,2,2,4,3,0,2,2,5,-2,0,3,2,5,-1,0,3,3,5,3,0,3,2,5,4,0,3,3,7,8,0,1,2,8,-5,0,1,4,8,7,0,1,2,8,8,0,13,2]} \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/theme/mainTheme.tres b/DungeonShooting_Godot/resource/theme/mainTheme.tres index 0e4833a..b485bed 100644 --- a/DungeonShooting_Godot/resource/theme/mainTheme.tres +++ b/DungeonShooting_Godot/resource/theme/mainTheme.tres @@ -485,4 +485,7 @@ LineEdit/styles/normal = SubResource("StyleBoxFlat_0jpwx") LineEdit/styles/read_only = SubResource("StyleBoxFlat_c3u8l") Panel/styles/panel = SubResource("57") +TextEdit/styles/focus = SubResource("StyleBoxFlat_em2wh") +TextEdit/styles/normal = SubResource("StyleBoxFlat_0jpwx") +TextEdit/styles/read_only = SubResource("StyleBoxFlat_c3u8l") TooltipLabel/font_sizes/font_size = 32 diff --git a/DungeonShooting_Godot/src/framework/map/data/DungeonRoomGroup.cs b/DungeonShooting_Godot/src/framework/map/data/DungeonRoomGroup.cs index 5d47401..76c12e2 100644 --- a/DungeonShooting_Godot/src/framework/map/data/DungeonRoomGroup.cs +++ b/DungeonShooting_Godot/src/framework/map/data/DungeonRoomGroup.cs @@ -57,10 +57,33 @@ [JsonInclude] public List EventList = new List(); + /// + /// 组包住 + /// + [JsonInclude] + public string Remark; + private bool _init = false; private Dictionary _weightRandomMap; /// + /// 获取所有房间数据 + /// + public List GetAllRoomList() + { + var list = new List(); + list.AddRange(BattleList); + list.AddRange(InletList); + list.AddRange(OutletList); + list.AddRange(BossList); + list.AddRange(ShopList); + list.AddRange(RewardList); + list.AddRange(ShopList); + list.AddRange(EventList); + return list; + } + + /// /// 获取指定类型房间集合 /// public List GetRoomList(DungeonRoomType roomType) diff --git a/DungeonShooting_Godot/src/framework/map/data/DungeonRoomInfo.cs b/DungeonShooting_Godot/src/framework/map/data/DungeonRoomInfo.cs index 08bd925..b9f23c9 100644 --- a/DungeonShooting_Godot/src/framework/map/data/DungeonRoomInfo.cs +++ b/DungeonShooting_Godot/src/framework/map/data/DungeonRoomInfo.cs @@ -29,7 +29,7 @@ /// 当前房间所属分组的名称 /// [JsonInclude] - public string GroupName = "unclaimed"; + public string GroupName; /// /// 房间类型 @@ -38,14 +38,20 @@ public DungeonRoomType RoomType = DungeonRoomType.Battle; /// - /// 房间文件名称 + /// 房间名称 /// [JsonInclude] - public string FileName; + public string RoomName; /// /// 房间权重, 值越大, 生成地牢是越容易出现该房间 /// [JsonInclude] public int Weight = ResourceManager.DefaultWeight; + + /// + /// 房间备注 + /// + [JsonInclude] + public string Remark; } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/map/data/DungeonRoomSplit.cs b/DungeonShooting_Godot/src/framework/map/data/DungeonRoomSplit.cs index 8368bb8..f4b650c 100644 --- a/DungeonShooting_Godot/src/framework/map/data/DungeonRoomSplit.cs +++ b/DungeonShooting_Godot/src/framework/map/data/DungeonRoomSplit.cs @@ -8,11 +8,11 @@ public class DungeonRoomSplit { /// - /// 房间场景路径 + /// 当前房间是否绘制完成, 也就是是否可用 /// [JsonInclude] - public string ScenePath; - + public bool Ready; + /// /// 房间配置路径 /// @@ -26,14 +26,14 @@ public string TilePath; /// - /// 房间配置数据, 第一次获取会要在资源中加载数据 + /// 房间配置数据, 第一次获取会在资源中加载数据 /// [JsonIgnore] public DungeonRoomInfo RoomInfo { get { - if (_roomInfo == null) + if (_roomInfo == null && RoomPath != null) { var asText = ResourceManager.LoadText(RoomPath); _roomInfo = JsonSerializer.Deserialize(asText); @@ -51,6 +51,7 @@ return _roomInfo; } + set => _roomInfo = value; } private DungeonRoomInfo _roomInfo; @@ -63,7 +64,7 @@ { get { - if (_tileInfo == null) + if (_tileInfo == null && TilePath != null) { var asText = ResourceManager.LoadText(TilePath); _tileInfo = JsonSerializer.Deserialize(asText); @@ -71,6 +72,7 @@ return _tileInfo; } + set => _tileInfo = value; } private DungeonTileInfo _tileInfo; diff --git a/DungeonShooting_Godot/src/game/GameApplication.cs b/DungeonShooting_Godot/src/game/GameApplication.cs index f552551..a8030eb 100644 --- a/DungeonShooting_Godot/src/game/GameApplication.cs +++ b/DungeonShooting_Godot/src/game/GameApplication.cs @@ -220,21 +220,22 @@ private void InitRoomConfig() { //加载房间配置信息 - var asText = ResourceManager.LoadText(ResourcePath.resource_map_RoomConfig_json); + var asText = ResourceManager.LoadText("res://resource/map/tileMaps/GroupConfig.json"); RoomConfig = JsonSerializer.Deserialize>(asText); //初始化RoomConfigMap RoomConfigMap = new Dictionary(); - foreach (var dungeonRoomGroup in RoomConfig) - { - foreach (var dungeonRoomType in Enum.GetValues()) - { - foreach (var dungeonRoomSplit in dungeonRoomGroup.Value.GetRoomList(dungeonRoomType)) - { - RoomConfigMap.Add(dungeonRoomSplit.ScenePath, dungeonRoomSplit); - } - } - } + //加载流程更改 + // foreach (var dungeonRoomGroup in RoomConfig) + // { + // foreach (var dungeonRoomType in Enum.GetValues()) + // { + // foreach (var dungeonRoomSplit in dungeonRoomGroup.Value.GetRoomList(dungeonRoomType)) + // { + // RoomConfigMap.Add(dungeonRoomSplit.ScenePath, dungeonRoomSplit); + // } + // } + // } } //窗体大小改变 diff --git a/DungeonShooting_Godot/src/game/GameConfig.cs b/DungeonShooting_Godot/src/game/GameConfig.cs index 23eaa93..9cb8fec 100644 --- a/DungeonShooting_Godot/src/game/GameConfig.cs +++ b/DungeonShooting_Godot/src/game/GameConfig.cs @@ -35,9 +35,9 @@ /// public const string RoomTileDir = "resource/map/tileMaps/"; /// - /// 房间配置汇总数据路径 + /// 房间组配置文件名称 /// - public const string RoomTileConfigFile = "resource/map/RoomConfig.json"; + public const string RoomGroupConfigFile = "GroupConfig.json"; /// /// ui预制体路径 /// diff --git a/DungeonShooting_Godot/src/game/event/EventEnum.cs b/DungeonShooting_Godot/src/game/event/EventEnum.cs index 839aa4f..5b532d2 100644 --- a/DungeonShooting_Godot/src/game/event/EventEnum.cs +++ b/DungeonShooting_Godot/src/game/event/EventEnum.cs @@ -61,4 +61,16 @@ /// 当玩家退出地牢时调用, 没有参数 /// OnExitDungeon, + + + //------------------------- 编辑器相关 -------------------------- + + /// + /// 创建地牢组完成时调用, 参数为 + /// + OnCreateGroupFinish, + /// + /// 创建地牢房间完成时调用, 参数为 + /// + OnCreateRoomFinish, } diff --git a/DungeonShooting_Godot/src/game/manager/MapProjectManager.cs b/DungeonShooting_Godot/src/game/manager/MapProjectManager.cs index 9535143..408c14f 100644 --- a/DungeonShooting_Godot/src/game/manager/MapProjectManager.cs +++ b/DungeonShooting_Godot/src/game/manager/MapProjectManager.cs @@ -2,62 +2,20 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text.Json; using Godot; public static class MapProjectManager { - public class MapGroupInfo - { - /// - /// 组名称 - /// - public string Name; - /// - /// 组路径 - /// - public string FullPath; - /// - /// 当前组所在的文件夹 - /// - public string RootPath; - } - - public class MapRoomInfo - { - /// - /// 房间名称 - /// - public string Name; - /// - /// 组名称 - /// - public string Group; - /// - /// 房间类型 - /// - public DungeonRoomType RoomType; - /// - /// 文件夹路径 - /// - public string FullPath; - /// - /// 预览图片 - /// - public string PrevImage; - /// - /// 当前组所在的文件夹 - /// - public string RootPath; - } - /// /// 扫描路径 /// - public static readonly List ScannerPaths = new List(); + public static string CustomMapPath { get; private set; } + /// - /// 组列表数据 + /// 地牢组数据, key: 组名称 /// - public static readonly Dictionary GroupData = new Dictionary(); + public static Dictionary GroupMap { get; private set; } private static bool _init; @@ -70,7 +28,7 @@ _init = true; #if TOOLS - ScannerPaths.Add(GameConfig.RoomTileDir); + CustomMapPath = GameConfig.RoomTileDir; #endif } @@ -79,73 +37,141 @@ /// public static void RefreshMapGroup() { - GroupData.Clear(); - foreach (var path in ScannerPaths) + var configFile = CustomMapPath + "/" + GameConfig.RoomGroupConfigFile; + if (File.Exists(configFile)) { - if (Directory.Exists(path)) + var configText = File.ReadAllText(configFile); + GroupMap = JsonSerializer.Deserialize>(configText); + foreach (var item in GroupMap) { - var info = new DirectoryInfo(path); - var directoryInfos = info.GetDirectories(); - foreach (var directoryInfo in directoryInfos) + var config = item.Value; + foreach (var roomSplit in config.BattleList) { - var projectInfo = new MapGroupInfo(); - projectInfo.Name = directoryInfo.Name; - projectInfo.FullPath = directoryInfo.FullName; - projectInfo.RootPath = info.FullName; - GroupData.TryAdd(projectInfo.FullPath, projectInfo); + _ = roomSplit.RoomInfo; + } + + foreach (var roomSplit in config.BossList) + { + _ = roomSplit.RoomInfo; + } + + foreach (var roomSplit in config.InletList) + { + _ = roomSplit.RoomInfo; + } + + foreach (var roomSplit in config.OutletList) + { + _ = roomSplit.RoomInfo; + } + + foreach (var roomSplit in config.EventList) + { + _ = roomSplit.RoomInfo; + } + + foreach (var roomSplit in config.RewardList) + { + _ = roomSplit.RoomInfo; + } + + foreach (var roomSplit in config.ShopList) + { + _ = roomSplit.RoomInfo; } } - else - { - GD.PrintErr("刷新地图组时发现不存在的路径: " + path); - } } + else + { + GD.Print("刷新地图组时未找到配置文件: " + configFile + ", 执行创建文件"); + GroupMap = new Dictionary(); + File.WriteAllText(configFile, "{}"); + } + } + + /// + /// 获取地牢房间配置文件加载路径 + /// + /// 组名 + /// 房间类型 + /// 房间名称 + public static string GetConfigPath(string groupName, DungeonRoomType roomType, string roomName) + { + return CustomMapPath + groupName + "/" + DungeonManager.DungeonRoomTypeToString(roomType) + "/" + roomName; } /// - /// 根据路径加载房间 + /// 获取房间地块配置文件名称 /// - public static MapRoomInfo[] LoadRoom(string rootPath, string groupName) + public static string GetTileInfoConfigName(string roomName) { - var path = rootPath + "\\" + groupName; - if (!Directory.Exists(path)) - { - GD.PrintErr("加载地牢房间时发现不存在的路径: " + path); - return new MapRoomInfo[0]; - } - - var list = new List(); - var dir = new DirectoryInfo(path); - var roomTypes = Enum.GetValues(); - foreach (var dungeonRoomType in roomTypes) - { - LoadRoomByType(list, dir, rootPath, groupName, dungeonRoomType); - } - - return list.ToArray(); + return roomName + "_tileInfo.json"; + } + + /// + /// 获取房间基础配置文件名称 + /// + public static string GetRoomInfoConfigName(string roomName) + { + return roomName + "_roomInfo.json"; } - private static void LoadRoomByType(List list, DirectoryInfo dir, string rootPath, string groupName, DungeonRoomType roomType) + /// + /// 创建地牢组 + /// + public static void CreateGroup(DungeonRoomGroup group) { - var typeName = DungeonManager.DungeonRoomTypeToString(roomType); - var path = dir.FullName + "\\" + typeName; - if (Directory.Exists(path)) + if (GroupMap.ContainsKey(group.GroupName)) { - var tempDir = new DirectoryInfo(path); - var directoryInfos = tempDir.GetDirectories(); - foreach (var directoryInfo in directoryInfos) + GD.PrintErr($"已经存在相同的地牢组: {group.GroupName}"); + return; + } + var configFile = CustomMapPath + "/" + GameConfig.RoomGroupConfigFile; + GroupMap.Add(group.GroupName, group); + //将组数据保存为json + var options = new JsonSerializerOptions(); + options.WriteIndented = true; + var jsonText = JsonSerializer.Serialize(GroupMap, options); + File.WriteAllText(configFile, jsonText); + //创建完成事件 + EventManager.EmitEvent(EventEnum.OnCreateGroupFinish, group); + } + + /// + /// 创建地牢房间 + /// + public static void CreateRoom(DungeonRoomSplit roomSplit) + { + var groupName = roomSplit.RoomInfo.GroupName; + if (GroupMap.TryGetValue(groupName, out var group)) + { + var configFile = CustomMapPath + "/" + GameConfig.RoomGroupConfigFile; + var roomList = group.GetRoomList(roomSplit.RoomInfo.RoomType); + roomList.Add(roomSplit); + + var configPath = GetConfigPath(roomSplit.RoomInfo.GroupName, roomSplit.RoomInfo.RoomType, roomSplit.RoomInfo.RoomName); + if (!Directory.Exists(configPath)) { - if (directoryInfo.GetFiles().Length > 0) - { - var room = new MapRoomInfo(); - room.Name = directoryInfo.Name; - room.FullPath = directoryInfo.FullName; - room.RoomType = roomType; - room.Group = groupName; - room.RootPath = rootPath; - list.Add(room); - } + Directory.CreateDirectory(configPath); } + + //将组数据保存为json + var options = new JsonSerializerOptions(); + options.WriteIndented = true; + var jsonText = JsonSerializer.Serialize(GroupMap, options); + File.WriteAllText(configFile, jsonText); + //将房间数据保存为json + var jsonText2 = JsonSerializer.Serialize(roomSplit.RoomInfo); + File.WriteAllText(roomSplit.RoomPath, jsonText2); + //将房间地块保存为json + var jsonText3 = JsonSerializer.Serialize(roomSplit.TileInfo); + File.WriteAllText(roomSplit.TilePath, jsonText3); + //创建完成事件 + EventManager.EmitEvent(EventEnum.OnCreateGroupFinish, roomSplit); + } + else + { + GD.PrintErr($"未找到地牢组: {groupName}"); } } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs index 5432aa9..aef8628 100644 --- a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs +++ b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs @@ -54,6 +54,7 @@ public const string prefab_ui_Loading_tscn = "res://prefab/ui/Loading.tscn"; public const string prefab_ui_Main_tscn = "res://prefab/ui/Main.tscn"; public const string prefab_ui_MapEditor_tscn = "res://prefab/ui/MapEditor.tscn"; + public const string prefab_ui_MapEditorCreateGroup_tscn = "res://prefab/ui/MapEditorCreateGroup.tscn"; public const string prefab_ui_MapEditorCreateRoom_tscn = "res://prefab/ui/MapEditorCreateRoom.tscn"; public const string prefab_ui_MapEditorProject_tscn = "res://prefab/ui/MapEditorProject.tscn"; public const string prefab_ui_MapEditorTools_tscn = "res://prefab/ui/MapEditorTools.tscn"; @@ -77,7 +78,6 @@ public const string resource_font_DinkieBitmap9pxItalicDemo_ttf = "res://resource/font/DinkieBitmap-9pxItalicDemo.ttf"; public const string resource_font_VonwaonBitmap12px_ttf = "res://resource/font/VonwaonBitmap-12px.ttf"; public const string resource_font_VonwaonBitmap16px_ttf = "res://resource/font/VonwaonBitmap-16px.ttf"; - public const string resource_map_RoomConfig_json = "res://resource/map/RoomConfig.json"; public const string resource_map_tileSet_TileSet1_tres = "res://resource/map/tileSet/TileSet1.tres"; public const string resource_map_tileSet_TileSet_old_tres = "res://resource/map/tileSet/TileSet_old.tres"; public const string resource_material_Blend_gdshader = "res://resource/material/Blend.gdshader"; diff --git a/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs b/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs index 7a10f3a..018ba74 100644 --- a/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs +++ b/DungeonShooting_Godot/src/game/manager/UiManager_Methods.cs @@ -13,6 +13,7 @@ public const string Loading = "Loading"; public const string Main = "Main"; public const string MapEditor = "MapEditor"; + public const string MapEditorCreateGroup = "MapEditorCreateGroup"; public const string MapEditorCreateRoom = "MapEditorCreateRoom"; public const string MapEditorProject = "MapEditorProject"; public const string MapEditorTools = "MapEditorTools"; @@ -301,6 +302,46 @@ } /// + /// 打开 MapEditorCreateGroup, 并返回UI实例 + /// + public static UI.MapEditorCreateGroup.MapEditorCreateGroupPanel Open_MapEditorCreateGroup() + { + return OpenUi(UiName.MapEditorCreateGroup); + } + + /// + /// 隐藏 MapEditorCreateGroup 的所有实例 + /// + public static void Hide_MapEditorCreateGroup() + { + var uiInstance = Get_MapEditorCreateGroup_Instance(); + foreach (var uiPanel in uiInstance) + { + uiPanel.HideUi(); + } + } + + /// + /// 销毁 MapEditorCreateGroup 的所有实例 + /// + public static void Dispose_MapEditorCreateGroup() + { + var uiInstance = Get_MapEditorCreateGroup_Instance(); + foreach (var uiPanel in uiInstance) + { + uiPanel.DisposeUi(); + } + } + + /// + /// 获取所有 MapEditorCreateGroup 的实例, 如果没有实例, 则返回一个空数组 + /// + public static UI.MapEditorCreateGroup.MapEditorCreateGroupPanel[] Get_MapEditorCreateGroup_Instance() + { + return GetUiInstance(nameof(UI.MapEditorCreateGroup.MapEditorCreateGroup)); + } + + /// /// 打开 MapEditorCreateRoom, 并返回UI实例 /// public static UI.MapEditorCreateRoom.MapEditorCreateRoomPanel Open_MapEditorCreateRoom() diff --git a/DungeonShooting_Godot/src/game/ui/mapEditor/MapEditorPanel.cs b/DungeonShooting_Godot/src/game/ui/mapEditor/MapEditorPanel.cs index 591863c..8294611 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditor/MapEditorPanel.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditor/MapEditorPanel.cs @@ -44,13 +44,9 @@ /// /// 加载地牢, 返回是否加载成功 /// - /// 文件夹路径 - /// 房间组名 - /// 房间类型 - /// 房间名称 - public bool LoadMap(string dir, string groupName, DungeonRoomType roomType, string roomName) + public bool LoadMap(DungeonRoomSplit roomSplit) { - return S_TileMap.Instance.Load(dir, groupName, roomType, roomName); + return S_TileMap.Instance.Load(roomSplit); } //调整地图显示区域大小 diff --git a/DungeonShooting_Godot/src/game/ui/mapEditor/TileView/EditorTileMap.cs b/DungeonShooting_Godot/src/game/ui/mapEditor/TileView/EditorTileMap.cs index 1a4d759..144c56b 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditor/TileView/EditorTileMap.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditor/TileView/EditorTileMap.cs @@ -81,15 +81,14 @@ private int _terrainSet = 0; private int _terrain = 0; private AutoTileConfig _autoTileConfig = new AutoTileConfig(); + + //原数据 + private DungeonRoomSplit _roomSplit; - private string _dir; - private string _groupName = "testGroup1"; - private string _fileName = "Room2"; + //变动过的数据 private Vector2I _roomPosition; private Vector2I _roomSize; private List _doorConfigs = new List(); - private DungeonRoomType _roomType = DungeonRoomType.Battle; - private int _weight = 100; //------------------------------- public override void _Ready() @@ -334,44 +333,17 @@ /// /// 加载地牢, 返回是否加载成功 /// - /// 文件夹路径 - /// 房间组名 - /// 房间类型 - /// 房间名称 - public bool Load(string dir, string groupName, DungeonRoomType roomType, string roomName) + public bool Load(DungeonRoomSplit roomSplit) { - _dir = dir; - _groupName = groupName; - _roomType = roomType; - _fileName = roomName; - - var path = GetConfigPath(dir, groupName, roomType, roomName) + "/"; - var tileInfoConfigPath = path + GetTileInfoConfigName(_fileName); - var roomInfoConfigPath = path + GetRoomInfoConfigName(_fileName); - - if (!File.Exists(tileInfoConfigPath)) - { - GD.PrintErr("地牢编辑器加载地牢时未找到文件: " + tileInfoConfigPath); - return false; - } - if (!File.Exists(roomInfoConfigPath)) - { - GD.PrintErr("地牢编辑器加载地牢时未找到文件: " + roomInfoConfigPath); - return false; - } - - var text = ResourceManager.LoadText(tileInfoConfigPath); - var tileInfo = JsonSerializer.Deserialize(text); - - var text2 = ResourceManager.LoadText(roomInfoConfigPath); - var roomInfo = JsonSerializer.Deserialize(text2); + _roomSplit = roomSplit; + var roomInfo = roomSplit.RoomInfo; + var tileInfo = roomSplit.TileInfo; _roomPosition = roomInfo.Position.AsVector2I(); _roomSize = roomInfo.Size.AsVector2I(); _doorConfigs.Clear(); _doorConfigs.AddRange(roomInfo.DoorAreaInfos); - _weight = roomInfo.Weight; - + //初始化层级数据 InitLayer(); @@ -727,22 +699,19 @@ private void SaveRoomInfoConfig() { //存入本地 - var path = GetConfigPath(_dir, _groupName, _roomType, _fileName); + var roomInfo = _roomSplit.RoomInfo; + var path = MapProjectManager.GetConfigPath(roomInfo.GroupName,roomInfo.RoomType, roomInfo.RoomName); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } - var roomInfo = new DungeonRoomInfo(); roomInfo.Position = new SerializeVector2(_roomPosition); roomInfo.Size = new SerializeVector2(_roomSize); - roomInfo.DoorAreaInfos = _doorConfigs; - roomInfo.RoomType = _roomType; - roomInfo.GroupName = _groupName; - roomInfo.FileName = _fileName; - roomInfo.Weight = _weight; + roomInfo.DoorAreaInfos.Clear(); + roomInfo.DoorAreaInfos.AddRange(_doorConfigs); - path += "/" + GetRoomInfoConfigName(_fileName); + path += "/" + MapProjectManager.GetRoomInfoConfigName(roomInfo.RoomName); var jsonStr = JsonSerializer.Serialize(roomInfo); File.WriteAllText(path, jsonStr); } @@ -751,7 +720,8 @@ public void SaveTileInfoConfig() { //存入本地 - var path = GetConfigPath(_dir, _groupName, _roomType, _fileName); + var roomInfo = _roomSplit.RoomInfo; + var path = MapProjectManager.GetConfigPath(roomInfo.GroupName,roomInfo.RoomType, roomInfo.RoomName); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); @@ -767,23 +737,8 @@ PushLayerDataToList(AutoMiddleLayer, _sourceId, tileInfo.Middle); PushLayerDataToList(AutoTopLayer, _sourceId, tileInfo.Top); - path += "/" + GetTileInfoConfigName(_fileName); + path += "/" + MapProjectManager.GetTileInfoConfigName(roomInfo.RoomName); var jsonStr = JsonSerializer.Serialize(tileInfo); File.WriteAllText(path, jsonStr); } - - private string GetConfigPath(string dir, string groupName, DungeonRoomType roomType, string fileName) - { - return dir + groupName + "/" + DungeonManager.DungeonRoomTypeToString(roomType) + "/" + fileName; - } - - private string GetTileInfoConfigName(string roomName) - { - return roomName + "_tileInfo.json"; - } - - private string GetRoomInfoConfigName(string roomName) - { - return roomName + "_roomInfo.json"; - } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/ui/mapEditorCreateGroup/MapEditorCreateGroup.cs b/DungeonShooting_Godot/src/game/ui/mapEditorCreateGroup/MapEditorCreateGroup.cs new file mode 100644 index 0000000..18be6a5 --- /dev/null +++ b/DungeonShooting_Godot/src/game/ui/mapEditorCreateGroup/MapEditorCreateGroup.cs @@ -0,0 +1,234 @@ +namespace UI.MapEditorCreateGroup; + +/// +/// Ui代码, 该类是根据ui场景自动生成的, 请不要手动编辑该类, 以免造成代码丢失 +/// +public abstract partial class MapEditorCreateGroup : UiBase +{ + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: MapEditorCreateGroup.MarginContainer + /// + public MarginContainer L_MarginContainer + { + get + { + if (_L_MarginContainer == null) _L_MarginContainer = new MarginContainer(this, GetNodeOrNull("MarginContainer")); + return _L_MarginContainer; + } + } + private MarginContainer _L_MarginContainer; + + + public MapEditorCreateGroup() : base(nameof(MapEditorCreateGroup)) + { + } + + public sealed override void OnInitNestedUi() + { + } + + /// + /// 类型: , 路径: MapEditorCreateGroup.MarginContainer.VBoxContainer.HBoxContainer.GroupNameLabel + /// + public class GroupNameLabel : UiNode + { + public GroupNameLabel(MapEditorCreateGroup uiPanel, Godot.Label node) : base(uiPanel, node) { } + public override GroupNameLabel Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: MapEditorCreateGroup.MarginContainer.VBoxContainer.HBoxContainer.GroupNameInput + /// + public class GroupNameInput : UiNode + { + public GroupNameInput(MapEditorCreateGroup uiPanel, Godot.LineEdit node) : base(uiPanel, node) { } + public override GroupNameInput Clone() => new (UiPanel, (Godot.LineEdit)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: MapEditorCreateGroup.MarginContainer.VBoxContainer.HBoxContainer + /// + public class HBoxContainer : UiNode + { + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: MapEditorCreateGroup.MarginContainer.VBoxContainer.GroupNameLabel + /// + public GroupNameLabel L_GroupNameLabel + { + get + { + if (_L_GroupNameLabel == null) _L_GroupNameLabel = new GroupNameLabel(UiPanel, Instance.GetNodeOrNull("GroupNameLabel")); + return _L_GroupNameLabel; + } + } + private GroupNameLabel _L_GroupNameLabel; + + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: MapEditorCreateGroup.MarginContainer.VBoxContainer.GroupNameInput + /// + public GroupNameInput L_GroupNameInput + { + get + { + if (_L_GroupNameInput == null) _L_GroupNameInput = new GroupNameInput(UiPanel, Instance.GetNodeOrNull("GroupNameInput")); + return _L_GroupNameInput; + } + } + private GroupNameInput _L_GroupNameInput; + + public HBoxContainer(MapEditorCreateGroup uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { } + public override HBoxContainer Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: MapEditorCreateGroup.MarginContainer.VBoxContainer.HBoxContainer5.RemarkNameLabel + /// + public class RemarkNameLabel : UiNode + { + public RemarkNameLabel(MapEditorCreateGroup uiPanel, Godot.Label node) : base(uiPanel, node) { } + public override RemarkNameLabel Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: MapEditorCreateGroup.MarginContainer.VBoxContainer.HBoxContainer5.RemarkInput + /// + public class RemarkInput : UiNode + { + public RemarkInput(MapEditorCreateGroup uiPanel, Godot.TextEdit node) : base(uiPanel, node) { } + public override RemarkInput Clone() => new (UiPanel, (Godot.TextEdit)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: MapEditorCreateGroup.MarginContainer.VBoxContainer.HBoxContainer5 + /// + public class HBoxContainer5 : UiNode + { + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: MapEditorCreateGroup.MarginContainer.VBoxContainer.RemarkNameLabel + /// + public RemarkNameLabel L_RemarkNameLabel + { + get + { + if (_L_RemarkNameLabel == null) _L_RemarkNameLabel = new RemarkNameLabel(UiPanel, Instance.GetNodeOrNull("RemarkNameLabel")); + return _L_RemarkNameLabel; + } + } + private RemarkNameLabel _L_RemarkNameLabel; + + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: MapEditorCreateGroup.MarginContainer.VBoxContainer.RemarkInput + /// + public RemarkInput L_RemarkInput + { + get + { + if (_L_RemarkInput == null) _L_RemarkInput = new RemarkInput(UiPanel, Instance.GetNodeOrNull("RemarkInput")); + return _L_RemarkInput; + } + } + private RemarkInput _L_RemarkInput; + + public HBoxContainer5(MapEditorCreateGroup uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { } + public override HBoxContainer5 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: MapEditorCreateGroup.MarginContainer.VBoxContainer + /// + public class VBoxContainer : UiNode + { + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: MapEditorCreateGroup.MarginContainer.HBoxContainer + /// + public HBoxContainer L_HBoxContainer + { + get + { + if (_L_HBoxContainer == null) _L_HBoxContainer = new HBoxContainer(UiPanel, Instance.GetNodeOrNull("HBoxContainer")); + return _L_HBoxContainer; + } + } + private HBoxContainer _L_HBoxContainer; + + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: MapEditorCreateGroup.MarginContainer.HBoxContainer5 + /// + public HBoxContainer5 L_HBoxContainer5 + { + get + { + if (_L_HBoxContainer5 == null) _L_HBoxContainer5 = new HBoxContainer5(UiPanel, Instance.GetNodeOrNull("HBoxContainer5")); + return _L_HBoxContainer5; + } + } + private HBoxContainer5 _L_HBoxContainer5; + + public VBoxContainer(MapEditorCreateGroup uiPanel, Godot.VBoxContainer node) : base(uiPanel, node) { } + public override VBoxContainer Clone() => new (UiPanel, (Godot.VBoxContainer)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: MapEditorCreateGroup.MarginContainer + /// + public class MarginContainer : UiNode + { + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: MapEditorCreateGroup.VBoxContainer + /// + public VBoxContainer L_VBoxContainer + { + get + { + if (_L_VBoxContainer == null) _L_VBoxContainer = new VBoxContainer(UiPanel, Instance.GetNodeOrNull("VBoxContainer")); + return _L_VBoxContainer; + } + } + private VBoxContainer _L_VBoxContainer; + + public MarginContainer(MapEditorCreateGroup uiPanel, Godot.MarginContainer node) : base(uiPanel, node) { } + public override MarginContainer Clone() => new (UiPanel, (Godot.MarginContainer)Instance.Duplicate()); + } + + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: MapEditorCreateGroup.MarginContainer.VBoxContainer.HBoxContainer.GroupNameLabel + /// + public GroupNameLabel S_GroupNameLabel => L_MarginContainer.L_VBoxContainer.L_HBoxContainer.L_GroupNameLabel; + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: MapEditorCreateGroup.MarginContainer.VBoxContainer.HBoxContainer.GroupNameInput + /// + public GroupNameInput S_GroupNameInput => L_MarginContainer.L_VBoxContainer.L_HBoxContainer.L_GroupNameInput; + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: MapEditorCreateGroup.MarginContainer.VBoxContainer.HBoxContainer + /// + public HBoxContainer S_HBoxContainer => L_MarginContainer.L_VBoxContainer.L_HBoxContainer; + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: MapEditorCreateGroup.MarginContainer.VBoxContainer.HBoxContainer5.RemarkNameLabel + /// + public RemarkNameLabel S_RemarkNameLabel => L_MarginContainer.L_VBoxContainer.L_HBoxContainer5.L_RemarkNameLabel; + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: MapEditorCreateGroup.MarginContainer.VBoxContainer.HBoxContainer5.RemarkInput + /// + public RemarkInput S_RemarkInput => L_MarginContainer.L_VBoxContainer.L_HBoxContainer5.L_RemarkInput; + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: MapEditorCreateGroup.MarginContainer.VBoxContainer.HBoxContainer5 + /// + public HBoxContainer5 S_HBoxContainer5 => L_MarginContainer.L_VBoxContainer.L_HBoxContainer5; + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: MapEditorCreateGroup.MarginContainer.VBoxContainer + /// + public VBoxContainer S_VBoxContainer => L_MarginContainer.L_VBoxContainer; + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: MapEditorCreateGroup.MarginContainer + /// + public MarginContainer S_MarginContainer => L_MarginContainer; + +} diff --git a/DungeonShooting_Godot/src/game/ui/mapEditorCreateGroup/MapEditorCreateGroupPanel.cs b/DungeonShooting_Godot/src/game/ui/mapEditorCreateGroup/MapEditorCreateGroupPanel.cs new file mode 100644 index 0000000..673bc8c --- /dev/null +++ b/DungeonShooting_Godot/src/game/ui/mapEditorCreateGroup/MapEditorCreateGroupPanel.cs @@ -0,0 +1,39 @@ +using System.IO; +using System.Text.RegularExpressions; +using Godot; + +namespace UI.MapEditorCreateGroup; + +public partial class MapEditorCreateGroupPanel : MapEditorCreateGroup +{ + + /// + /// 填完数据后获取数据对象, 并进行验证, 如果验证失败, 则返回 null + /// + public DungeonRoomGroup GetGroupInfo() + { + //组名 + var groupName = S_GroupNameInput.Instance.Text; + + //检查名称是否合规 + if (!Regex.IsMatch(groupName, "^\\w+$")) + { + EditorTipsManager.ShowTips("错误", "组名称'" + groupName + "'不符合名称约束, 组名称只允许包含大小写字母和数字!"); + return null; + } + + //验证是否有同名组 + var path = MapProjectManager.CustomMapPath + groupName; + var dir = new DirectoryInfo(path); + if (dir.Exists && dir.GetDirectories().Length > 0) + { + EditorTipsManager.ShowTips("错误", $"已经有相同路径的房间了!"); + return null; + } + + var group = new DungeonRoomGroup(); + group.GroupName = groupName; + group.Remark = S_RemarkInput.Instance.Text; + return group; + } +} diff --git a/DungeonShooting_Godot/src/game/ui/mapEditorCreateRoom/MapEditorCreateRoom.cs b/DungeonShooting_Godot/src/game/ui/mapEditorCreateRoom/MapEditorCreateRoom.cs index e49eb11..b59e673 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditorCreateRoom/MapEditorCreateRoom.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditorCreateRoom/MapEditorCreateRoom.cs @@ -240,6 +240,59 @@ } /// + /// 类型: , 路径: MapEditorCreateRoom.MarginContainer.VBoxContainer.HBoxContainer5.RemarkNameLabel + /// + public class RemarkNameLabel : UiNode + { + public RemarkNameLabel(MapEditorCreateRoom uiPanel, Godot.Label node) : base(uiPanel, node) { } + public override RemarkNameLabel Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: MapEditorCreateRoom.MarginContainer.VBoxContainer.HBoxContainer5.RemarkInput + /// + public class RemarkInput : UiNode + { + public RemarkInput(MapEditorCreateRoom uiPanel, Godot.TextEdit node) : base(uiPanel, node) { } + public override RemarkInput Clone() => new (UiPanel, (Godot.TextEdit)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: MapEditorCreateRoom.MarginContainer.VBoxContainer.HBoxContainer5 + /// + public class HBoxContainer5 : UiNode + { + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: MapEditorCreateRoom.MarginContainer.VBoxContainer.RemarkNameLabel + /// + public RemarkNameLabel L_RemarkNameLabel + { + get + { + if (_L_RemarkNameLabel == null) _L_RemarkNameLabel = new RemarkNameLabel(UiPanel, Instance.GetNodeOrNull("RemarkNameLabel")); + return _L_RemarkNameLabel; + } + } + private RemarkNameLabel _L_RemarkNameLabel; + + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: MapEditorCreateRoom.MarginContainer.VBoxContainer.RemarkInput + /// + public RemarkInput L_RemarkInput + { + get + { + if (_L_RemarkInput == null) _L_RemarkInput = new RemarkInput(UiPanel, Instance.GetNodeOrNull("RemarkInput")); + return _L_RemarkInput; + } + } + private RemarkInput _L_RemarkInput; + + public HBoxContainer5(MapEditorCreateRoom uiPanel, Godot.HBoxContainer node) : base(uiPanel, node) { } + public override HBoxContainer5 Clone() => new (UiPanel, (Godot.HBoxContainer)Instance.Duplicate()); + } + + /// /// 类型: , 路径: MapEditorCreateRoom.MarginContainer.VBoxContainer /// public class VBoxContainer : UiNode @@ -296,6 +349,19 @@ } private HBoxContainer4 _L_HBoxContainer4; + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: MapEditorCreateRoom.MarginContainer.HBoxContainer5 + /// + public HBoxContainer5 L_HBoxContainer5 + { + get + { + if (_L_HBoxContainer5 == null) _L_HBoxContainer5 = new HBoxContainer5(UiPanel, Instance.GetNodeOrNull("HBoxContainer5")); + return _L_HBoxContainer5; + } + } + private HBoxContainer5 _L_HBoxContainer5; + public VBoxContainer(MapEditorCreateRoom uiPanel, Godot.VBoxContainer node) : base(uiPanel, node) { } public override VBoxContainer Clone() => new (UiPanel, (Godot.VBoxContainer)Instance.Duplicate()); } @@ -384,6 +450,21 @@ public HBoxContainer4 S_HBoxContainer4 => L_MarginContainer.L_VBoxContainer.L_HBoxContainer4; /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: MapEditorCreateRoom.MarginContainer.VBoxContainer.HBoxContainer5.RemarkNameLabel + /// + public RemarkNameLabel S_RemarkNameLabel => L_MarginContainer.L_VBoxContainer.L_HBoxContainer5.L_RemarkNameLabel; + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: MapEditorCreateRoom.MarginContainer.VBoxContainer.HBoxContainer5.RemarkInput + /// + public RemarkInput S_RemarkInput => L_MarginContainer.L_VBoxContainer.L_HBoxContainer5.L_RemarkInput; + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: MapEditorCreateRoom.MarginContainer.VBoxContainer.HBoxContainer5 + /// + public HBoxContainer5 S_HBoxContainer5 => L_MarginContainer.L_VBoxContainer.L_HBoxContainer5; + + /// /// 场景中唯一名称的节点, 节点类型: , 节点路径: MapEditorCreateRoom.MarginContainer.VBoxContainer /// public VBoxContainer S_VBoxContainer => L_MarginContainer.L_VBoxContainer; diff --git a/DungeonShooting_Godot/src/game/ui/mapEditorCreateRoom/MapEditorCreateRoomPanel.cs b/DungeonShooting_Godot/src/game/ui/mapEditorCreateRoom/MapEditorCreateRoomPanel.cs index 881db90..03857a8 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditorCreateRoom/MapEditorCreateRoomPanel.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditorCreateRoom/MapEditorCreateRoomPanel.cs @@ -16,11 +16,12 @@ //初始化选项 var groupButton = S_GroupSelect.Instance; var index = 0; - foreach (var mapGroupInfo in MapProjectManager.GroupData) + foreach (var mapGroupInfo in MapProjectManager.GroupMap) { var id = index++; - _groupMap.Add(mapGroupInfo.Value.Name, id); - groupButton.AddItem(mapGroupInfo.Value.Name, id); + var groupGroupName = mapGroupInfo.Value.GroupName; + _groupMap.Add(groupGroupName, id); + groupButton.AddItem(groupGroupName, id); } var selectButton = S_TypeSelect.Instance; @@ -58,14 +59,15 @@ /// /// 填完数据后获取数据对象, 并进行验证, 如果验证失败, 则返回 null /// - public MapProjectManager.MapRoomInfo GetRoomInfo() + public DungeonRoomSplit GetRoomInfo() { - var mapRoomInfo = new MapProjectManager.MapRoomInfo(); - mapRoomInfo.Name = S_RoomNameInput.Instance.Text; + var roomInfo = new DungeonRoomInfo(); + roomInfo.RoomName = S_RoomNameInput.Instance.Text; + roomInfo.Remark = S_RemarkInput.Instance.Text; //检查名称是否合规 - if (!Regex.IsMatch(mapRoomInfo.Name, "^\\w+$")) + if (!Regex.IsMatch(roomInfo.RoomName, "^\\w+$")) { - EditorTipsManager.ShowTips("错误", "房间名称'" + mapRoomInfo.Name + "'不符合名称约束, 房间名称只允许包含大小写字母和数字!"); + EditorTipsManager.ShowTips("错误", "房间名称'" + roomInfo.RoomName + "'不符合名称约束, 房间名称只允许包含大小写字母和数字!"); return null; } @@ -74,29 +76,45 @@ { if (pair.Value == groupIndex) { - mapRoomInfo.Group = pair.Key; + roomInfo.GroupName = pair.Key; } } - if (mapRoomInfo.Group == null) + if (roomInfo.GroupName == null) { EditorTipsManager.ShowTips("错误", "组名错误!"); return null; } var typeIndex = S_TypeSelect.Instance.Selected; - mapRoomInfo.RoomType = (DungeonRoomType)typeIndex; + roomInfo.RoomType = (DungeonRoomType)typeIndex; //检测是否有同名房间 - var temp = mapRoomInfo.Group + "/" + DungeonManager.DungeonRoomTypeToString(mapRoomInfo.RoomType) + "/" + mapRoomInfo.Name; - var path = GameConfig.RoomTileDir + temp; - var dir = new DirectoryInfo(path); + var temp = roomInfo.GroupName + "/" + DungeonManager.DungeonRoomTypeToString(roomInfo.RoomType) + "/" + roomInfo.RoomName; + var dirPath = MapProjectManager.CustomMapPath + temp; + var dir = new DirectoryInfo(dirPath); if (dir.Exists && dir.GetFiles().Length > 0) { EditorTipsManager.ShowTips("错误", $"已经有相同路径的房间了!\n路径: {temp}"); return null; } - - return mapRoomInfo; + + roomInfo.Size = new SerializeVector2(); + roomInfo.Position = new SerializeVector2(); + roomInfo.DoorAreaInfos = new List(); + + var roomSplit = new DungeonRoomSplit(); + roomSplit.RoomPath = dirPath + "/" + MapProjectManager.GetRoomInfoConfigName(roomInfo.RoomName); + roomSplit.RoomInfo = roomInfo; + + var tileInfo = new DungeonTileInfo(); + tileInfo.NavigationList = new List(); + tileInfo.Floor = new List(); + tileInfo.Middle = new List(); + tileInfo.Top = new List(); + + roomSplit.TilePath = dirPath + "/" + MapProjectManager.GetTileInfoConfigName(roomInfo.RoomName); + roomSplit.TileInfo = tileInfo; + return roomSplit; } } diff --git a/DungeonShooting_Godot/src/game/ui/mapEditorProject/GroupButtonCell.cs b/DungeonShooting_Godot/src/game/ui/mapEditorProject/GroupButtonCell.cs index ed6eb3b..23e00d5 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditorProject/GroupButtonCell.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditorProject/GroupButtonCell.cs @@ -2,17 +2,17 @@ namespace UI.MapEditorProject; -public class GroupButtonCell : UiCell +public class GroupButtonCell : UiCell { protected override void OnInit() { CellNode.Instance.Pressed += OnClick; } - protected override void OnSetData(MapProjectManager.MapGroupInfo data) + protected override void OnSetData(DungeonRoomGroup info) { - CellNode.Instance.Text = data.Name; - CellNode.Instance.TooltipText = "路径: " + data.FullPath; + CellNode.Instance.Text = info.GroupName; + CellNode.Instance.TooltipText = "路径: " + MapProjectManager.CustomMapPath + "/" + info.GroupName; } protected override void OnRefreshIndex() diff --git a/DungeonShooting_Godot/src/game/ui/mapEditorProject/MapEditorProjectPanel.cs b/DungeonShooting_Godot/src/game/ui/mapEditorProject/MapEditorProjectPanel.cs index 46dcd57..2fdd88b 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditorProject/MapEditorProjectPanel.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditorProject/MapEditorProjectPanel.cs @@ -1,7 +1,9 @@ using System; +using System.Collections.Generic; using System.Linq; using Godot; using UI.EditorWindow; +using UI.MapEditorCreateGroup; using UI.MapEditorCreateRoom; namespace UI.MapEditorProject; @@ -11,16 +13,13 @@ /// /// 当前选中的组 /// - public MapProjectManager.MapGroupInfo SelectGroupInfo; - /// - /// 选中的组所包含的房间数据 - /// - public MapProjectManager.MapRoomInfo[] SelectRoomInfo; - + public DungeonRoomGroup SelectGroupInfo; + //当前显示的组数据 - private UiGrid _groupGrid; + private UiGrid _groupGrid; //当前显示的房间数据 - private UiGrid _roomGrid; + private UiGrid _roomGrid; + private EventFactory _eventFactory; public override void OnCreateUi() { @@ -34,11 +33,11 @@ optionButton.AddItem(DungeonManager.DungeonRoomTypeToDescribeString(dungeonRoomType), (int)dungeonRoomType); } - _groupGrid = new UiGrid(S_GroupButton, typeof(GroupButtonCell)); + _groupGrid = new UiGrid(S_GroupButton, typeof(GroupButtonCell)); _groupGrid.SetCellOffset(new Vector2I(0, 2)); _groupGrid.SetHorizontalExpand(true); - _roomGrid = new UiGrid(S_RoomButton, typeof(RoomButtonCell)); + _roomGrid = new UiGrid(S_RoomButton, typeof(RoomButtonCell)); _roomGrid.SetAutoColumns(true); _roomGrid.SetCellOffset(new Vector2I(10, 10)); _roomGrid.SetHorizontalExpand(true); @@ -48,13 +47,19 @@ { S_GroupSearchButton.Instance.Pressed += OnSearchButtonClick; S_RoomAddButton.Instance.Pressed += OnCreateRoomClick; + S_GroupAddButton.Instance.Pressed += OnCreateGroupClick; RefreshGroup(); + _eventFactory = EventManager.CreateEventFactory(); + _eventFactory.AddEventListener(EventEnum.OnCreateGroupFinish, OnCreateGroupFinish); + _eventFactory.AddEventListener(EventEnum.OnCreateRoomFinish, OnCreateRoomFinish); } public override void OnHideUi() { S_GroupSearchButton.Instance.Pressed -= OnSearchButtonClick; S_RoomAddButton.Instance.Pressed -= OnCreateRoomClick; + S_GroupAddButton.Instance.Pressed -= OnCreateGroupClick; + _eventFactory.RemoveAllEventListener(); } public override void OnDisposeUi() @@ -75,24 +80,23 @@ OnSearchButtonClick(); } - public void SelectGroup(MapProjectManager.MapGroupInfo group) + public void SelectGroup(DungeonRoomGroup group) { SelectGroupInfo = group; - SelectRoomInfo = MapProjectManager.LoadRoom(group.RootPath, group.Name); - _roomGrid.SetDataList(SelectRoomInfo); + _roomGrid.SetDataList(group.GetAllRoomList().ToArray()); } /// /// 选择地图并打开地图编辑器 /// - public void SelectRoom(MapProjectManager.MapRoomInfo room) + public void SelectRoom(DungeonRoomSplit room) { HideUi(); //打开地牢Ui var mapEditor = UiManager.Open_MapEditor(); mapEditor.PrevUi = this; //加载地牢 - mapEditor.LoadMap(room.RootPath, room.Group, room.RoomType, room.Name); + mapEditor.LoadMap(room); } //搜索组按钮点击 @@ -103,28 +107,57 @@ if (!string.IsNullOrEmpty(text)) { var str = text.Trim().ToLower(); - var result = MapProjectManager.GroupData.Values.Where(info => + var list = new List(); + foreach (var valuePair in MapProjectManager.GroupMap) { - return info.Name.Trim().ToLower().Contains(str); - }); - _groupGrid.SetDataList(result.ToArray()); + if (valuePair.Value.GroupName.Trim().ToLower().Contains(str)) + { + list.Add(valuePair.Value); + } + } + _groupGrid.SetDataList(list.ToArray()); } else { - _groupGrid.SetDataList(MapProjectManager.GroupData.Values.ToArray()); + _groupGrid.SetDataList(MapProjectManager.GroupMap.Values.ToArray()); } } + + //创建组按钮点击 + private void OnCreateGroupClick() + { + var window = UiManager.Open_EditorWindow(); + window.SetWindowTitle("创建地牢组"); + window.SetWindowSize(new Vector2I(700, 500)); + var body = window.OpenBody(UiManager.UiName.MapEditorCreateGroup); + window.SetButtonList( + new EditorWindowPanel.ButtonData("确定", () => + { + //获取填写的数据, 并创建ui + var groupInfo = body.GetGroupInfo(); + if (groupInfo != null) + { + window.CloseWindow(); + CreateGroup(groupInfo); + } + }), + new EditorWindowPanel.ButtonData("取消", () => + { + window.CloseWindow(); + }) + ); + } //创建地牢房间按钮点击 private void OnCreateRoomClick() { var window = UiManager.Open_EditorWindow(); window.SetWindowTitle("创建地牢房间"); - window.SetWindowSize(new Vector2I(700, 500)); + window.SetWindowSize(new Vector2I(700, 600)); var body = window.OpenBody(UiManager.UiName.MapEditorCreateRoom); if (SelectGroupInfo != null) { - body.SetSelectGroup(SelectGroupInfo.Name); + body.SetSelectGroup(SelectGroupInfo.GroupName); } body.SetSelectType(S_RoomTypeButton.Instance.Selected); @@ -132,11 +165,11 @@ new EditorWindowPanel.ButtonData("确定", () => { //获取填写的数据, 并创建ui - var mapRoomInfo = body.GetRoomInfo(); - if (mapRoomInfo != null) + var roomSplit = body.GetRoomInfo(); + if (roomSplit != null) { window.CloseWindow(); - CreateRoom(mapRoomInfo); + CreateRoom(roomSplit); } }), new EditorWindowPanel.ButtonData("取消", () => @@ -146,8 +179,26 @@ ); } + //创建地牢组 + private void CreateGroup(DungeonRoomGroup group) + { + MapProjectManager.CreateGroup(group); + } + //创建房间 - private void CreateRoom(MapProjectManager.MapRoomInfo roomInfo) + private void CreateRoom(DungeonRoomSplit roomSplit) + { + MapProjectManager.CreateRoom(roomSplit); + } + + //创建地牢组完成 + private void OnCreateGroupFinish(object group) + { + OnSearchButtonClick(); + } + + //创建地牢房间完成 + private void OnCreateRoomFinish(object roomSplit) { } diff --git a/DungeonShooting_Godot/src/game/ui/mapEditorProject/RoomButtonCell.cs b/DungeonShooting_Godot/src/game/ui/mapEditorProject/RoomButtonCell.cs index cc0a0ec..ed10445 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditorProject/RoomButtonCell.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditorProject/RoomButtonCell.cs @@ -2,7 +2,7 @@ namespace UI.MapEditorProject; -public class RoomButtonCell : UiCell +public class RoomButtonCell : UiCell { private bool _focus = false; @@ -12,12 +12,12 @@ CellNode.Instance.FocusExited += OnFocusExited; } - protected override void OnSetData(MapProjectManager.MapRoomInfo data) + protected override void OnSetData(DungeonRoomSplit data) { _focus = false; - CellNode.L_RoomName.Instance.Text = data.Name; - CellNode.L_RoomType.Instance.Text = DungeonManager.DungeonRoomTypeToDescribeString(data.RoomType); - CellNode.Instance.TooltipText = "路径: " + data.FullPath; + CellNode.L_RoomName.Instance.Text = data.RoomInfo.RoomName; + CellNode.L_RoomType.Instance.Text = DungeonManager.DungeonRoomTypeToDescribeString(data.RoomInfo.RoomType); + CellNode.Instance.TooltipText = "路径: " + data.RoomPath; CellNode.Instance.ReleaseFocus(); }