Created
April 1, 2024 02:39
-
-
Save Hellzbellz123/e7c09811d806a3dd7b83ce90c0635850 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// TODO: rethink this code too only spawn 1 hallway per room | |
// maybe try this apporach again now that the room ids are | |
pub fn plan_hallways_two( | |
mut cmds: Commands, | |
mut dungeon_root: Query<&mut DungeonSettings, With<DungeonContainerTag>>, | |
room_query: Query<(&GlobalTransform, &mut PlacedRoom), With<DungeonRoomTag>>, | |
mut exit_query: Query<(&GlobalTransform, &mut RoomExit)>, | |
) { | |
let mut settings = dungeon_root.single_mut(); | |
let mut hallways: Vec<PlacedHallWay> = Vec::new(); | |
let mut rng = ThreadRng::default(); | |
for (_, working_room) in &room_query { | |
info!("working on room {}", working_room.name); | |
let Some(wanted_start) = working_room | |
.exits | |
.iter() | |
.filter(|f| { | |
!exit_query | |
.get(**f) | |
.expect("room exit missing component") | |
.1 | |
.hallway_connected | |
}) | |
.map(|f| (*f, exit_query.get(*f).expect("exit missing components"))) | |
.choose(&mut rng) | |
else { | |
warn!("all room exits were full"); | |
continue; | |
}; | |
let Some(end_room) = &room_query | |
.iter() | |
.filter(|f| { | |
// end room should not be start room | |
f.1.id != working_room.id && | |
// // end room should not be room already having a hallway | |
// hallways.iter().all(|h| f.1.id != h.connected_rooms.0 || f.1.id != h.connected_rooms.1) && | |
// end room should have more than 1 exit | |
f.1.exits.len() > 1 && | |
// end exit should not one that already has a hallway attached | |
f.1.exits | |
.iter() | |
.any(|f| {exit_query.get(*f).expect("msg").1.hallway_connected == false}) | |
}) | |
.min_by(|a, b| { | |
let distance1 = a.1 | |
.position | |
.distance_squared(wanted_start.1 .0.translation().truncate().as_ivec2()); | |
let distance2 = b.1 | |
.position | |
.distance_squared(wanted_start.1 .0.translation().truncate().as_ivec2()); | |
distance1.cmp(&distance2) | |
}) else {continue}; | |
let Some(wanted_end) = end_room | |
.1 | |
.exits | |
.iter() | |
.filter(|f| { | |
exit_query | |
.get(**f) | |
.expect("room exit missing component") | |
.1 | |
.hallway_connected | |
== false | |
}) | |
.map(|f| (*f, exit_query.get(*f).expect("msg"))) | |
.min_by(|a, b| { | |
let distance1 = | |
a.1 .0 | |
.translation() | |
.distance_squared(wanted_start.1 .0.translation()); | |
let distance2 = | |
b.1 .0 | |
.translation() | |
.distance_squared(wanted_start.1 .0.translation()); | |
distance1.total_cmp(&distance2) | |
}) | |
else { | |
continue; | |
}; | |
let length = wanted_start | |
.1 | |
.0 | |
.translation() | |
.distance_squared(wanted_end.1 .0.translation()) as f32; | |
hallways.push(PlacedHallWay { | |
start_pos: wanted_start.1 .0.translation().truncate().as_ivec2(), | |
end_pos: wanted_end.1 .0.translation().truncate().as_ivec2(), | |
distance: length, | |
connected_rooms: (wanted_start.1 .1.parent, wanted_end.1 .1.parent), | |
}); | |
if let Ok(changed_exits) = exit_query.get_many_mut([wanted_start.0, wanted_end.0]) { | |
for mut exit in changed_exits { | |
exit.1.hallway_connected = true | |
} | |
} | |
} | |
settings.positioned_hallways = hallways; | |
cmds.insert_resource(NextState(Some(GeneratorState::PlaceHallwayRoots))); | |
} | |
// TODO: rethink this code too only spawn 1 hallway per room | |
pub fn plan_hallways_one( | |
mut cmds: Commands, | |
mut dungeon_root: Query<&mut DungeonSettings, With<DungeonContainerTag>>, | |
room_query: Query<(&GlobalTransform, &mut PlacedRoom), With<DungeonRoomTag>>, | |
mut exit_query: Query<(&GlobalTransform, &mut RoomExit)>, | |
) { | |
let mut settings = dungeon_root.single_mut(); | |
let mut hallways: Vec<PlacedHallWay> = Vec::new(); | |
let unused_exits = exit_query | |
.iter() | |
.map(|f| f.1) | |
.map(|f| f.clone()) | |
.collect::<Vec<RoomExit>>(); | |
let mut exit_pairs = Vec::new(); | |
let mut distances = Vec::new(); | |
// Calculate distances between all exits | |
for i in 0..unused_exits.len() { | |
for j in 0..unused_exits.len() { | |
let exit1 = &unused_exits[i]; | |
let exit2 = &unused_exits[j]; | |
let room1 = room_query | |
.iter() | |
.find(|f| f.1.id == exit1.parent) | |
.expect("msg"); | |
let room2 = room_query | |
.iter() | |
.find(|f| f.1.id == exit2.parent) | |
.expect("msg"); | |
if room2.1.exits.len().le(&2) && room1.1.exits.len().le(&2) { | |
continue; | |
} | |
if exit1.parent.eq(&exit2.parent) { | |
info!("functionally same exits, skipping"); | |
continue; | |
} | |
let distance: i32 = exit1.position.distance_squared(exit2.position); | |
distances.push((i, j, distance)); | |
} | |
} | |
// Sort distances | |
distances.sort_by(|a, b| a.2.partial_cmp(&b.2).unwrap()); | |
// Pair by distance | |
let mut paired_set = Vec::new(); | |
for pair in distances { | |
let (idx1, idx2, _) = pair; | |
let exit1 = unused_exits[idx1].clone(); | |
let exit2 = unused_exits[idx2].clone(); | |
if exit_pairs.iter().any(|(a, b): &(RoomExit, RoomExit)| { | |
a.parent == exit1.parent || b.parent == exit1.parent //|| a.parent == exit2.parent || b.parent == exit2.parent | |
}) { | |
continue; | |
} | |
if !paired_set.contains(&idx1) && !paired_set.contains(&idx2) { | |
exit_pairs.push((unused_exits[idx1].clone(), unused_exits[idx2].clone())); | |
paired_set.push(idx1); | |
paired_set.push(idx2); | |
} | |
} | |
for (wanted_start, wanted_end) in exit_pairs { | |
hallways.push(PlacedHallWay { | |
start_pos: wanted_start.position, | |
end_pos: wanted_end.position, | |
distance: wanted_start.position.distance_squared(wanted_end.position) as f32, | |
connected_rooms: (wanted_start.parent, wanted_end.parent), | |
}); | |
if let Some((_, mut start)) = exit_query | |
.iter_mut() | |
.find(|(_, exit)| **exit == wanted_start) | |
{ | |
start.hallway_connected = true | |
} | |
if let Some((_, mut end)) = exit_query.iter_mut().find(|(_, exit)| **exit == wanted_end) { | |
end.hallway_connected = true | |
} | |
} | |
settings.positioned_hallways = hallways; | |
cmds.insert_resource(NextState(Some(GeneratorState::PlaceHallwayRoots))); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment