| 1124 | } |
| 1125 | |
| 1126 | void DungeonGeneratorWriter::flushLiquid() { |
| 1127 | // For each liquid type, find each contiguous region of liquid, then |
| 1128 | // pressurize that region based on the highest position in the region |
| 1129 | |
| 1130 | Map<LiquidId, Set<Vec2I>> unpressurizedLiquids; |
| 1131 | for (auto& p : m_pendingLiquids) |
| 1132 | unpressurizedLiquids[p.second.liquid].add(p.first); |
| 1133 | |
| 1134 | for (auto& liquidPair : unpressurizedLiquids) { |
| 1135 | auto& unpressurized = liquidPair.second; |
| 1136 | while (!unpressurized.empty()) { |
| 1137 | // Start with the first unpressurized block as the open set. |
| 1138 | Vec2I firstBlock = unpressurized.takeFirst(); |
| 1139 | List<Vec2I> openSet = {firstBlock}; |
| 1140 | Set<Vec2I> contiguousRegion = {firstBlock}; |
| 1141 | |
| 1142 | // For each element in the previous open set, add all connected blocks |
| 1143 | // in |
| 1144 | // the unpressurized set to the new open set and to the total contiguous |
| 1145 | // region, taking them from the unpressurized set. |
| 1146 | while (!openSet.empty()) { |
| 1147 | auto oldOpenSet = take(openSet); |
| 1148 | for (auto const& p : oldOpenSet) { |
| 1149 | for (auto dir : {Vec2I(1, 0), Vec2I(-1, 0), Vec2I(0, 1), Vec2I(0, -1)}) { |
| 1150 | Vec2I pos = p + dir; |
| 1151 | if (unpressurized.remove(pos)) { |
| 1152 | contiguousRegion.add(pos); |
| 1153 | openSet.append(pos); |
| 1154 | } |
| 1155 | } |
| 1156 | } |
| 1157 | } |
| 1158 | |
| 1159 | // Once we have found no more blocks in the unpressurized set to add to |
| 1160 | // the open set, then we have taken a contiguous region out of the |
| 1161 | // unpressurized set. Pressurize it based on the highest point. |
| 1162 | int highestPoint = lowest<int>(); |
| 1163 | for (auto const& p : contiguousRegion) |
| 1164 | highestPoint = max(highestPoint, p[1]); |
| 1165 | for (auto const& p : contiguousRegion) |
| 1166 | m_pendingLiquids[p].pressure = 1.0f + highestPoint - p[1]; |
| 1167 | } |
| 1168 | } |
| 1169 | |
| 1170 | for (auto& p : m_pendingLiquids) |
| 1171 | setLiquid(p.first, p.second); |
| 1172 | |
| 1173 | m_pendingLiquids.clear(); |
| 1174 | } |
| 1175 | |
| 1176 | void DungeonGeneratorWriter::flush() { |
| 1177 | auto geometry = m_facade->getWorldGeometry(); |