mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Switch back to 100 attempts for each site, optimization of
find_site_loc, and fix pre-existing bugs. * In two spots, there were suspicious conversions between chunk positions / world positions that I removed. Everything, here should just be in chunk positions afaict! * Optimized by skipping further checks if `in_suitable_loc` is false (main optimization (10x speedup for desert city site location finding attempts)) as well as only computing `in_suitable_loc` once (minor optimization).
This commit is contained in:
parent
ddf9e0eaab
commit
d29a1ec052
@ -707,10 +707,7 @@ impl Civs {
|
|||||||
13..=18 => SiteKind::SavannahPit,
|
13..=18 => SiteKind::SavannahPit,
|
||||||
_ => SiteKind::Refactor,
|
_ => SiteKind::Refactor,
|
||||||
};
|
};
|
||||||
// TODO: A desert city fails all 100 attemps here on startup and each failed
|
let site = attempt(100, || {
|
||||||
// attempt takes ~10 ms on my machine (so overall it takes about 1
|
|
||||||
// second). Use less brute force method?
|
|
||||||
let site = attempt(/* 100 */ 15, || {
|
|
||||||
let avoid_town_enemies =
|
let avoid_town_enemies =
|
||||||
ProximityRequirements::new().avoid_all_of(self.town_enemies(), 60);
|
ProximityRequirements::new().avoid_all_of(self.town_enemies(), 60);
|
||||||
let loc = find_site_loc(ctx, &avoid_town_enemies, kind)?;
|
let loc = find_site_loc(ctx, &avoid_town_enemies, kind)?;
|
||||||
@ -1433,19 +1430,18 @@ fn loc_suitable_for_walking(sim: &WorldSim, loc: Vec2<i32>) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return true if a site could be constructed between a location and a chunk
|
|
||||||
/// next to it is permitted (TODO: by whom?)
|
|
||||||
fn site_in_dir(sim: &WorldSim, a: Vec2<i32>, dir: Vec2<i32>, site_kind: SiteKind) -> bool {
|
|
||||||
loc_suitable_for_site(sim, a, site_kind) && loc_suitable_for_site(sim, a + dir, site_kind)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return true if a position is suitable for site construction (TODO:
|
/// Return true if a position is suitable for site construction (TODO:
|
||||||
/// criteria?)
|
/// criteria?)
|
||||||
fn loc_suitable_for_site(sim: &WorldSim, loc: Vec2<i32>, site_kind: SiteKind) -> bool {
|
fn loc_suitable_for_site(
|
||||||
|
sim: &WorldSim,
|
||||||
|
loc: Vec2<i32>,
|
||||||
|
site_kind: SiteKind,
|
||||||
|
is_suitable_loc: bool,
|
||||||
|
) -> bool {
|
||||||
fn check_chunk_occupation(sim: &WorldSim, loc: Vec2<i32>, radius: i32) -> bool {
|
fn check_chunk_occupation(sim: &WorldSim, loc: Vec2<i32>, radius: i32) -> bool {
|
||||||
for x in (-radius)..radius {
|
for x in (-radius)..radius {
|
||||||
for y in (-radius)..radius {
|
for y in (-radius)..radius {
|
||||||
let check_loc = loc + Vec2::new(x, y).cpos_to_wpos();
|
let check_loc = loc + Vec2::new(x, y);
|
||||||
if sim.get(check_loc).map_or(false, |c| !c.sites.is_empty()) {
|
if sim.get(check_loc).map_or(false, |c| !c.sites.is_empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1453,8 +1449,9 @@ fn loc_suitable_for_site(sim: &WorldSim, loc: Vec2<i32>, site_kind: SiteKind) ->
|
|||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
let not_occupied = check_chunk_occupation(sim, loc, site_kind.exclusion_radius());
|
let not_occupied = || check_chunk_occupation(sim, loc, site_kind.exclusion_radius());
|
||||||
site_kind.is_suitable_loc(loc, sim) && not_occupied
|
// only check occupation if the location is suitable
|
||||||
|
is_suitable_loc && not_occupied()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to search for a location that's suitable for site construction
|
/// Attempt to search for a location that's suitable for site construction
|
||||||
@ -1474,16 +1471,15 @@ fn find_site_loc(
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
if proximity_reqs.satisfied_by(test_loc) {
|
let is_suitable_loc = site_kind.is_suitable_loc(test_loc, ctx.sim);
|
||||||
if loc_suitable_for_site(ctx.sim, test_loc, site_kind) {
|
if is_suitable_loc && proximity_reqs.satisfied_by(test_loc) {
|
||||||
|
if loc_suitable_for_site(ctx.sim, test_loc, site_kind, is_suitable_loc) {
|
||||||
return Some(test_loc);
|
return Some(test_loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
loc = ctx.sim.get(test_loc).and_then(|c| {
|
// If the current location is suitable and meets proximity requirements,
|
||||||
site_kind
|
// try nearby spot downhill.
|
||||||
.is_suitable_loc(test_loc, ctx.sim)
|
loc = ctx.sim.get(test_loc).and_then(|c| c.downhill);
|
||||||
.then_some(c.downhill?.wpos_to_cpos())
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user