Fixed tile growing
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
element_types={
|
element_types={
|
||||||
"corner1": {
|
"corner1": {
|
||||||
"name": "corner1",
|
"name": "corner1",
|
||||||
"sockets": [ Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, -2 ), Transform( 7.54979e-08, 0, -1, 0, 1, 0, 1, 0, 7.54979e-08, 2, 0, -4 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, -2 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, -2 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ) ]
|
"sockets": [ Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 7.54979e-08, 0, -1, 0, 1, 0, 1, 0, 7.54979e-08, 0, 0, -2 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ) ]
|
||||||
},
|
},
|
||||||
"e1": {
|
"e1": {
|
||||||
"name": "e1",
|
"name": "e1",
|
||||||
@@ -15,11 +15,11 @@ element_types={
|
|||||||
},
|
},
|
||||||
"just_floor": {
|
"just_floor": {
|
||||||
"name": "just_floor",
|
"name": "just_floor",
|
||||||
"sockets": [ Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ) ]
|
"sockets": [ Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0, 2 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ) ]
|
||||||
},
|
},
|
||||||
"side_wall": {
|
"side_wall": {
|
||||||
"name": "side_wall",
|
"name": "side_wall",
|
||||||
"sockets": [ Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -2 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -2 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ) ]
|
"sockets": [ Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ), Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ) ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elements={
|
elements={
|
||||||
@@ -384,9 +384,9 @@ grid_layouts={
|
|||||||
"index": 78,
|
"index": 78,
|
||||||
"rotation": 0
|
"rotation": 0
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "corner",
|
||||||
"index": 79,
|
"index": 79,
|
||||||
"rotation": 0
|
"rotation": 1
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "empty",
|
||||||
"index": 80,
|
"index": 80,
|
||||||
@@ -1159,11 +1159,11 @@ grid_layouts={
|
|||||||
"index": 28,
|
"index": 28,
|
||||||
"rotation": 0
|
"rotation": 0
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "normal_floor",
|
||||||
"index": 29,
|
"index": 29,
|
||||||
"rotation": 0
|
"rotation": 0
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "normal_floor",
|
||||||
"index": 30,
|
"index": 30,
|
||||||
"rotation": 0
|
"rotation": 0
|
||||||
}, {
|
}, {
|
||||||
@@ -1359,9 +1359,9 @@ grid_layouts={
|
|||||||
"index": 78,
|
"index": 78,
|
||||||
"rotation": 0
|
"rotation": 0
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "corner",
|
||||||
"index": 79,
|
"index": 79,
|
||||||
"rotation": 0
|
"rotation": 1
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "empty",
|
||||||
"index": 80,
|
"index": 80,
|
||||||
@@ -1432,13 +1432,13 @@ grid_layouts={
|
|||||||
"index": 15,
|
"index": 15,
|
||||||
"rotation": 0
|
"rotation": 0
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "side_wall",
|
||||||
"index": 16,
|
"index": 16,
|
||||||
"rotation": 0
|
"rotation": 2
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "corner",
|
||||||
"index": 17,
|
"index": 17,
|
||||||
"rotation": 0
|
"rotation": 2
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "empty",
|
||||||
"index": 18,
|
"index": 18,
|
||||||
@@ -1504,9 +1504,9 @@ grid_layouts={
|
|||||||
"index": 33,
|
"index": 33,
|
||||||
"rotation": 0
|
"rotation": 0
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "normal_floor",
|
||||||
"index": 34,
|
"index": 34,
|
||||||
"rotation": 0
|
"rotation": 2
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "empty",
|
||||||
"index": 35,
|
"index": 35,
|
||||||
@@ -1612,9 +1612,9 @@ grid_layouts={
|
|||||||
"index": 60,
|
"index": 60,
|
||||||
"rotation": 0
|
"rotation": 0
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "side_wall",
|
||||||
"index": 61,
|
"index": 61,
|
||||||
"rotation": 0
|
"rotation": 1
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "empty",
|
||||||
"index": 62,
|
"index": 62,
|
||||||
@@ -1646,15 +1646,15 @@ grid_layouts={
|
|||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "empty",
|
||||||
"index": 69,
|
"index": 69,
|
||||||
"rotation": 0
|
"rotation": 1
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "side_window",
|
||||||
"index": 70,
|
"index": 70,
|
||||||
"rotation": 0
|
"rotation": 1
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "empty",
|
||||||
"index": 71,
|
"index": 71,
|
||||||
"rotation": 0
|
"rotation": 3
|
||||||
}, {
|
}, {
|
||||||
"element": "corner",
|
"element": "corner",
|
||||||
"index": 72,
|
"index": 72,
|
||||||
@@ -1684,9 +1684,9 @@ grid_layouts={
|
|||||||
"index": 78,
|
"index": 78,
|
||||||
"rotation": 0
|
"rotation": 0
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "corner",
|
||||||
"index": 79,
|
"index": 79,
|
||||||
"rotation": 0
|
"rotation": 1
|
||||||
}, {
|
}, {
|
||||||
"element": "empty",
|
"element": "empty",
|
||||||
"index": 80,
|
"index": 80,
|
||||||
|
|||||||
@@ -330,43 +330,89 @@ columns = 2
|
|||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
margin_top = 719.0
|
margin_top = 719.0
|
||||||
margin_right = 314.0
|
margin_right = 314.0
|
||||||
margin_bottom = 847.0
|
margin_bottom = 999.0
|
||||||
|
|
||||||
[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/layout_editor"]
|
[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/layout_editor"]
|
||||||
margin_left = 7.0
|
margin_left = 7.0
|
||||||
margin_top = 7.0
|
margin_top = 7.0
|
||||||
margin_right = 307.0
|
margin_right = 307.0
|
||||||
margin_bottom = 121.0
|
margin_bottom = 273.0
|
||||||
|
|
||||||
[node name="grid_elements" type="OptionButton" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
[node name="grid_elements" type="OptionButton" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
margin_right = 300.0
|
margin_right = 300.0
|
||||||
margin_bottom = 20.0
|
margin_bottom = 20.0
|
||||||
|
|
||||||
[node name="clear_grid_cell" type="Button" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
[node name="select_rotation" type="OptionButton" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
margin_top = 24.0
|
margin_top = 24.0
|
||||||
margin_right = 300.0
|
margin_right = 300.0
|
||||||
margin_bottom = 44.0
|
margin_bottom = 44.0
|
||||||
text = "Clear cell"
|
text = "0"
|
||||||
|
items = [ "0", null, false, 0, null, "90", null, false, 1, null, "180", null, false, 2, null, "270", null, false, 3, null ]
|
||||||
|
selected = 0
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
[node name="clear_grid_cell" type="Button" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
margin_top = 48.0
|
margin_top = 48.0
|
||||||
margin_right = 300.0
|
margin_right = 300.0
|
||||||
margin_bottom = 62.0
|
margin_bottom = 68.0
|
||||||
|
text = "Clear cell"
|
||||||
|
|
||||||
|
[node name="grow_cell_button" type="Button" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 72.0
|
||||||
|
margin_right = 300.0
|
||||||
|
margin_bottom = 92.0
|
||||||
|
text = "Grow"
|
||||||
|
|
||||||
|
[node name="HSeparator" type="HSeparator" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
||||||
|
margin_top = 96.0
|
||||||
|
margin_right = 300.0
|
||||||
|
margin_bottom = 100.0
|
||||||
|
|
||||||
|
[node name="grid_elements_corner" type="OptionButton" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 104.0
|
||||||
|
margin_right = 300.0
|
||||||
|
margin_bottom = 124.0
|
||||||
|
|
||||||
|
[node name="grid_elements_side" type="OptionButton" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 128.0
|
||||||
|
margin_right = 300.0
|
||||||
|
margin_bottom = 148.0
|
||||||
|
|
||||||
|
[node name="grid_elements_floor" type="OptionButton" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 152.0
|
||||||
|
margin_right = 300.0
|
||||||
|
margin_bottom = 172.0
|
||||||
|
|
||||||
|
[node name="make_room_button" type="Button" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 176.0
|
||||||
|
margin_right = 300.0
|
||||||
|
margin_bottom = 196.0
|
||||||
|
text = "Make Room"
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
||||||
|
margin_top = 200.0
|
||||||
|
margin_right = 300.0
|
||||||
|
margin_bottom = 214.0
|
||||||
text = "Level"
|
text = "Level"
|
||||||
|
|
||||||
[node name="level_value" type="SpinBox" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
[node name="level_value" type="SpinBox" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
margin_top = 66.0
|
margin_top = 218.0
|
||||||
margin_right = 300.0
|
margin_right = 300.0
|
||||||
margin_bottom = 90.0
|
margin_bottom = 242.0
|
||||||
|
|
||||||
[node name="layout_selector" type="OptionButton" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
[node name="layout_selector" type="OptionButton" parent="VBoxContainer/layout_editor/VBoxContainer"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
margin_top = 94.0
|
margin_top = 246.0
|
||||||
margin_right = 300.0
|
margin_right = 300.0
|
||||||
margin_bottom = 114.0
|
margin_bottom = 266.0
|
||||||
|
|
||||||
[node name="BuildingLayoutEditor" type="BuildingLayoutEditor" parent="."]
|
[node name="BuildingLayoutEditor" type="BuildingLayoutEditor" parent="."]
|
||||||
source = ExtResource( 2 )
|
source = ExtResource( 2 )
|
||||||
@@ -375,7 +421,7 @@ source = ExtResource( 2 )
|
|||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
|
|
||||||
[node name="refcube" type="MeshInstance" parent="refcube"]
|
[node name="refcube" type="MeshInstance" parent="refcube"]
|
||||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 4, -2 )
|
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4, 0 )
|
||||||
mesh = SubResource( 3 )
|
mesh = SubResource( 3 )
|
||||||
skeleton = NodePath("../..")
|
skeleton = NodePath("../..")
|
||||||
|
|
||||||
|
|||||||
@@ -16,718 +16,9 @@
|
|||||||
#include <editor/editor_node.h>
|
#include <editor/editor_node.h>
|
||||||
#include <flecs/flecs.h>
|
#include <flecs/flecs.h>
|
||||||
#include "editor_event.h"
|
#include "editor_event.h"
|
||||||
|
#include "element_data.h"
|
||||||
#include "building_layout_editor.h"
|
#include "building_layout_editor.h"
|
||||||
|
|
||||||
template <class T> T *get_as_node(const String &path)
|
|
||||||
{
|
|
||||||
Node *scene;
|
|
||||||
if (Engine::get_singleton()->is_editor_hint())
|
|
||||||
scene = EditorNode::get_singleton()->get_edited_scene();
|
|
||||||
else
|
|
||||||
scene = SceneTree::get_singleton()->get_current_scene();
|
|
||||||
assert(scene);
|
|
||||||
Node *node = scene->get_node(NodePath(path));
|
|
||||||
if (!node)
|
|
||||||
print_error("Failed to get " + path);
|
|
||||||
assert(node);
|
|
||||||
T *ret = Object::cast_to<T>(node);
|
|
||||||
if (!ret)
|
|
||||||
print_error("Failed to assign " + path);
|
|
||||||
assert(ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void select_control_item(const String &path, const String &item)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
T *ctl = get_as_node<T>(path);
|
|
||||||
int selected = -1;
|
|
||||||
for (i = 0; i < ctl->get_item_count(); i++)
|
|
||||||
if (ctl->get_item_text(i) == item) {
|
|
||||||
selected = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (selected >= 0) {
|
|
||||||
ctl->select(selected);
|
|
||||||
print_line("selected: " + item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
template <class T> void select_control_item(T *ctl, const String &item)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int selected = -1;
|
|
||||||
for (i = 0; i < ctl->get_item_count(); i++)
|
|
||||||
if (ctl->get_item_text(i) == item) {
|
|
||||||
selected = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (selected >= 0) {
|
|
||||||
ctl->select(selected);
|
|
||||||
print_line("selected: " + item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ELEMENT_SOCKETS 16
|
|
||||||
class ElementData {
|
|
||||||
flecs::world ecs;
|
|
||||||
static ElementData *singleton;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static ElementData *get_singleton()
|
|
||||||
{
|
|
||||||
if (!singleton)
|
|
||||||
singleton = memnew(ElementData);
|
|
||||||
return singleton;
|
|
||||||
}
|
|
||||||
static void cleanup()
|
|
||||||
{
|
|
||||||
if (singleton)
|
|
||||||
memdelete(singleton);
|
|
||||||
}
|
|
||||||
struct grid_element_type {
|
|
||||||
String name;
|
|
||||||
Transform sockets[ELEMENT_SOCKETS];
|
|
||||||
};
|
|
||||||
struct grid_element {
|
|
||||||
String name;
|
|
||||||
String type;
|
|
||||||
String mesh_names[ELEMENT_SOCKETS];
|
|
||||||
};
|
|
||||||
int grid_step{ 4 };
|
|
||||||
int grid_size{ 9 };
|
|
||||||
struct grid_cell {
|
|
||||||
String element;
|
|
||||||
int rotation;
|
|
||||||
};
|
|
||||||
struct grid_layouts {};
|
|
||||||
struct grid_layout {};
|
|
||||||
struct grid_layout_base {
|
|
||||||
int floor_count;
|
|
||||||
};
|
|
||||||
struct grid_layout_exterior {};
|
|
||||||
struct grid_layout_interior {};
|
|
||||||
struct grid_floor {};
|
|
||||||
struct grid_floor_item {
|
|
||||||
int index;
|
|
||||||
String element;
|
|
||||||
int rotation;
|
|
||||||
};
|
|
||||||
struct grid_floor_item_node {
|
|
||||||
Spatial *node;
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ElementData()
|
|
||||||
{
|
|
||||||
ecs.component<struct grid_layouts>();
|
|
||||||
ecs.component<struct grid_layout>();
|
|
||||||
ecs.component<struct grid_layout_exterior>();
|
|
||||||
ecs.component<struct grid_layout_interior>();
|
|
||||||
ecs.component<struct grid_floor>();
|
|
||||||
ecs.component<struct grid_floor_item>();
|
|
||||||
ecs.component<struct grid_floor_item_node>();
|
|
||||||
flecs::entity e = ecs.entity("grid_layouts");
|
|
||||||
e.add<grid_layouts>();
|
|
||||||
create_new_layout("default");
|
|
||||||
create_new_exterior_floor("default");
|
|
||||||
create_new_interior_floor("default");
|
|
||||||
load_data();
|
|
||||||
struct grid_element_type t_empty;
|
|
||||||
struct grid_element e_empty;
|
|
||||||
t_empty.name = "empty";
|
|
||||||
e_empty.name = "empty";
|
|
||||||
e_empty.type = "empty";
|
|
||||||
element_type["empty"] = t_empty;
|
|
||||||
elements["empty"] = e_empty;
|
|
||||||
ecs.observer<struct grid_floor_item_node>()
|
|
||||||
.event(flecs::OnRemove)
|
|
||||||
.each([](flecs::entity em,
|
|
||||||
struct grid_floor_item_node &s) {
|
|
||||||
if (s.node)
|
|
||||||
s.node->queue_delete();
|
|
||||||
s.node = nullptr;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
HashMap<String, struct grid_element_type> element_type;
|
|
||||||
HashMap<String, struct grid_element> elements;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void create_new_layout(const String &key)
|
|
||||||
{
|
|
||||||
flecs::entity top = ecs.lookup("grid_layouts");
|
|
||||||
assert(top.is_valid());
|
|
||||||
flecs::entity layout =
|
|
||||||
ecs.entity(key.ascii().ptr()).child_of(top);
|
|
||||||
// one floor by default
|
|
||||||
layout.add<struct grid_layout>();
|
|
||||||
flecs::entity extr = ecs.entity("exterior").child_of(layout);
|
|
||||||
extr.add<grid_layout_exterior>();
|
|
||||||
flecs::entity intr = ecs.entity("interior").child_of(layout);
|
|
||||||
intr.add<grid_layout_interior>();
|
|
||||||
intr.set<grid_layout_base>({ 0 });
|
|
||||||
extr.set<grid_layout_base>({ 0 });
|
|
||||||
}
|
|
||||||
void create_new_exterior_floor(const String &key)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
flecs::entity ext = get_base(key, true);
|
|
||||||
assert(ext.is_valid());
|
|
||||||
struct grid_layout_base *l = ext.get_mut<grid_layout_base>();
|
|
||||||
int floor = l->floor_count;
|
|
||||||
flecs::entity fl =
|
|
||||||
ecs.entity(("floor_" + itos(floor)).ascii().ptr())
|
|
||||||
.child_of(ext);
|
|
||||||
assert(fl.is_valid());
|
|
||||||
|
|
||||||
for (i = 0; i < grid_size * grid_size; i++) {
|
|
||||||
flecs::entity item =
|
|
||||||
ecs.entity(("item_" + itos(i)).ascii().ptr())
|
|
||||||
.child_of(fl);
|
|
||||||
item.set<grid_floor_item>({ i, "empty", 0 });
|
|
||||||
}
|
|
||||||
l->floor_count++;
|
|
||||||
}
|
|
||||||
void create_new_interior_floor(const String &key)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
flecs::entity intr = get_base(key, false);
|
|
||||||
assert(intr.is_valid());
|
|
||||||
struct grid_layout_base *l = intr.get_mut<grid_layout_base>();
|
|
||||||
int floor = l->floor_count;
|
|
||||||
flecs::entity fl =
|
|
||||||
ecs.entity(("floor_" + itos(floor)).ascii().ptr())
|
|
||||||
.child_of(intr);
|
|
||||||
assert(fl.is_valid());
|
|
||||||
|
|
||||||
for (i = 0; i < grid_size * grid_size; i++) {
|
|
||||||
flecs::entity item =
|
|
||||||
ecs.entity(("item_" + itos(i)).ascii().ptr())
|
|
||||||
.child_of(fl);
|
|
||||||
item.set<grid_floor_item>({ i, "empty", 0 });
|
|
||||||
}
|
|
||||||
l->floor_count++;
|
|
||||||
}
|
|
||||||
inline int constexpr get_grid_size()
|
|
||||||
{
|
|
||||||
return grid_size;
|
|
||||||
}
|
|
||||||
flecs::entity get_base(const String &key, bool exterior) const
|
|
||||||
{
|
|
||||||
flecs::entity top = ecs.lookup("grid_layouts");
|
|
||||||
assert(top.is_valid());
|
|
||||||
flecs::entity layout = top.lookup(key.ascii().ptr());
|
|
||||||
assert(layout.is_valid());
|
|
||||||
flecs::entity base;
|
|
||||||
if (exterior)
|
|
||||||
base = layout.lookup("exterior");
|
|
||||||
else
|
|
||||||
base = layout.lookup("interior");
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
flecs::entity get_floor(const String &key, bool exterior, int fl) const
|
|
||||||
{
|
|
||||||
flecs::entity base = get_base(key, exterior);
|
|
||||||
assert(base.is_valid());
|
|
||||||
String floor_key = "floor_" + itos(fl);
|
|
||||||
flecs::entity floor_e = base.lookup(floor_key.ascii().ptr());
|
|
||||||
return floor_e;
|
|
||||||
}
|
|
||||||
bool has_floor(const String &key, bool exterior, int fl) const
|
|
||||||
{
|
|
||||||
flecs::entity floor_e = get_floor(key, exterior, fl);
|
|
||||||
if (!floor_e.is_valid())
|
|
||||||
return false;
|
|
||||||
flecs::entity item_e = floor_e.lookup("item_0");
|
|
||||||
return item_e.is_valid();
|
|
||||||
}
|
|
||||||
void ensure_floor(const String &key, bool exterior, int fl)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
if (has_floor(key, exterior, fl))
|
|
||||||
return;
|
|
||||||
flecs::entity base = get_base(key, exterior);
|
|
||||||
flecs::entity floor_e =
|
|
||||||
ecs.entity(("floor_" + itos(fl)).ascii().ptr())
|
|
||||||
.child_of(base);
|
|
||||||
assert(floor_e.is_valid());
|
|
||||||
for (i = 0; i < grid_size * grid_size; i++) {
|
|
||||||
flecs::entity item =
|
|
||||||
ecs.entity(("item_" + itos(i)).ascii().ptr())
|
|
||||||
.child_of(floor_e);
|
|
||||||
item.set<grid_floor_item>({ i, "empty", 0 });
|
|
||||||
}
|
|
||||||
assert(has_floor(key, exterior, fl));
|
|
||||||
print_line("ensured floor: " + itos(fl));
|
|
||||||
}
|
|
||||||
inline flecs::entity get_grid_entity(const String &key, bool exterior,
|
|
||||||
int fl, int i) const
|
|
||||||
{
|
|
||||||
flecs::entity base = get_floor(key, exterior, fl);
|
|
||||||
assert(base.is_valid());
|
|
||||||
String item_key = "item_" + itos(i);
|
|
||||||
flecs::entity item_data = base.lookup(item_key.ascii().ptr());
|
|
||||||
if (!item_data.is_valid())
|
|
||||||
print_error("lookup failed: " + item_key);
|
|
||||||
assert(item_data.is_valid());
|
|
||||||
return item_data;
|
|
||||||
}
|
|
||||||
inline const String &get_grid_element(const String &key, bool exterior,
|
|
||||||
int fl, int i) const
|
|
||||||
{
|
|
||||||
flecs::entity item_data = get_grid_entity(key, exterior, fl, i);
|
|
||||||
const String &element =
|
|
||||||
item_data.get<grid_floor_item>()->element;
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
inline int get_grid_rotation(const String &key, bool exterior, int fl,
|
|
||||||
int i) const
|
|
||||||
{
|
|
||||||
flecs::entity item_data = get_grid_entity(key, exterior, fl, i);
|
|
||||||
int rotation = item_data.get<grid_floor_item>()->rotation;
|
|
||||||
return rotation;
|
|
||||||
}
|
|
||||||
void set_grid_element(const String &key, bool exterior, int fl, int i,
|
|
||||||
const String &element)
|
|
||||||
{
|
|
||||||
flecs::entity item_data = get_grid_entity(key, exterior, fl, i);
|
|
||||||
item_data.get_mut<grid_floor_item>()->element = element;
|
|
||||||
}
|
|
||||||
void set_grid_rotation(const String &key, bool exterior, int fl, int i,
|
|
||||||
int rotation)
|
|
||||||
{
|
|
||||||
flecs::entity item_data = get_grid_entity(key, exterior, fl, i);
|
|
||||||
item_data.get_mut<grid_floor_item>()->rotation = rotation;
|
|
||||||
}
|
|
||||||
Spatial *get_grid_node(const String &key, bool exterior, int fl, int i)
|
|
||||||
{
|
|
||||||
assert(has_floor(key, exterior, fl));
|
|
||||||
flecs::entity item_data = get_grid_entity(key, exterior, fl, i);
|
|
||||||
if (!item_data.has<struct grid_floor_item_node>()) {
|
|
||||||
Spatial *sp = memnew(Spatial);
|
|
||||||
get_as_node<Spatial>("%bg_floor")
|
|
||||||
->call_deferred("add_child", sp);
|
|
||||||
item_data.set<struct grid_floor_item_node>({ sp });
|
|
||||||
int x = i % grid_size;
|
|
||||||
int z = i / grid_size;
|
|
||||||
int rotation = get_grid_rotation(key, exterior, fl, i);
|
|
||||||
sp->set_transform(Transform(
|
|
||||||
Basis().rotated(Vector3(0, 1, 0),
|
|
||||||
Math_PI * rotation / 2.0f),
|
|
||||||
Vector3((x - 4) * 4, 1 + 5 * fl, (z - 4) * 4) -
|
|
||||||
get_as_node<Spatial>("%bg_floor")
|
|
||||||
->get_transform()
|
|
||||||
.origin));
|
|
||||||
}
|
|
||||||
return item_data.get<struct grid_floor_item_node>()->node;
|
|
||||||
}
|
|
||||||
int get_closest_node_on_floor(const String &key, bool exterior, int fl,
|
|
||||||
const Vector3 &position)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
assert(has_floor(key, exterior, fl));
|
|
||||||
flecs::entity floor_e = get_floor(key, exterior, fl);
|
|
||||||
assert(floor_e.is_valid());
|
|
||||||
int selected = -1;
|
|
||||||
float dst = Math_INF;
|
|
||||||
for (i = 0; i < grid_size * grid_size; i++) {
|
|
||||||
Spatial *node = get_grid_node(key, exterior, fl, i);
|
|
||||||
Vector3 pos = node->get_transform().origin;
|
|
||||||
float mdst = position.distance_squared_to(pos);
|
|
||||||
if (dst > mdst) {
|
|
||||||
dst = mdst;
|
|
||||||
selected = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return selected;
|
|
||||||
}
|
|
||||||
void get_grid_layouts_key_list(List<String> *keys)
|
|
||||||
{
|
|
||||||
flecs::entity top = ecs.lookup("grid_layouts");
|
|
||||||
assert(top.is_valid());
|
|
||||||
flecs::query_builder<const struct grid_layout> qb =
|
|
||||||
ecs.query_builder<const struct grid_layout>().with(
|
|
||||||
flecs::ChildOf, top);
|
|
||||||
flecs::query<const struct grid_layout> q = qb.build();
|
|
||||||
q.each([keys](flecs::entity e, const struct grid_layout &data) {
|
|
||||||
keys->push_back(String(e.name()));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
void serialize_layouts(Dictionary &store)
|
|
||||||
{
|
|
||||||
flecs::entity top = ecs.lookup("grid_layouts");
|
|
||||||
assert(top.is_valid());
|
|
||||||
top.children([this, &store](flecs::entity l) {
|
|
||||||
Dictionary layout, exterior_layout, interior_layout;
|
|
||||||
if (l.has<struct grid_layout>()) {
|
|
||||||
flecs::entity intr = l.lookup("interior");
|
|
||||||
assert(intr.is_valid());
|
|
||||||
flecs::entity extr = l.lookup("exterior");
|
|
||||||
assert(extr.is_valid());
|
|
||||||
intr.children([this, &interior_layout](
|
|
||||||
flecs::entity intr_fl) {
|
|
||||||
if (intr_fl.has<struct grid_floor>()) {
|
|
||||||
Array items;
|
|
||||||
intr_fl.children([&items](
|
|
||||||
flecs::entity
|
|
||||||
floor_item) {
|
|
||||||
if (floor_item.has<
|
|
||||||
struct grid_floor_item>()) {
|
|
||||||
const struct grid_floor_item *item =
|
|
||||||
floor_item
|
|
||||||
.get<struct grid_floor_item>();
|
|
||||||
Dictionary sitem;
|
|
||||||
sitem["index"] =
|
|
||||||
item->index;
|
|
||||||
sitem["element"] =
|
|
||||||
item->element;
|
|
||||||
sitem["rotation"] =
|
|
||||||
item->rotation;
|
|
||||||
items.push_back(
|
|
||||||
sitem);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
String floor_key(
|
|
||||||
intr_fl.name());
|
|
||||||
interior_layout[floor_key] =
|
|
||||||
items;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
extr.children([this, &exterior_layout](
|
|
||||||
flecs::entity extr_fl) {
|
|
||||||
Array items;
|
|
||||||
extr_fl.children([&items](
|
|
||||||
flecs::entity
|
|
||||||
floor_item) {
|
|
||||||
if (floor_item.has<
|
|
||||||
struct grid_floor_item>()) {
|
|
||||||
const struct grid_floor_item *item =
|
|
||||||
floor_item.get<
|
|
||||||
struct grid_floor_item>();
|
|
||||||
Dictionary sitem;
|
|
||||||
sitem["index"] =
|
|
||||||
item->index;
|
|
||||||
sitem["element"] =
|
|
||||||
item->element;
|
|
||||||
sitem["rotation"] =
|
|
||||||
item->rotation;
|
|
||||||
items.push_back(sitem);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
String floor_key(extr_fl.name());
|
|
||||||
exterior_layout[floor_key] = items;
|
|
||||||
});
|
|
||||||
layout["interior"] = interior_layout;
|
|
||||||
layout["exterior"] = exterior_layout;
|
|
||||||
}
|
|
||||||
String layout_name(l.name());
|
|
||||||
store[layout_name] = layout;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
void unserialize_layouts(const Dictionary &store)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
flecs::entity top = ecs.lookup("grid_layouts");
|
|
||||||
assert(top.is_valid());
|
|
||||||
// delete all layouts
|
|
||||||
top.children([this](flecs::entity l) { l.destruct(); });
|
|
||||||
List<Variant> layout_keys;
|
|
||||||
store.get_key_list(&layout_keys);
|
|
||||||
List<Variant>::Element *e;
|
|
||||||
e = layout_keys.front();
|
|
||||||
while (e) {
|
|
||||||
String layout_name = e->get();
|
|
||||||
flecs::entity layout =
|
|
||||||
ecs.entity(layout_name.ascii().ptr())
|
|
||||||
.child_of(top);
|
|
||||||
layout.add<grid_layout>();
|
|
||||||
flecs::entity extr =
|
|
||||||
ecs.entity("exterior").child_of(layout);
|
|
||||||
extr.add<grid_layout_exterior>();
|
|
||||||
extr.set<grid_layout_base>({ 0 });
|
|
||||||
flecs::entity intr =
|
|
||||||
ecs.entity("interior").child_of(layout);
|
|
||||||
intr.add<grid_layout_interior>();
|
|
||||||
intr.set<grid_layout_base>({ 0 });
|
|
||||||
Dictionary store_layout = store[e->get()];
|
|
||||||
Dictionary store_interior = store_layout["interior"];
|
|
||||||
Dictionary store_exterior = store_layout["exterior"];
|
|
||||||
List<Variant>::Element *ve;
|
|
||||||
List<Variant> interior_keys;
|
|
||||||
List<Variant> exterior_keys;
|
|
||||||
store_interior.get_key_list(&interior_keys);
|
|
||||||
store_exterior.get_key_list(&exterior_keys);
|
|
||||||
for (ve = interior_keys.front(); ve; ve = ve->next()) {
|
|
||||||
String floor_key = ve->get();
|
|
||||||
if (floor_key.begins_with("floor_")) {
|
|
||||||
flecs::entity floor_e =
|
|
||||||
ecs.entity(floor_key.ascii()
|
|
||||||
.ptr())
|
|
||||||
.child_of(intr);
|
|
||||||
assert(floor_e.is_valid());
|
|
||||||
floor_e.add<struct grid_floor>();
|
|
||||||
const Array &floor_interior =
|
|
||||||
store_interior[floor_key];
|
|
||||||
for (i = 0; i < floor_interior.size();
|
|
||||||
i++) {
|
|
||||||
const Dictionary &item =
|
|
||||||
floor_interior[i];
|
|
||||||
int index = item["index"];
|
|
||||||
String element =
|
|
||||||
item["element"];
|
|
||||||
int rotation = item["rotation"];
|
|
||||||
String item_key =
|
|
||||||
"item_" + itos(index);
|
|
||||||
flecs::entity item_e =
|
|
||||||
ecs.entity(item_key.ascii()
|
|
||||||
.ptr())
|
|
||||||
.child_of(
|
|
||||||
floor_e);
|
|
||||||
item_e.set<grid_floor_item>(
|
|
||||||
{ index, element,
|
|
||||||
rotation });
|
|
||||||
}
|
|
||||||
struct grid_layout_base *l = intr.get_mut<
|
|
||||||
struct grid_layout_base>();
|
|
||||||
l->floor_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (ve = exterior_keys.front(); ve; ve = ve->next()) {
|
|
||||||
String floor_key = ve->get();
|
|
||||||
if (floor_key.begins_with("floor_")) {
|
|
||||||
flecs::entity floor_e =
|
|
||||||
ecs.entity(floor_key.ascii()
|
|
||||||
.ptr())
|
|
||||||
.child_of(extr);
|
|
||||||
assert(floor_e.is_valid());
|
|
||||||
floor_e.add<struct grid_floor>();
|
|
||||||
const Array &floor_exterior =
|
|
||||||
store_exterior[floor_key];
|
|
||||||
for (i = 0; i < floor_exterior.size();
|
|
||||||
i++) {
|
|
||||||
const Dictionary &item =
|
|
||||||
floor_exterior[i];
|
|
||||||
int index = item["index"];
|
|
||||||
String element =
|
|
||||||
item["element"];
|
|
||||||
int rotation = item["rotation"];
|
|
||||||
String item_key =
|
|
||||||
"item_" + itos(index);
|
|
||||||
flecs::entity item_e =
|
|
||||||
ecs.entity(item_key.ascii()
|
|
||||||
.ptr())
|
|
||||||
.child_of(
|
|
||||||
floor_e);
|
|
||||||
item_e.set<grid_floor_item>(
|
|
||||||
{ index, element,
|
|
||||||
rotation });
|
|
||||||
}
|
|
||||||
struct grid_layout_base *l = extr.get_mut<
|
|
||||||
struct grid_layout_base>();
|
|
||||||
l->floor_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
e = e->next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void get_element_type_key_list(List<String> *keys)
|
|
||||||
{
|
|
||||||
element_type.get_key_list(keys);
|
|
||||||
}
|
|
||||||
void create_element_type(const String &key)
|
|
||||||
{
|
|
||||||
assert(!element_type.has(key));
|
|
||||||
struct grid_element_type g;
|
|
||||||
g.name = key;
|
|
||||||
element_type[key] = g;
|
|
||||||
}
|
|
||||||
void set_element_type_socket(const String &key, int socket,
|
|
||||||
const Transform &xform)
|
|
||||||
{
|
|
||||||
assert(element_type.has(key));
|
|
||||||
assert(socket >= 0 && socket < ELEMENT_SOCKETS);
|
|
||||||
element_type[key].sockets[socket] = xform;
|
|
||||||
}
|
|
||||||
void set_element_type_name(const String &key, const String &name)
|
|
||||||
{
|
|
||||||
assert(element_type.has(key));
|
|
||||||
element_type[key].name = name;
|
|
||||||
}
|
|
||||||
bool has_element_type(const String &key)
|
|
||||||
{
|
|
||||||
return element_type.has(key);
|
|
||||||
}
|
|
||||||
Transform get_element_type_socket(const String &key, int socket)
|
|
||||||
{
|
|
||||||
assert(element_type.has(key));
|
|
||||||
assert(socket >= 0 && socket < ELEMENT_SOCKETS);
|
|
||||||
return element_type[key].sockets[socket];
|
|
||||||
}
|
|
||||||
int get_element_type_size()
|
|
||||||
{
|
|
||||||
return element_type.size();
|
|
||||||
}
|
|
||||||
void create_element(const String &key, const String &type)
|
|
||||||
{
|
|
||||||
struct grid_element g;
|
|
||||||
assert(!elements.has(key));
|
|
||||||
assert(element_type.has(type));
|
|
||||||
g.name = key;
|
|
||||||
g.type = type;
|
|
||||||
elements[key] = g;
|
|
||||||
}
|
|
||||||
void set_element_type(const String &key, const String &type)
|
|
||||||
{
|
|
||||||
assert(elements.has(key));
|
|
||||||
assert(element_type.has(type));
|
|
||||||
elements[key].type = type;
|
|
||||||
}
|
|
||||||
const String &get_element_type(const String &key) const
|
|
||||||
{
|
|
||||||
assert(elements.has(key));
|
|
||||||
return elements[key].type;
|
|
||||||
}
|
|
||||||
void set_element_mesh_name(const String &key, int socket,
|
|
||||||
const String &mesh_name)
|
|
||||||
{
|
|
||||||
assert(elements.has(key));
|
|
||||||
assert(socket >= 0 && socket < ELEMENT_SOCKETS);
|
|
||||||
elements[key].mesh_names[socket] = mesh_name;
|
|
||||||
}
|
|
||||||
const String &get_element_mesh_name(const String &key, int socket)
|
|
||||||
{
|
|
||||||
assert(elements.has(key));
|
|
||||||
assert(socket >= 0 && socket < ELEMENT_SOCKETS);
|
|
||||||
return elements[key].mesh_names[socket];
|
|
||||||
}
|
|
||||||
int get_element_size()
|
|
||||||
{
|
|
||||||
return elements.size();
|
|
||||||
}
|
|
||||||
void get_element_key_list(List<String> *keys)
|
|
||||||
{
|
|
||||||
elements.get_key_list(keys);
|
|
||||||
}
|
|
||||||
bool has_element(const String &key)
|
|
||||||
{
|
|
||||||
return elements.has(key);
|
|
||||||
}
|
|
||||||
void save_data()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
ConfigFile config;
|
|
||||||
Dictionary conf_element_types;
|
|
||||||
Dictionary conf_elements;
|
|
||||||
Dictionary conf_exterior_grid;
|
|
||||||
List<String> keys;
|
|
||||||
List<String>::Element *e;
|
|
||||||
element_type.get_key_list(&keys);
|
|
||||||
e = keys.front();
|
|
||||||
while (e) {
|
|
||||||
Dictionary item;
|
|
||||||
const struct grid_element_type &g =
|
|
||||||
element_type[e->get()];
|
|
||||||
if (e->get() == "empty") {
|
|
||||||
e = e->next();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
item["name"] = e->get();
|
|
||||||
Array sockets;
|
|
||||||
sockets.resize(ELEMENT_SOCKETS);
|
|
||||||
for (i = 0; i < ELEMENT_SOCKETS; i++)
|
|
||||||
sockets[i] = g.sockets[i];
|
|
||||||
item["sockets"] = sockets;
|
|
||||||
|
|
||||||
conf_element_types[e->get()] = item;
|
|
||||||
e = e->next();
|
|
||||||
}
|
|
||||||
keys.clear();
|
|
||||||
elements.get_key_list(&keys);
|
|
||||||
e = keys.front();
|
|
||||||
while (e) {
|
|
||||||
Dictionary item;
|
|
||||||
const struct grid_element &g = elements[e->get()];
|
|
||||||
if (e->get() == "empty") {
|
|
||||||
e = e->next();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
item["name"] = e->get();
|
|
||||||
item["type"] = g.type;
|
|
||||||
Array mesh_names;
|
|
||||||
mesh_names.resize(ELEMENT_SOCKETS);
|
|
||||||
for (i = 0; i < ELEMENT_SOCKETS; i++)
|
|
||||||
mesh_names[i] = g.mesh_names[i];
|
|
||||||
item["mesh_names"] = mesh_names;
|
|
||||||
|
|
||||||
conf_elements[e->get()] = item;
|
|
||||||
e = e->next();
|
|
||||||
}
|
|
||||||
// TODO: support multiple layouts;
|
|
||||||
serialize_layouts(conf_exterior_grid);
|
|
||||||
|
|
||||||
config.set_value("buildings_layout", "element_types",
|
|
||||||
conf_element_types);
|
|
||||||
config.set_value("buildings_layout", "elements", conf_elements);
|
|
||||||
config.set_value("buildings_layout", "grid_layouts",
|
|
||||||
conf_exterior_grid);
|
|
||||||
config.save("res://astream/blayout.conf");
|
|
||||||
}
|
|
||||||
void load_data()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
ConfigFile config;
|
|
||||||
Dictionary conf_element_types;
|
|
||||||
Dictionary conf_elements;
|
|
||||||
Dictionary conf_grid_layouts;
|
|
||||||
List<Variant> keys;
|
|
||||||
List<Variant>::Element *e;
|
|
||||||
elements.clear();
|
|
||||||
element_type.clear();
|
|
||||||
config.load("res://astream/blayout.conf");
|
|
||||||
conf_element_types = config.get_value(
|
|
||||||
"buildings_layout", "element_types", Dictionary());
|
|
||||||
conf_elements = config.get_value("buildings_layout", "elements",
|
|
||||||
Dictionary());
|
|
||||||
conf_grid_layouts = config.get_value(
|
|
||||||
"buildings_layout", "grid_layouts", Dictionary());
|
|
||||||
conf_element_types.get_key_list(&keys);
|
|
||||||
e = keys.front();
|
|
||||||
while (e) {
|
|
||||||
String key = e->get();
|
|
||||||
Dictionary item = conf_element_types[key];
|
|
||||||
assert(item.has("sockets"));
|
|
||||||
create_element_type(key);
|
|
||||||
Array sockets = item["sockets"];
|
|
||||||
for (i = 0; i < sockets.size(); i++)
|
|
||||||
set_element_type_socket(key, i, sockets[i]);
|
|
||||||
e = e->next();
|
|
||||||
}
|
|
||||||
keys.clear();
|
|
||||||
conf_elements.get_key_list(&keys);
|
|
||||||
e = keys.front();
|
|
||||||
while (e) {
|
|
||||||
String key = e->get();
|
|
||||||
Dictionary item = conf_elements[key];
|
|
||||||
assert(item.has("type"));
|
|
||||||
assert(item.has("mesh_names"));
|
|
||||||
String type = item["type"];
|
|
||||||
print_line("loading element: " + key +
|
|
||||||
" type: " + type);
|
|
||||||
if (key == "empty") {
|
|
||||||
e = e->next();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
create_element(key, type);
|
|
||||||
Array mesh_names = item["mesh_names"];
|
|
||||||
for (i = 0; i < mesh_names.size(); i++)
|
|
||||||
set_element_mesh_name(key, i, mesh_names[i]);
|
|
||||||
e = e->next();
|
|
||||||
}
|
|
||||||
unserialize_layouts(conf_grid_layouts);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ElementData *ElementData::singleton = nullptr;
|
|
||||||
|
|
||||||
class LayoutEditor : public Object {
|
class LayoutEditor : public Object {
|
||||||
GDCLASS(LayoutEditor, Object)
|
GDCLASS(LayoutEditor, Object)
|
||||||
BuildingLayoutEditor *editor;
|
BuildingLayoutEditor *editor;
|
||||||
@@ -737,6 +28,7 @@ class LayoutEditor : public Object {
|
|||||||
String current_layout;
|
String current_layout;
|
||||||
bool is_exterior;
|
bool is_exterior;
|
||||||
int current_floor;
|
int current_floor;
|
||||||
|
String select_rotation;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LayoutEditor(BuildingLayoutEditor *editor)
|
LayoutEditor(BuildingLayoutEditor *editor)
|
||||||
@@ -748,6 +40,7 @@ public:
|
|||||||
, current_layout("default")
|
, current_layout("default")
|
||||||
, is_exterior(true)
|
, is_exterior(true)
|
||||||
, current_floor(0)
|
, current_floor(0)
|
||||||
|
, select_rotation("%select_rotation")
|
||||||
{
|
{
|
||||||
get_as_node<OptionButton>(grid_elements)
|
get_as_node<OptionButton>(grid_elements)
|
||||||
->connect("item_selected", this, "select_grid_element");
|
->connect("item_selected", this, "select_grid_element");
|
||||||
@@ -755,6 +48,11 @@ public:
|
|||||||
sb->connect("value_changed", this, "set_current_floor");
|
sb->connect("value_changed", this, "set_current_floor");
|
||||||
sb->set_min(-6);
|
sb->set_min(-6);
|
||||||
sb->set_max(6);
|
sb->set_max(6);
|
||||||
|
get_as_node<OptionButton>(select_rotation)
|
||||||
|
->connect("item_selected", this,
|
||||||
|
"select_grid_rotation");
|
||||||
|
get_as_node<Button>("%grow_cell_button")
|
||||||
|
->connect("pressed", this, "grow_cell");
|
||||||
}
|
}
|
||||||
virtual ~LayoutEditor()
|
virtual ~LayoutEditor()
|
||||||
{
|
{
|
||||||
@@ -892,6 +190,16 @@ public:
|
|||||||
current_cell);
|
current_cell);
|
||||||
select_control_item<OptionButton>(
|
select_control_item<OptionButton>(
|
||||||
"%grid_elements", element);
|
"%grid_elements", element);
|
||||||
|
int rotation =
|
||||||
|
ElementData::get_singleton()
|
||||||
|
->get_grid_rotation(
|
||||||
|
current_layout,
|
||||||
|
is_exterior,
|
||||||
|
current_floor,
|
||||||
|
current_cell);
|
||||||
|
get_as_node<OptionButton>(
|
||||||
|
"%select_rotation")
|
||||||
|
->select(rotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -922,12 +230,53 @@ public:
|
|||||||
current_layout, is_exterior,
|
current_layout, is_exterior,
|
||||||
current_floor, current_cell));
|
current_floor, current_cell));
|
||||||
}
|
}
|
||||||
|
void select_grid_rotation(int index)
|
||||||
|
{
|
||||||
|
print_line("rotation: " + itos(index));
|
||||||
|
const String &element =
|
||||||
|
ElementData::get_singleton()->get_grid_element(
|
||||||
|
current_layout, is_exterior, current_floor,
|
||||||
|
current_cell);
|
||||||
|
ElementData::get_singleton()->set_grid_rotation(
|
||||||
|
current_layout, is_exterior, current_floor,
|
||||||
|
current_cell, index);
|
||||||
|
editor->visualize_element_at(
|
||||||
|
element, ElementData::get_singleton()->get_grid_node(
|
||||||
|
current_layout, is_exterior,
|
||||||
|
current_floor, current_cell));
|
||||||
|
}
|
||||||
|
void grow_cell()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
ElementData::get_singleton()->grow_cell(current_layout,
|
||||||
|
is_exterior,
|
||||||
|
current_floor,
|
||||||
|
current_cell);
|
||||||
|
int grid_size = ElementData::get_singleton()->get_grid_size();
|
||||||
|
for (i = 0; i < grid_size * grid_size; i++) {
|
||||||
|
Spatial *sp =
|
||||||
|
ElementData::get_singleton()->get_grid_node(
|
||||||
|
current_layout, is_exterior,
|
||||||
|
current_floor, i);
|
||||||
|
const String &element =
|
||||||
|
ElementData::get_singleton()->get_grid_element(
|
||||||
|
current_layout, is_exterior,
|
||||||
|
current_floor, i);
|
||||||
|
editor->visualize_element_at(element, sp);
|
||||||
|
}
|
||||||
|
print_line("grow_cell");
|
||||||
|
}
|
||||||
|
|
||||||
static void _bind_methods()
|
static void _bind_methods()
|
||||||
{
|
{
|
||||||
ClassDB::bind_method(D_METHOD("select_grid_element", "index"),
|
ClassDB::bind_method(D_METHOD("select_grid_element", "index"),
|
||||||
&LayoutEditor::select_grid_element);
|
&LayoutEditor::select_grid_element);
|
||||||
ClassDB::bind_method(D_METHOD("set_current_floor", "value"),
|
ClassDB::bind_method(D_METHOD("set_current_floor", "value"),
|
||||||
&LayoutEditor::set_current_floor);
|
&LayoutEditor::set_current_floor);
|
||||||
|
ClassDB::bind_method(D_METHOD("select_grid_rotation", "index"),
|
||||||
|
&LayoutEditor::select_grid_rotation);
|
||||||
|
ClassDB::bind_method(D_METHOD("grow_cell"),
|
||||||
|
&LayoutEditor::grow_cell);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
123
src/modules/stream/buildings/element_data.cpp
Normal file
123
src/modules/stream/buildings/element_data.cpp
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
#undef NDEBUG
|
||||||
|
#include "element_data.h"
|
||||||
|
ElementData *ElementData::singleton = nullptr;
|
||||||
|
List<int> ElementData::get_grow_cells(const String &key, bool exterior, int fl,
|
||||||
|
int cell) const
|
||||||
|
{
|
||||||
|
List<int> grow_cells;
|
||||||
|
int x = cell % grid_size;
|
||||||
|
int z = cell / grid_size;
|
||||||
|
bool grow_west = true, grow_south = true, grow_east = true,
|
||||||
|
grow_north = true;
|
||||||
|
if (x == 0)
|
||||||
|
grow_west = false;
|
||||||
|
else if (x >= grid_size - 1)
|
||||||
|
grow_east = false;
|
||||||
|
if (z == 0)
|
||||||
|
grow_south = false;
|
||||||
|
else if (z >= grid_size - 1)
|
||||||
|
grow_north = false;
|
||||||
|
if (grow_west) {
|
||||||
|
int cell_ = (x - 1) + z * grid_size;
|
||||||
|
grow_cells.push_back(cell_);
|
||||||
|
}
|
||||||
|
if (grow_west && grow_south) {
|
||||||
|
int cell_ = (x - 1) + (z - 1) * grid_size;
|
||||||
|
grow_cells.push_back(cell_);
|
||||||
|
}
|
||||||
|
if (grow_south) {
|
||||||
|
int cell_ = x + (z - 1) * grid_size;
|
||||||
|
grow_cells.push_back(cell_);
|
||||||
|
}
|
||||||
|
if (grow_south && grow_east) {
|
||||||
|
int cell_ = (x + 1) + (z - 1) * grid_size;
|
||||||
|
grow_cells.push_back(cell_);
|
||||||
|
}
|
||||||
|
if (grow_east) {
|
||||||
|
int cell_ = (x + 1) + z * grid_size;
|
||||||
|
grow_cells.push_back(cell_);
|
||||||
|
}
|
||||||
|
if (grow_east && grow_north) {
|
||||||
|
int cell_ = (x + 1) + (z + 1) * grid_size;
|
||||||
|
grow_cells.push_back(cell_);
|
||||||
|
}
|
||||||
|
if (grow_north) {
|
||||||
|
int cell_ = x + (z + 1) * grid_size;
|
||||||
|
grow_cells.push_back(cell_);
|
||||||
|
}
|
||||||
|
if (grow_north && grow_west) {
|
||||||
|
int cell_ = (x - 1) + (z + 1) * grid_size;
|
||||||
|
grow_cells.push_back(cell_);
|
||||||
|
}
|
||||||
|
return grow_cells;
|
||||||
|
}
|
||||||
|
void ElementData::grow_cell(const String &key, bool exterior, int fl, int cell)
|
||||||
|
{
|
||||||
|
List<int> queue;
|
||||||
|
List<int> input_cells;
|
||||||
|
List<int> output_cells;
|
||||||
|
const String &element = get_grid_element(key, exterior, fl, cell);
|
||||||
|
print_line("grow_cell: " + element);
|
||||||
|
if (element == "empty")
|
||||||
|
return;
|
||||||
|
int rotation = get_grid_rotation(key, exterior, fl, cell);
|
||||||
|
queue.push_back(cell);
|
||||||
|
// collect all the same elements adjacent to current one
|
||||||
|
while (!queue.empty()) {
|
||||||
|
int c = queue.front()->get();
|
||||||
|
queue.pop_front();
|
||||||
|
const String &el = get_grid_element(key, exterior, fl, c);
|
||||||
|
int rot = get_grid_rotation(key, exterior, fl, c);
|
||||||
|
if (el == element && rot == rotation) {
|
||||||
|
print_line("adding cell: " + itos(c));
|
||||||
|
// do not place original cell in inputs
|
||||||
|
if (input_cells.find(c) == nullptr)
|
||||||
|
input_cells.push_back(c);
|
||||||
|
List<int> cells = get_grow_cells(key, exterior, fl, c);
|
||||||
|
while (!cells.empty()) {
|
||||||
|
int item = cells.front()->get();
|
||||||
|
cells.pop_front();
|
||||||
|
if (input_cells.find(item) == nullptr &&
|
||||||
|
queue.find(item) == nullptr)
|
||||||
|
queue.push_back(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print_line("input_cells: " + itos(input_cells.size()));
|
||||||
|
queue = input_cells;
|
||||||
|
while (!queue.empty()) {
|
||||||
|
int c = queue.front()->get();
|
||||||
|
queue.pop_front();
|
||||||
|
const String &el = get_grid_element(key, exterior, fl, c);
|
||||||
|
if (el == element) {
|
||||||
|
List<int> cells = get_grow_cells(key, exterior, fl, c);
|
||||||
|
while (!cells.empty()) {
|
||||||
|
int g = cells.front()->get();
|
||||||
|
cells.pop_front();
|
||||||
|
const String &em =
|
||||||
|
get_grid_element(key, exterior, fl, g);
|
||||||
|
if (em == "empty" && queue.find(g) == nullptr)
|
||||||
|
queue.push_back(g);
|
||||||
|
}
|
||||||
|
} else if (el == "empty") {
|
||||||
|
if (output_cells.find(c) == nullptr)
|
||||||
|
output_cells.push_back(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
queue = output_cells;
|
||||||
|
while (!queue.empty()) {
|
||||||
|
int c = queue.front()->get();
|
||||||
|
queue.pop_front();
|
||||||
|
const String &cell_element =
|
||||||
|
get_grid_element(key, exterior, fl, c);
|
||||||
|
assert(cell_element == "empty");
|
||||||
|
if (cell_element == "empty") {
|
||||||
|
set_grid_element(key, exterior, fl, c, element);
|
||||||
|
set_grid_rotation(key, exterior, fl, c, rotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print_line("initial cell: " + itos(cell));
|
||||||
|
print_line("input_cells: " + itos(input_cells.size()));
|
||||||
|
print_line("output_cells: " + itos(output_cells.size()));
|
||||||
|
}
|
||||||
729
src/modules/stream/buildings/element_data.h
Normal file
729
src/modules/stream/buildings/element_data.h
Normal file
@@ -0,0 +1,729 @@
|
|||||||
|
#ifndef ELEMENT_DATA_H
|
||||||
|
#define ELEMENT_DATA_H
|
||||||
|
#include <vector>
|
||||||
|
#include <core/ustring.h>
|
||||||
|
#include <scene/main/node.h>
|
||||||
|
#include <core/engine.h>
|
||||||
|
#include <editor/editor_node.h>
|
||||||
|
#include <flecs/flecs.h>
|
||||||
|
template <class T> T *get_as_node(const String &path)
|
||||||
|
{
|
||||||
|
Node *scene;
|
||||||
|
if (Engine::get_singleton()->is_editor_hint())
|
||||||
|
scene = EditorNode::get_singleton()->get_edited_scene();
|
||||||
|
else
|
||||||
|
scene = SceneTree::get_singleton()->get_current_scene();
|
||||||
|
assert(scene);
|
||||||
|
Node *node = scene->get_node(NodePath(path));
|
||||||
|
if (!node)
|
||||||
|
print_error("Failed to get " + path);
|
||||||
|
assert(node);
|
||||||
|
T *ret = Object::cast_to<T>(node);
|
||||||
|
if (!ret)
|
||||||
|
print_error("Failed to assign " + path);
|
||||||
|
assert(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void select_control_item(const String &path, const String &item)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
T *ctl = get_as_node<T>(path);
|
||||||
|
int selected = -1;
|
||||||
|
for (i = 0; i < ctl->get_item_count(); i++)
|
||||||
|
if (ctl->get_item_text(i) == item) {
|
||||||
|
selected = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (selected >= 0) {
|
||||||
|
ctl->select(selected);
|
||||||
|
print_line("selected: " + item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <class T> void select_control_item(T *ctl, const String &item)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int selected = -1;
|
||||||
|
for (i = 0; i < ctl->get_item_count(); i++)
|
||||||
|
if (ctl->get_item_text(i) == item) {
|
||||||
|
selected = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (selected >= 0) {
|
||||||
|
ctl->select(selected);
|
||||||
|
print_line("selected: " + item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#define ELEMENT_SOCKETS 16
|
||||||
|
class ElementData {
|
||||||
|
flecs::world ecs;
|
||||||
|
static ElementData *singleton;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static ElementData *get_singleton()
|
||||||
|
{
|
||||||
|
if (!singleton)
|
||||||
|
singleton = memnew(ElementData);
|
||||||
|
return singleton;
|
||||||
|
}
|
||||||
|
static void cleanup()
|
||||||
|
{
|
||||||
|
if (singleton)
|
||||||
|
memdelete(singleton);
|
||||||
|
}
|
||||||
|
struct grid_element_type {
|
||||||
|
String name;
|
||||||
|
Transform sockets[ELEMENT_SOCKETS];
|
||||||
|
};
|
||||||
|
struct grid_element {
|
||||||
|
String name;
|
||||||
|
String type;
|
||||||
|
String mesh_names[ELEMENT_SOCKETS];
|
||||||
|
};
|
||||||
|
int grid_step{ 4 };
|
||||||
|
int grid_size{ 9 };
|
||||||
|
struct grid_cell {
|
||||||
|
String element;
|
||||||
|
int rotation;
|
||||||
|
};
|
||||||
|
struct grid_layouts {};
|
||||||
|
struct grid_layout {};
|
||||||
|
struct grid_layout_base {
|
||||||
|
int floor_count;
|
||||||
|
};
|
||||||
|
struct grid_layout_exterior {};
|
||||||
|
struct grid_layout_interior {};
|
||||||
|
struct grid_floor {};
|
||||||
|
struct grid_floor_item {
|
||||||
|
int index;
|
||||||
|
String element;
|
||||||
|
int rotation;
|
||||||
|
};
|
||||||
|
struct grid_floor_item_node {
|
||||||
|
Spatial *node;
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ElementData()
|
||||||
|
{
|
||||||
|
ecs.component<struct grid_layouts>();
|
||||||
|
ecs.component<struct grid_layout>();
|
||||||
|
ecs.component<struct grid_layout_exterior>();
|
||||||
|
ecs.component<struct grid_layout_interior>();
|
||||||
|
ecs.component<struct grid_floor>();
|
||||||
|
ecs.component<struct grid_floor_item>();
|
||||||
|
ecs.component<struct grid_floor_item_node>();
|
||||||
|
flecs::entity e = ecs.entity("grid_layouts");
|
||||||
|
e.add<grid_layouts>();
|
||||||
|
create_new_layout("default");
|
||||||
|
create_new_exterior_floor("default");
|
||||||
|
create_new_interior_floor("default");
|
||||||
|
load_data();
|
||||||
|
struct grid_element_type t_empty;
|
||||||
|
struct grid_element e_empty;
|
||||||
|
t_empty.name = "empty";
|
||||||
|
e_empty.name = "empty";
|
||||||
|
e_empty.type = "empty";
|
||||||
|
element_type["empty"] = t_empty;
|
||||||
|
elements["empty"] = e_empty;
|
||||||
|
ecs.observer<struct grid_floor_item_node>()
|
||||||
|
.event(flecs::OnRemove)
|
||||||
|
.each([](flecs::entity em,
|
||||||
|
struct grid_floor_item_node &s) {
|
||||||
|
if (s.node)
|
||||||
|
s.node->queue_delete();
|
||||||
|
s.node = nullptr;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
HashMap<String, struct grid_element_type> element_type;
|
||||||
|
HashMap<String, struct grid_element> elements;
|
||||||
|
|
||||||
|
public:
|
||||||
|
List<int> get_grow_cells(const String &key, bool exterior, int fl,
|
||||||
|
int cell) const;
|
||||||
|
void grow_cell(const String &key, bool exterior, int fl, int cell);
|
||||||
|
void create_new_layout(const String &key)
|
||||||
|
{
|
||||||
|
flecs::entity top = ecs.lookup("grid_layouts");
|
||||||
|
assert(top.is_valid());
|
||||||
|
flecs::entity layout =
|
||||||
|
ecs.entity(key.ascii().ptr()).child_of(top);
|
||||||
|
// one floor by default
|
||||||
|
layout.add<struct grid_layout>();
|
||||||
|
flecs::entity extr = ecs.entity("exterior").child_of(layout);
|
||||||
|
extr.add<grid_layout_exterior>();
|
||||||
|
flecs::entity intr = ecs.entity("interior").child_of(layout);
|
||||||
|
intr.add<grid_layout_interior>();
|
||||||
|
intr.set<grid_layout_base>({ 0 });
|
||||||
|
extr.set<grid_layout_base>({ 0 });
|
||||||
|
}
|
||||||
|
void create_new_exterior_floor(const String &key)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
flecs::entity ext = get_base(key, true);
|
||||||
|
assert(ext.is_valid());
|
||||||
|
struct grid_layout_base *l = ext.get_mut<grid_layout_base>();
|
||||||
|
int floor = l->floor_count;
|
||||||
|
flecs::entity fl =
|
||||||
|
ecs.entity(("floor_" + itos(floor)).ascii().ptr())
|
||||||
|
.child_of(ext);
|
||||||
|
assert(fl.is_valid());
|
||||||
|
|
||||||
|
for (i = 0; i < grid_size * grid_size; i++) {
|
||||||
|
flecs::entity item =
|
||||||
|
ecs.entity(("item_" + itos(i)).ascii().ptr())
|
||||||
|
.child_of(fl);
|
||||||
|
item.set<grid_floor_item>({ i, "empty", 0 });
|
||||||
|
}
|
||||||
|
l->floor_count++;
|
||||||
|
}
|
||||||
|
void create_new_interior_floor(const String &key)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
flecs::entity intr = get_base(key, false);
|
||||||
|
assert(intr.is_valid());
|
||||||
|
struct grid_layout_base *l = intr.get_mut<grid_layout_base>();
|
||||||
|
int floor = l->floor_count;
|
||||||
|
flecs::entity fl =
|
||||||
|
ecs.entity(("floor_" + itos(floor)).ascii().ptr())
|
||||||
|
.child_of(intr);
|
||||||
|
assert(fl.is_valid());
|
||||||
|
|
||||||
|
for (i = 0; i < grid_size * grid_size; i++) {
|
||||||
|
flecs::entity item =
|
||||||
|
ecs.entity(("item_" + itos(i)).ascii().ptr())
|
||||||
|
.child_of(fl);
|
||||||
|
item.set<grid_floor_item>({ i, "empty", 0 });
|
||||||
|
}
|
||||||
|
l->floor_count++;
|
||||||
|
}
|
||||||
|
inline int constexpr get_grid_size()
|
||||||
|
{
|
||||||
|
return grid_size;
|
||||||
|
}
|
||||||
|
flecs::entity get_base(const String &key, bool exterior) const
|
||||||
|
{
|
||||||
|
flecs::entity top = ecs.lookup("grid_layouts");
|
||||||
|
assert(top.is_valid());
|
||||||
|
flecs::entity layout = top.lookup(key.ascii().ptr());
|
||||||
|
assert(layout.is_valid());
|
||||||
|
flecs::entity base;
|
||||||
|
if (exterior)
|
||||||
|
base = layout.lookup("exterior");
|
||||||
|
else
|
||||||
|
base = layout.lookup("interior");
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
flecs::entity get_floor(const String &key, bool exterior, int fl) const
|
||||||
|
{
|
||||||
|
flecs::entity base = get_base(key, exterior);
|
||||||
|
assert(base.is_valid());
|
||||||
|
String floor_key = "floor_" + itos(fl);
|
||||||
|
flecs::entity floor_e = base.lookup(floor_key.ascii().ptr());
|
||||||
|
return floor_e;
|
||||||
|
}
|
||||||
|
bool has_floor(const String &key, bool exterior, int fl) const
|
||||||
|
{
|
||||||
|
flecs::entity floor_e = get_floor(key, exterior, fl);
|
||||||
|
if (!floor_e.is_valid())
|
||||||
|
return false;
|
||||||
|
flecs::entity item_e = floor_e.lookup("item_0");
|
||||||
|
return item_e.is_valid();
|
||||||
|
}
|
||||||
|
void ensure_floor(const String &key, bool exterior, int fl)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (has_floor(key, exterior, fl))
|
||||||
|
return;
|
||||||
|
flecs::entity base = get_base(key, exterior);
|
||||||
|
flecs::entity floor_e =
|
||||||
|
ecs.entity(("floor_" + itos(fl)).ascii().ptr())
|
||||||
|
.child_of(base);
|
||||||
|
assert(floor_e.is_valid());
|
||||||
|
for (i = 0; i < grid_size * grid_size; i++) {
|
||||||
|
flecs::entity item =
|
||||||
|
ecs.entity(("item_" + itos(i)).ascii().ptr())
|
||||||
|
.child_of(floor_e);
|
||||||
|
item.set<grid_floor_item>({ i, "empty", 0 });
|
||||||
|
}
|
||||||
|
assert(has_floor(key, exterior, fl));
|
||||||
|
print_line("ensured floor: " + itos(fl));
|
||||||
|
}
|
||||||
|
inline flecs::entity get_grid_entity(const String &key, bool exterior,
|
||||||
|
int fl, int i) const
|
||||||
|
{
|
||||||
|
flecs::entity base = get_floor(key, exterior, fl);
|
||||||
|
assert(base.is_valid());
|
||||||
|
String item_key = "item_" + itos(i);
|
||||||
|
flecs::entity item_data = base.lookup(item_key.ascii().ptr());
|
||||||
|
if (!item_data.is_valid())
|
||||||
|
print_error("lookup failed: " + item_key);
|
||||||
|
assert(item_data.is_valid());
|
||||||
|
return item_data;
|
||||||
|
}
|
||||||
|
inline const String &get_grid_element(const String &key, bool exterior,
|
||||||
|
int fl, int i) const
|
||||||
|
{
|
||||||
|
flecs::entity item_data = get_grid_entity(key, exterior, fl, i);
|
||||||
|
const String &element =
|
||||||
|
item_data.get<grid_floor_item>()->element;
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
inline int get_grid_rotation(const String &key, bool exterior, int fl,
|
||||||
|
int i) const
|
||||||
|
{
|
||||||
|
flecs::entity item_data = get_grid_entity(key, exterior, fl, i);
|
||||||
|
int rotation = item_data.get<grid_floor_item>()->rotation;
|
||||||
|
return rotation;
|
||||||
|
}
|
||||||
|
void set_grid_element(const String &key, bool exterior, int fl, int i,
|
||||||
|
const String &element)
|
||||||
|
{
|
||||||
|
flecs::entity item_data = get_grid_entity(key, exterior, fl, i);
|
||||||
|
item_data.get_mut<grid_floor_item>()->element = element;
|
||||||
|
}
|
||||||
|
void set_grid_rotation(const String &key, bool exterior, int fl, int i,
|
||||||
|
int rotation)
|
||||||
|
{
|
||||||
|
flecs::entity item_data = get_grid_entity(key, exterior, fl, i);
|
||||||
|
item_data.get_mut<grid_floor_item>()->rotation = rotation;
|
||||||
|
}
|
||||||
|
Spatial *get_grid_node(const String &key, bool exterior, int fl, int i)
|
||||||
|
{
|
||||||
|
assert(has_floor(key, exterior, fl));
|
||||||
|
flecs::entity item_data = get_grid_entity(key, exterior, fl, i);
|
||||||
|
if (!item_data.has<struct grid_floor_item_node>()) {
|
||||||
|
Spatial *sp = memnew(Spatial);
|
||||||
|
get_as_node<Spatial>("%bg_floor")
|
||||||
|
->call_deferred("add_child", sp);
|
||||||
|
item_data.set<struct grid_floor_item_node>({ sp });
|
||||||
|
int x = i % grid_size;
|
||||||
|
int z = i / grid_size;
|
||||||
|
int rotation = get_grid_rotation(key, exterior, fl, i);
|
||||||
|
sp->set_transform(Transform(
|
||||||
|
Basis().rotated(Vector3(0, 1, 0),
|
||||||
|
Math_PI * rotation / 2.0f),
|
||||||
|
Vector3((x - 4) * 4, 1 + 5 * fl, (z - 4) * 4) -
|
||||||
|
get_as_node<Spatial>("%bg_floor")
|
||||||
|
->get_transform()
|
||||||
|
.origin));
|
||||||
|
} else {
|
||||||
|
int rotation = get_grid_rotation(key, exterior, fl, i);
|
||||||
|
const struct grid_floor_item_node *item =
|
||||||
|
item_data.get<struct grid_floor_item_node>();
|
||||||
|
Spatial *node = item->node;
|
||||||
|
Transform xform = node->get_transform();
|
||||||
|
xform.basis = Basis().rotated(
|
||||||
|
Vector3(0, 1, 0), rotation * Math_PI / 2.0f);
|
||||||
|
node->set_transform(xform);
|
||||||
|
}
|
||||||
|
return item_data.get<struct grid_floor_item_node>()->node;
|
||||||
|
}
|
||||||
|
int get_closest_node_on_floor(const String &key, bool exterior, int fl,
|
||||||
|
const Vector3 &position)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
assert(has_floor(key, exterior, fl));
|
||||||
|
flecs::entity floor_e = get_floor(key, exterior, fl);
|
||||||
|
assert(floor_e.is_valid());
|
||||||
|
int selected = -1;
|
||||||
|
float dst = Math_INF;
|
||||||
|
for (i = 0; i < grid_size * grid_size; i++) {
|
||||||
|
Spatial *node = get_grid_node(key, exterior, fl, i);
|
||||||
|
Vector3 pos = node->get_transform().origin;
|
||||||
|
float mdst = position.distance_squared_to(pos);
|
||||||
|
if (dst > mdst) {
|
||||||
|
dst = mdst;
|
||||||
|
selected = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
void get_grid_layouts_key_list(List<String> *keys)
|
||||||
|
{
|
||||||
|
flecs::entity top = ecs.lookup("grid_layouts");
|
||||||
|
assert(top.is_valid());
|
||||||
|
flecs::query_builder<const struct grid_layout> qb =
|
||||||
|
ecs.query_builder<const struct grid_layout>().with(
|
||||||
|
flecs::ChildOf, top);
|
||||||
|
flecs::query<const struct grid_layout> q = qb.build();
|
||||||
|
q.each([keys](flecs::entity e, const struct grid_layout &data) {
|
||||||
|
keys->push_back(String(e.name()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
void serialize_layouts(Dictionary &store)
|
||||||
|
{
|
||||||
|
flecs::entity top = ecs.lookup("grid_layouts");
|
||||||
|
assert(top.is_valid());
|
||||||
|
top.children([this, &store](flecs::entity l) {
|
||||||
|
Dictionary layout, exterior_layout, interior_layout;
|
||||||
|
if (l.has<struct grid_layout>()) {
|
||||||
|
flecs::entity intr = l.lookup("interior");
|
||||||
|
assert(intr.is_valid());
|
||||||
|
flecs::entity extr = l.lookup("exterior");
|
||||||
|
assert(extr.is_valid());
|
||||||
|
intr.children([this, &interior_layout](
|
||||||
|
flecs::entity intr_fl) {
|
||||||
|
if (intr_fl.has<struct grid_floor>()) {
|
||||||
|
Array items;
|
||||||
|
intr_fl.children([&items](
|
||||||
|
flecs::entity
|
||||||
|
floor_item) {
|
||||||
|
if (floor_item.has<
|
||||||
|
struct grid_floor_item>()) {
|
||||||
|
const struct grid_floor_item *item =
|
||||||
|
floor_item
|
||||||
|
.get<struct grid_floor_item>();
|
||||||
|
Dictionary sitem;
|
||||||
|
sitem["index"] =
|
||||||
|
item->index;
|
||||||
|
sitem["element"] =
|
||||||
|
item->element;
|
||||||
|
sitem["rotation"] =
|
||||||
|
item->rotation;
|
||||||
|
items.push_back(
|
||||||
|
sitem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
String floor_key(
|
||||||
|
intr_fl.name());
|
||||||
|
interior_layout[floor_key] =
|
||||||
|
items;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
extr.children([this, &exterior_layout](
|
||||||
|
flecs::entity extr_fl) {
|
||||||
|
Array items;
|
||||||
|
extr_fl.children([&items](
|
||||||
|
flecs::entity
|
||||||
|
floor_item) {
|
||||||
|
if (floor_item.has<
|
||||||
|
struct grid_floor_item>()) {
|
||||||
|
const struct grid_floor_item *item =
|
||||||
|
floor_item.get<
|
||||||
|
struct grid_floor_item>();
|
||||||
|
Dictionary sitem;
|
||||||
|
sitem["index"] =
|
||||||
|
item->index;
|
||||||
|
sitem["element"] =
|
||||||
|
item->element;
|
||||||
|
sitem["rotation"] =
|
||||||
|
item->rotation;
|
||||||
|
items.push_back(sitem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
String floor_key(extr_fl.name());
|
||||||
|
exterior_layout[floor_key] = items;
|
||||||
|
});
|
||||||
|
layout["interior"] = interior_layout;
|
||||||
|
layout["exterior"] = exterior_layout;
|
||||||
|
}
|
||||||
|
String layout_name(l.name());
|
||||||
|
store[layout_name] = layout;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
void unserialize_layouts(const Dictionary &store)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
flecs::entity top = ecs.lookup("grid_layouts");
|
||||||
|
assert(top.is_valid());
|
||||||
|
// delete all layouts
|
||||||
|
top.children([this](flecs::entity l) { l.destruct(); });
|
||||||
|
List<Variant> layout_keys;
|
||||||
|
store.get_key_list(&layout_keys);
|
||||||
|
List<Variant>::Element *e;
|
||||||
|
e = layout_keys.front();
|
||||||
|
while (e) {
|
||||||
|
String layout_name = e->get();
|
||||||
|
flecs::entity layout =
|
||||||
|
ecs.entity(layout_name.ascii().ptr())
|
||||||
|
.child_of(top);
|
||||||
|
layout.add<grid_layout>();
|
||||||
|
flecs::entity extr =
|
||||||
|
ecs.entity("exterior").child_of(layout);
|
||||||
|
extr.add<grid_layout_exterior>();
|
||||||
|
extr.set<grid_layout_base>({ 0 });
|
||||||
|
flecs::entity intr =
|
||||||
|
ecs.entity("interior").child_of(layout);
|
||||||
|
intr.add<grid_layout_interior>();
|
||||||
|
intr.set<grid_layout_base>({ 0 });
|
||||||
|
Dictionary store_layout = store[e->get()];
|
||||||
|
Dictionary store_interior = store_layout["interior"];
|
||||||
|
Dictionary store_exterior = store_layout["exterior"];
|
||||||
|
List<Variant>::Element *ve;
|
||||||
|
List<Variant> interior_keys;
|
||||||
|
List<Variant> exterior_keys;
|
||||||
|
store_interior.get_key_list(&interior_keys);
|
||||||
|
store_exterior.get_key_list(&exterior_keys);
|
||||||
|
for (ve = interior_keys.front(); ve; ve = ve->next()) {
|
||||||
|
String floor_key = ve->get();
|
||||||
|
if (floor_key.begins_with("floor_")) {
|
||||||
|
flecs::entity floor_e =
|
||||||
|
ecs.entity(floor_key.ascii()
|
||||||
|
.ptr())
|
||||||
|
.child_of(intr);
|
||||||
|
assert(floor_e.is_valid());
|
||||||
|
floor_e.add<struct grid_floor>();
|
||||||
|
const Array &floor_interior =
|
||||||
|
store_interior[floor_key];
|
||||||
|
for (i = 0; i < floor_interior.size();
|
||||||
|
i++) {
|
||||||
|
const Dictionary &item =
|
||||||
|
floor_interior[i];
|
||||||
|
int index = item["index"];
|
||||||
|
String element =
|
||||||
|
item["element"];
|
||||||
|
int rotation = item["rotation"];
|
||||||
|
String item_key =
|
||||||
|
"item_" + itos(index);
|
||||||
|
flecs::entity item_e =
|
||||||
|
ecs.entity(item_key.ascii()
|
||||||
|
.ptr())
|
||||||
|
.child_of(
|
||||||
|
floor_e);
|
||||||
|
item_e.set<grid_floor_item>(
|
||||||
|
{ index, element,
|
||||||
|
rotation });
|
||||||
|
}
|
||||||
|
struct grid_layout_base *l = intr.get_mut<
|
||||||
|
struct grid_layout_base>();
|
||||||
|
l->floor_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (ve = exterior_keys.front(); ve; ve = ve->next()) {
|
||||||
|
String floor_key = ve->get();
|
||||||
|
if (floor_key.begins_with("floor_")) {
|
||||||
|
flecs::entity floor_e =
|
||||||
|
ecs.entity(floor_key.ascii()
|
||||||
|
.ptr())
|
||||||
|
.child_of(extr);
|
||||||
|
assert(floor_e.is_valid());
|
||||||
|
floor_e.add<struct grid_floor>();
|
||||||
|
const Array &floor_exterior =
|
||||||
|
store_exterior[floor_key];
|
||||||
|
for (i = 0; i < floor_exterior.size();
|
||||||
|
i++) {
|
||||||
|
const Dictionary &item =
|
||||||
|
floor_exterior[i];
|
||||||
|
int index = item["index"];
|
||||||
|
String element =
|
||||||
|
item["element"];
|
||||||
|
int rotation = item["rotation"];
|
||||||
|
String item_key =
|
||||||
|
"item_" + itos(index);
|
||||||
|
flecs::entity item_e =
|
||||||
|
ecs.entity(item_key.ascii()
|
||||||
|
.ptr())
|
||||||
|
.child_of(
|
||||||
|
floor_e);
|
||||||
|
item_e.set<grid_floor_item>(
|
||||||
|
{ index, element,
|
||||||
|
rotation });
|
||||||
|
}
|
||||||
|
struct grid_layout_base *l = extr.get_mut<
|
||||||
|
struct grid_layout_base>();
|
||||||
|
l->floor_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e = e->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void get_element_type_key_list(List<String> *keys)
|
||||||
|
{
|
||||||
|
element_type.get_key_list(keys);
|
||||||
|
}
|
||||||
|
void create_element_type(const String &key)
|
||||||
|
{
|
||||||
|
assert(!element_type.has(key));
|
||||||
|
struct grid_element_type g;
|
||||||
|
g.name = key;
|
||||||
|
element_type[key] = g;
|
||||||
|
}
|
||||||
|
void set_element_type_socket(const String &key, int socket,
|
||||||
|
const Transform &xform)
|
||||||
|
{
|
||||||
|
assert(element_type.has(key));
|
||||||
|
assert(socket >= 0 && socket < ELEMENT_SOCKETS);
|
||||||
|
element_type[key].sockets[socket] = xform;
|
||||||
|
}
|
||||||
|
void set_element_type_name(const String &key, const String &name)
|
||||||
|
{
|
||||||
|
assert(element_type.has(key));
|
||||||
|
element_type[key].name = name;
|
||||||
|
}
|
||||||
|
bool has_element_type(const String &key)
|
||||||
|
{
|
||||||
|
return element_type.has(key);
|
||||||
|
}
|
||||||
|
Transform get_element_type_socket(const String &key, int socket)
|
||||||
|
{
|
||||||
|
assert(element_type.has(key));
|
||||||
|
assert(socket >= 0 && socket < ELEMENT_SOCKETS);
|
||||||
|
return element_type[key].sockets[socket];
|
||||||
|
}
|
||||||
|
int get_element_type_size()
|
||||||
|
{
|
||||||
|
return element_type.size();
|
||||||
|
}
|
||||||
|
void create_element(const String &key, const String &type)
|
||||||
|
{
|
||||||
|
struct grid_element g;
|
||||||
|
assert(!elements.has(key));
|
||||||
|
assert(element_type.has(type));
|
||||||
|
g.name = key;
|
||||||
|
g.type = type;
|
||||||
|
elements[key] = g;
|
||||||
|
}
|
||||||
|
void set_element_type(const String &key, const String &type)
|
||||||
|
{
|
||||||
|
assert(elements.has(key));
|
||||||
|
assert(element_type.has(type));
|
||||||
|
elements[key].type = type;
|
||||||
|
}
|
||||||
|
const String &get_element_type(const String &key) const
|
||||||
|
{
|
||||||
|
assert(elements.has(key));
|
||||||
|
return elements[key].type;
|
||||||
|
}
|
||||||
|
void set_element_mesh_name(const String &key, int socket,
|
||||||
|
const String &mesh_name)
|
||||||
|
{
|
||||||
|
assert(elements.has(key));
|
||||||
|
assert(socket >= 0 && socket < ELEMENT_SOCKETS);
|
||||||
|
elements[key].mesh_names[socket] = mesh_name;
|
||||||
|
}
|
||||||
|
const String &get_element_mesh_name(const String &key, int socket)
|
||||||
|
{
|
||||||
|
assert(elements.has(key));
|
||||||
|
assert(socket >= 0 && socket < ELEMENT_SOCKETS);
|
||||||
|
return elements[key].mesh_names[socket];
|
||||||
|
}
|
||||||
|
int get_element_size()
|
||||||
|
{
|
||||||
|
return elements.size();
|
||||||
|
}
|
||||||
|
void get_element_key_list(List<String> *keys)
|
||||||
|
{
|
||||||
|
elements.get_key_list(keys);
|
||||||
|
}
|
||||||
|
bool has_element(const String &key)
|
||||||
|
{
|
||||||
|
return elements.has(key);
|
||||||
|
}
|
||||||
|
void save_data()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
ConfigFile config;
|
||||||
|
Dictionary conf_element_types;
|
||||||
|
Dictionary conf_elements;
|
||||||
|
Dictionary conf_exterior_grid;
|
||||||
|
List<String> keys;
|
||||||
|
List<String>::Element *e;
|
||||||
|
element_type.get_key_list(&keys);
|
||||||
|
e = keys.front();
|
||||||
|
while (e) {
|
||||||
|
Dictionary item;
|
||||||
|
const struct grid_element_type &g =
|
||||||
|
element_type[e->get()];
|
||||||
|
if (e->get() == "empty") {
|
||||||
|
e = e->next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
item["name"] = e->get();
|
||||||
|
Array sockets;
|
||||||
|
sockets.resize(ELEMENT_SOCKETS);
|
||||||
|
for (i = 0; i < ELEMENT_SOCKETS; i++)
|
||||||
|
sockets[i] = g.sockets[i];
|
||||||
|
item["sockets"] = sockets;
|
||||||
|
|
||||||
|
conf_element_types[e->get()] = item;
|
||||||
|
e = e->next();
|
||||||
|
}
|
||||||
|
keys.clear();
|
||||||
|
elements.get_key_list(&keys);
|
||||||
|
e = keys.front();
|
||||||
|
while (e) {
|
||||||
|
Dictionary item;
|
||||||
|
const struct grid_element &g = elements[e->get()];
|
||||||
|
if (e->get() == "empty") {
|
||||||
|
e = e->next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
item["name"] = e->get();
|
||||||
|
item["type"] = g.type;
|
||||||
|
Array mesh_names;
|
||||||
|
mesh_names.resize(ELEMENT_SOCKETS);
|
||||||
|
for (i = 0; i < ELEMENT_SOCKETS; i++)
|
||||||
|
mesh_names[i] = g.mesh_names[i];
|
||||||
|
item["mesh_names"] = mesh_names;
|
||||||
|
|
||||||
|
conf_elements[e->get()] = item;
|
||||||
|
e = e->next();
|
||||||
|
}
|
||||||
|
// TODO: support multiple layouts;
|
||||||
|
serialize_layouts(conf_exterior_grid);
|
||||||
|
|
||||||
|
config.set_value("buildings_layout", "element_types",
|
||||||
|
conf_element_types);
|
||||||
|
config.set_value("buildings_layout", "elements", conf_elements);
|
||||||
|
config.set_value("buildings_layout", "grid_layouts",
|
||||||
|
conf_exterior_grid);
|
||||||
|
config.save("res://astream/blayout.conf");
|
||||||
|
}
|
||||||
|
void load_data()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
ConfigFile config;
|
||||||
|
Dictionary conf_element_types;
|
||||||
|
Dictionary conf_elements;
|
||||||
|
Dictionary conf_grid_layouts;
|
||||||
|
List<Variant> keys;
|
||||||
|
List<Variant>::Element *e;
|
||||||
|
elements.clear();
|
||||||
|
element_type.clear();
|
||||||
|
config.load("res://astream/blayout.conf");
|
||||||
|
conf_element_types = config.get_value(
|
||||||
|
"buildings_layout", "element_types", Dictionary());
|
||||||
|
conf_elements = config.get_value("buildings_layout", "elements",
|
||||||
|
Dictionary());
|
||||||
|
conf_grid_layouts = config.get_value(
|
||||||
|
"buildings_layout", "grid_layouts", Dictionary());
|
||||||
|
conf_element_types.get_key_list(&keys);
|
||||||
|
e = keys.front();
|
||||||
|
while (e) {
|
||||||
|
String key = e->get();
|
||||||
|
Dictionary item = conf_element_types[key];
|
||||||
|
assert(item.has("sockets"));
|
||||||
|
create_element_type(key);
|
||||||
|
Array sockets = item["sockets"];
|
||||||
|
for (i = 0; i < sockets.size(); i++)
|
||||||
|
set_element_type_socket(key, i, sockets[i]);
|
||||||
|
e = e->next();
|
||||||
|
}
|
||||||
|
keys.clear();
|
||||||
|
conf_elements.get_key_list(&keys);
|
||||||
|
e = keys.front();
|
||||||
|
while (e) {
|
||||||
|
String key = e->get();
|
||||||
|
Dictionary item = conf_elements[key];
|
||||||
|
assert(item.has("type"));
|
||||||
|
assert(item.has("mesh_names"));
|
||||||
|
String type = item["type"];
|
||||||
|
print_line("loading element: " + key +
|
||||||
|
" type: " + type);
|
||||||
|
if (key == "empty") {
|
||||||
|
e = e->next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
create_element(key, type);
|
||||||
|
Array mesh_names = item["mesh_names"];
|
||||||
|
for (i = 0; i < mesh_names.size(); i++)
|
||||||
|
set_element_mesh_name(key, i, mesh_names[i]);
|
||||||
|
e = e->next();
|
||||||
|
}
|
||||||
|
unserialize_layouts(conf_grid_layouts);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user