mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'fix-dungeon-collision' into 'master'
Fix dungeon collision See merge request veloren/veloren!3131
This commit is contained in:
commit
cb45cea6a0
@ -112,7 +112,7 @@ impl Civs {
|
|||||||
29..=31 => (SiteKind::Tree, 4),
|
29..=31 => (SiteKind::Tree, 4),
|
||||||
_ => (SiteKind::Dungeon, 0),
|
_ => (SiteKind::Dungeon, 0),
|
||||||
};
|
};
|
||||||
let loc = find_site_loc(&mut ctx, None, size)?;
|
let loc = find_site_loc(&mut ctx, None, size, kind)?;
|
||||||
Some(this.establish_site(&mut ctx.reseed(), loc, |place| Site {
|
Some(this.establish_site(&mut ctx.reseed(), loc, |place| Site {
|
||||||
kind,
|
kind,
|
||||||
center: loc,
|
center: loc,
|
||||||
@ -437,7 +437,7 @@ impl Civs {
|
|||||||
|
|
||||||
fn birth_civ(&mut self, ctx: &mut GenCtx<impl Rng>) -> Option<Id<Civ>> {
|
fn birth_civ(&mut self, ctx: &mut GenCtx<impl Rng>) -> Option<Id<Civ>> {
|
||||||
let site = attempt(5, || {
|
let site = attempt(5, || {
|
||||||
let loc = find_site_loc(ctx, None, 1)?;
|
let loc = find_site_loc(ctx, None, 1, SiteKind::Settlement)?;
|
||||||
Some(self.establish_site(ctx, loc, |place| Site {
|
Some(self.establish_site(ctx, loc, |place| Site {
|
||||||
kind: SiteKind::Settlement,
|
kind: SiteKind::Settlement,
|
||||||
site_tmp: None,
|
site_tmp: None,
|
||||||
@ -911,14 +911,26 @@ 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
|
/// Return true if a site could be constructed between a location and a chunk
|
||||||
/// next to it is permitted (TODO: by whom?)
|
/// next to it is permitted (TODO: by whom?)
|
||||||
fn site_in_dir(sim: &WorldSim, a: Vec2<i32>, dir: Vec2<i32>) -> bool {
|
fn site_in_dir(sim: &WorldSim, a: Vec2<i32>, dir: Vec2<i32>, site_kind: SiteKind) -> bool {
|
||||||
loc_suitable_for_site(sim, a) && loc_suitable_for_site(sim, a + dir)
|
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>) -> bool {
|
fn loc_suitable_for_site(sim: &WorldSim, loc: Vec2<i32>, site_kind: SiteKind) -> bool {
|
||||||
if let Some(chunk) = sim.get(loc) {
|
fn check_chunk_occupation(sim: &WorldSim, loc: Vec2<i32>, radius: i32) -> bool {
|
||||||
|
for x in (-radius)..radius {
|
||||||
|
for y in (-radius)..radius {
|
||||||
|
let check_loc =
|
||||||
|
loc + Vec2::new(x, y).map2(TerrainChunkSize::RECT_SIZE, |e, sz| e * sz as i32);
|
||||||
|
if sim.get(check_loc).map_or(true, |c| !c.sites.is_empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
(if let Some(chunk) = sim.get(loc) {
|
||||||
!chunk.river.is_ocean()
|
!chunk.river.is_ocean()
|
||||||
&& !chunk.river.is_lake()
|
&& !chunk.river.is_lake()
|
||||||
&& !chunk.river.is_river()
|
&& !chunk.river.is_river()
|
||||||
@ -928,7 +940,7 @@ fn loc_suitable_for_site(sim: &WorldSim, loc: Vec2<i32>) -> bool {
|
|||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}) && check_chunk_occupation(sim, loc, site_kind.exclusion_radius())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to search for a location that's suitable for site construction
|
/// Attempt to search for a location that's suitable for site construction
|
||||||
@ -936,6 +948,7 @@ fn find_site_loc(
|
|||||||
ctx: &mut GenCtx<impl Rng>,
|
ctx: &mut GenCtx<impl Rng>,
|
||||||
near: Option<(Vec2<i32>, f32)>,
|
near: Option<(Vec2<i32>, f32)>,
|
||||||
size: i32,
|
size: i32,
|
||||||
|
site_kind: SiteKind,
|
||||||
) -> Option<Vec2<i32>> {
|
) -> Option<Vec2<i32>> {
|
||||||
const MAX_ATTEMPTS: usize = 100;
|
const MAX_ATTEMPTS: usize = 100;
|
||||||
let mut loc = None;
|
let mut loc = None;
|
||||||
@ -957,7 +970,7 @@ fn find_site_loc(
|
|||||||
});
|
});
|
||||||
|
|
||||||
for offset in Spiral2d::new().take((size * 2 + 1).pow(2) as usize) {
|
for offset in Spiral2d::new().take((size * 2 + 1).pow(2) as usize) {
|
||||||
if loc_suitable_for_site(ctx.sim, test_loc + offset) {
|
if loc_suitable_for_site(ctx.sim, test_loc + offset, site_kind) {
|
||||||
return Some(test_loc);
|
return Some(test_loc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1015,7 +1028,7 @@ impl fmt::Display for Site {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum SiteKind {
|
pub enum SiteKind {
|
||||||
Settlement,
|
Settlement,
|
||||||
Dungeon,
|
Dungeon,
|
||||||
@ -1024,6 +1037,16 @@ pub enum SiteKind {
|
|||||||
Tree,
|
Tree,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SiteKind {
|
||||||
|
pub fn exclusion_radius(&self) -> i32 {
|
||||||
|
// FIXME: Provide specific values for each individual SiteKind
|
||||||
|
match self {
|
||||||
|
SiteKind::Dungeon => 4,
|
||||||
|
_ => 2, // This is just an arbitrary value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Site {
|
impl Site {
|
||||||
pub fn is_dungeon(&self) -> bool { matches!(self.kind, SiteKind::Dungeon) }
|
pub fn is_dungeon(&self) -> bool { matches!(self.kind, SiteKind::Dungeon) }
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user