mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
short bridges
This commit is contained in:
parent
3bb66cf2ff
commit
78e227d317
@ -8,7 +8,7 @@ use crate::{
|
||||
site::{namegen::NameGen, Castle, Settlement, Site as WorldSite, Tree},
|
||||
site2,
|
||||
util::{attempt, seed_expan, DHashMap, NEIGHBORS},
|
||||
Index, Land,
|
||||
Index, IndexRef, Land,
|
||||
};
|
||||
use common::{
|
||||
astar::Astar,
|
||||
@ -252,65 +252,73 @@ impl Civs {
|
||||
});
|
||||
|
||||
let mut rng = ctx.reseed().rng;
|
||||
let site = index.sites.insert(match &sim_site.kind {
|
||||
SiteKind::Settlement => {
|
||||
WorldSite::settlement(Settlement::generate(wpos, Some(ctx.sim), &mut rng))
|
||||
},
|
||||
SiteKind::Dungeon => WorldSite::dungeon(site2::Site::generate_dungeon(
|
||||
&Land::from_sim(ctx.sim),
|
||||
&mut rng,
|
||||
wpos,
|
||||
)),
|
||||
SiteKind::Castle => {
|
||||
WorldSite::castle(Castle::generate(wpos, Some(ctx.sim), &mut rng))
|
||||
},
|
||||
SiteKind::Refactor => WorldSite::refactor(site2::Site::generate_city(
|
||||
&Land::from_sim(ctx.sim),
|
||||
&mut rng,
|
||||
wpos,
|
||||
)),
|
||||
SiteKind::CliffTown => WorldSite::cliff_town(site2::Site::generate_cliff_town(
|
||||
&Land::from_sim(ctx.sim),
|
||||
&mut rng,
|
||||
wpos,
|
||||
)),
|
||||
SiteKind::SavannahPit => WorldSite::savannah_pit(
|
||||
site2::Site::generate_savannah_pit(&Land::from_sim(ctx.sim), &mut rng, wpos),
|
||||
),
|
||||
SiteKind::DesertCity => WorldSite::desert_city(site2::Site::generate_desert_city(
|
||||
&Land::from_sim(ctx.sim),
|
||||
&mut rng,
|
||||
wpos,
|
||||
)),
|
||||
SiteKind::Tree => {
|
||||
WorldSite::tree(Tree::generate(wpos, &Land::from_sim(ctx.sim), &mut rng))
|
||||
},
|
||||
SiteKind::GiantTree => WorldSite::giant_tree(site2::Site::generate_giant_tree(
|
||||
&Land::from_sim(ctx.sim),
|
||||
&mut rng,
|
||||
wpos,
|
||||
)),
|
||||
SiteKind::Gnarling => WorldSite::gnarling(site2::Site::generate_gnarling(
|
||||
&Land::from_sim(ctx.sim),
|
||||
&mut rng,
|
||||
wpos,
|
||||
)),
|
||||
SiteKind::ChapelSite => WorldSite::chapel_site(site2::Site::generate_chapel_site(
|
||||
&Land::from_sim(ctx.sim),
|
||||
&mut rng,
|
||||
wpos,
|
||||
)),
|
||||
SiteKind::Citadel => WorldSite::gnarling(site2::Site::generate_citadel(
|
||||
&Land::from_sim(ctx.sim),
|
||||
&mut rng,
|
||||
wpos,
|
||||
)),
|
||||
SiteKind::Bridge(a, b) => WorldSite::bridge(site2::Site::generate_bridge(
|
||||
&Land::from_sim(ctx.sim),
|
||||
&mut rng,
|
||||
*a,
|
||||
*b,
|
||||
)),
|
||||
let site = index.sites.insert({
|
||||
let index_ref = IndexRef {
|
||||
colors: &index.colors(),
|
||||
features: &index.features(),
|
||||
index,
|
||||
};
|
||||
match &sim_site.kind {
|
||||
SiteKind::Settlement => {
|
||||
WorldSite::settlement(Settlement::generate(wpos, Some(ctx.sim), &mut rng))
|
||||
},
|
||||
SiteKind::Dungeon => WorldSite::dungeon(site2::Site::generate_dungeon(
|
||||
&Land::from_sim(ctx.sim),
|
||||
&mut rng,
|
||||
wpos,
|
||||
)),
|
||||
SiteKind::Castle => {
|
||||
WorldSite::castle(Castle::generate(wpos, Some(ctx.sim), &mut rng))
|
||||
},
|
||||
SiteKind::Refactor => WorldSite::refactor(site2::Site::generate_city(
|
||||
&Land::from_sim(ctx.sim),
|
||||
&mut rng,
|
||||
wpos,
|
||||
)),
|
||||
SiteKind::CliffTown => WorldSite::cliff_town(site2::Site::generate_cliff_town(
|
||||
&Land::from_sim(ctx.sim),
|
||||
&mut rng,
|
||||
wpos,
|
||||
)),
|
||||
SiteKind::SavannahPit => {
|
||||
WorldSite::savannah_pit(site2::Site::generate_savannah_pit(
|
||||
&Land::from_sim(ctx.sim),
|
||||
&mut rng,
|
||||
wpos,
|
||||
))
|
||||
},
|
||||
SiteKind::DesertCity => WorldSite::desert_city(
|
||||
site2::Site::generate_desert_city(&Land::from_sim(ctx.sim), &mut rng, wpos),
|
||||
),
|
||||
SiteKind::Tree => {
|
||||
WorldSite::tree(Tree::generate(wpos, &Land::from_sim(ctx.sim), &mut rng))
|
||||
},
|
||||
SiteKind::GiantTree => WorldSite::giant_tree(site2::Site::generate_giant_tree(
|
||||
&Land::from_sim(ctx.sim),
|
||||
&mut rng,
|
||||
wpos,
|
||||
)),
|
||||
SiteKind::Gnarling => WorldSite::gnarling(site2::Site::generate_gnarling(
|
||||
&Land::from_sim(ctx.sim),
|
||||
&mut rng,
|
||||
wpos,
|
||||
)),
|
||||
SiteKind::ChapelSite => WorldSite::chapel_site(
|
||||
site2::Site::generate_chapel_site(&Land::from_sim(ctx.sim), &mut rng, wpos),
|
||||
),
|
||||
SiteKind::Citadel => WorldSite::gnarling(site2::Site::generate_citadel(
|
||||
&Land::from_sim(ctx.sim),
|
||||
&mut rng,
|
||||
wpos,
|
||||
)),
|
||||
SiteKind::Bridge(a, b) => WorldSite::bridge(site2::Site::generate_bridge(
|
||||
&Land::from_sim(ctx.sim),
|
||||
index_ref,
|
||||
&mut rng,
|
||||
*a,
|
||||
*b,
|
||||
)),
|
||||
}
|
||||
});
|
||||
sim_site.site_tmp = Some(site);
|
||||
let site_ref = &index.sites[site];
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::sim;
|
||||
use crate::{column::ColumnGen, sim, util::Sampler, ColumnSample, IndexRef};
|
||||
use common::{terrain::TerrainChunkSize, vol::RectVolSize};
|
||||
use vek::*;
|
||||
|
||||
@ -45,4 +45,13 @@ impl<'a> Land<'a> {
|
||||
) -> Option<(f32, Vec2<f32>, sim::Path, Vec2<f32>)> {
|
||||
self.sim.and_then(|sim| sim.get_nearest_path(wpos))
|
||||
}
|
||||
|
||||
pub fn column_sample<'sample>(
|
||||
&'sample self,
|
||||
wpos: Vec2<i32>,
|
||||
index: IndexRef<'sample>,
|
||||
) -> Option<ColumnSample<'sample>> {
|
||||
self.sim
|
||||
.and_then(|sim| ColumnGen::new(sim).get((wpos, index, None)))
|
||||
}
|
||||
}
|
||||
|
@ -1148,9 +1148,10 @@ impl Painter {
|
||||
|
||||
let stairs = self.ramp(
|
||||
Aabb {
|
||||
min: (corner - right.to_vec2() * (stair_len + thickness))
|
||||
.with_z(z - stair_len),
|
||||
max: (corner - right.to_vec2() * (thickness - 1) - forward.to_vec2() * thickness)
|
||||
min: (corner - right.to_vec2() * (stair_len + thickness)).with_z(z - stair_len),
|
||||
max: (corner
|
||||
- right.to_vec2() * (thickness - 1)
|
||||
- forward.to_vec2() * thickness)
|
||||
.with_z(z + 1),
|
||||
}
|
||||
.made_valid(),
|
||||
|
@ -13,7 +13,7 @@ use crate::{
|
||||
sim::Path,
|
||||
site::{namegen::NameGen, SpawnRules},
|
||||
util::{attempt, DHashSet, Grid, CARDINALS, SQUARE_4, SQUARE_9},
|
||||
Canvas, Land,
|
||||
Canvas, IndexRef, Land,
|
||||
};
|
||||
use common::{
|
||||
astar::Astar,
|
||||
@ -990,6 +990,7 @@ impl Site {
|
||||
|
||||
pub fn generate_bridge(
|
||||
land: &Land,
|
||||
index: IndexRef,
|
||||
rng: &mut impl Rng,
|
||||
start: Vec2<i32>,
|
||||
end: Vec2<i32>,
|
||||
@ -1012,6 +1013,18 @@ impl Site {
|
||||
|
||||
let orth = (start_tile - end_tile).yx().map(|dir| dir.signum().abs());
|
||||
|
||||
let start_aabr = Aabr {
|
||||
min: start_tile.map2(end_tile, |a, b| a.min(b)) - orth * width,
|
||||
max: start_tile.map2(end_tile, |a, b| a.max(b)) + 1 + orth * width,
|
||||
};
|
||||
|
||||
|
||||
let bridge = plot::Bridge::generate(land, index, &mut rng, &site, start_tile, end_tile);
|
||||
|
||||
let start_tile = site.wpos_tile_pos(bridge.start.xy());
|
||||
let end_tile = site.wpos_tile_pos(bridge.end.xy());
|
||||
|
||||
let width = (bridge.width + TILE_SIZE as i32 / 2) / TILE_SIZE as i32;
|
||||
let aabr = Aabr {
|
||||
min: start_tile.map2(end_tile, |a, b| a.min(b)) - orth * width,
|
||||
max: start_tile.map2(end_tile, |a, b| a.max(b)) + 1 + orth * width,
|
||||
@ -1020,20 +1033,18 @@ impl Site {
|
||||
site.create_road(
|
||||
land,
|
||||
&mut rng,
|
||||
aabr.min - 1,
|
||||
aabr.min - 1 + orth * (3 + width * 2),
|
||||
bridge.dir.select_aabr_with(aabr, aabr.center()) + bridge.dir.to_vec2(),
|
||||
bridge.dir.select_aabr_with(start_aabr, aabr.center()),
|
||||
2,
|
||||
);
|
||||
site.create_road(
|
||||
land,
|
||||
&mut rng,
|
||||
aabr.max + 1,
|
||||
aabr.max + 1 - orth * (3 + width * 2),
|
||||
(-bridge.dir).select_aabr_with(aabr, aabr.center()) - bridge.dir.to_vec2(),
|
||||
(-bridge.dir).select_aabr_with(start_aabr, aabr.center()),
|
||||
2,
|
||||
);
|
||||
|
||||
let bridge = plot::Bridge::generate(land, &mut rng, &site, start_tile, end_tile, width);
|
||||
|
||||
|
||||
let plot = site.create_plot(Plot {
|
||||
kind: PlotKind::Bridge(bridge),
|
||||
root_tile: start_tile,
|
||||
@ -1047,6 +1058,40 @@ impl Site {
|
||||
hard_alt: None,
|
||||
});
|
||||
|
||||
|
||||
let size = (1.5 + rng.gen::<f32>().powf(5.0) * 1.0).round() as u32;
|
||||
if let Some((aabr, door_tile, door_dir)) = attempt(32, || {
|
||||
site.find_roadside_aabr(
|
||||
&mut rng,
|
||||
4..(size + 1).pow(2),
|
||||
Extent2::broadcast(size),
|
||||
)
|
||||
}) {
|
||||
let house = plot::House::generate(
|
||||
land,
|
||||
&mut reseed(&mut rng),
|
||||
&site,
|
||||
door_tile,
|
||||
door_dir,
|
||||
aabr,
|
||||
);
|
||||
let house_alt = house.alt;
|
||||
let plot = site.create_plot(Plot {
|
||||
kind: PlotKind::House(house),
|
||||
root_tile: aabr.center(),
|
||||
tiles: aabr_tiles(aabr).collect(),
|
||||
seed: rng.gen(),
|
||||
});
|
||||
|
||||
site.blit_aabr(aabr, Tile {
|
||||
kind: TileKind::Building,
|
||||
plot: Some(plot),
|
||||
hard_alt: Some(house_alt),
|
||||
});
|
||||
} else {
|
||||
site.make_plaza(land, &mut rng);
|
||||
}
|
||||
|
||||
site
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ enum RoofKind {
|
||||
enum BridgeKind {
|
||||
Flat,
|
||||
Tower(RoofKind),
|
||||
Short,
|
||||
}
|
||||
|
||||
fn aabb(min: Vec3<i32>, max: Vec3<i32>) -> Aabb<i32> {
|
||||
@ -24,6 +25,92 @@ fn aabb(min: Vec3<i32>, max: Vec3<i32>) -> Aabb<i32> {
|
||||
}
|
||||
}
|
||||
|
||||
fn render_short(bridge: &Bridge, painter: &Painter) {
|
||||
let rock = Fill::Brick(BlockKind::Rock, Rgb::gray(70), 25);
|
||||
let light_rock = Fill::Block(Block::new(BlockKind::Rock, Rgb::gray(140)));
|
||||
|
||||
let bridge_width = 3;
|
||||
|
||||
let orth_dir = bridge.dir.orthogonal();
|
||||
|
||||
let orthogonal = orth_dir.to_vec2();
|
||||
let forward = bridge.dir.to_vec2();
|
||||
|
||||
let len = (bridge.start.xy() - bridge.end.xy())
|
||||
.map(|e| e.abs())
|
||||
.reduce_max();
|
||||
let inset = 4;
|
||||
|
||||
let height = bridge.end.z + len / 3 - inset;
|
||||
|
||||
let side = orthogonal * bridge_width;
|
||||
|
||||
let remove = painter.vault(
|
||||
aabb(
|
||||
(bridge.start.xy() - side + forward * inset).with_z(bridge.start.z),
|
||||
(bridge.end.xy() + side - forward * inset).with_z(height),
|
||||
),
|
||||
orth_dir,
|
||||
);
|
||||
|
||||
let ramp_in = len / 3;
|
||||
|
||||
let top = height + 2;
|
||||
|
||||
let outset = 7;
|
||||
|
||||
let up_ramp = |point: Vec3<i32>, dir: Dir, side_len: i32| {
|
||||
let forward = dir.to_vec2();
|
||||
let side = dir.orthogonal().to_vec2() * side_len;
|
||||
painter.ramp(
|
||||
aabb(
|
||||
(point.xy() - side - forward * (top - point.z - ramp_in + outset))
|
||||
.with_z(bridge.start.z),
|
||||
(point.xy() + side + forward * ramp_in).with_z(top),
|
||||
),
|
||||
top - point.z + 1 + outset,
|
||||
dir,
|
||||
)
|
||||
};
|
||||
|
||||
let bridge_prim = |side_len: i32| {
|
||||
let side = orthogonal * side_len;
|
||||
painter
|
||||
.aabb(aabb(
|
||||
(bridge.start.xy() - side + forward * ramp_in).with_z(bridge.start.z),
|
||||
(bridge.end.xy() + side - forward * ramp_in).with_z(top),
|
||||
))
|
||||
.union(up_ramp(bridge.start, bridge.dir, side_len).union(up_ramp(
|
||||
bridge.end,
|
||||
-bridge.dir,
|
||||
side_len,
|
||||
)))
|
||||
};
|
||||
|
||||
let b = bridge_prim(bridge_width);
|
||||
|
||||
let t = 4;
|
||||
b.union(painter.aabb(aabb(
|
||||
(bridge.start.xy() - side - forward * (top - bridge.start.z - ramp_in + outset)).with_z(bridge.start.z - t),
|
||||
(bridge.end.xy() + side + forward * (top - bridge.end.z - ramp_in + outset)).with_z(bridge.start.z),
|
||||
)))
|
||||
.translate(Vec3::new(0, 0, t))
|
||||
.without(b)
|
||||
.clear();
|
||||
|
||||
b.without(remove).fill(rock.clone());
|
||||
|
||||
let prim = bridge_prim(bridge_width + 1);
|
||||
|
||||
prim.translate(Vec3::unit_z())
|
||||
.without(prim)
|
||||
.without(painter.aabb(aabb(
|
||||
bridge.start - side - forward * outset,
|
||||
(bridge.end.xy() + side + forward * outset).with_z(top + 1),
|
||||
)))
|
||||
.fill(light_rock);
|
||||
}
|
||||
|
||||
fn render_flat(bridge: &Bridge, painter: &Painter) {
|
||||
let rock = Fill::Block(Block::new(BlockKind::Rock, Rgb::gray(50)));
|
||||
|
||||
@ -98,9 +185,10 @@ fn render_tower(bridge: &Bridge, painter: &Painter, roof_kind: &RoofKind) {
|
||||
|
||||
let tower_end = bridge.end.z + tower_height_extend;
|
||||
|
||||
let tower_center = bridge.start.xy() + forward * tower_size;
|
||||
let tower_aabr = Aabr {
|
||||
min: bridge.start.xy() - tower_size,
|
||||
max: bridge.start.xy() + tower_size,
|
||||
min: tower_center - tower_size,
|
||||
max: tower_center + tower_size,
|
||||
};
|
||||
|
||||
let len = (bridge.dir.select(bridge.end.xy()) - bridge.dir.select_aabr(tower_aabr)).abs();
|
||||
@ -119,7 +207,7 @@ fn render_tower(bridge: &Bridge, painter: &Painter, roof_kind: &RoofKind) {
|
||||
))
|
||||
.clear();
|
||||
|
||||
let c = bridge.start.xy() - forward * tower_size;
|
||||
let c = (-bridge.dir).select_aabr_with(tower_aabr, tower_aabr.center());
|
||||
painter
|
||||
.aabb(aabb(
|
||||
(c - orthogonal).with_z(bridge.start.z),
|
||||
@ -139,7 +227,7 @@ fn render_tower(bridge: &Bridge, painter: &Painter, roof_kind: &RoofKind) {
|
||||
.without(painter.ramp(ramp_aabb, ramp_height, -bridge.dir))
|
||||
.clear();
|
||||
|
||||
let c = bridge.start.xy() + forward * tower_size;
|
||||
let c = bridge.dir.select_aabr_with(tower_aabr, tower_aabr.center());
|
||||
painter
|
||||
.aabb(aabb(
|
||||
(c - orthogonal).with_z(bridge.end.z),
|
||||
@ -236,7 +324,12 @@ fn render_tower(bridge: &Bridge, painter: &Painter, roof_kind: &RoofKind) {
|
||||
.fill(Fill::Sprite(SpriteKind::FireBowlGround));
|
||||
},
|
||||
RoofKind::Hipped => {
|
||||
painter.pyramid(aabb((tower_aabr.min - 1).with_z(tower_end + 1), (tower_aabr.max + 1).with_z(tower_end + 2 + tower_size))).fill(wood.clone());
|
||||
painter
|
||||
.pyramid(aabb(
|
||||
(tower_aabr.min - 1).with_z(tower_end + 1),
|
||||
(tower_aabr.max + 1).with_z(tower_end + 2 + tower_size),
|
||||
))
|
||||
.fill(wood.clone());
|
||||
},
|
||||
}
|
||||
|
||||
@ -251,11 +344,11 @@ fn render_tower(bridge: &Bridge, painter: &Painter, roof_kind: &RoofKind) {
|
||||
let offset = forward * p;
|
||||
|
||||
let size = bridge_width * orthogonal + forward * size;
|
||||
let start = bridge.dir.select_aabr_with(tower_aabr, tower_aabr.center());
|
||||
let start = bridge.dir.select_aabr_with(tower_aabr, tower_aabr.center()) + forward;
|
||||
painter
|
||||
.aabb(aabb(
|
||||
(start - orthogonal * bridge_width).with_z(bridge.center.z - 10),
|
||||
bridge.end.with_z(bridge.end.z - 1) + orthogonal * bridge_width,
|
||||
(bridge.end + orthogonal * bridge_width).with_z(bridge.end.z - 1),
|
||||
))
|
||||
.without(
|
||||
painter
|
||||
@ -270,6 +363,13 @@ fn render_tower(bridge: &Bridge, painter: &Painter, roof_kind: &RoofKind) {
|
||||
)
|
||||
.fill(rock.clone());
|
||||
|
||||
painter
|
||||
.aabb(aabb(
|
||||
(start - orthogonal * bridge_width).with_z(bridge.end.z),
|
||||
(bridge.end + orthogonal * bridge_width).with_z(bridge.end.z + 5),
|
||||
))
|
||||
.clear();
|
||||
|
||||
let light_spacing = 10;
|
||||
let n = len / light_spacing;
|
||||
let p = len / n;
|
||||
@ -285,51 +385,104 @@ fn render_tower(bridge: &Bridge, painter: &Painter, roof_kind: &RoofKind) {
|
||||
}
|
||||
|
||||
pub struct Bridge {
|
||||
start: Vec3<i32>,
|
||||
end: Vec3<i32>,
|
||||
center: Vec3<i32>,
|
||||
dir: Dir,
|
||||
kind: BridgeKind,
|
||||
pub(crate) start: Vec3<i32>,
|
||||
pub(crate) end: Vec3<i32>,
|
||||
pub(crate) width: i32,
|
||||
pub(crate) dir: Dir,
|
||||
center: Vec3<i32>,
|
||||
kind: BridgeKind,
|
||||
}
|
||||
|
||||
impl Bridge {
|
||||
pub fn generate(
|
||||
land: &Land,
|
||||
index: IndexRef,
|
||||
rng: &mut impl Rng,
|
||||
site: &Site,
|
||||
start: Vec2<i32>,
|
||||
end: Vec2<i32>,
|
||||
width: i32,
|
||||
) -> Self {
|
||||
let start = site.tile_center_wpos(start);
|
||||
let end = site.tile_center_wpos(end);
|
||||
let width = width * TILE_SIZE as i32 + TILE_SIZE as i32 / 2;
|
||||
let start = site.tile_wpos(start);
|
||||
let end = site.tile_wpos(end);
|
||||
|
||||
let center = (start + end) / 2;
|
||||
let min_water_dist = 5;
|
||||
let find_edge = |start: Vec2<i32>, end: Vec2<i32>| {
|
||||
let mut test_start = start;
|
||||
let dir = Dir::from_vector(end - start).to_vec2();
|
||||
let mut last_alt = if let Some(col) = land.column_sample(start, index) {
|
||||
col.alt as i32
|
||||
} else {
|
||||
return test_start.with_z(land.get_alt_approx(start) as i32);
|
||||
};
|
||||
let mut step = 0;
|
||||
loop {
|
||||
if let Some(sample) = land.column_sample(test_start + step * dir, index) {
|
||||
let alt = sample.alt as i32;
|
||||
if last_alt - alt > 1 + (step + 3) / 4
|
||||
|| sample.riverless_alt - sample.alt > 2.0
|
||||
{
|
||||
break test_start.with_z(last_alt);
|
||||
} else {
|
||||
let water_dist = sample.water_dist.unwrap_or(16.0) as i32;
|
||||
|
||||
let mut start = start.with_z(land.get_alt_approx(start) as i32);
|
||||
let mut end = end.with_z(land.get_alt_approx(end) as i32);
|
||||
if start.z > end.z {
|
||||
std::mem::swap(&mut start, &mut end);
|
||||
}
|
||||
test_start += step * dir;
|
||||
|
||||
if water_dist <= min_water_dist {
|
||||
break test_start.with_z(alt);
|
||||
}
|
||||
|
||||
step = water_dist - min_water_dist;
|
||||
|
||||
last_alt = alt;
|
||||
}
|
||||
} else {
|
||||
break test_start.with_z(last_alt);
|
||||
}
|
||||
|
||||
/*
|
||||
let alt = land.get_alt_approx(test_start + dir);
|
||||
let is_water = land.get_chunk_wpos(test_start + dir * 5).map_or(false, |chunk| chunk.river.river_kind.is_some());
|
||||
if is_water || last_alt - alt as i32 > 1 || start.z - alt as i32 > 5 {
|
||||
break test_start.with_z(last_alt);
|
||||
}
|
||||
last_alt = alt as i32;
|
||||
|
||||
test_start += dir;
|
||||
*/
|
||||
}
|
||||
};
|
||||
|
||||
let test_start = find_edge(start, end);
|
||||
|
||||
let test_end = find_edge(end, start);
|
||||
|
||||
let (start, end) = if test_start.z < test_end.z {
|
||||
(test_start, test_end)
|
||||
} else {
|
||||
(test_end, test_start)
|
||||
};
|
||||
|
||||
let center = (start.xy() + end.xy()) / 2;
|
||||
let center = center.with_z(land.get_alt_approx(center) as i32);
|
||||
|
||||
let len = (start.xy() - end.xy()).map(|e| e.abs()).reduce_max();
|
||||
|
||||
Self {
|
||||
start,
|
||||
end,
|
||||
center,
|
||||
dir: Dir::from_vector(end.xy() - start.xy()),
|
||||
kind: if end.z - start.z > 10 {
|
||||
kind: if end.z - start.z > 14 {
|
||||
BridgeKind::Tower(match rng.gen_range(0..=2) {
|
||||
0 => RoofKind::Crenelated,
|
||||
_ => RoofKind::Hipped,
|
||||
})
|
||||
} else if len < 40 {
|
||||
BridgeKind::Short
|
||||
} else {
|
||||
BridgeKind::Flat
|
||||
},
|
||||
width,
|
||||
width: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -337,8 +490,9 @@ impl Bridge {
|
||||
impl Structure for Bridge {
|
||||
fn render(&self, _site: &Site, _land: &Land, painter: &Painter) {
|
||||
match &self.kind {
|
||||
BridgeKind::Flat => render_flat(&self, painter),
|
||||
BridgeKind::Tower(roof) => render_tower(&self, painter, roof),
|
||||
BridgeKind::Flat => render_flat(self, painter),
|
||||
BridgeKind::Tower(roof) => render_tower(self, painter, roof),
|
||||
BridgeKind::Short => render_short(self, painter),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ pub enum Dir {
|
||||
}
|
||||
|
||||
impl Dir {
|
||||
|
||||
pub const ALL: [Dir; 4] = [Dir::X, Dir::Y, Dir::NegX, Dir::NegY];
|
||||
|
||||
pub fn choose(rng: &mut impl Rng) -> Dir {
|
||||
|
Loading…
Reference in New Issue
Block a user