Allocate rooms in zones started
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
[layouts]
|
[layouts]
|
||||||
|
|
||||||
entries=[ {
|
entries=[ {
|
||||||
"children": [ 3, 4 ],
|
"children": [ 4, 5 ],
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
"floor_index": 0,
|
"floor_index": 0,
|
||||||
"index": 0,
|
"index": 0,
|
||||||
@@ -9,7 +9,7 @@ entries=[ {
|
|||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "layout"
|
"type": "layout"
|
||||||
}, {
|
}, {
|
||||||
"children": [ 5, 6, 7 ],
|
"children": [ 6, 7, 8 ],
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
"floor_index": 0,
|
"floor_index": 0,
|
||||||
"index": 1,
|
"index": 1,
|
||||||
@@ -17,7 +17,7 @@ entries=[ {
|
|||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "layout"
|
"type": "layout"
|
||||||
}, {
|
}, {
|
||||||
"children": [ 8, 9, 10, 11, 12 ],
|
"children": [ 9, 10, 11, 12, 13 ],
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
"floor_index": 0,
|
"floor_index": 0,
|
||||||
"index": 2,
|
"index": 2,
|
||||||
@@ -25,136 +25,126 @@ entries=[ {
|
|||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "layout"
|
"type": "layout"
|
||||||
}, {
|
}, {
|
||||||
"children": [ 13, 14 ],
|
"children": [ 14, 15, 16, 17 ],
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
"commands": [ ],
|
||||||
|
"floor_index": 0,
|
||||||
"index": 3,
|
"index": 3,
|
||||||
|
"name": "v4",
|
||||||
|
"order": 4,
|
||||||
|
"type": "layout"
|
||||||
|
}, {
|
||||||
|
"children": [ 18, 19 ],
|
||||||
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
|
"index": 4,
|
||||||
"name": "zone_0",
|
"name": "zone_0",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "zone",
|
"type": "zone",
|
||||||
"zone_type": 1
|
"zone_type": 1
|
||||||
}, {
|
}, {
|
||||||
"children": [ 15, 16, 17 ],
|
"children": [ 20, 21, 22 ],
|
||||||
"commands": [ [ 4, [ ] ] ],
|
"commands": [ [ 4, [ ] ] ],
|
||||||
"index": 4,
|
|
||||||
"name": "zone_1",
|
|
||||||
"order": 1,
|
|
||||||
"type": "zone",
|
|
||||||
"zone_type": 0
|
|
||||||
}, {
|
|
||||||
"children": [ 18, 19, 20, 21 ],
|
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
|
||||||
"index": 5,
|
"index": 5,
|
||||||
"name": "zone_1",
|
"name": "zone_1",
|
||||||
|
"order": 1,
|
||||||
|
"type": "zone",
|
||||||
|
"zone_type": 0
|
||||||
|
}, {
|
||||||
|
"children": [ 23, 24, 25, 26 ],
|
||||||
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
|
"index": 6,
|
||||||
|
"name": "zone_1",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "zone",
|
"type": "zone",
|
||||||
"zone_type": 1
|
"zone_type": 1
|
||||||
}, {
|
}, {
|
||||||
"children": [ 22, 23, 24 ],
|
"children": [ 27, 28, 29 ],
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
"index": 6,
|
"index": 7,
|
||||||
"name": "zone_0",
|
"name": "zone_0",
|
||||||
"order": 1,
|
"order": 1,
|
||||||
"type": "zone",
|
"type": "zone",
|
||||||
"zone_type": 0
|
"zone_type": 0
|
||||||
}, {
|
}, {
|
||||||
"children": [ 25, 26 ],
|
"children": [ 30, 31 ],
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
"index": 7,
|
"index": 8,
|
||||||
"name": "unit_0",
|
"name": "unit_0",
|
||||||
"order": 3,
|
"order": 3,
|
||||||
"type": "unit"
|
"type": "unit"
|
||||||
}, {
|
}, {
|
||||||
"children": [ 27, 28 ],
|
"children": [ 32, 33 ],
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
"index": 8,
|
"index": 9,
|
||||||
"name": "zone_0",
|
"name": "zone_0",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "zone",
|
"type": "zone",
|
||||||
"zone_type": 1
|
"zone_type": 1
|
||||||
}, {
|
}, {
|
||||||
"children": [ 29, 30 ],
|
"children": [ 34, 35 ],
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
"index": 9,
|
"index": 10,
|
||||||
"name": "unit_0",
|
"name": "unit_0",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "unit"
|
"type": "unit"
|
||||||
}, {
|
}, {
|
||||||
"children": [ 31, 32 ],
|
"children": [ 36, 37 ],
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
"index": 10,
|
"index": 11,
|
||||||
"name": "unit_1",
|
"name": "unit_1",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "unit"
|
"type": "unit"
|
||||||
}, {
|
}, {
|
||||||
"children": [ 33, 34 ],
|
"children": [ 38, 39 ],
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
"index": 11,
|
"index": 12,
|
||||||
"name": "unit_2",
|
"name": "unit_2",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "unit"
|
"type": "unit"
|
||||||
}, {
|
}, {
|
||||||
"children": [ 35, 36 ],
|
"children": [ 40, 41 ],
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
"index": 12,
|
"index": 13,
|
||||||
"name": "unit_3",
|
"name": "unit_3",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "unit"
|
"type": "unit"
|
||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ 42, 43 ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ ],
|
||||||
"index": 13,
|
|
||||||
"name": "living_room_0",
|
|
||||||
"order": 1,
|
|
||||||
"room_area": 144.0,
|
|
||||||
"room_type": 300,
|
|
||||||
"type": "room",
|
|
||||||
"window": true
|
|
||||||
}, {
|
|
||||||
"children": [ ],
|
|
||||||
"commands": [ [ 5, [ ] ] ],
|
|
||||||
"index": 14,
|
"index": 14,
|
||||||
"name": "kitchen_0",
|
"name": "zone_0",
|
||||||
"order": 2,
|
|
||||||
"room_area": 16.0,
|
|
||||||
"room_type": 302,
|
|
||||||
"type": "room",
|
|
||||||
"window": true
|
|
||||||
}, {
|
|
||||||
"children": [ ],
|
|
||||||
"commands": [ [ 5, [ ] ] ],
|
|
||||||
"index": 15,
|
|
||||||
"name": "wc_0",
|
|
||||||
"order": 0,
|
|
||||||
"room_area": 16.0,
|
|
||||||
"room_type": 200,
|
|
||||||
"type": "room",
|
|
||||||
"window": false
|
|
||||||
}, {
|
|
||||||
"children": [ ],
|
|
||||||
"commands": [ [ 5, [ ] ], [ 3, [ ] ] ],
|
|
||||||
"index": 16,
|
|
||||||
"name": "bathroom_0",
|
|
||||||
"order": 1,
|
"order": 1,
|
||||||
"room_area": 16.0,
|
"type": "zone",
|
||||||
"room_type": 201,
|
"zone_type": 0
|
||||||
"type": "room",
|
|
||||||
"window": false
|
|
||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ 44, 45 ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ ],
|
||||||
"index": 17,
|
"index": 15,
|
||||||
"name": "bedroom_0",
|
"name": "zone_1",
|
||||||
"order": 2,
|
"order": 2,
|
||||||
"room_area": 64.0,
|
"type": "zone",
|
||||||
"room_type": 202,
|
"zone_type": 0
|
||||||
"type": "room",
|
}, {
|
||||||
"window": true
|
"children": [ 46, 47, 48 ],
|
||||||
|
"commands": [ ],
|
||||||
|
"index": 16,
|
||||||
|
"name": "zone_2",
|
||||||
|
"order": 3,
|
||||||
|
"type": "zone",
|
||||||
|
"zone_type": 0
|
||||||
|
}, {
|
||||||
|
"children": [ 49, 50, 51, 52 ],
|
||||||
|
"commands": [ ],
|
||||||
|
"index": 17,
|
||||||
|
"name": "zone_3",
|
||||||
|
"order": 4,
|
||||||
|
"type": "zone",
|
||||||
|
"zone_type": 1
|
||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ [ 5, [ ] ] ],
|
||||||
"index": 18,
|
"index": 18,
|
||||||
"name": "living_room_0",
|
"name": "living_room_0",
|
||||||
"order": 0,
|
"order": 1,
|
||||||
"room_area": 144.0,
|
"room_area": 144.0,
|
||||||
"room_type": 300,
|
"room_type": 300,
|
||||||
"type": "room",
|
"type": "room",
|
||||||
@@ -164,6 +154,56 @@ entries=[ {
|
|||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ [ 5, [ ] ] ],
|
||||||
"index": 19,
|
"index": 19,
|
||||||
"name": "kitchen_0",
|
"name": "kitchen_0",
|
||||||
|
"order": 2,
|
||||||
|
"room_area": 16.0,
|
||||||
|
"room_type": 302,
|
||||||
|
"type": "room",
|
||||||
|
"window": true
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 20,
|
||||||
|
"name": "wc_0",
|
||||||
|
"order": 0,
|
||||||
|
"room_area": 16.0,
|
||||||
|
"room_type": 200,
|
||||||
|
"type": "room",
|
||||||
|
"window": false
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ], [ 3, [ ] ] ],
|
||||||
|
"index": 21,
|
||||||
|
"name": "bathroom_0",
|
||||||
|
"order": 1,
|
||||||
|
"room_area": 16.0,
|
||||||
|
"room_type": 201,
|
||||||
|
"type": "room",
|
||||||
|
"window": false
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 22,
|
||||||
|
"name": "bedroom_0",
|
||||||
|
"order": 2,
|
||||||
|
"room_area": 64.0,
|
||||||
|
"room_type": 202,
|
||||||
|
"type": "room",
|
||||||
|
"window": true
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 23,
|
||||||
|
"name": "living_room_0",
|
||||||
|
"order": 0,
|
||||||
|
"room_area": 144.0,
|
||||||
|
"room_type": 300,
|
||||||
|
"type": "room",
|
||||||
|
"window": true
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 24,
|
||||||
|
"name": "kitchen_0",
|
||||||
"order": 1,
|
"order": 1,
|
||||||
"room_area": 64.0,
|
"room_area": 64.0,
|
||||||
"room_type": 302,
|
"room_type": 302,
|
||||||
@@ -172,7 +212,7 @@ entries=[ {
|
|||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ [ 5, [ ] ] ],
|
||||||
"index": 20,
|
"index": 25,
|
||||||
"name": "storage_room_0",
|
"name": "storage_room_0",
|
||||||
"order": 2,
|
"order": 2,
|
||||||
"room_area": 16.0,
|
"room_area": 16.0,
|
||||||
@@ -182,7 +222,7 @@ entries=[ {
|
|||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ], [ 4, [ ] ] ],
|
"commands": [ [ 5, [ ] ], [ 4, [ ] ] ],
|
||||||
"index": 21,
|
"index": 26,
|
||||||
"name": "enterance_0",
|
"name": "enterance_0",
|
||||||
"order": 3,
|
"order": 3,
|
||||||
"room_area": 16.0,
|
"room_area": 16.0,
|
||||||
@@ -192,7 +232,7 @@ entries=[ {
|
|||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ [ 5, [ ] ] ],
|
||||||
"index": 22,
|
"index": 27,
|
||||||
"name": "wc_0",
|
"name": "wc_0",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"room_area": 16.0,
|
"room_area": 16.0,
|
||||||
@@ -202,7 +242,7 @@ entries=[ {
|
|||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ [ 5, [ ] ] ],
|
||||||
"index": 23,
|
"index": 28,
|
||||||
"name": "bathroom_0",
|
"name": "bathroom_0",
|
||||||
"order": 1,
|
"order": 1,
|
||||||
"room_area": 16.0,
|
"room_area": 16.0,
|
||||||
@@ -212,7 +252,7 @@ entries=[ {
|
|||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ [ 5, [ ] ] ],
|
||||||
"index": 24,
|
"index": 29,
|
||||||
"name": "bedroom_0",
|
"name": "bedroom_0",
|
||||||
"order": 2,
|
"order": 2,
|
||||||
"room_area": 64.0,
|
"room_area": 64.0,
|
||||||
@@ -220,17 +260,17 @@ entries=[ {
|
|||||||
"type": "room",
|
"type": "room",
|
||||||
"window": true
|
"window": true
|
||||||
}, {
|
}, {
|
||||||
"children": [ 37, 38, 39 ],
|
"children": [ 53, 54, 55 ],
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
"index": 25,
|
"index": 30,
|
||||||
"name": "zone_0",
|
"name": "zone_0",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "zone",
|
"type": "zone",
|
||||||
"zone_type": 0
|
"zone_type": 0
|
||||||
}, {
|
}, {
|
||||||
"children": [ 40, 41 ],
|
"children": [ 56, 57 ],
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
"index": 26,
|
"index": 31,
|
||||||
"name": "zone_1",
|
"name": "zone_1",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "zone",
|
"type": "zone",
|
||||||
@@ -238,7 +278,7 @@ entries=[ {
|
|||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ [ 5, [ ] ] ],
|
||||||
"index": 27,
|
"index": 32,
|
||||||
"name": "enterance_0",
|
"name": "enterance_0",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"room_area": 64.0,
|
"room_area": 64.0,
|
||||||
@@ -246,9 +286,9 @@ entries=[ {
|
|||||||
"type": "room",
|
"type": "room",
|
||||||
"window": true
|
"window": true
|
||||||
}, {
|
}, {
|
||||||
"children": [ 42 ],
|
"children": [ 58 ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ [ 5, [ ] ] ],
|
||||||
"index": 28,
|
"index": 33,
|
||||||
"name": "stair_0",
|
"name": "stair_0",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"room_area": 16.0,
|
"room_area": 16.0,
|
||||||
@@ -256,83 +296,73 @@ entries=[ {
|
|||||||
"type": "room",
|
"type": "room",
|
||||||
"window": true
|
"window": true
|
||||||
}, {
|
}, {
|
||||||
"children": [ 43, 44, 45 ],
|
"children": [ 59, 60, 61 ],
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
|
||||||
"index": 29,
|
|
||||||
"name": "zone_0",
|
|
||||||
"order": 0,
|
|
||||||
"type": "zone",
|
|
||||||
"zone_type": 0
|
|
||||||
}, {
|
|
||||||
"children": [ 46, 47 ],
|
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
|
||||||
"index": 30,
|
|
||||||
"name": "zone_1",
|
|
||||||
"order": 0,
|
|
||||||
"type": "zone",
|
|
||||||
"zone_type": 1
|
|
||||||
}, {
|
|
||||||
"children": [ 48 ],
|
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
|
||||||
"index": 31,
|
|
||||||
"name": "zone_0",
|
|
||||||
"order": 0,
|
|
||||||
"type": "zone",
|
|
||||||
"zone_type": 0
|
|
||||||
}, {
|
|
||||||
"children": [ 49, 50 ],
|
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
|
||||||
"index": 32,
|
|
||||||
"name": "zone_1",
|
|
||||||
"order": 0,
|
|
||||||
"type": "zone",
|
|
||||||
"zone_type": 1
|
|
||||||
}, {
|
|
||||||
"children": [ 51 ],
|
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
|
||||||
"index": 33,
|
|
||||||
"name": "zone_0",
|
|
||||||
"order": 0,
|
|
||||||
"type": "zone",
|
|
||||||
"zone_type": 0
|
|
||||||
}, {
|
|
||||||
"children": [ 52 ],
|
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
"index": 34,
|
"index": 34,
|
||||||
"name": "zone_1",
|
|
||||||
"order": 1,
|
|
||||||
"type": "zone",
|
|
||||||
"zone_type": 1
|
|
||||||
}, {
|
|
||||||
"children": [ 53 ],
|
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
|
||||||
"index": 35,
|
|
||||||
"name": "zone_0",
|
"name": "zone_0",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "zone",
|
"type": "zone",
|
||||||
"zone_type": 0
|
"zone_type": 0
|
||||||
}, {
|
}, {
|
||||||
"children": [ 54 ],
|
"children": [ 62, 63 ],
|
||||||
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
|
"index": 35,
|
||||||
|
"name": "zone_1",
|
||||||
|
"order": 0,
|
||||||
|
"type": "zone",
|
||||||
|
"zone_type": 1
|
||||||
|
}, {
|
||||||
|
"children": [ 64 ],
|
||||||
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
"index": 36,
|
"index": 36,
|
||||||
|
"name": "zone_0",
|
||||||
|
"order": 0,
|
||||||
|
"type": "zone",
|
||||||
|
"zone_type": 0
|
||||||
|
}, {
|
||||||
|
"children": [ 65, 66 ],
|
||||||
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
|
"index": 37,
|
||||||
|
"name": "zone_1",
|
||||||
|
"order": 0,
|
||||||
|
"type": "zone",
|
||||||
|
"zone_type": 1
|
||||||
|
}, {
|
||||||
|
"children": [ 67 ],
|
||||||
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
|
"index": 38,
|
||||||
|
"name": "zone_0",
|
||||||
|
"order": 0,
|
||||||
|
"type": "zone",
|
||||||
|
"zone_type": 0
|
||||||
|
}, {
|
||||||
|
"children": [ 68 ],
|
||||||
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
|
"index": 39,
|
||||||
|
"name": "zone_1",
|
||||||
|
"order": 1,
|
||||||
|
"type": "zone",
|
||||||
|
"zone_type": 1
|
||||||
|
}, {
|
||||||
|
"children": [ 69 ],
|
||||||
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
|
"index": 40,
|
||||||
|
"name": "zone_0",
|
||||||
|
"order": 0,
|
||||||
|
"type": "zone",
|
||||||
|
"zone_type": 0
|
||||||
|
}, {
|
||||||
|
"children": [ 70 ],
|
||||||
|
"commands": [ [ 3, [ ] ], [ 4, [ ] ] ],
|
||||||
|
"index": 41,
|
||||||
"name": "zone_1",
|
"name": "zone_1",
|
||||||
"order": 1,
|
"order": 1,
|
||||||
"type": "zone",
|
"type": "zone",
|
||||||
"zone_type": 1
|
"zone_type": 1
|
||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ ],
|
||||||
"index": 37,
|
"index": 42,
|
||||||
"name": "bathroom_0",
|
|
||||||
"order": 0,
|
|
||||||
"room_area": 16.0,
|
|
||||||
"room_type": 201,
|
|
||||||
"type": "room",
|
|
||||||
"window": false
|
|
||||||
}, {
|
|
||||||
"children": [ ],
|
|
||||||
"commands": [ [ 5, [ ] ] ],
|
|
||||||
"index": 38,
|
|
||||||
"name": "wc_0",
|
"name": "wc_0",
|
||||||
"order": 1,
|
"order": 1,
|
||||||
"room_area": 16.0,
|
"room_area": 16.0,
|
||||||
@@ -341,65 +371,27 @@ entries=[ {
|
|||||||
"window": false
|
"window": false
|
||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ ],
|
||||||
"index": 39,
|
"index": 43,
|
||||||
"name": "bedroom_0",
|
"name": "bedroom_0",
|
||||||
"order": 2,
|
"order": 2,
|
||||||
"room_area": 36.0,
|
"room_area": 64.0,
|
||||||
"room_type": 202,
|
"room_type": 202,
|
||||||
"type": "room",
|
"type": "room",
|
||||||
"window": true
|
"window": true
|
||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
|
||||||
"index": 40,
|
|
||||||
"name": "living_room_0",
|
|
||||||
"order": 0,
|
|
||||||
"room_area": 36.0,
|
|
||||||
"room_type": 300,
|
|
||||||
"type": "room",
|
|
||||||
"window": true
|
|
||||||
}, {
|
|
||||||
"children": [ ],
|
|
||||||
"commands": [ [ 5, [ ] ] ],
|
|
||||||
"index": 41,
|
|
||||||
"name": "kitchen_0",
|
|
||||||
"order": 1,
|
|
||||||
"room_area": 16.0,
|
|
||||||
"room_type": 302,
|
|
||||||
"type": "room",
|
|
||||||
"window": true
|
|
||||||
}, {
|
|
||||||
"children": [ 55, 56 ],
|
|
||||||
"commands": [ ],
|
"commands": [ ],
|
||||||
"floor_index": 1,
|
"index": 44,
|
||||||
"index": 42,
|
|
||||||
"name": "floor_0",
|
|
||||||
"order": 0,
|
|
||||||
"type": "floor"
|
|
||||||
}, {
|
|
||||||
"children": [ ],
|
|
||||||
"commands": [ [ 5, [ ] ] ],
|
|
||||||
"index": 43,
|
|
||||||
"name": "wc_0",
|
"name": "wc_0",
|
||||||
"order": 0,
|
"order": 1,
|
||||||
"room_area": 16.0,
|
"room_area": 16.0,
|
||||||
"room_type": 200,
|
"room_type": 200,
|
||||||
"type": "room",
|
"type": "room",
|
||||||
"window": false
|
"window": false
|
||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ ],
|
||||||
"index": 44,
|
|
||||||
"name": "bathroom_0",
|
|
||||||
"order": 1,
|
|
||||||
"room_area": 16.0,
|
|
||||||
"room_type": 201,
|
|
||||||
"type": "room",
|
|
||||||
"window": false
|
|
||||||
}, {
|
|
||||||
"children": [ ],
|
|
||||||
"commands": [ [ 5, [ ] ] ],
|
|
||||||
"index": 45,
|
"index": 45,
|
||||||
"name": "bedroom_0",
|
"name": "bedroom_0",
|
||||||
"order": 2,
|
"order": 2,
|
||||||
@@ -409,18 +401,38 @@ entries=[ {
|
|||||||
"window": true
|
"window": true
|
||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ ],
|
||||||
"index": 46,
|
"index": 46,
|
||||||
"name": "kitchen_0",
|
"name": "wc_0",
|
||||||
"order": 0,
|
"order": 1,
|
||||||
"room_area": 16.0,
|
"room_area": 16.0,
|
||||||
"room_type": 302,
|
"room_type": 200,
|
||||||
"type": "room",
|
"type": "room",
|
||||||
"window": true
|
"window": false
|
||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ ],
|
||||||
"index": 47,
|
"index": 47,
|
||||||
|
"name": "bathroom_0",
|
||||||
|
"order": 2,
|
||||||
|
"room_area": 16.0,
|
||||||
|
"room_type": 201,
|
||||||
|
"type": "room",
|
||||||
|
"window": false
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ ],
|
||||||
|
"index": 48,
|
||||||
|
"name": "bathroom_1",
|
||||||
|
"order": 3,
|
||||||
|
"room_area": 144.0,
|
||||||
|
"room_type": 201,
|
||||||
|
"type": "room",
|
||||||
|
"window": false
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ ],
|
||||||
|
"index": 49,
|
||||||
"name": "living_room_0",
|
"name": "living_room_0",
|
||||||
"order": 1,
|
"order": 1,
|
||||||
"room_area": 144.0,
|
"room_area": 144.0,
|
||||||
@@ -429,52 +441,32 @@ entries=[ {
|
|||||||
"window": true
|
"window": true
|
||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ ],
|
||||||
"index": 48,
|
"index": 50,
|
||||||
"name": "bathroom_0",
|
|
||||||
"order": 0,
|
|
||||||
"room_area": 16.0,
|
|
||||||
"room_type": 201,
|
|
||||||
"type": "room",
|
|
||||||
"window": false
|
|
||||||
}, {
|
|
||||||
"children": [ ],
|
|
||||||
"commands": [ [ 5, [ ] ] ],
|
|
||||||
"index": 49,
|
|
||||||
"name": "kitchen_0",
|
"name": "kitchen_0",
|
||||||
"order": 0,
|
"order": 2,
|
||||||
"room_area": 64.0,
|
"room_area": 64.0,
|
||||||
"room_type": 302,
|
"room_type": 302,
|
||||||
"type": "room",
|
"type": "room",
|
||||||
"window": true
|
"window": true
|
||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ ],
|
||||||
"index": 50,
|
"index": 51,
|
||||||
"name": "living_room_0",
|
"name": "dining_room_0",
|
||||||
"order": 1,
|
"order": 3,
|
||||||
"room_area": 64.0,
|
"room_area": 144.0,
|
||||||
"room_type": 300,
|
"room_type": 303,
|
||||||
"type": "room",
|
"type": "room",
|
||||||
"window": true
|
"window": true
|
||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ ],
|
||||||
"index": 51,
|
|
||||||
"name": "wc_0",
|
|
||||||
"order": 0,
|
|
||||||
"room_area": 16.0,
|
|
||||||
"room_type": 200,
|
|
||||||
"type": "room",
|
|
||||||
"window": false
|
|
||||||
}, {
|
|
||||||
"children": [ ],
|
|
||||||
"commands": [ [ 5, [ ] ] ],
|
|
||||||
"index": 52,
|
"index": 52,
|
||||||
"name": "living_room_0",
|
"name": "enterance_0",
|
||||||
"order": 0,
|
"order": 4,
|
||||||
"room_area": 64.0,
|
"room_area": 16.0,
|
||||||
"room_type": 300,
|
"room_type": 304,
|
||||||
"type": "room",
|
"type": "room",
|
||||||
"window": true
|
"window": true
|
||||||
}, {
|
}, {
|
||||||
@@ -491,6 +483,144 @@ entries=[ {
|
|||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ [ 5, [ ] ] ],
|
"commands": [ [ 5, [ ] ] ],
|
||||||
"index": 54,
|
"index": 54,
|
||||||
|
"name": "wc_0",
|
||||||
|
"order": 1,
|
||||||
|
"room_area": 16.0,
|
||||||
|
"room_type": 200,
|
||||||
|
"type": "room",
|
||||||
|
"window": false
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 55,
|
||||||
|
"name": "bedroom_0",
|
||||||
|
"order": 2,
|
||||||
|
"room_area": 36.0,
|
||||||
|
"room_type": 202,
|
||||||
|
"type": "room",
|
||||||
|
"window": true
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 56,
|
||||||
|
"name": "living_room_0",
|
||||||
|
"order": 0,
|
||||||
|
"room_area": 36.0,
|
||||||
|
"room_type": 300,
|
||||||
|
"type": "room",
|
||||||
|
"window": true
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 57,
|
||||||
|
"name": "kitchen_0",
|
||||||
|
"order": 1,
|
||||||
|
"room_area": 16.0,
|
||||||
|
"room_type": 302,
|
||||||
|
"type": "room",
|
||||||
|
"window": true
|
||||||
|
}, {
|
||||||
|
"children": [ 71, 72 ],
|
||||||
|
"commands": [ ],
|
||||||
|
"floor_index": 1,
|
||||||
|
"index": 58,
|
||||||
|
"name": "floor_0",
|
||||||
|
"order": 0,
|
||||||
|
"type": "floor"
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 59,
|
||||||
|
"name": "wc_0",
|
||||||
|
"order": 0,
|
||||||
|
"room_area": 16.0,
|
||||||
|
"room_type": 200,
|
||||||
|
"type": "room",
|
||||||
|
"window": false
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 60,
|
||||||
|
"name": "bathroom_0",
|
||||||
|
"order": 1,
|
||||||
|
"room_area": 16.0,
|
||||||
|
"room_type": 201,
|
||||||
|
"type": "room",
|
||||||
|
"window": false
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 61,
|
||||||
|
"name": "bedroom_0",
|
||||||
|
"order": 2,
|
||||||
|
"room_area": 64.0,
|
||||||
|
"room_type": 202,
|
||||||
|
"type": "room",
|
||||||
|
"window": true
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 62,
|
||||||
|
"name": "kitchen_0",
|
||||||
|
"order": 0,
|
||||||
|
"room_area": 16.0,
|
||||||
|
"room_type": 302,
|
||||||
|
"type": "room",
|
||||||
|
"window": true
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 63,
|
||||||
|
"name": "living_room_0",
|
||||||
|
"order": 1,
|
||||||
|
"room_area": 144.0,
|
||||||
|
"room_type": 300,
|
||||||
|
"type": "room",
|
||||||
|
"window": true
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 64,
|
||||||
|
"name": "bathroom_0",
|
||||||
|
"order": 0,
|
||||||
|
"room_area": 16.0,
|
||||||
|
"room_type": 201,
|
||||||
|
"type": "room",
|
||||||
|
"window": false
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 65,
|
||||||
|
"name": "kitchen_0",
|
||||||
|
"order": 0,
|
||||||
|
"room_area": 64.0,
|
||||||
|
"room_type": 302,
|
||||||
|
"type": "room",
|
||||||
|
"window": true
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 66,
|
||||||
|
"name": "living_room_0",
|
||||||
|
"order": 1,
|
||||||
|
"room_area": 64.0,
|
||||||
|
"room_type": 300,
|
||||||
|
"type": "room",
|
||||||
|
"window": true
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 67,
|
||||||
|
"name": "wc_0",
|
||||||
|
"order": 0,
|
||||||
|
"room_area": 16.0,
|
||||||
|
"room_type": 200,
|
||||||
|
"type": "room",
|
||||||
|
"window": false
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 68,
|
||||||
"name": "living_room_0",
|
"name": "living_room_0",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"room_area": 64.0,
|
"room_area": 64.0,
|
||||||
@@ -498,24 +628,44 @@ entries=[ {
|
|||||||
"type": "room",
|
"type": "room",
|
||||||
"window": true
|
"window": true
|
||||||
}, {
|
}, {
|
||||||
"children": [ 57 ],
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 69,
|
||||||
|
"name": "bathroom_0",
|
||||||
|
"order": 0,
|
||||||
|
"room_area": 16.0,
|
||||||
|
"room_type": 201,
|
||||||
|
"type": "room",
|
||||||
|
"window": false
|
||||||
|
}, {
|
||||||
|
"children": [ ],
|
||||||
|
"commands": [ [ 5, [ ] ] ],
|
||||||
|
"index": 70,
|
||||||
|
"name": "living_room_0",
|
||||||
|
"order": 0,
|
||||||
|
"room_area": 64.0,
|
||||||
|
"room_type": 300,
|
||||||
|
"type": "room",
|
||||||
|
"window": true
|
||||||
|
}, {
|
||||||
|
"children": [ 73 ],
|
||||||
"commands": [ ],
|
"commands": [ ],
|
||||||
"index": 55,
|
"index": 71,
|
||||||
"name": "zone_0",
|
"name": "zone_0",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "zone",
|
"type": "zone",
|
||||||
"zone_type": 1
|
"zone_type": 1
|
||||||
}, {
|
}, {
|
||||||
"children": [ 58, 59 ],
|
"children": [ 74, 75 ],
|
||||||
"commands": [ ],
|
"commands": [ ],
|
||||||
"index": 56,
|
"index": 72,
|
||||||
"name": "unit_0",
|
"name": "unit_0",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "unit"
|
"type": "unit"
|
||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ ],
|
"commands": [ ],
|
||||||
"index": 57,
|
"index": 73,
|
||||||
"name": "storage_room_0",
|
"name": "storage_room_0",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"room_area": 64.0,
|
"room_area": 64.0,
|
||||||
@@ -523,17 +673,17 @@ entries=[ {
|
|||||||
"type": "room",
|
"type": "room",
|
||||||
"window": true
|
"window": true
|
||||||
}, {
|
}, {
|
||||||
"children": [ 60 ],
|
"children": [ 76 ],
|
||||||
"commands": [ ],
|
"commands": [ ],
|
||||||
"index": 58,
|
"index": 74,
|
||||||
"name": "zone_0",
|
"name": "zone_0",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "zone",
|
"type": "zone",
|
||||||
"zone_type": 0
|
"zone_type": 0
|
||||||
}, {
|
}, {
|
||||||
"children": [ 61 ],
|
"children": [ 77 ],
|
||||||
"commands": [ ],
|
"commands": [ ],
|
||||||
"index": 59,
|
"index": 75,
|
||||||
"name": "zone_1",
|
"name": "zone_1",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"type": "zone",
|
"type": "zone",
|
||||||
@@ -541,7 +691,7 @@ entries=[ {
|
|||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ ],
|
"commands": [ ],
|
||||||
"index": 60,
|
"index": 76,
|
||||||
"name": "wc_0",
|
"name": "wc_0",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"room_area": 16.0,
|
"room_area": 16.0,
|
||||||
@@ -551,7 +701,7 @@ entries=[ {
|
|||||||
}, {
|
}, {
|
||||||
"children": [ ],
|
"children": [ ],
|
||||||
"commands": [ ],
|
"commands": [ ],
|
||||||
"index": 61,
|
"index": 77,
|
||||||
"name": "living_room_0",
|
"name": "living_room_0",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
"room_area": 16.0,
|
"room_area": 16.0,
|
||||||
|
|||||||
@@ -57,10 +57,17 @@ public:
|
|||||||
void queue_grow_cell(flecs::entity seed_e, int id);
|
void queue_grow_cell(flecs::entity seed_e, int id);
|
||||||
void growth_module(flecs::world &ecs,
|
void growth_module(flecs::world &ecs,
|
||||||
const String &module_name);
|
const String &module_name);
|
||||||
|
void room_growth_module(flecs::world &ecs,
|
||||||
|
const String &module_name);
|
||||||
void create_floor_components(
|
void create_floor_components(
|
||||||
flecs::entity floor_e, flecs::entity base_floor_e,
|
flecs::entity floor_e, flecs::entity base_floor_e,
|
||||||
const WorldEditor::components::buildings_layout_grid_size
|
const WorldEditor::components::buildings_layout_grid_size
|
||||||
&size);
|
&size);
|
||||||
|
void create_region(flecs::entity floor_e, flecs::entity seed_e,
|
||||||
|
flecs::entity region_e,
|
||||||
|
const Vector2i &position, float area);
|
||||||
|
bool check_region(flecs::entity floor_e, int index,
|
||||||
|
const Rect2i &rect);
|
||||||
graph_module(flecs::world &ecs);
|
graph_module(flecs::world &ecs);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -868,7 +868,48 @@ void BuildingLayoutGraphUI::draw_2d_grid_view(Control *draw)
|
|||||||
Math::randf(),
|
Math::randf(),
|
||||||
1);
|
1);
|
||||||
draw->draw_rect(Rect2(dx, dy, dsize, dsize),
|
draw->draw_rect(Rect2(dx, dy, dsize, dsize),
|
||||||
colors[cell.type]);
|
colors[cell.type], true);
|
||||||
|
draw->draw_rect(Rect2(dx, dy, dsize, dsize),
|
||||||
|
Color(0.1f, 0.1f, 0.1f, 1.0f),
|
||||||
|
false);
|
||||||
|
if (fc.has<WorldEditor::components::
|
||||||
|
outside_wall>())
|
||||||
|
draw->draw_circle(
|
||||||
|
Vector2(dx + 0.5f * dsize,
|
||||||
|
dy + 0.5f * dsize),
|
||||||
|
dsize * 0.4f,
|
||||||
|
Color(0, 0, 1, 1));
|
||||||
|
if (fc.has<WorldEditor::components::border>())
|
||||||
|
draw->draw_circle(
|
||||||
|
Vector2(dx + 0.5f * dsize,
|
||||||
|
dy + 0.5f * dsize),
|
||||||
|
dsize * 0.2f,
|
||||||
|
Color(1, 0.3, 1, 1));
|
||||||
|
int mcount = 0;
|
||||||
|
fc.each<WorldEditor::components::
|
||||||
|
belongs_room>([dx, dy, dsize,
|
||||||
|
&mcount, &draw,
|
||||||
|
&colors](
|
||||||
|
flecs::entity
|
||||||
|
re) {
|
||||||
|
assert(mcount == 0);
|
||||||
|
if (!colors.has(String(re.path()))) {
|
||||||
|
colors[String(re.path())] =
|
||||||
|
Color(Math::randf(),
|
||||||
|
Math::randf(),
|
||||||
|
Math::randf(),
|
||||||
|
1.0f);
|
||||||
|
draw->draw_rect(
|
||||||
|
Rect2(dx + 0.1f * dsize,
|
||||||
|
dy + 0.1f * dsize,
|
||||||
|
0.8f * dsize,
|
||||||
|
0.8f * dsize),
|
||||||
|
colors[String(
|
||||||
|
re.path())],
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
mcount++;
|
||||||
|
});
|
||||||
print_line(
|
print_line(
|
||||||
"draw cell: (" + itos(x) + ", " +
|
"draw cell: (" + itos(x) + ", " +
|
||||||
itos(y) + ") (" + String::num(dx) +
|
itos(y) + ") (" + String::num(dx) +
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "world_editor.h"
|
#include "world_editor.h"
|
||||||
#include "editor_event.h"
|
#include "editor_event.h"
|
||||||
#include "building_layout_graph.h"
|
#include "building_layout_graph.h"
|
||||||
|
#include "graph_module.h"
|
||||||
|
|
||||||
#define MIN_ROOM_SIZE 16 /* 4 * 4 tiles */
|
#define MIN_ROOM_SIZE 16 /* 4 * 4 tiles */
|
||||||
|
|
||||||
@@ -265,584 +266,73 @@ void BuildingLayoutGraph::graph_module::queue_grow_cell(flecs::entity seed_e,
|
|||||||
WorldEditor::components::buildings_layout_grid_queue>();
|
WorldEditor::components::buildings_layout_grid_queue>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
|
||||||
const String &module_name)
|
|
||||||
{
|
|
||||||
struct growth_regions {
|
|
||||||
struct region {
|
|
||||||
Rect2i rect;
|
|
||||||
bool can_grow_square;
|
|
||||||
};
|
|
||||||
HashMap<flecs::entity_t, struct region> regions;
|
|
||||||
};
|
|
||||||
ecs.component<growth_regions>();
|
|
||||||
flecs::entity GraphFilter = ecs.entity("GraphFilter")
|
|
||||||
.add(flecs::Phase)
|
|
||||||
.depends_on(flecs::OnUpdate);
|
|
||||||
GraphFilter.disable();
|
|
||||||
|
|
||||||
struct make_random {
|
|
||||||
int seed;
|
|
||||||
int next;
|
|
||||||
make_random(int seed)
|
|
||||||
: seed(seed)
|
|
||||||
, next(seed)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
int get()
|
|
||||||
{
|
|
||||||
next = next * 1103515245 + 12345;
|
|
||||||
return (int)((unsigned)next >> 16) % 32768;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct grid_calc {
|
|
||||||
int grid_size;
|
|
||||||
int index2x(int index)
|
|
||||||
{
|
|
||||||
return index % grid_size;
|
|
||||||
}
|
|
||||||
int index2y(int index)
|
|
||||||
{
|
|
||||||
return index / grid_size;
|
|
||||||
}
|
|
||||||
void get_cadidates(int index, int *candidates)
|
|
||||||
{
|
|
||||||
int i, j, idx = 0;
|
|
||||||
int x = index2x(index);
|
|
||||||
int y = index2y(index);
|
|
||||||
|
|
||||||
for (i = -1; i < 2; i++) {
|
|
||||||
for (j = -1; j < 2; j++)
|
|
||||||
if (i != 0 || j != 0) {
|
|
||||||
int cx = x + i, cy = y + j;
|
|
||||||
if (cx >= 0 && cx < grid_size &&
|
|
||||||
cy >= 0 && cy < grid_size) {
|
|
||||||
int id = cx +
|
|
||||||
grid_size * cy;
|
|
||||||
candidates[idx++] = id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
grid_calc(flecs::entity layout_e)
|
|
||||||
: grid_size(
|
|
||||||
layout_e.get<WorldEditor::components::
|
|
||||||
buildings_layout_grid_size>()
|
|
||||||
->grid_size)
|
|
||||||
{
|
|
||||||
assert(layout_e.is_valid());
|
|
||||||
}
|
|
||||||
grid_calc(int grid_size)
|
|
||||||
: grid_size(grid_size)
|
|
||||||
{
|
|
||||||
assert(grid_size > 0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct grid_misc {
|
|
||||||
LocalVector<Pair<flecs::entity_t, Vector2i> > positions;
|
|
||||||
LocalVector<Vector2i> accepted;
|
|
||||||
struct make_random r;
|
|
||||||
grid_misc()
|
|
||||||
: r(100)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void get_dim_candidates(const Vector2i &base, int dim,
|
|
||||||
Vector2i *candidates)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
std::vector<Vector2i> candidates_data = {
|
|
||||||
/* clang-format off */
|
|
||||||
{ base.x + dim, base.y },
|
|
||||||
{ base.x + dim, base.y + dim },
|
|
||||||
{ base.x, base.y + dim },
|
|
||||||
{ base.x - dim, base.y + dim },
|
|
||||||
{ base.x - dim, base.y },
|
|
||||||
{ base.x - dim, base.y - dim },
|
|
||||||
{ base.x, base.y - dim },
|
|
||||||
{ base.x + dim, base.y - dim },
|
|
||||||
/* clang-format on */
|
|
||||||
};
|
|
||||||
for (i = 0; i < (int)candidates_data.size(); i++)
|
|
||||||
candidates[i] = candidates_data[i];
|
|
||||||
}
|
|
||||||
void setup_floor(
|
|
||||||
flecs::entity grid_e, flecs::entity_t base_et,
|
|
||||||
const WorldEditor::components::buildings_layout_grid_size
|
|
||||||
&size,
|
|
||||||
BuildingLayoutGraph::graph_module *obj)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
flecs::entity base_floor_e =
|
|
||||||
grid_e.world().entity(base_et);
|
|
||||||
flecs::log::warn("base_floor: %s",
|
|
||||||
base_floor_e.path().c_str());
|
|
||||||
int floor_index =
|
|
||||||
base_floor_e
|
|
||||||
.get<WorldEditor::components::
|
|
||||||
buildings_layout_floor_index>()
|
|
||||||
->index;
|
|
||||||
String floor_name = "floor_" + itos(floor_index);
|
|
||||||
flecs::entity floor_e =
|
|
||||||
grid_e.lookup(floor_name.ascii().ptr());
|
|
||||||
print_line("grid: " + String(grid_e.path()));
|
|
||||||
print_line("floor: " + floor_name);
|
|
||||||
assert(floor_e.is_valid());
|
|
||||||
assert(grid_e.is_valid());
|
|
||||||
obj->create_floor_components(floor_e, base_floor_e,
|
|
||||||
size);
|
|
||||||
flecs::log::warn("grid floor: %s",
|
|
||||||
floor_e.path().c_str());
|
|
||||||
for (i = 0; i < (int)positions.size(); i++)
|
|
||||||
for (j = 0; j < (int)positions.size(); j++) {
|
|
||||||
if (i == j)
|
|
||||||
continue;
|
|
||||||
if (positions[i].second ==
|
|
||||||
positions[j].second)
|
|
||||||
flecs::log::err(
|
|
||||||
"duplicate positions");
|
|
||||||
assert(positions[i].second !=
|
|
||||||
positions[j].second);
|
|
||||||
}
|
|
||||||
for (i = 0; i < (int)positions.size(); i++) {
|
|
||||||
int cell_id =
|
|
||||||
positions[i].second.x +
|
|
||||||
size.grid_size * positions[i].second.y;
|
|
||||||
flecs::entity region_e = grid_e.world().entity(
|
|
||||||
positions[i].first);
|
|
||||||
assert(region_e.is_valid());
|
|
||||||
assert(floor_e.is_valid());
|
|
||||||
flecs::entity cell_e = obj->create_cell(
|
|
||||||
floor_e, region_e, cell_id);
|
|
||||||
assert(cell_e.is_valid());
|
|
||||||
flecs::log::warn("grid cell: %s",
|
|
||||||
cell_e.path().c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
float get_entity_area(flecs::entity e) const
|
|
||||||
{
|
|
||||||
return e.get<WorldEditor::components::
|
|
||||||
buildings_layout_area>()
|
|
||||||
->area;
|
|
||||||
}
|
|
||||||
float get_entity_area(flecs::world &&ecs,
|
|
||||||
flecs::entity_t et) const
|
|
||||||
{
|
|
||||||
flecs::entity e = ecs.entity(et);
|
|
||||||
return e.get<WorldEditor::components::
|
|
||||||
buildings_layout_area>()
|
|
||||||
->area;
|
|
||||||
}
|
|
||||||
float get_entity_area(flecs::world &ecs,
|
|
||||||
flecs::entity_t et) const
|
|
||||||
{
|
|
||||||
flecs::entity e = ecs.entity(et);
|
|
||||||
return e.get<WorldEditor::components::
|
|
||||||
buildings_layout_area>()
|
|
||||||
->area;
|
|
||||||
}
|
|
||||||
int get_base_radius(flecs::world &&ecs,
|
|
||||||
flecs::entity_t et) const
|
|
||||||
{
|
|
||||||
float base_area = get_entity_area(ecs, et);
|
|
||||||
int base_radius =
|
|
||||||
(int)((Math::sqrt(base_area) * 1.5f) / 2.0f) /
|
|
||||||
4; /* grid conversion */
|
|
||||||
return base_radius;
|
|
||||||
}
|
|
||||||
int get_base_radius(flecs::world &ecs, flecs::entity_t et) const
|
|
||||||
{
|
|
||||||
float base_area = get_entity_area(ecs, et);
|
|
||||||
int base_radius =
|
|
||||||
(int)((Math::sqrt(base_area) * 1.5f) / 2.0f) /
|
|
||||||
4; /* grid conversion */
|
|
||||||
return base_radius;
|
|
||||||
}
|
|
||||||
int distance_squared(const Vector2i &p1,
|
|
||||||
const Vector2i &p2) const
|
|
||||||
{
|
|
||||||
int lx = p2.x - p1.x;
|
|
||||||
int ly = p2.y - p1.y;
|
|
||||||
return lx * lx + ly * ly;
|
|
||||||
}
|
|
||||||
bool check_candidates_tolerance(const Vector2i check)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
bool ret = true;
|
|
||||||
for (i = 0; i < (int)positions.size(); i++)
|
|
||||||
if (distance_squared(check,
|
|
||||||
positions[i].second) < 1) {
|
|
||||||
ret = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
void filter_candidates(
|
|
||||||
flecs::entity ce, float area,
|
|
||||||
const WorldEditor::components::buildings_layout_grid_size
|
|
||||||
&size)
|
|
||||||
{
|
|
||||||
int which = which_position();
|
|
||||||
if (positions.empty()) {
|
|
||||||
/* starting at grid center */
|
|
||||||
Vector2i start_pos(size.grid_size / 2,
|
|
||||||
size.grid_size / 2);
|
|
||||||
positions.push_back(
|
|
||||||
Pair<flecs::entity_t, Vector2i>(
|
|
||||||
ce.id(), start_pos));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while (1) {
|
|
||||||
int j, k;
|
|
||||||
const Vector2i &base = positions[which].second;
|
|
||||||
flecs::entity_t base_et =
|
|
||||||
positions[which].first;
|
|
||||||
int base_radius =
|
|
||||||
get_base_radius(ce.world(), base_et);
|
|
||||||
base_radius = MAX(1, base_radius);
|
|
||||||
int local_radius =
|
|
||||||
(int)((Math::sqrt(area) * 1.5f) /
|
|
||||||
2.0f) /
|
|
||||||
4; /* grid conversion */
|
|
||||||
local_radius = MAX(1, local_radius);
|
|
||||||
int dim = base_radius + local_radius;
|
|
||||||
dim = MAX(1, dim);
|
|
||||||
/* grid coordinates */
|
|
||||||
Vector2i candidates[8];
|
|
||||||
get_dim_candidates(base, dim, &candidates[0]);
|
|
||||||
for (j = 0; j < (int)(sizeof(candidates) /
|
|
||||||
sizeof(candidates[0]));
|
|
||||||
j++) {
|
|
||||||
print_line("candidate: " +
|
|
||||||
itos(candidates[j].x) +
|
|
||||||
", " +
|
|
||||||
itos(candidates[j].y));
|
|
||||||
if (candidates[j].x < 0 ||
|
|
||||||
candidates[j].x >= size.grid_size)
|
|
||||||
continue;
|
|
||||||
if (candidates[j].y < 0 ||
|
|
||||||
candidates[j].y >= size.grid_size)
|
|
||||||
continue;
|
|
||||||
if (!check_candidates_tolerance(
|
|
||||||
candidates[j]))
|
|
||||||
continue;
|
|
||||||
for (k = 0; k < (int)positions.size();
|
|
||||||
k++) {
|
|
||||||
assert(k <
|
|
||||||
(int)positions.size());
|
|
||||||
flecs::entity_t pbase_et =
|
|
||||||
positions[k].first;
|
|
||||||
float parea = get_entity_area(
|
|
||||||
ce.world(), pbase_et);
|
|
||||||
int pdim =
|
|
||||||
(int)((Math::sqrt(
|
|
||||||
parea) *
|
|
||||||
1.5f) /
|
|
||||||
2.0f) /
|
|
||||||
4; /* radius converted to grid 4x4*/
|
|
||||||
int radius =
|
|
||||||
pdim + local_radius;
|
|
||||||
int radius_sq = radius * radius;
|
|
||||||
if (distance_squared(
|
|
||||||
positions[k].second,
|
|
||||||
candidates[j]) <
|
|
||||||
radius_sq)
|
|
||||||
continue;
|
|
||||||
assert(check_candidates_tolerance(
|
|
||||||
candidates[j]));
|
|
||||||
accepted.push_back(
|
|
||||||
candidates[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (accepted.size() == 0) {
|
|
||||||
which = which_position();
|
|
||||||
print_line(
|
|
||||||
"reset choice: " + itos(which) +
|
|
||||||
" " + itos(positions.size()));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
assert(accepted.size() > 0);
|
|
||||||
const Vector2i &selected =
|
|
||||||
accepted[which_selected()];
|
|
||||||
assert(check_candidates_tolerance(selected));
|
|
||||||
Pair<flecs::entity_t, Vector2i> m(ce.id(),
|
|
||||||
selected);
|
|
||||||
positions.push_back(m);
|
|
||||||
flecs::log::warn("add position: %d, %d",
|
|
||||||
selected.x, selected.y);
|
|
||||||
accepted.clear();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int which_position()
|
|
||||||
{
|
|
||||||
int which;
|
|
||||||
if (positions.size() == 0)
|
|
||||||
return -1;
|
|
||||||
which = r.get() % positions.size();
|
|
||||||
assert(which < (int)positions.size());
|
|
||||||
return which;
|
|
||||||
}
|
|
||||||
int which_selected()
|
|
||||||
{
|
|
||||||
int which;
|
|
||||||
if (accepted.size() == 0)
|
|
||||||
return -1;
|
|
||||||
which = r.get() % accepted.size();
|
|
||||||
assert(which < (int)accepted.size());
|
|
||||||
return which;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ecs.system<const WorldEditor::components::buildings_layout_grid_size>(
|
|
||||||
"CreateGrid")
|
|
||||||
.kind(GraphSolve)
|
|
||||||
.write<WorldEditor::components::buildings_layout_grid>()
|
|
||||||
.each([this](flecs::iter &it, size_t count,
|
|
||||||
const WorldEditor::components::
|
|
||||||
buildings_layout_grid_size &size) {
|
|
||||||
struct grid_misc grid;
|
|
||||||
flecs::entity graph_e = it.entity(count);
|
|
||||||
graph_e.world().defer_suspend();
|
|
||||||
flecs::log::warn("creating grid for: %s",
|
|
||||||
graph_e.path().c_str());
|
|
||||||
flecs::entity grid_base_e = get_layout_grid_base();
|
|
||||||
flecs::entity grid_e =
|
|
||||||
grid_base_e.lookup(graph_e.name());
|
|
||||||
assert(grid_e.is_valid());
|
|
||||||
flecs::log::warn("creating grid for: %s: %s",
|
|
||||||
graph_e.path().c_str(),
|
|
||||||
grid_e.path().c_str());
|
|
||||||
/* starting at grid center */
|
|
||||||
const List<Pair<int, flecs::entity_t> >::Element *me =
|
|
||||||
size.floors.front();
|
|
||||||
while (me) {
|
|
||||||
flecs::query<const WorldEditor::components::
|
|
||||||
buildings_layout_area>
|
|
||||||
q = graph_e.world()
|
|
||||||
.query_builder<
|
|
||||||
const WorldEditor::components::
|
|
||||||
buildings_layout_area>()
|
|
||||||
.with(flecs::ChildOf,
|
|
||||||
me->get().second)
|
|
||||||
.scope_open()
|
|
||||||
.with<WorldEditor::components::
|
|
||||||
buildings_layout_zone>()
|
|
||||||
.or_()
|
|
||||||
.with<WorldEditor::components::
|
|
||||||
buildings_layout_unit>()
|
|
||||||
.scope_close()
|
|
||||||
.build();
|
|
||||||
q.each([size,
|
|
||||||
&grid](flecs::entity ce,
|
|
||||||
const WorldEditor::components::
|
|
||||||
buildings_layout_area
|
|
||||||
&area) {
|
|
||||||
flecs::log::warn(
|
|
||||||
"generating positions for: %s",
|
|
||||||
ce.path().c_str());
|
|
||||||
grid.filter_candidates(ce, area.area,
|
|
||||||
size);
|
|
||||||
});
|
|
||||||
grid.setup_floor(grid_e, me->get().second, size,
|
|
||||||
this);
|
|
||||||
|
|
||||||
me = me->next();
|
|
||||||
}
|
|
||||||
graph_e.world().defer_resume();
|
|
||||||
});
|
|
||||||
ecs.system("AssembleSkeletonEnd")
|
|
||||||
.kind(GraphSolve)
|
|
||||||
.run([module_name](flecs::iter &it) {
|
|
||||||
print_line("Assembling skeleton done...");
|
|
||||||
it.world()
|
|
||||||
.lookup((module_name + "::GraphSolveZones")
|
|
||||||
.ascii()
|
|
||||||
.ptr())
|
|
||||||
.disable();
|
|
||||||
it.world()
|
|
||||||
.lookup((module_name + "::GraphFilter")
|
|
||||||
.ascii()
|
|
||||||
.ptr())
|
|
||||||
.enable();
|
|
||||||
EditorEvent::get_singleton()->event.emit(
|
|
||||||
"update_layout_view", varray());
|
|
||||||
// assert(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
ecs.system<WorldEditor::components::buildings_layout_grid_floor>(
|
|
||||||
"GrowFloorRegions")
|
|
||||||
.kind(0)
|
|
||||||
.each([this](flecs::entity floor_e,
|
|
||||||
WorldEditor::components::buildings_layout_grid_floor
|
|
||||||
&fl) {
|
|
||||||
/* TODO: limit growth per region too */
|
|
||||||
struct grid_calc grid(fl.grid_size);
|
|
||||||
if (fl.size_left <= 0)
|
|
||||||
return;
|
|
||||||
flecs::query<const WorldEditor::components::
|
|
||||||
buildings_layout_grid_cell>
|
|
||||||
q = floor_e.world()
|
|
||||||
.query_builder<
|
|
||||||
const WorldEditor::components::
|
|
||||||
buildings_layout_grid_cell>()
|
|
||||||
.with(flecs::ChildOf, floor_e)
|
|
||||||
.without<WorldEditor::components::
|
|
||||||
final_cell>()
|
|
||||||
.build();
|
|
||||||
q.each([this, &floor_e, &fl,
|
|
||||||
&grid](flecs::entity et,
|
|
||||||
const WorldEditor::components::
|
|
||||||
buildings_layout_grid_cell &cell) {
|
|
||||||
int index = cell.index;
|
|
||||||
assert(et.is_valid());
|
|
||||||
int i;
|
|
||||||
LocalVector<int> candidates;
|
|
||||||
candidates.resize(8);
|
|
||||||
grid.get_cadidates(cell.index,
|
|
||||||
candidates.ptr());
|
|
||||||
int extended = 0;
|
|
||||||
for (i = 0; i < (int)candidates.size(); i++) {
|
|
||||||
if (have_cell(floor_e, candidates[i]))
|
|
||||||
continue;
|
|
||||||
queue_grow_cell(et, candidates[i]);
|
|
||||||
extended++;
|
|
||||||
}
|
|
||||||
if (extended == 0)
|
|
||||||
et.add<WorldEditor::components::
|
|
||||||
final_cell>();
|
|
||||||
print_line("size: " + itos(grid.grid_size) +
|
|
||||||
" index: " + itos(index));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
ecs.system<const WorldEditor::components::buildings_layout_grid_cell>(
|
|
||||||
"GrowRegions")
|
|
||||||
.kind(0)
|
|
||||||
.without<WorldEditor::components::final_cell>()
|
|
||||||
.read<WorldEditor::components::buildings_layout_grid_size>()
|
|
||||||
.write<WorldEditor::components::buildings_layout_grid_cell>()
|
|
||||||
.write<WorldEditor::components::buildings_layout_grid_floor>()
|
|
||||||
.write<WorldEditor::components::buildings_layout_grid_queue>()
|
|
||||||
.each([this](flecs::entity e,
|
|
||||||
const WorldEditor::components::
|
|
||||||
buildings_layout_grid_cell &cell) {
|
|
||||||
e.world().defer_suspend();
|
|
||||||
int index = cell.index;
|
|
||||||
assert(e.is_valid());
|
|
||||||
flecs::entity floor_e = e.parent();
|
|
||||||
assert(floor_e.is_valid());
|
|
||||||
|
|
||||||
flecs::entity grid_e = floor_e.parent();
|
|
||||||
assert(grid_e.is_valid());
|
|
||||||
String layout_name(grid_e.name());
|
|
||||||
flecs::entity base_e = get_layout_base();
|
|
||||||
flecs::entity layout_e =
|
|
||||||
base_e.lookup(layout_name.ascii().ptr());
|
|
||||||
assert(layout_e.is_valid());
|
|
||||||
struct grid_calc grid(layout_e);
|
|
||||||
int i;
|
|
||||||
LocalVector<int> candidates;
|
|
||||||
candidates.resize(8);
|
|
||||||
grid.get_cadidates(cell.index, candidates.ptr());
|
|
||||||
int extended = 0;
|
|
||||||
for (i = 0; i < (int)candidates.size(); i++) {
|
|
||||||
if (have_cell(floor_e, candidates[i]))
|
|
||||||
continue;
|
|
||||||
queue_grow_cell(e, candidates[i]);
|
|
||||||
#if 0
|
|
||||||
String c_name = "cell_" + itos(candidates[i]);
|
|
||||||
flecs::entity c_e =
|
|
||||||
e.parent().lookup(c_name.ascii().ptr());
|
|
||||||
#endif
|
|
||||||
extended++;
|
|
||||||
}
|
|
||||||
if (extended == 0)
|
|
||||||
e.add<WorldEditor::components::final_cell>();
|
|
||||||
print_line("size: " + itos(grid.grid_size) +
|
|
||||||
" index: " + itos(index));
|
|
||||||
e.world().defer_resume();
|
|
||||||
});
|
|
||||||
ecs.system<WorldEditor::components::buildings_layout_grid_floor,
|
|
||||||
WorldEditor::components::buildings_layout_grid_queue>(
|
|
||||||
"GrowCommitQueue")
|
|
||||||
.kind(0)
|
|
||||||
.each([this](flecs::entity e,
|
|
||||||
WorldEditor::components::buildings_layout_grid_floor
|
|
||||||
&fl,
|
|
||||||
WorldEditor::components::buildings_layout_grid_queue
|
|
||||||
&queue) {
|
|
||||||
List<Pair<flecs::entity_t, int> >::Element *me =
|
|
||||||
queue.queue.front();
|
|
||||||
while (me) {
|
|
||||||
flecs::entity seed_e =
|
|
||||||
e.world().entity(me->get().first);
|
|
||||||
int id = me->get().second;
|
|
||||||
if (!fl.cells.has(id)) {
|
|
||||||
grow_cell(seed_e, id);
|
|
||||||
fl.cells.insert(id);
|
|
||||||
}
|
|
||||||
me = me->next();
|
|
||||||
}
|
|
||||||
queue.queue.clear();
|
|
||||||
e.remove<WorldEditor::components::
|
|
||||||
buildings_layout_grid_queue>();
|
|
||||||
});
|
|
||||||
ecs.system("RunGrow").kind(GraphFilter).run([module_name](flecs::iter &it) {
|
|
||||||
int i;
|
|
||||||
it.world().defer_suspend();
|
|
||||||
print_line("Running grow...");
|
|
||||||
for (i = 0; i < 10; i++) {
|
|
||||||
it.world()
|
|
||||||
.system(it.world().lookup(
|
|
||||||
(module_name + "::GrowFloorRegions")
|
|
||||||
.ascii()
|
|
||||||
.ptr()))
|
|
||||||
.run();
|
|
||||||
it.world()
|
|
||||||
.system(it.world().lookup(
|
|
||||||
(module_name + "::GrowCommitQueue")
|
|
||||||
.ascii()
|
|
||||||
.ptr()))
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
it.world().defer_resume();
|
|
||||||
flecs::query<const WorldEditor::components::
|
|
||||||
buildings_layout_grid_floor>
|
|
||||||
q = it.world()
|
|
||||||
.query_builder<
|
|
||||||
const WorldEditor::components::
|
|
||||||
buildings_layout_grid_floor>()
|
|
||||||
.build();
|
|
||||||
int count_left = 0;
|
|
||||||
int count_run = 0;
|
|
||||||
q.each([&count_left,
|
|
||||||
&count_run](flecs::entity e,
|
|
||||||
const WorldEditor::components::
|
|
||||||
buildings_layout_grid_floor &fl) {
|
|
||||||
count_run++;
|
|
||||||
count_left += MAX(0, fl.size_left);
|
|
||||||
});
|
|
||||||
// assert(false);
|
|
||||||
if (count_run > 0 && count_left <= 0) {
|
|
||||||
it.world()
|
|
||||||
.lookup((module_name + "::GraphFilter")
|
|
||||||
.ascii()
|
|
||||||
.ptr())
|
|
||||||
.disable();
|
|
||||||
print_line("Grow done");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildingLayoutGraph::graph_module::create_floor_components(
|
void BuildingLayoutGraph::graph_module::create_floor_components(
|
||||||
flecs::entity floor_e, flecs::entity base_floor_e,
|
flecs::entity floor_e, flecs::entity base_floor_e,
|
||||||
const WorldEditor::components::buildings_layout_grid_size &size)
|
const WorldEditor::components::buildings_layout_grid_size &size)
|
||||||
{
|
{
|
||||||
floor_e.set<WorldEditor::components::buildings_layout_grid_floor>(
|
floor_e.set<WorldEditor::components::buildings_layout_grid_floor>(
|
||||||
{ Set<int>(), size.grid_size, size.growth_size });
|
{ Set<int>(), size.grid_size, size.growth_size });
|
||||||
|
floor_e.set<growth_regions>(
|
||||||
|
{ Vector<struct growth_regions::region>() });
|
||||||
floor_e.add<WorldEditor::components::belongs>(base_floor_e);
|
floor_e.add<WorldEditor::components::belongs>(base_floor_e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BuildingLayoutGraph::graph_module::create_region(flecs::entity floor_e,
|
||||||
|
flecs::entity seed_e,
|
||||||
|
flecs::entity region_e,
|
||||||
|
const Vector2i &position,
|
||||||
|
float area)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct growth_regions::region r;
|
||||||
|
r.seed_et = seed_e.id();
|
||||||
|
r.region_et = region_e.id();
|
||||||
|
r.rect.position = position;
|
||||||
|
r.rect.size = Vector2i(1, 1);
|
||||||
|
r.remains_area = MAX((int)(area * 2.0f) / 16 + 1, 16);
|
||||||
|
r.can_grow_square = true;
|
||||||
|
bool ok = true;
|
||||||
|
assert(check_region(floor_e, -1, r.rect));
|
||||||
|
const struct growth_regions *reg = floor_e.get<growth_regions>();
|
||||||
|
for (i = 0; i < reg->regions.size(); i++) {
|
||||||
|
if (reg->regions[i].region_et == r.region_et) {
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (reg->regions[i].rect.position == r.rect.position) {
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.remains_area -= 1;
|
||||||
|
assert(ok);
|
||||||
|
if (ok) {
|
||||||
|
floor_e.get_mut<growth_regions>()->regions.push_back(r);
|
||||||
|
floor_e.modified<growth_regions>();
|
||||||
|
flecs::log::warn("region created for %s",
|
||||||
|
region_e.path().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BuildingLayoutGraph::graph_module::check_region(flecs::entity floor_e,
|
||||||
|
int index,
|
||||||
|
const Rect2i &rect)
|
||||||
|
{
|
||||||
|
const Vector<growth_regions::region> ®ions =
|
||||||
|
floor_e.get<growth_regions>()->regions;
|
||||||
|
int i;
|
||||||
|
bool ret = true;
|
||||||
|
for (i = 0; i < regions.size(); i++) {
|
||||||
|
if (i == index)
|
||||||
|
continue;
|
||||||
|
if (rect.intersects(regions[i].rect)) {
|
||||||
|
ret = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
|
BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
|
||||||
{
|
{
|
||||||
ecs.module<BuildingLayoutGraph::graph_module>();
|
ecs.module<BuildingLayoutGraph::graph_module>();
|
||||||
@@ -893,6 +383,11 @@ BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
|
|||||||
GraphSolve = ecs.entity("GraphSolve")
|
GraphSolve = ecs.entity("GraphSolve")
|
||||||
.add(flecs::Phase)
|
.add(flecs::Phase)
|
||||||
.depends_on(GraphSolveFloors);
|
.depends_on(GraphSolveFloors);
|
||||||
|
flecs::entity GraphAssembleSkeleton =
|
||||||
|
ecs.entity("GraphAssembleSkeleton")
|
||||||
|
.add(flecs::Phase)
|
||||||
|
.depends_on(GraphSolve);
|
||||||
|
GraphAssembleSkeleton.disable();
|
||||||
flecs::entity GraphPostSolve = ecs.entity("GraphPostSolve")
|
flecs::entity GraphPostSolve = ecs.entity("GraphPostSolve")
|
||||||
.add(flecs::Phase)
|
.add(flecs::Phase)
|
||||||
.depends_on(flecs::PostUpdate);
|
.depends_on(flecs::PostUpdate);
|
||||||
@@ -1060,9 +555,36 @@ BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
|
|||||||
buildings_layout_area &area) {
|
buildings_layout_area &area) {
|
||||||
if (area.area < MIN_ROOM_SIZE) {
|
if (area.area < MIN_ROOM_SIZE) {
|
||||||
badness++;
|
badness++;
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (badness == 0) {
|
||||||
|
it.world()
|
||||||
|
.lookup((module_name +
|
||||||
|
"::GraphSolveUnits")
|
||||||
|
.ascii()
|
||||||
|
.ptr())
|
||||||
|
.enable();
|
||||||
|
it.world()
|
||||||
|
.lookup((module_name +
|
||||||
|
"::GraphSolveFloors")
|
||||||
|
.ascii()
|
||||||
|
.ptr())
|
||||||
|
.enable();
|
||||||
|
} else {
|
||||||
|
it.world()
|
||||||
|
.lookup((module_name +
|
||||||
|
"::GraphSolveUnits")
|
||||||
|
.ascii()
|
||||||
|
.ptr())
|
||||||
|
.disable();
|
||||||
|
it.world()
|
||||||
|
.lookup((module_name +
|
||||||
|
"::GraphSolveFloors")
|
||||||
|
.ascii()
|
||||||
|
.ptr())
|
||||||
|
.disable();
|
||||||
|
}
|
||||||
|
|
||||||
print_line("Zones processing done...");
|
print_line("Zones processing done...");
|
||||||
});
|
});
|
||||||
ecs.system("UnitsStart")
|
ecs.system("UnitsStart")
|
||||||
@@ -1279,10 +801,19 @@ BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
|
|||||||
buildings_layout_area &area) {
|
buildings_layout_area &area) {
|
||||||
if (area.area < MIN_ROOM_SIZE) {
|
if (area.area < MIN_ROOM_SIZE) {
|
||||||
badness++;
|
badness++;
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
print_line("Floor processing done...");
|
if (badness == 0) {
|
||||||
|
flecs::world w = it.world();
|
||||||
|
// create indices
|
||||||
|
w.lookup((module_name +
|
||||||
|
"::GraphAssembleSkeleton")
|
||||||
|
.ascii()
|
||||||
|
.ptr())
|
||||||
|
.enable();
|
||||||
|
print_line("Floor processing done...");
|
||||||
|
} else
|
||||||
|
print_line("Still processing...");
|
||||||
});
|
});
|
||||||
#if 0
|
#if 0
|
||||||
ecs.system<const WorldEditor::components::buildings_layout_graph,
|
ecs.system<const WorldEditor::components::buildings_layout_graph,
|
||||||
@@ -1325,14 +856,14 @@ BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
|
|||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
ecs.system("AssembleSkeletonStart")
|
ecs.system("AssembleSkeletonStart")
|
||||||
.kind(GraphSolve)
|
.kind(GraphAssembleSkeleton)
|
||||||
.run([module_name](flecs::iter &it) {
|
.run([module_name](flecs::iter &it) {
|
||||||
print_line("Assembling skeleton...");
|
print_line("Assembling skeleton...");
|
||||||
});
|
});
|
||||||
|
|
||||||
ecs.system<const WorldEditor::components::buildings_layout_graph>(
|
ecs.system<const WorldEditor::components::buildings_layout_graph>(
|
||||||
"AssembleSkeleton")
|
"AssembleSkeleton")
|
||||||
.kind(GraphSolve)
|
.kind(GraphAssembleSkeleton)
|
||||||
.read<WorldEditor::components::buildings_layout_order>()
|
.read<WorldEditor::components::buildings_layout_order>()
|
||||||
.read<WorldEditor::components::buildings_layout_area>()
|
.read<WorldEditor::components::buildings_layout_area>()
|
||||||
.read<WorldEditor::components::buildings_layout_commands>()
|
.read<WorldEditor::components::buildings_layout_commands>()
|
||||||
@@ -1486,7 +1017,7 @@ BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
|
|||||||
&area) {
|
&area) {
|
||||||
int grid_size = (int)(Math::sqrt(area.area) * 1.5) + 1;
|
int grid_size = (int)(Math::sqrt(area.area) * 1.5) + 1;
|
||||||
int growth_size =
|
int growth_size =
|
||||||
(int)Math::ceil(area.area * 2.0f / 4.0f) + 1;
|
(int)Math::ceil(area.area * 1.3f / 16.0f) + 1;
|
||||||
flecs::entity graph_e = it.entity(count);
|
flecs::entity graph_e = it.entity(count);
|
||||||
List<flecs::entity> queue;
|
List<flecs::entity> queue;
|
||||||
queue.push_back(graph_e);
|
queue.push_back(graph_e);
|
||||||
@@ -1608,6 +1139,7 @@ BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
|
|||||||
it.world().defer_resume();
|
it.world().defer_resume();
|
||||||
});
|
});
|
||||||
growth_module(ecs, module_name);
|
growth_module(ecs, module_name);
|
||||||
|
room_growth_module(ecs, module_name);
|
||||||
#if 0
|
#if 0
|
||||||
ecs.system<WorldEditor::components::buildings_layout_grid_floor>(
|
ecs.system<WorldEditor::components::buildings_layout_grid_floor>(
|
||||||
"AssignGridSizeToFloor")
|
"AssignGridSizeToFloor")
|
||||||
|
|||||||
28
src/modules/stream/ui/graph_module.h
Normal file
28
src/modules/stream/ui/graph_module.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef GRAPH_MODULE_H_
|
||||||
|
#define GRAPH_MODULE_H_
|
||||||
|
struct growth_regions {
|
||||||
|
struct region {
|
||||||
|
flecs::entity_t seed_et;
|
||||||
|
flecs::entity_t region_et;
|
||||||
|
Rect2i rect;
|
||||||
|
int remains_area;
|
||||||
|
bool can_grow_square;
|
||||||
|
};
|
||||||
|
Vector<struct region> regions;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct make_random {
|
||||||
|
int seed;
|
||||||
|
int next;
|
||||||
|
make_random(int seed)
|
||||||
|
: seed(seed)
|
||||||
|
, next(seed)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
int get()
|
||||||
|
{
|
||||||
|
next = next * 1103515245 + 12345;
|
||||||
|
return (int)((unsigned)next >> 16) % 32768;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
790
src/modules/stream/ui/graph_module_growth.cpp
Normal file
790
src/modules/stream/ui/graph_module_growth.cpp
Normal file
@@ -0,0 +1,790 @@
|
|||||||
|
#include "base_data.h"
|
||||||
|
#include "editor_event.h"
|
||||||
|
#include "world_editor.h"
|
||||||
|
#include "building_layout_graph.h"
|
||||||
|
#include "graph_module.h"
|
||||||
|
|
||||||
|
void BuildingLayoutGraph::graph_module::growth_module(flecs::world &ecs,
|
||||||
|
const String &module_name)
|
||||||
|
{
|
||||||
|
ecs.component<growth_regions>();
|
||||||
|
flecs::entity GraphFilter = ecs.entity("GraphFilter")
|
||||||
|
.add(flecs::Phase)
|
||||||
|
.depends_on(flecs::OnUpdate);
|
||||||
|
GraphFilter.disable();
|
||||||
|
|
||||||
|
struct grid_calc {
|
||||||
|
int grid_size;
|
||||||
|
int index2x(int index)
|
||||||
|
{
|
||||||
|
return index % grid_size;
|
||||||
|
}
|
||||||
|
int index2y(int index)
|
||||||
|
{
|
||||||
|
return index / grid_size;
|
||||||
|
}
|
||||||
|
void get_cadidates(int index, int *candidates)
|
||||||
|
{
|
||||||
|
int i, j, idx = 0;
|
||||||
|
int x = index2x(index);
|
||||||
|
int y = index2y(index);
|
||||||
|
|
||||||
|
for (i = -1; i < 2; i++) {
|
||||||
|
for (j = -1; j < 2; j++)
|
||||||
|
if (i != 0 || j != 0) {
|
||||||
|
int cx = x + i, cy = y + j;
|
||||||
|
if (cx >= 0 && cx < grid_size &&
|
||||||
|
cy >= 0 && cy < grid_size) {
|
||||||
|
int id = cx +
|
||||||
|
grid_size * cy;
|
||||||
|
candidates[idx++] = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
grid_calc(flecs::entity layout_e)
|
||||||
|
: grid_size(
|
||||||
|
layout_e.get<WorldEditor::components::
|
||||||
|
buildings_layout_grid_size>()
|
||||||
|
->grid_size)
|
||||||
|
{
|
||||||
|
assert(layout_e.is_valid());
|
||||||
|
}
|
||||||
|
grid_calc(int grid_size)
|
||||||
|
: grid_size(grid_size)
|
||||||
|
{
|
||||||
|
assert(grid_size > 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct grid_misc {
|
||||||
|
LocalVector<Pair<flecs::entity_t, Vector2i> > positions;
|
||||||
|
LocalVector<Vector2i> accepted;
|
||||||
|
struct make_random r;
|
||||||
|
grid_misc()
|
||||||
|
: r(100)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void get_dim_candidates(const Vector2i &base, int dim,
|
||||||
|
Vector2i *candidates)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
std::vector<Vector2i> candidates_data = {
|
||||||
|
/* clang-format off */
|
||||||
|
{ base.x + dim, base.y },
|
||||||
|
{ base.x, base.y + dim },
|
||||||
|
{ base.x - dim, base.y },
|
||||||
|
{ base.x, base.y - dim },
|
||||||
|
{ base.x + dim, base.y },
|
||||||
|
{ base.x, base.y + dim },
|
||||||
|
{ base.x - dim, base.y },
|
||||||
|
{ base.x, base.y - dim },
|
||||||
|
/* clang-format on */
|
||||||
|
};
|
||||||
|
for (i = 0; i < (int)candidates_data.size(); i++)
|
||||||
|
candidates[i] = candidates_data[i];
|
||||||
|
}
|
||||||
|
void setup_floor(
|
||||||
|
flecs::entity grid_e, flecs::entity_t base_et,
|
||||||
|
const WorldEditor::components::buildings_layout_grid_size
|
||||||
|
&size,
|
||||||
|
BuildingLayoutGraph::graph_module *obj)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
flecs::entity base_floor_e =
|
||||||
|
grid_e.world().entity(base_et);
|
||||||
|
flecs::log::warn("base_floor: %s",
|
||||||
|
base_floor_e.path().c_str());
|
||||||
|
int floor_index =
|
||||||
|
base_floor_e
|
||||||
|
.get<WorldEditor::components::
|
||||||
|
buildings_layout_floor_index>()
|
||||||
|
->index;
|
||||||
|
String floor_name = "floor_" + itos(floor_index);
|
||||||
|
flecs::entity floor_e =
|
||||||
|
grid_e.lookup(floor_name.ascii().ptr());
|
||||||
|
print_line("grid: " + String(grid_e.path()));
|
||||||
|
print_line("floor: " + floor_name);
|
||||||
|
assert(floor_e.is_valid());
|
||||||
|
assert(grid_e.is_valid());
|
||||||
|
obj->create_floor_components(floor_e, base_floor_e,
|
||||||
|
size);
|
||||||
|
flecs::log::warn("grid floor: %s",
|
||||||
|
floor_e.path().c_str());
|
||||||
|
for (i = 0; i < (int)positions.size(); i++)
|
||||||
|
for (j = 0; j < (int)positions.size(); j++) {
|
||||||
|
if (i == j)
|
||||||
|
continue;
|
||||||
|
if (positions[i].second ==
|
||||||
|
positions[j].second)
|
||||||
|
flecs::log::err(
|
||||||
|
"duplicate positions");
|
||||||
|
assert(positions[i].second !=
|
||||||
|
positions[j].second);
|
||||||
|
}
|
||||||
|
for (i = 0; i < (int)positions.size(); i++) {
|
||||||
|
int cell_id =
|
||||||
|
positions[i].second.x +
|
||||||
|
size.grid_size * positions[i].second.y;
|
||||||
|
flecs::entity region_e = grid_e.world().entity(
|
||||||
|
positions[i].first);
|
||||||
|
float area =
|
||||||
|
region_e.get<WorldEditor::components::
|
||||||
|
buildings_layout_area>()
|
||||||
|
->area;
|
||||||
|
assert(region_e.is_valid());
|
||||||
|
assert(floor_e.is_valid());
|
||||||
|
Rect2i check;
|
||||||
|
check.position = positions[i].second;
|
||||||
|
check.size = Vector2i(1, 1);
|
||||||
|
assert(obj->check_region(floor_e, -1, check));
|
||||||
|
flecs::entity cell_e = obj->create_cell(
|
||||||
|
floor_e, region_e, cell_id);
|
||||||
|
assert(cell_e.is_valid());
|
||||||
|
obj->create_region(floor_e, cell_e, region_e,
|
||||||
|
positions[i].second, area);
|
||||||
|
flecs::log::warn("grid cell: %s",
|
||||||
|
cell_e.path().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float get_entity_area(flecs::entity e) const
|
||||||
|
{
|
||||||
|
return e.get<WorldEditor::components::
|
||||||
|
buildings_layout_area>()
|
||||||
|
->area;
|
||||||
|
}
|
||||||
|
float get_entity_area(flecs::world &&ecs,
|
||||||
|
flecs::entity_t et) const
|
||||||
|
{
|
||||||
|
flecs::entity e = ecs.entity(et);
|
||||||
|
return e.get<WorldEditor::components::
|
||||||
|
buildings_layout_area>()
|
||||||
|
->area;
|
||||||
|
}
|
||||||
|
float get_entity_area(flecs::world &ecs,
|
||||||
|
flecs::entity_t et) const
|
||||||
|
{
|
||||||
|
flecs::entity e = ecs.entity(et);
|
||||||
|
return e.get<WorldEditor::components::
|
||||||
|
buildings_layout_area>()
|
||||||
|
->area;
|
||||||
|
}
|
||||||
|
int get_base_radius(flecs::world &&ecs,
|
||||||
|
flecs::entity_t et) const
|
||||||
|
{
|
||||||
|
float base_area = get_entity_area(ecs, et);
|
||||||
|
int base_radius =
|
||||||
|
(int)((Math::sqrt(base_area) * 1.6f) / 2.0f) /
|
||||||
|
4; /* grid conversion */
|
||||||
|
return base_radius;
|
||||||
|
}
|
||||||
|
int get_base_radius(flecs::world &ecs, flecs::entity_t et) const
|
||||||
|
{
|
||||||
|
float base_area = get_entity_area(ecs, et);
|
||||||
|
int base_radius =
|
||||||
|
(int)((Math::sqrt(base_area) * 1.6f) / 2.0f) /
|
||||||
|
4; /* grid conversion */
|
||||||
|
return base_radius;
|
||||||
|
}
|
||||||
|
int distance_squared(const Vector2i &p1,
|
||||||
|
const Vector2i &p2) const
|
||||||
|
{
|
||||||
|
int lx = p2.x - p1.x;
|
||||||
|
int ly = p2.y - p1.y;
|
||||||
|
return lx * lx + ly * ly;
|
||||||
|
}
|
||||||
|
bool check_candidates_tolerance(const Vector2i check)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
bool ret = true;
|
||||||
|
for (i = 0; i < (int)positions.size(); i++)
|
||||||
|
if (distance_squared(check,
|
||||||
|
positions[i].second) < 1) {
|
||||||
|
ret = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
bool check_candidate(const Vector2i &candidate)
|
||||||
|
{
|
||||||
|
int m;
|
||||||
|
bool bad = false;
|
||||||
|
for (m = 0; m < (int)positions.size(); m++) {
|
||||||
|
Rect2i check1, check2;
|
||||||
|
check1.position = positions[m].second;
|
||||||
|
check1.size = Vector2i(1, 1);
|
||||||
|
check2.position = candidate;
|
||||||
|
check2.size = Vector2i(1, 1);
|
||||||
|
if (check1.intersects(check2)) {
|
||||||
|
bad = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !bad;
|
||||||
|
}
|
||||||
|
bool accept_candidate(flecs::entity ce,
|
||||||
|
const Vector2i &candidate, float area)
|
||||||
|
{
|
||||||
|
int k;
|
||||||
|
int local_radius =
|
||||||
|
(int)((Math::sqrt(area) * 1.6f) / 2.0f) /
|
||||||
|
4; /* grid conversion */
|
||||||
|
local_radius = MAX(1, local_radius);
|
||||||
|
bool ok = false;
|
||||||
|
for (k = 0; k < (int)positions.size(); k++) {
|
||||||
|
assert(k < (int)positions.size());
|
||||||
|
flecs::entity_t pbase_et = positions[k].first;
|
||||||
|
float parea =
|
||||||
|
get_entity_area(ce.world(), pbase_et);
|
||||||
|
int pdim = (int)((Math::sqrt(parea) * 1.5f) /
|
||||||
|
2.0f) /
|
||||||
|
4; /* radius converted to grid 4x4*/
|
||||||
|
int radius = pdim + local_radius;
|
||||||
|
int radius_sq = radius * radius;
|
||||||
|
if (distance_squared(positions[k].second,
|
||||||
|
candidate) < radius_sq)
|
||||||
|
continue;
|
||||||
|
assert(check_candidates_tolerance(candidate));
|
||||||
|
accepted.push_back(candidate);
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
bool process_candidates(
|
||||||
|
flecs::entity ce, const Vector2i &base, float area,
|
||||||
|
const WorldEditor::components::buildings_layout_grid_size
|
||||||
|
&size,
|
||||||
|
flecs::entity_t base_et, int dim)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
int base_radius = get_base_radius(ce.world(), base_et);
|
||||||
|
base_radius = MAX(1, base_radius);
|
||||||
|
int local_radius =
|
||||||
|
(int)((Math::sqrt(area) * 1.6f) / 2.0f) /
|
||||||
|
4; /* grid conversion */
|
||||||
|
local_radius = MAX(1, local_radius);
|
||||||
|
// int dim = base_radius + local_radius;
|
||||||
|
// dim = MAX(4, dim);
|
||||||
|
int md = 1;
|
||||||
|
if (size.grid_size > 30)
|
||||||
|
md = 8;
|
||||||
|
else if (size.grid_size > 20)
|
||||||
|
md = 6;
|
||||||
|
else if (size.grid_size > 15)
|
||||||
|
md = 4;
|
||||||
|
else if (size.grid_size > 10)
|
||||||
|
md = 2;
|
||||||
|
Rect2i clip(md, md, size.grid_size - md * 2,
|
||||||
|
size.grid_size - md * 2);
|
||||||
|
Vector2i candidates[8];
|
||||||
|
get_dim_candidates(base, dim, &candidates[0]);
|
||||||
|
for (j = 0; j < (int)(sizeof(candidates) /
|
||||||
|
sizeof(candidates[0]));
|
||||||
|
j++) {
|
||||||
|
print_line("base: " + itos(base.x) + ", " +
|
||||||
|
itos(base.y));
|
||||||
|
print_line("possible candidate: " +
|
||||||
|
itos(candidates[j].x) + ", " +
|
||||||
|
itos(candidates[j].y));
|
||||||
|
if (!clip.has_point(candidates[j])) {
|
||||||
|
print_line("clipped by grid field");
|
||||||
|
print_line(clip.operator String());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!check_candidates_tolerance(
|
||||||
|
candidates[j])) {
|
||||||
|
print_line(
|
||||||
|
"too close to existing positions");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!check_candidate(candidates[j])) {
|
||||||
|
print_line(
|
||||||
|
"too close to existing positions (rect)");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
print_line("valid candidate: " +
|
||||||
|
itos(candidates[j].x) + ", " +
|
||||||
|
itos(candidates[j].y));
|
||||||
|
accept_candidate(ce, candidates[j], area);
|
||||||
|
}
|
||||||
|
if (accepted.size() > 0)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void filter_candidates(
|
||||||
|
flecs::entity ce, float area,
|
||||||
|
const WorldEditor::components::buildings_layout_grid_size
|
||||||
|
&size)
|
||||||
|
{
|
||||||
|
if (positions.empty()) {
|
||||||
|
/* starting at grid center */
|
||||||
|
Vector2i start_pos(size.grid_size / 2,
|
||||||
|
size.grid_size / 2);
|
||||||
|
positions.push_back(
|
||||||
|
Pair<flecs::entity_t, Vector2i>(
|
||||||
|
ce.id(), start_pos));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (1) {
|
||||||
|
int which = which_position();
|
||||||
|
const Vector2i &base = positions[which].second;
|
||||||
|
flecs::entity_t base_et =
|
||||||
|
positions[which].first;
|
||||||
|
int base_radius =
|
||||||
|
get_base_radius(ce.world(), base_et);
|
||||||
|
base_radius = MAX(1, base_radius);
|
||||||
|
int local_radius =
|
||||||
|
(int)((Math::sqrt(area) * 1.6f) /
|
||||||
|
2.0f) /
|
||||||
|
4; /* grid conversion */
|
||||||
|
local_radius = MAX(1, local_radius);
|
||||||
|
int dim = base_radius + local_radius;
|
||||||
|
dim = MAX(1, dim);
|
||||||
|
process_candidates(ce, base, area, size,
|
||||||
|
base_et, dim);
|
||||||
|
if (accepted.size() == 0) {
|
||||||
|
assert(positions.size() > 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
assert(accepted.size() > 0);
|
||||||
|
const Vector2i &selected =
|
||||||
|
accepted[which_selected()];
|
||||||
|
assert(check_candidates_tolerance(selected));
|
||||||
|
Pair<flecs::entity_t, Vector2i> m(ce.id(),
|
||||||
|
selected);
|
||||||
|
check_candidate(selected);
|
||||||
|
positions.push_back(m);
|
||||||
|
flecs::log::warn("add position: %d, %d",
|
||||||
|
selected.x, selected.y);
|
||||||
|
accepted.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int which_position()
|
||||||
|
{
|
||||||
|
int which;
|
||||||
|
if (positions.size() == 0)
|
||||||
|
return -1;
|
||||||
|
which = r.get() % positions.size();
|
||||||
|
assert(which < (int)positions.size());
|
||||||
|
return which;
|
||||||
|
}
|
||||||
|
int which_selected()
|
||||||
|
{
|
||||||
|
int which;
|
||||||
|
if (accepted.size() == 0)
|
||||||
|
return -1;
|
||||||
|
which = r.get() % accepted.size();
|
||||||
|
assert(which < (int)accepted.size());
|
||||||
|
return which;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ecs.system<const WorldEditor::components::buildings_layout_grid_size>(
|
||||||
|
"CreateGrid")
|
||||||
|
.kind(GraphSolve)
|
||||||
|
.write<WorldEditor::components::buildings_layout_grid>()
|
||||||
|
.each([this](flecs::iter &it, size_t count,
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_size &size) {
|
||||||
|
struct grid_misc grid;
|
||||||
|
flecs::entity graph_e = it.entity(count);
|
||||||
|
graph_e.world().defer_suspend();
|
||||||
|
flecs::log::warn("creating grid for: %s",
|
||||||
|
graph_e.path().c_str());
|
||||||
|
flecs::entity grid_base_e = get_layout_grid_base();
|
||||||
|
flecs::entity grid_e =
|
||||||
|
grid_base_e.lookup(graph_e.name());
|
||||||
|
assert(grid_e.is_valid());
|
||||||
|
flecs::log::warn("creating grid for: %s: %s",
|
||||||
|
graph_e.path().c_str(),
|
||||||
|
grid_e.path().c_str());
|
||||||
|
/* starting at grid center */
|
||||||
|
const List<Pair<int, flecs::entity_t> >::Element *me =
|
||||||
|
size.floors.front();
|
||||||
|
while (me) {
|
||||||
|
flecs::query<const WorldEditor::components::
|
||||||
|
buildings_layout_area>
|
||||||
|
q = graph_e.world()
|
||||||
|
.query_builder<
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_area>()
|
||||||
|
.with(flecs::ChildOf,
|
||||||
|
me->get().second)
|
||||||
|
.scope_open()
|
||||||
|
.with<WorldEditor::components::
|
||||||
|
buildings_layout_zone>()
|
||||||
|
.or_()
|
||||||
|
.with<WorldEditor::components::
|
||||||
|
buildings_layout_unit>()
|
||||||
|
.scope_close()
|
||||||
|
.build();
|
||||||
|
q.each([size,
|
||||||
|
&grid](flecs::entity ce,
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_area
|
||||||
|
&area) {
|
||||||
|
flecs::log::warn(
|
||||||
|
"generating positions for: %s",
|
||||||
|
ce.path().c_str());
|
||||||
|
grid.filter_candidates(ce, area.area,
|
||||||
|
size);
|
||||||
|
});
|
||||||
|
grid.setup_floor(grid_e, me->get().second, size,
|
||||||
|
this);
|
||||||
|
|
||||||
|
me = me->next();
|
||||||
|
}
|
||||||
|
graph_e.world().defer_resume();
|
||||||
|
});
|
||||||
|
ecs.system("AssembleSkeletonEnd")
|
||||||
|
.kind(GraphSolve)
|
||||||
|
.run([module_name](flecs::iter &it) {
|
||||||
|
print_line("Assembling skeleton done...");
|
||||||
|
it.world()
|
||||||
|
.lookup((module_name + "::GraphSolveZones")
|
||||||
|
.ascii()
|
||||||
|
.ptr())
|
||||||
|
.disable();
|
||||||
|
it.world()
|
||||||
|
.lookup((module_name + "::GraphFilter")
|
||||||
|
.ascii()
|
||||||
|
.ptr())
|
||||||
|
.enable();
|
||||||
|
EditorEvent::get_singleton()->event.emit(
|
||||||
|
"update_layout_view", varray());
|
||||||
|
// assert(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
ecs.system<WorldEditor::components::buildings_layout_grid_floor,
|
||||||
|
growth_regions>("GrowFloorRectRegions")
|
||||||
|
.kind(0)
|
||||||
|
.each([this](flecs::entity floor_e,
|
||||||
|
WorldEditor::components::buildings_layout_grid_floor
|
||||||
|
&fl,
|
||||||
|
growth_regions &g) {
|
||||||
|
int i;
|
||||||
|
bool grown = true;
|
||||||
|
int state = 0;
|
||||||
|
while (1) {
|
||||||
|
while (grown) {
|
||||||
|
grown = false;
|
||||||
|
for (i = 0; i < g.regions.size(); i++) {
|
||||||
|
Rect2i mrect =
|
||||||
|
g.regions[i].rect;
|
||||||
|
if (state == 0) {
|
||||||
|
if (!g.regions[i]
|
||||||
|
.can_grow_square)
|
||||||
|
continue;
|
||||||
|
if (g.regions[i]
|
||||||
|
.remains_area <=
|
||||||
|
0) {
|
||||||
|
g.regions
|
||||||
|
.write[i]
|
||||||
|
.can_grow_square =
|
||||||
|
false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mrect = g.regions[i].rect;
|
||||||
|
int old_area = mrect.get_area();
|
||||||
|
if (state == 0) {
|
||||||
|
mrect = g.regions[i]
|
||||||
|
.rect;
|
||||||
|
|
||||||
|
assert(check_region(
|
||||||
|
floor_e, i,
|
||||||
|
mrect));
|
||||||
|
mrect = mrect.grow(1);
|
||||||
|
Rect2i clip(
|
||||||
|
0, 0,
|
||||||
|
fl.grid_size,
|
||||||
|
fl.grid_size);
|
||||||
|
if (!clip.encloses(
|
||||||
|
mrect))
|
||||||
|
continue;
|
||||||
|
bool ok = check_region(
|
||||||
|
floor_e, i,
|
||||||
|
mrect);
|
||||||
|
if (!ok)
|
||||||
|
continue;
|
||||||
|
int new_area =
|
||||||
|
mrect.get_area();
|
||||||
|
int area_diff =
|
||||||
|
new_area -
|
||||||
|
old_area;
|
||||||
|
if (area_diff > 0) {
|
||||||
|
g.regions
|
||||||
|
.write[i]
|
||||||
|
.rect =
|
||||||
|
mrect;
|
||||||
|
g.regions
|
||||||
|
.write[i]
|
||||||
|
.remains_area -=
|
||||||
|
area_diff;
|
||||||
|
grown = true;
|
||||||
|
}
|
||||||
|
} else if (state == 1) {
|
||||||
|
int d;
|
||||||
|
mrect = g.regions[i]
|
||||||
|
.rect;
|
||||||
|
if (g.regions[i]
|
||||||
|
.remains_area <=
|
||||||
|
0)
|
||||||
|
break;
|
||||||
|
bool ok = true;
|
||||||
|
for (d = 0; d < 4;
|
||||||
|
d++) {
|
||||||
|
mrect = g.regions[i]
|
||||||
|
.rect;
|
||||||
|
assert(check_region(
|
||||||
|
floor_e,
|
||||||
|
i,
|
||||||
|
mrect));
|
||||||
|
switch (d) {
|
||||||
|
case 0:
|
||||||
|
mrect.position
|
||||||
|
.y -=
|
||||||
|
1;
|
||||||
|
mrect.size
|
||||||
|
.y +=
|
||||||
|
1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
mrect.size
|
||||||
|
.y +=
|
||||||
|
1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
mrect.position
|
||||||
|
.x -=
|
||||||
|
1;
|
||||||
|
mrect.size
|
||||||
|
.x +=
|
||||||
|
1;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
mrect.size
|
||||||
|
.x +=
|
||||||
|
1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Rect2i clip(
|
||||||
|
0, 0,
|
||||||
|
fl.grid_size,
|
||||||
|
fl.grid_size);
|
||||||
|
if (!clip.encloses(
|
||||||
|
mrect)) {
|
||||||
|
ok = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = check_region(
|
||||||
|
floor_e,
|
||||||
|
i,
|
||||||
|
mrect);
|
||||||
|
if (ok) {
|
||||||
|
int new_area =
|
||||||
|
mrect.get_area();
|
||||||
|
int area_diff =
|
||||||
|
new_area -
|
||||||
|
old_area;
|
||||||
|
if (area_diff >
|
||||||
|
0) {
|
||||||
|
g.regions
|
||||||
|
.write[i]
|
||||||
|
.rect =
|
||||||
|
mrect;
|
||||||
|
g.regions
|
||||||
|
.write[i]
|
||||||
|
.remains_area -=
|
||||||
|
area_diff;
|
||||||
|
grown = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state++;
|
||||||
|
grown = true;
|
||||||
|
if (state == 2)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (i = 0; i < g.regions.size(); i++) {
|
||||||
|
int x, y;
|
||||||
|
Rect2i rect = g.regions[i].rect;
|
||||||
|
for (x = rect.position.x;
|
||||||
|
x <= rect.position.x + rect.size.x; x++)
|
||||||
|
for (y = rect.position.y;
|
||||||
|
y <= rect.position.y + rect.size.y;
|
||||||
|
y++) {
|
||||||
|
int id = x + fl.grid_size * y;
|
||||||
|
if (!fl.cells.has(id)) {
|
||||||
|
flecs::entity seed_e =
|
||||||
|
floor_e.world().entity(
|
||||||
|
g.regions[i]
|
||||||
|
.seed_et);
|
||||||
|
assert(seed_e.is_valid());
|
||||||
|
queue_grow_cell(seed_e,
|
||||||
|
id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ecs.system<WorldEditor::components::buildings_layout_grid_floor>(
|
||||||
|
"GrowFloorRegions")
|
||||||
|
.kind(0)
|
||||||
|
.each([this](flecs::entity floor_e,
|
||||||
|
WorldEditor::components::buildings_layout_grid_floor
|
||||||
|
&fl) {
|
||||||
|
/* TODO: limit growth per region too */
|
||||||
|
struct grid_calc grid(fl.grid_size);
|
||||||
|
if (fl.size_left <= 0)
|
||||||
|
return;
|
||||||
|
flecs::query<const WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell>
|
||||||
|
q = floor_e.world()
|
||||||
|
.query_builder<
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell>()
|
||||||
|
.with(flecs::ChildOf, floor_e)
|
||||||
|
.without<WorldEditor::components::
|
||||||
|
final_cell>()
|
||||||
|
.build();
|
||||||
|
q.each([this, &floor_e, &fl,
|
||||||
|
&grid](flecs::entity et,
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell &cell) {
|
||||||
|
int index = cell.index;
|
||||||
|
assert(et.is_valid());
|
||||||
|
int i;
|
||||||
|
LocalVector<int> candidates;
|
||||||
|
candidates.resize(8);
|
||||||
|
grid.get_cadidates(cell.index,
|
||||||
|
candidates.ptr());
|
||||||
|
int extended = 0;
|
||||||
|
for (i = 0; i < (int)candidates.size(); i++) {
|
||||||
|
if (have_cell(floor_e, candidates[i]))
|
||||||
|
continue;
|
||||||
|
queue_grow_cell(et, candidates[i]);
|
||||||
|
extended++;
|
||||||
|
}
|
||||||
|
if (extended == 0)
|
||||||
|
et.add<WorldEditor::components::
|
||||||
|
final_cell>();
|
||||||
|
print_line("size: " + itos(grid.grid_size) +
|
||||||
|
" index: " + itos(index));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
ecs.system<const WorldEditor::components::buildings_layout_grid_cell>(
|
||||||
|
"GrowRegions")
|
||||||
|
.kind(0)
|
||||||
|
.without<WorldEditor::components::final_cell>()
|
||||||
|
.read<WorldEditor::components::buildings_layout_grid_size>()
|
||||||
|
.write<WorldEditor::components::buildings_layout_grid_cell>()
|
||||||
|
.write<WorldEditor::components::buildings_layout_grid_floor>()
|
||||||
|
.write<WorldEditor::components::buildings_layout_grid_queue>()
|
||||||
|
.each([this](flecs::entity e,
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell &cell) {
|
||||||
|
e.world().defer_suspend();
|
||||||
|
int index = cell.index;
|
||||||
|
assert(e.is_valid());
|
||||||
|
flecs::entity floor_e = e.parent();
|
||||||
|
assert(floor_e.is_valid());
|
||||||
|
|
||||||
|
flecs::entity grid_e = floor_e.parent();
|
||||||
|
assert(grid_e.is_valid());
|
||||||
|
String layout_name(grid_e.name());
|
||||||
|
flecs::entity base_e = get_layout_base();
|
||||||
|
flecs::entity layout_e =
|
||||||
|
base_e.lookup(layout_name.ascii().ptr());
|
||||||
|
assert(layout_e.is_valid());
|
||||||
|
struct grid_calc grid(layout_e);
|
||||||
|
int i;
|
||||||
|
LocalVector<int> candidates;
|
||||||
|
candidates.resize(8);
|
||||||
|
grid.get_cadidates(cell.index, candidates.ptr());
|
||||||
|
int extended = 0;
|
||||||
|
for (i = 0; i < (int)candidates.size(); i++) {
|
||||||
|
if (have_cell(floor_e, candidates[i]))
|
||||||
|
continue;
|
||||||
|
queue_grow_cell(e, candidates[i]);
|
||||||
|
#if 0
|
||||||
|
String c_name = "cell_" + itos(candidates[i]);
|
||||||
|
flecs::entity c_e =
|
||||||
|
e.parent().lookup(c_name.ascii().ptr());
|
||||||
|
#endif
|
||||||
|
extended++;
|
||||||
|
}
|
||||||
|
if (extended == 0)
|
||||||
|
e.add<WorldEditor::components::final_cell>();
|
||||||
|
print_line("size: " + itos(grid.grid_size) +
|
||||||
|
" index: " + itos(index));
|
||||||
|
e.world().defer_resume();
|
||||||
|
});
|
||||||
|
ecs.system<WorldEditor::components::buildings_layout_grid_floor,
|
||||||
|
WorldEditor::components::buildings_layout_grid_queue>(
|
||||||
|
"GrowCommitQueue")
|
||||||
|
.kind(0)
|
||||||
|
.each([this](flecs::entity e,
|
||||||
|
WorldEditor::components::buildings_layout_grid_floor
|
||||||
|
&fl,
|
||||||
|
WorldEditor::components::buildings_layout_grid_queue
|
||||||
|
&queue) {
|
||||||
|
List<Pair<flecs::entity_t, int> >::Element *me =
|
||||||
|
queue.queue.front();
|
||||||
|
while (me) {
|
||||||
|
flecs::entity seed_e =
|
||||||
|
e.world().entity(me->get().first);
|
||||||
|
int id = me->get().second;
|
||||||
|
if (!fl.cells.has(id)) {
|
||||||
|
grow_cell(seed_e, id);
|
||||||
|
fl.cells.insert(id);
|
||||||
|
}
|
||||||
|
me = me->next();
|
||||||
|
}
|
||||||
|
queue.queue.clear();
|
||||||
|
e.remove<WorldEditor::components::
|
||||||
|
buildings_layout_grid_queue>();
|
||||||
|
});
|
||||||
|
ecs.system("RunGrow")
|
||||||
|
.kind(GraphFilter)
|
||||||
|
.run([module_name](flecs::iter &it) {
|
||||||
|
int i;
|
||||||
|
it.world().defer_suspend();
|
||||||
|
print_line("Running grow...");
|
||||||
|
for (i = 0; i < 100; i++) {
|
||||||
|
it.world()
|
||||||
|
.system(it.world().lookup(
|
||||||
|
(module_name +
|
||||||
|
"::GrowFloorRectRegions")
|
||||||
|
.ascii()
|
||||||
|
.ptr()))
|
||||||
|
.run();
|
||||||
|
it.world()
|
||||||
|
.system(it.world().lookup(
|
||||||
|
(module_name +
|
||||||
|
"::GrowCommitQueue")
|
||||||
|
.ascii()
|
||||||
|
.ptr()))
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
it.world()
|
||||||
|
.system(it.world().lookup(
|
||||||
|
(module_name + "::GrowFloorRegions")
|
||||||
|
.ascii()
|
||||||
|
.ptr()))
|
||||||
|
.run();
|
||||||
|
it.world()
|
||||||
|
.system(it.world().lookup(
|
||||||
|
(module_name + "::GrowCommitQueue")
|
||||||
|
.ascii()
|
||||||
|
.ptr()))
|
||||||
|
.run();
|
||||||
|
#endif
|
||||||
|
it.world().defer_resume();
|
||||||
|
});
|
||||||
|
}
|
||||||
380
src/modules/stream/ui/graph_module_rooms.cpp
Normal file
380
src/modules/stream/ui/graph_module_rooms.cpp
Normal file
@@ -0,0 +1,380 @@
|
|||||||
|
#include "base_data.h"
|
||||||
|
#include "world_editor.h"
|
||||||
|
#include "building_layout_graph.h"
|
||||||
|
#include "graph_module.h"
|
||||||
|
|
||||||
|
void BuildingLayoutGraph::graph_module::room_growth_module(
|
||||||
|
flecs::world &ecs, const String &module_name)
|
||||||
|
{
|
||||||
|
flecs::entity GraphFilter = ecs.entity("GraphFilter");
|
||||||
|
assert(GraphFilter.is_valid());
|
||||||
|
flecs::entity GraphMarkData = ecs.entity("GraphMarkData")
|
||||||
|
.add(flecs::Phase)
|
||||||
|
.depends_on(flecs::OnUpdate);
|
||||||
|
GraphMarkData.disable();
|
||||||
|
flecs::entity GraphProcessRooms = ecs.entity("GraphProcessRooms")
|
||||||
|
.add(flecs::Phase)
|
||||||
|
.depends_on(flecs::OnUpdate);
|
||||||
|
GraphProcessRooms.disable();
|
||||||
|
|
||||||
|
ecs.system("CheckGrow").kind(GraphFilter).run([module_name](flecs::iter &it) {
|
||||||
|
flecs::query<const WorldEditor::components::
|
||||||
|
buildings_layout_grid_floor>
|
||||||
|
q = it.world()
|
||||||
|
.query_builder<
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_floor>()
|
||||||
|
.build();
|
||||||
|
int count_left = 0;
|
||||||
|
int count_run = 0;
|
||||||
|
q.each([&count_left,
|
||||||
|
&count_run](flecs::entity e,
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_floor &fl) {
|
||||||
|
count_run++;
|
||||||
|
count_left += MAX(0, fl.size_left);
|
||||||
|
});
|
||||||
|
// assert(false);
|
||||||
|
if (count_run > 0 && count_left <= 0) {
|
||||||
|
it.world()
|
||||||
|
.lookup((module_name + "::GraphFilter")
|
||||||
|
.ascii()
|
||||||
|
.ptr())
|
||||||
|
.disable();
|
||||||
|
print_line("Grow done");
|
||||||
|
it.world()
|
||||||
|
.lookup((module_name + "::GraphMarkData")
|
||||||
|
.ascii()
|
||||||
|
.ptr())
|
||||||
|
.enable();
|
||||||
|
print_line("Mark started...");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ecs.system<const WorldEditor::components::buildings_layout_grid_cell>(
|
||||||
|
"MarkExternalWall")
|
||||||
|
.kind(GraphMarkData)
|
||||||
|
.without<WorldEditor::components::outside_wall>()
|
||||||
|
.read<WorldEditor::components::buildings_layout_grid_floor>()
|
||||||
|
.write<WorldEditor::components::outside_wall>()
|
||||||
|
.write<WorldEditor::components::final_cell>()
|
||||||
|
.each([](flecs::entity e,
|
||||||
|
const WorldEditor::components::buildings_layout_grid_cell
|
||||||
|
&cell) {
|
||||||
|
int grid_size =
|
||||||
|
e.parent()
|
||||||
|
.get<WorldEditor::components::
|
||||||
|
buildings_layout_grid_floor>()
|
||||||
|
->grid_size;
|
||||||
|
int i;
|
||||||
|
Vector2i position(cell.index % grid_size,
|
||||||
|
cell.index / grid_size);
|
||||||
|
Vector2 west(position.x - 1, position.y);
|
||||||
|
Vector2 north(position.x, position.y - 1);
|
||||||
|
Vector2 east(position.x + 1, position.y);
|
||||||
|
Vector2 south(position.x, position.y + 1);
|
||||||
|
int west_id = west.x + grid_size * west.y;
|
||||||
|
int north_id = north.x + grid_size * north.y;
|
||||||
|
int east_id = east.x + grid_size * east.y;
|
||||||
|
int south_id = south.x + grid_size * south.y;
|
||||||
|
std::vector<int> neighbors = { west_id, north_id,
|
||||||
|
east_id, south_id };
|
||||||
|
bool outside = false;
|
||||||
|
bool border = false;
|
||||||
|
for (i = 0; i < (int)neighbors.size(); i++) {
|
||||||
|
int id = neighbors[i];
|
||||||
|
print_line("id=" + itos(id));
|
||||||
|
if (!e.parent()
|
||||||
|
.get<WorldEditor::components::
|
||||||
|
buildings_layout_grid_floor>()
|
||||||
|
->cells.has(id)) {
|
||||||
|
outside = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < (int)neighbors.size(); i++) {
|
||||||
|
int id = neighbors[i];
|
||||||
|
print_line("id=" + itos(id));
|
||||||
|
String neighbor_name = "cell_" + itos(id);
|
||||||
|
flecs::entity neighbor_e = e.parent().lookup(
|
||||||
|
neighbor_name.ascii().ptr());
|
||||||
|
if (!neighbor_e.is_valid())
|
||||||
|
continue;
|
||||||
|
const WorldEditor::components::buildings_layout_grid_cell
|
||||||
|
*neighbor_cell = neighbor_e.get<
|
||||||
|
WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell>();
|
||||||
|
if (cell.type != neighbor_cell->type) {
|
||||||
|
border = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (outside)
|
||||||
|
e.add<WorldEditor::components::outside_wall>();
|
||||||
|
else
|
||||||
|
e.add<WorldEditor::components::final_cell>();
|
||||||
|
if (border)
|
||||||
|
e.add<WorldEditor::components::border>();
|
||||||
|
print_line("outside: " + itos(outside));
|
||||||
|
print_line("position: " + (position.operator String()));
|
||||||
|
print_line("grid size: " + itos(grid_size));
|
||||||
|
print_line("tile index: " + itos(cell.index));
|
||||||
|
});
|
||||||
|
ecs.system("CheckMark")
|
||||||
|
.kind(GraphMarkData)
|
||||||
|
.run([module_name](flecs::iter &it) {
|
||||||
|
int tile_count = 0, inside_count = 0, wall_count = 0;
|
||||||
|
it.world()
|
||||||
|
.query_builder<
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell>()
|
||||||
|
.build()
|
||||||
|
.each([&tile_count, &inside_count, &wall_count](
|
||||||
|
flecs::entity e,
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell
|
||||||
|
&cell) {
|
||||||
|
tile_count++;
|
||||||
|
if (e.has<WorldEditor::components::
|
||||||
|
outside_wall>())
|
||||||
|
wall_count++;
|
||||||
|
if (e.has<WorldEditor::components::
|
||||||
|
final_cell>())
|
||||||
|
inside_count++;
|
||||||
|
});
|
||||||
|
if (tile_count > 0 && wall_count > 0 &&
|
||||||
|
inside_count > 0 &&
|
||||||
|
tile_count == wall_count + inside_count) {
|
||||||
|
it.world()
|
||||||
|
.lookup((module_name +
|
||||||
|
"::GraphMarkData")
|
||||||
|
.ascii()
|
||||||
|
.ptr())
|
||||||
|
.disable();
|
||||||
|
it.world()
|
||||||
|
.lookup((module_name +
|
||||||
|
"::GraphProcessRooms")
|
||||||
|
.ascii()
|
||||||
|
.ptr())
|
||||||
|
.enable();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
struct prio_queue {
|
||||||
|
HashMap<int, flecs::entity> entities;
|
||||||
|
Set<int> tile_selection[4];
|
||||||
|
Vector<int> tile_selection_array[4];
|
||||||
|
struct make_random r;
|
||||||
|
bool dirty;
|
||||||
|
prio_queue()
|
||||||
|
: r(make_random(100))
|
||||||
|
, dirty(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void add_tile(int prio, int id, flecs::entity ec)
|
||||||
|
{
|
||||||
|
if (!tile_selection[prio].has(id))
|
||||||
|
tile_selection[prio].insert(id);
|
||||||
|
if (!entities.has(id))
|
||||||
|
entities[id] = ec;
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
void update()
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
tile_selection_array[i].resize(
|
||||||
|
tile_selection[i].size());
|
||||||
|
j = 0;
|
||||||
|
Set<int>::Element *m =
|
||||||
|
tile_selection[i].front();
|
||||||
|
while (m) {
|
||||||
|
tile_selection_array[i].write[j++] =
|
||||||
|
m->get();
|
||||||
|
m = m->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void dump()
|
||||||
|
{
|
||||||
|
if (dirty) {
|
||||||
|
update();
|
||||||
|
dirty = false;
|
||||||
|
}
|
||||||
|
print_line("0: " +
|
||||||
|
itos(tile_selection_array[0].size()));
|
||||||
|
print_line("1: " +
|
||||||
|
itos(tile_selection_array[1].size()));
|
||||||
|
print_line("2: " +
|
||||||
|
itos(tile_selection_array[2].size()));
|
||||||
|
}
|
||||||
|
int get_random_tile(int prio)
|
||||||
|
{
|
||||||
|
assert(tile_selection[prio].size() > 0);
|
||||||
|
int sel = r.get() % tile_selection[prio].size();
|
||||||
|
int id = tile_selection_array[prio][sel];
|
||||||
|
assert(entities.has(id));
|
||||||
|
tile_selection_array[prio].erase(id);
|
||||||
|
tile_selection[prio].erase(id);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
void delete_neighbors(int id)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
flecs::entity selected_e = entities[id];
|
||||||
|
int grid_size =
|
||||||
|
selected_e.parent()
|
||||||
|
.get<WorldEditor::components::
|
||||||
|
buildings_layout_grid_floor>()
|
||||||
|
->grid_size;
|
||||||
|
Vector2i base(id % grid_size, id / grid_size);
|
||||||
|
for (i = -1; i < 2; i++)
|
||||||
|
for (j = -1; j < 2; j++) {
|
||||||
|
if (i == 0 && j == 0)
|
||||||
|
continue;
|
||||||
|
Vector2i neighbor =
|
||||||
|
base + Vector2i(i, j);
|
||||||
|
int neighbor_id =
|
||||||
|
neighbor.x +
|
||||||
|
grid_size * neighbor.y;
|
||||||
|
tile_selection_array[0].erase(
|
||||||
|
neighbor_id);
|
||||||
|
tile_selection[0].erase(neighbor_id);
|
||||||
|
if (!tile_selection[3].has(
|
||||||
|
neighbor_id)) {
|
||||||
|
tile_selection_array[3]
|
||||||
|
.push_back(neighbor_id);
|
||||||
|
tile_selection[3].insert(
|
||||||
|
neighbor_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int take_tile()
|
||||||
|
{
|
||||||
|
if (dirty) {
|
||||||
|
update();
|
||||||
|
dirty = false;
|
||||||
|
}
|
||||||
|
if (tile_selection[0].size() > 0) {
|
||||||
|
int id = get_random_tile(0);
|
||||||
|
delete_neighbors(id);
|
||||||
|
return id;
|
||||||
|
} else {
|
||||||
|
int prio;
|
||||||
|
flecs::log::warn(
|
||||||
|
"out of normal tiles, using outside wall and zone borders");
|
||||||
|
for (prio = 1; prio < 4; prio++) {
|
||||||
|
if (tile_selection[prio].size() > 0) {
|
||||||
|
int id = get_random_tile(prio);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flecs::log::err("failed to allocate room initial tile");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
flecs::entity get_entity(int id)
|
||||||
|
{
|
||||||
|
assert(entities.has(id));
|
||||||
|
return entities[id];
|
||||||
|
}
|
||||||
|
int get_total_size()
|
||||||
|
{
|
||||||
|
int ret = 0, i;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
ret += tile_selection[i].size();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ecs.system<const WorldEditor::components::buildings_layout_zone,
|
||||||
|
const WorldEditor::components::buildings_layout_floor_index>(
|
||||||
|
"ProcessFloor0Rooms")
|
||||||
|
.kind(GraphProcessRooms)
|
||||||
|
.read<WorldEditor::components::belongs>()
|
||||||
|
.read<WorldEditor::components::outside_wall>()
|
||||||
|
.read<WorldEditor::components::border>()
|
||||||
|
.each([](flecs::entity e,
|
||||||
|
const WorldEditor::components::buildings_layout_zone
|
||||||
|
&zone,
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_floor_index &idx) {
|
||||||
|
if (idx.index != 0)
|
||||||
|
return;
|
||||||
|
// make_random r(1001);
|
||||||
|
struct prio_queue prio;
|
||||||
|
e.world()
|
||||||
|
.query_builder<
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell>()
|
||||||
|
.with<WorldEditor::components::belongs>(e)
|
||||||
|
.without<WorldEditor::components::outside_wall>()
|
||||||
|
.without<WorldEditor::components::border>()
|
||||||
|
.build()
|
||||||
|
.each([&prio](flecs::entity ec,
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell
|
||||||
|
&cell) {
|
||||||
|
prio.add_tile(0, cell.index, ec);
|
||||||
|
});
|
||||||
|
e.world()
|
||||||
|
.query_builder<
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell>()
|
||||||
|
.with<WorldEditor::components::belongs>(e)
|
||||||
|
.without<WorldEditor::components::outside_wall>()
|
||||||
|
.with<WorldEditor::components::border>()
|
||||||
|
.build()
|
||||||
|
.each([&prio](flecs::entity ec,
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell
|
||||||
|
&cell) {
|
||||||
|
prio.add_tile(1, cell.index, ec);
|
||||||
|
});
|
||||||
|
e.world()
|
||||||
|
.query_builder<
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell>()
|
||||||
|
.with<WorldEditor::components::belongs>(e)
|
||||||
|
.with<WorldEditor::components::outside_wall>()
|
||||||
|
.build()
|
||||||
|
.each([&prio](flecs::entity ec,
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_grid_cell
|
||||||
|
&cell) {
|
||||||
|
prio.add_tile(2, cell.index, ec);
|
||||||
|
});
|
||||||
|
prio.update();
|
||||||
|
prio.dump();
|
||||||
|
if (prio.get_total_size() == 0) {
|
||||||
|
flecs::log::err(
|
||||||
|
"no tiles allocated for zone: %s",
|
||||||
|
e.path().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int count = 0, assigned_count = 0;
|
||||||
|
e.world()
|
||||||
|
.query_builder<const WorldEditor::components::
|
||||||
|
buildings_layout_room>()
|
||||||
|
.with(flecs::ChildOf, e)
|
||||||
|
.build()
|
||||||
|
.each([&prio, &count, &assigned_count](
|
||||||
|
flecs::entity ec,
|
||||||
|
const WorldEditor::components::
|
||||||
|
buildings_layout_room
|
||||||
|
&room) {
|
||||||
|
int id = prio.take_tile();
|
||||||
|
if (id >= 0) {
|
||||||
|
flecs::entity selected_e =
|
||||||
|
prio.get_entity(id);
|
||||||
|
selected_e.add<
|
||||||
|
WorldEditor::components::
|
||||||
|
belongs_room>(
|
||||||
|
ec);
|
||||||
|
assigned_count++;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
});
|
||||||
|
if (assigned_count < count)
|
||||||
|
flecs::log::err(
|
||||||
|
"not all rooms were assigned: %d < %d",
|
||||||
|
assigned_count, count);
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -120,6 +120,9 @@ public:
|
|||||||
int growth_size;
|
int growth_size;
|
||||||
};
|
};
|
||||||
struct belongs {};
|
struct belongs {};
|
||||||
|
struct border {};
|
||||||
|
struct belongs_room {};
|
||||||
|
struct outside_wall {};
|
||||||
struct buildings_layout_grid_floor {
|
struct buildings_layout_grid_floor {
|
||||||
Set<int> cells;
|
Set<int> cells;
|
||||||
int grid_size;
|
int grid_size;
|
||||||
|
|||||||
Reference in New Issue
Block a user