mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
better flat
This commit is contained in:
parent
6d2b39c254
commit
179c6dab8f
@ -189,10 +189,7 @@ impl Civs {
|
||||
SiteKind::GiantTree => (12i32, 8.0),
|
||||
SiteKind::Gnarling => (16i32, 10.0),
|
||||
SiteKind::Citadel => (16i32, 0.0),
|
||||
SiteKind::Bridge(start, end) => {
|
||||
let e = (end - start).map(|e| e.abs()).reduce_max();
|
||||
((e + 1) / 2, ((e + 1) / 2) as f32 / 2.0)
|
||||
},
|
||||
SiteKind::Bridge(_, _) => (0, 0.0),
|
||||
};
|
||||
|
||||
let (raise, raise_dist, make_waypoint): (f32, i32, bool) = match &site.kind {
|
||||
@ -1264,9 +1261,9 @@ fn walk_in_dir(
|
||||
3.0 // + (1.0 - b_chunk.tree_density) * 20.0 // Prefer going through forests, for aesthetics
|
||||
};
|
||||
Some((a + dir, 1.0 + hill_cost + water_cost + wild_cost))
|
||||
} else if dir.x == 0 || dir.y == 0 {
|
||||
} else if NEIGHBORS.iter().all(|p| get_bridge(a + p).is_none()) && (dir.x == 0 || dir.y == 0) {
|
||||
(4..=5).find_map(|i| {
|
||||
loc_suitable_for_walking(sim, a + dir * i).then(|| (a + dir * i, i as f32 * 30.0))
|
||||
loc_suitable_for_walking(sim, a + dir * i).then(|| (a + dir * i, 400.0 + (i - 4) as f32 * 10.0))
|
||||
})
|
||||
} else {
|
||||
None
|
||||
@ -1276,13 +1273,10 @@ fn walk_in_dir(
|
||||
/// Return true if a position is suitable for walking on
|
||||
fn loc_suitable_for_walking(sim: &WorldSim, loc: Vec2<i32>) -> bool {
|
||||
if sim.get(loc).is_some() {
|
||||
NEIGHBORS
|
||||
.iter()
|
||||
.find(|n| {
|
||||
sim.get(loc + *n)
|
||||
.map_or(false, |chunk| chunk.river.near_water())
|
||||
})
|
||||
.is_none()
|
||||
!NEIGHBORS.iter().any(|n| {
|
||||
sim.get(loc + *n)
|
||||
.map_or(false, |chunk| chunk.river.near_water())
|
||||
})
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@ -1626,7 +1620,7 @@ impl Site {
|
||||
}
|
||||
|
||||
pub fn is_castle(&self) -> bool { matches!(self.kind, SiteKind::Castle) }
|
||||
|
||||
|
||||
pub fn is_bridge(&self) -> bool { matches!(self.kind, SiteKind::Bridge(_, _)) }
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
use crate::{
|
||||
column::ColumnSample,
|
||||
sim::{RiverKind, WorldSim},
|
||||
CONFIG, IndexRef, site::SiteKind,
|
||||
site::SiteKind,
|
||||
IndexRef, CONFIG,
|
||||
};
|
||||
use common::{
|
||||
terrain::{
|
||||
@ -118,17 +119,21 @@ pub fn sample_pos(
|
||||
sample.river.river_kind,
|
||||
sample.river.spline_derivative,
|
||||
sample.path.0.is_way(),
|
||||
sample.sites.iter().any(|site| match &index.sites.get(*site).kind {
|
||||
SiteKind::Bridge(bridge) => if let Some(plot) = bridge.wpos_tile(TerrainChunkSize::center_wpos(pos)).plot {
|
||||
match bridge.plot(plot).kind {
|
||||
crate::site2::PlotKind::Bridge(_) => true,
|
||||
_ => false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
},
|
||||
_ => false,
|
||||
}),
|
||||
sample
|
||||
.sites
|
||||
.iter()
|
||||
.any(|site| match &index.sites.get(*site).kind {
|
||||
SiteKind::Bridge(bridge) => {
|
||||
if let Some(plot) =
|
||||
bridge.wpos_tile(TerrainChunkSize::center_wpos(pos)).plot
|
||||
{
|
||||
matches!(bridge.plot(plot).kind, crate::site2::PlotKind::Bridge(_))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
},
|
||||
_ => false,
|
||||
}),
|
||||
)
|
||||
})
|
||||
.unwrap_or((
|
||||
|
@ -15,7 +15,7 @@ use common::{
|
||||
vol::ReadVol,
|
||||
};
|
||||
use num::cast::AsPrimitive;
|
||||
use std::{cell::RefCell, sync::Arc, ops::RangeBounds};
|
||||
use std::{cell::RefCell, ops::RangeBounds, sync::Arc};
|
||||
use vek::*;
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -386,8 +386,7 @@ impl Fill {
|
||||
Self::contains_at(tree, *prim, pos.map2(*vec, i32::saturating_sub))
|
||||
},
|
||||
Primitive::Scale(prim, vec) => {
|
||||
let center =
|
||||
Self::get_bounds(tree, *prim).as_::<f32>().center();
|
||||
let center = Self::get_bounds(tree, *prim).as_::<f32>().center();
|
||||
let fpos = pos.as_::<f32>();
|
||||
let spos = (center + ((fpos - center) / vec))
|
||||
.map(|x| x.round())
|
||||
@ -779,9 +778,8 @@ impl Painter {
|
||||
self.prim(Primitive::Cylinder(aabb.made_valid()))
|
||||
}
|
||||
|
||||
|
||||
/// Returns a `PrimitiveRef` of the largest horizontal cylinder that fits in the
|
||||
/// provided Aabb.
|
||||
/// Returns a `PrimitiveRef` of the largest horizontal cylinder that fits in
|
||||
/// the provided Aabb.
|
||||
pub fn horizontal_cylinder(&self, aabb: Aabb<i32>, dir: Dir) -> PrimitiveRef {
|
||||
let aabr = Aabr::from(aabb);
|
||||
let length = dir.select(aabr.size());
|
||||
@ -790,7 +788,8 @@ impl Painter {
|
||||
min: (aabr.min - dir.abs().to_vec2() * height).with_z(aabb.min.z),
|
||||
max: (dir.abs().select_with(aabr.min, aabr.max)).with_z(aabb.min.z + length),
|
||||
};
|
||||
self.cylinder(aabb).rotate_about((-dir.abs()).from_z_mat3(), aabr.min.with_z(aabb.min.z))
|
||||
self.cylinder(aabb)
|
||||
.rotate_about((-dir.abs()).from_z_mat3(), aabr.min.with_z(aabb.min.z))
|
||||
}
|
||||
|
||||
/// Returns a `PrimitiveRef` of a cylinder using a radius check where a
|
||||
@ -1072,40 +1071,21 @@ impl Painter {
|
||||
/// |_____|/
|
||||
/// ```
|
||||
pub fn vault(&self, aabb: Aabb<i32>, dir: Dir) -> PrimitiveRef {
|
||||
let aabr = Aabr::from(aabb);
|
||||
let a = dir.select_aabr(aabr);
|
||||
let b = (-dir).select_aabr(aabr);
|
||||
let dmin = a.min(b);
|
||||
let dmax = a.max(b);
|
||||
let length = dmax - dmin;
|
||||
let h = dir.orthogonal().select(Vec3::from(aabb.size()).xy());
|
||||
|
||||
let c = dir.rotated_cw().select_aabr(aabr);
|
||||
let d = dir.rotated_ccw().select_aabr(aabr);
|
||||
let omin = c.min(d);
|
||||
let omax = c.max(d);
|
||||
let diameter = omax - omin;
|
||||
let radius = (diameter + 1) / 2;
|
||||
let min = (a * dir.to_vec2() + c * dir.orthogonal().to_vec2()).with_z(aabb.max.z);
|
||||
let mut prim = self.horizontal_cylinder(Aabb {
|
||||
min: aabb.min.with_z(aabb.max.z - h),
|
||||
max: aabb.max,
|
||||
}, dir);
|
||||
|
||||
self.cylinder(
|
||||
Aabb {
|
||||
min,
|
||||
max: (a * dir.to_vec2()
|
||||
+ diameter * (-dir).to_vec2()
|
||||
+ d * dir.orthogonal().to_vec2())
|
||||
.with_z(aabb.max.z + length),
|
||||
}
|
||||
.made_valid(),
|
||||
)
|
||||
.rotate_about(dir.abs().from_z_mat3(), min)
|
||||
.without(self.aabb(Aabb {
|
||||
min: aabb.min.with_z(aabb.min.z - radius),
|
||||
max: aabb.max.with_z(aabb.min.z),
|
||||
}))
|
||||
.union(self.aabb(Aabb {
|
||||
if aabb.size().d < h {
|
||||
prim = prim.intersect(self.aabb(aabb));
|
||||
}
|
||||
|
||||
self.aabb(Aabb {
|
||||
min: aabb.min,
|
||||
max: aabb.max.with_z(aabb.max.z - radius),
|
||||
}))
|
||||
max: aabb.max.with_z(aabb.max.z - h / 2),
|
||||
}).union(prim)
|
||||
}
|
||||
|
||||
/// Place aabbs around another aabb in a symmetric and distributed manner.
|
||||
@ -1293,7 +1273,9 @@ impl<'a> PrimitiveTransform for PrimitiveRef<'a> {
|
||||
self.painter.prim(Primitive::rotate_about(self, rot, point))
|
||||
}
|
||||
|
||||
fn scale(self, scale: Vec3<impl AsPrimitive<f32>>) -> Self { self.painter.prim(Primitive::scale(self, scale.as_())) }
|
||||
fn scale(self, scale: Vec3<impl AsPrimitive<f32>>) -> Self {
|
||||
self.painter.prim(Primitive::scale(self, scale.as_()))
|
||||
}
|
||||
|
||||
fn repeat(self, offset: Vec3<i32>, count: u32) -> Self {
|
||||
self.painter.prim(Primitive::repeat(self, offset, count))
|
||||
|
@ -1018,7 +1018,6 @@ impl Site {
|
||||
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());
|
||||
@ -1044,7 +1043,7 @@ impl Site {
|
||||
(-bridge.dir).select_aabr_with(start_aabr, aabr.center()),
|
||||
2,
|
||||
);
|
||||
|
||||
|
||||
let plot = site.create_plot(Plot {
|
||||
kind: PlotKind::Bridge(bridge),
|
||||
root_tile: start_tile,
|
||||
|
@ -25,16 +25,20 @@ struct HeightenedViaduct {
|
||||
}
|
||||
|
||||
impl HeightenedViaduct {
|
||||
fn random(rng: &mut impl Rng) -> Self {
|
||||
fn random(rng: &mut impl Rng, height: i32) -> Self {
|
||||
let vault_spacing = *[3, 4, 5, 7].choose(rng).unwrap();
|
||||
Self {
|
||||
slope_inv: rng.gen_range(6..=8),
|
||||
bridge_start_offset: rng.gen_range(5..=12),
|
||||
vault_spacing: rng.gen_range(3..=4),
|
||||
bridge_start_offset: rng.gen_range({
|
||||
let min = (5 - height / 3).max(0);
|
||||
min..=(12 - height).max(min)
|
||||
}),
|
||||
vault_spacing,
|
||||
vault_size: *[(3, 16), (1, 4), (1, 4), (1, 4), (5, 32), (5, 32)]
|
||||
.choose(rng)
|
||||
.unwrap(),
|
||||
side_vault_size: *[(4, 5), (7, 10), (7, 10), (13, 20)].choose(rng).unwrap(),
|
||||
holes: rng.gen_bool(0.5),
|
||||
holes: vault_spacing > 4 && rng.gen_bool(0.8),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -53,25 +57,32 @@ impl BridgeKind {
|
||||
start: Vec3<i32>,
|
||||
center: Vec3<i32>,
|
||||
end: Vec3<i32>,
|
||||
|
||||
name: &str,
|
||||
) -> BridgeKind {
|
||||
let len = (start.xy() - end.xy()).map(|e| e.abs()).reduce_max();
|
||||
let height = end.z - start.z;
|
||||
let down = start.z - center.z;
|
||||
(0..=3)
|
||||
.filter_map(|bridge| match bridge {
|
||||
0 if end.z - start.z > 17 => Some(BridgeKind::Tower(match rng.gen_range(0..=2) {
|
||||
0 if height >= 16 => Some(BridgeKind::Tower(match rng.gen_range(0..=2) {
|
||||
0 => RoofKind::Crenelated,
|
||||
_ => RoofKind::Hipped,
|
||||
})),
|
||||
1 if len < 40 => Some(BridgeKind::Short),
|
||||
2 if end.z - start.z < 5 && start.z - center.z < 16 => Some(
|
||||
BridgeKind::HeightenedViaduct(HeightenedViaduct::random(rng)),
|
||||
),
|
||||
3 if end.z - start.z < 9 && start.z - center.z > 10 => Some(BridgeKind::HangBridge),
|
||||
2 if height < 15 && down < 16 => Some(BridgeKind::HeightenedViaduct(
|
||||
HeightenedViaduct::random(rng, height),
|
||||
)),
|
||||
3 if height < 9 && down > 10 => Some(BridgeKind::HangBridge),
|
||||
_ => None,
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter()
|
||||
.choose(rng)
|
||||
.unwrap_or(BridgeKind::Flat)
|
||||
.unwrap_or_else(|| {
|
||||
println!("Pick: {name}\n\tlen: {len}\n\theight: {height}\n\tdown: {down}\n");
|
||||
BridgeKind::Flat
|
||||
})
|
||||
}
|
||||
|
||||
fn width(&self) -> i32 {
|
||||
@ -190,59 +201,89 @@ fn render_short(bridge: &Bridge, painter: &Painter) {
|
||||
|
||||
fn render_flat(bridge: &Bridge, painter: &Painter) {
|
||||
let rock = Fill::Block(Block::new(BlockKind::Rock, Rgb::gray(50)));
|
||||
let light_rock = Fill::Block(Block::new(BlockKind::Rock, Rgb::gray(130)));
|
||||
|
||||
let dz = bridge.end.z - bridge.start.z;
|
||||
let orthogonal = bridge.dir.orthogonal().to_vec2();
|
||||
let orth_dir = bridge.dir.orthogonal();
|
||||
|
||||
let orthogonal = orth_dir.to_vec2();
|
||||
let forward = bridge.dir.to_vec2();
|
||||
let inset = 5;
|
||||
|
||||
let len = (bridge.end.xy() - bridge.start.xy())
|
||||
.map(|e| e.abs())
|
||||
.reduce_max();
|
||||
let upset = bridge.end.z - bridge.start.z;
|
||||
let height = bridge.end.z - bridge.start.z;
|
||||
|
||||
let size = tweak!(8);
|
||||
let hole = painter
|
||||
.cylinder(aabb(
|
||||
bridge.center.with_z(bridge.end.z - 3 - bridge.width() * 2) - Vec2::broadcast(size),
|
||||
bridge.center.with_z(bridge.end.z + 2) + Vec2::broadcast(size),
|
||||
))
|
||||
.rotate_about(
|
||||
bridge.dir.orthogonal().from_z_mat3(),
|
||||
bridge
|
||||
.center
|
||||
.as_()
|
||||
.with_z(bridge.end.z as f32 - 1.5 - bridge.width() as f32),
|
||||
let bridge_width = bridge.width();
|
||||
let side = orthogonal * bridge_width;
|
||||
|
||||
let aabr = Aabr {
|
||||
min: bridge.start.xy() - side,
|
||||
max: bridge.end.xy() + side,
|
||||
}
|
||||
.made_valid();
|
||||
|
||||
let [ramp_aabr, aabr] = bridge.dir.split_aabr(aabr, height);
|
||||
|
||||
let ramp_prim = |ramp_aabr: Aabr<i32>, offset: i32| {
|
||||
painter
|
||||
.aabb(aabb(
|
||||
ramp_aabr.min.with_z(bridge.start.z - 10 + offset),
|
||||
ramp_aabr.max.with_z(bridge.start.z - 1 + offset),
|
||||
))
|
||||
.union(painter.ramp(
|
||||
aabb(
|
||||
ramp_aabr.min.with_z(bridge.start.z + offset),
|
||||
ramp_aabr.max.with_z(bridge.end.z + offset),
|
||||
),
|
||||
height + 1,
|
||||
bridge.dir,
|
||||
))
|
||||
};
|
||||
|
||||
ramp_prim(ramp_aabr, 1).fill(light_rock.clone());
|
||||
|
||||
let ramp_aabr = orth_dir.trim_aabr(ramp_aabr, 1);
|
||||
ramp_prim(ramp_aabr, 5).clear();
|
||||
ramp_prim(ramp_aabr, 0).fill(rock.clone());
|
||||
|
||||
let vault_width = 12;
|
||||
let vault_offset = 5;
|
||||
let bridge_thickness = 4;
|
||||
|
||||
let [vault, _] = bridge.dir.split_aabr(aabr, vault_width);
|
||||
|
||||
let len = bridge.dir.select(aabr.size());
|
||||
let true_offset = vault_width + vault_offset;
|
||||
let n = len / true_offset;
|
||||
let p = len / n;
|
||||
|
||||
let holes = painter
|
||||
.vault(
|
||||
aabb(
|
||||
vault.min.with_z(bridge.center.z - 20),
|
||||
vault.max.with_z(bridge.end.z - bridge_thickness - 1),
|
||||
),
|
||||
orth_dir,
|
||||
)
|
||||
.scale(
|
||||
bridge.dir.abs().to_vec3().as_()
|
||||
* ((len as f32 - upset as f32 * tweak!(2.0)) / (size as f32 * 2.0) - 1.0)
|
||||
+ 1.0,
|
||||
);
|
||||
.repeat((forward * p).with_z(0), n as u32);
|
||||
|
||||
painter
|
||||
.ramp(
|
||||
aabb(
|
||||
bridge.start.with_z(bridge.start.z - inset)
|
||||
- orthogonal * bridge.width()
|
||||
- forward * inset,
|
||||
bridge.start.with_z(bridge.end.z) + orthogonal * bridge.width() + forward * dz,
|
||||
),
|
||||
dz + inset + 1,
|
||||
bridge.dir,
|
||||
)
|
||||
.union(
|
||||
painter
|
||||
.aabb(aabb(
|
||||
bridge.start.with_z(bridge.end.z - 3 - size) - orthogonal * bridge.width()
|
||||
+ forward * dz,
|
||||
bridge.start.with_z(bridge.end.z)
|
||||
+ orthogonal * bridge.width()
|
||||
+ forward * forward * (bridge.end.xy() - bridge.start.xy()),
|
||||
))
|
||||
.without(hole),
|
||||
)
|
||||
.fill(rock);
|
||||
.aabb(aabb(
|
||||
aabr.min.with_z(bridge.center.z - 10),
|
||||
aabr.max.with_z(bridge.end.z + 1),
|
||||
))
|
||||
.without(holes)
|
||||
.fill(light_rock);
|
||||
|
||||
let aabr = orth_dir.trim_aabr(aabr, 1);
|
||||
painter
|
||||
.aabb(aabb(
|
||||
aabr.min.with_z(bridge.end.z + 1),
|
||||
aabr.max.with_z(bridge.end.z + 8),
|
||||
)).clear();
|
||||
|
||||
painter
|
||||
.aabb(aabb(
|
||||
aabr.min.with_z(bridge.end.z),
|
||||
aabr.max.with_z(bridge.end.z),
|
||||
)).fill(rock);
|
||||
}
|
||||
|
||||
fn render_heightened_viaduct(bridge: &Bridge, painter: &Painter, data: &HeightenedViaduct) {
|
||||
@ -262,12 +303,6 @@ fn render_heightened_viaduct(bridge: &Bridge, painter: &Painter, data: &Heighten
|
||||
let bridge_start_z = bridge.end.z + data.bridge_start_offset;
|
||||
let bridge_top = bridge_start_z + len / slope_inv / 2;
|
||||
|
||||
// painter.ramp(aabb(
|
||||
// bridge.start - side,
|
||||
// (bridge.start.xy() + side + forward * (bridge_start_z -
|
||||
// bridge.start.z)).with_z(bridge_start_z), ), bridge_start_z -
|
||||
// bridge.start.z, bridge.dir).fill(rock);
|
||||
|
||||
let bridge_width = bridge.width();
|
||||
let side = orthogonal * bridge_width;
|
||||
|
||||
@ -415,8 +450,8 @@ fn render_heightened_viaduct(bridge: &Bridge, painter: &Painter, data: &Heighten
|
||||
}
|
||||
}
|
||||
|
||||
bridge_prim(bridge_width).without(remove).fill(rock.clone());
|
||||
b.translate(-Vec3::unit_z()).fill(light_rock.clone());
|
||||
bridge_prim(bridge_width).without(remove).fill(rock);
|
||||
b.translate(-Vec3::unit_z()).fill(light_rock);
|
||||
|
||||
br.translate(Vec3::unit_z() * 5)
|
||||
.without(br.translate(-Vec3::unit_z()))
|
||||
@ -625,7 +660,7 @@ fn render_tower(bridge: &Bridge, painter: &Painter, roof_kind: &RoofKind) {
|
||||
(tower_aabr.min - 1).with_z(tower_end + 1),
|
||||
(tower_aabr.max + 1).with_z(tower_end + 2 + tower_size),
|
||||
))
|
||||
.fill(wood.clone());
|
||||
.fill(wood);
|
||||
},
|
||||
}
|
||||
|
||||
@ -650,14 +685,14 @@ fn render_tower(bridge: &Bridge, painter: &Painter, roof_kind: &RoofKind) {
|
||||
painter
|
||||
.vault(
|
||||
aabb(
|
||||
(start + offset - size).with_z(bridge.center.z - 10),
|
||||
(start + offset + size).with_z(bridge.end.z - 3),
|
||||
(start + offset / 2 - size).with_z(bridge.center.z - 10),
|
||||
(start + offset / 2 + size).with_z(bridge.end.z - 3),
|
||||
),
|
||||
orth_dir,
|
||||
)
|
||||
.repeat(offset.with_z(0), n as u32),
|
||||
)
|
||||
.fill(rock.clone());
|
||||
.fill(rock);
|
||||
|
||||
painter
|
||||
.aabb(aabb(
|
||||
@ -740,8 +775,10 @@ fn render_hang(bridge: &Bridge, painter: &Painter) {
|
||||
|
||||
let xsqr = (x * x) as f32;
|
||||
let hsqr = (h * h) as f32;
|
||||
let w = ((xsqr + (xsqr * (4.0 * hsqr + xsqr)).sqrt()) / 2.0).sqrt().ceil() + 1.0;
|
||||
|
||||
let w = ((xsqr + (xsqr * (4.0 * hsqr + xsqr)).sqrt()) / 2.0)
|
||||
.sqrt()
|
||||
.ceil()
|
||||
+ 1.0;
|
||||
|
||||
let bottom = top - (h - (hsqr - hsqr * x as f32 / w).sqrt().ceil() as i32);
|
||||
|
||||
@ -756,7 +793,10 @@ fn render_hang(bridge: &Bridge, painter: &Painter) {
|
||||
),
|
||||
orth_dir,
|
||||
)
|
||||
.intersect(painter.aabb(aabb(aabr.min.with_z(bottom), aabr.max.with_z(bottom + h * 2))));
|
||||
.intersect(painter.aabb(aabb(
|
||||
aabr.min.with_z(bottom),
|
||||
aabr.max.with_z(bottom + h * 2),
|
||||
)));
|
||||
|
||||
cylinder.fill(wood.clone());
|
||||
|
||||
@ -773,14 +813,34 @@ fn render_hang(bridge: &Bridge, painter: &Painter) {
|
||||
.translate(Vec3::unit_z())
|
||||
.fill(Fill::Sprite(SpriteKind::Rope));
|
||||
|
||||
edges.translate(Vec3::unit_z() * 2).fill(wood.clone());
|
||||
edges.translate(Vec3::unit_z() * 2).fill(wood);
|
||||
|
||||
let column_height = 3;
|
||||
let column_range = top..=top + column_height;
|
||||
painter.column(bridge.dir.select_aabr_with(ramp_f, ramp_f.min), column_range.clone()).fill(rock.clone());
|
||||
painter.column(bridge.dir.select_aabr_with(ramp_f, ramp_f.max), column_range.clone()).fill(rock.clone());
|
||||
painter.column((-bridge.dir).select_aabr_with(ramp_b, ramp_b.min), column_range.clone()).fill(rock.clone());
|
||||
painter.column((-bridge.dir).select_aabr_with(ramp_b, ramp_b.max), column_range.clone()).fill(rock.clone());
|
||||
painter
|
||||
.column(
|
||||
bridge.dir.select_aabr_with(ramp_f, ramp_f.min),
|
||||
column_range.clone(),
|
||||
)
|
||||
.fill(rock.clone());
|
||||
painter
|
||||
.column(
|
||||
bridge.dir.select_aabr_with(ramp_f, ramp_f.max),
|
||||
column_range.clone(),
|
||||
)
|
||||
.fill(rock.clone());
|
||||
painter
|
||||
.column(
|
||||
(-bridge.dir).select_aabr_with(ramp_b, ramp_b.min),
|
||||
column_range.clone(),
|
||||
)
|
||||
.fill(rock.clone());
|
||||
painter
|
||||
.column(
|
||||
(-bridge.dir).select_aabr_with(ramp_b, ramp_b.max),
|
||||
column_range,
|
||||
)
|
||||
.fill(rock);
|
||||
}
|
||||
|
||||
pub struct Bridge {
|
||||
@ -852,7 +912,7 @@ impl Bridge {
|
||||
|
||||
let center = (start.xy() + end.xy()) / 2;
|
||||
let center = center.with_z(land.get_alt_approx(center) as i32);
|
||||
let bridge = BridgeKind::random(rng, start, center, end);
|
||||
let bridge = BridgeKind::random(rng, start, center, end, site.name());
|
||||
Self {
|
||||
start,
|
||||
end,
|
||||
|
@ -221,7 +221,10 @@ impl Dir {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn split_aabr<T>(self, aabr: Aabr<T>, offset: T) -> [Aabr<T>; 2] where T: Copy + PartialOrd + Add<T, Output = T> + Sub<T, Output = T> {
|
||||
pub fn split_aabr<T>(self, aabr: Aabr<T>, offset: T) -> [Aabr<T>; 2]
|
||||
where
|
||||
T: Copy + PartialOrd + Add<T, Output = T> + Sub<T, Output = T>,
|
||||
{
|
||||
match self {
|
||||
Dir::X => aabr.split_at_x(aabr.min.x + offset),
|
||||
Dir::Y => aabr.split_at_y(aabr.min.y + offset),
|
||||
@ -236,6 +239,13 @@ impl Dir {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trim_aabr(self, aabr: Aabr<i32>, offset: i32) -> Aabr<i32> {
|
||||
Aabr {
|
||||
min: aabr.min + self.abs().to_vec2() * offset,
|
||||
max: aabr.max - self.abs().to_vec2() * offset,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extend_aabr(self, aabr: Aabr<i32>, amount: i32) -> Aabr<i32> {
|
||||
match self {
|
||||
Dir::X => Aabr {
|
||||
|
Loading…
Reference in New Issue
Block a user