mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Castle and cave tweaks
This commit is contained in:
parent
dfecf0dad6
commit
a966841c5a
@ -258,15 +258,23 @@ impl Civs {
|
||||
|
||||
ctx.sim.get_mut(locs[0].0).unwrap().cave.0.neighbors |=
|
||||
1 << ((to_prev_idx as u8 + 4) % 8);
|
||||
ctx.sim.get_mut(locs[1].0).unwrap().cave.0.neighbors |=
|
||||
(1 << (to_prev_idx as u8)) | (1 << (to_next_idx as u8));
|
||||
ctx.sim.get_mut(locs[2].0).unwrap().cave.0.neighbors |=
|
||||
1 << ((to_next_idx as u8 + 4) % 8);
|
||||
let mut chunk = ctx.sim.get_mut(locs[1].0).unwrap();
|
||||
chunk.cave.0.neighbors |= (1 << (to_prev_idx as u8)) | (1 << (to_next_idx as u8));
|
||||
let depth = locs[1].1 * 250.0 - 20.0;
|
||||
}
|
||||
|
||||
for (i, loc) in path.iter().enumerate() {
|
||||
let mut chunk = ctx.sim.get_mut(loc.0).unwrap();
|
||||
let depth = loc.1 * 250.0 - 20.0;
|
||||
chunk.cave.1.alt =
|
||||
chunk.alt - depth + ctx.rng.gen_range(-4.0, 4.0) * (depth > 10.0) as i32 as f32;
|
||||
chunk.cave.1.width = ctx.rng.gen_range(6.0, 32.0);
|
||||
chunk.cave.0.offset = Vec2::new(ctx.rng.gen_range(-16, 17), ctx.rng.gen_range(-16, 17));
|
||||
|
||||
if chunk.cave.1.alt + chunk.cave.1.width + 5.0 > chunk.alt {
|
||||
chunk.spawn_rate = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,7 @@ pub struct Castle {
|
||||
towers: Vec<Tower>,
|
||||
keeps: Vec<Keep>,
|
||||
rounded_towers: bool,
|
||||
ridged: bool,
|
||||
}
|
||||
|
||||
pub struct GenCtx<'a, R: Rng> {
|
||||
@ -114,6 +115,7 @@ impl Castle {
|
||||
})
|
||||
.collect(),
|
||||
rounded_towers: ctx.rng.gen(),
|
||||
ridged: ctx.rng.gen(),
|
||||
keeps: (0..keep_count)
|
||||
.map(|i| {
|
||||
let angle = (i as f32 / keep_count as f32) * f32::consts::PI * 2.0;
|
||||
@ -123,7 +125,7 @@ impl Castle {
|
||||
|
||||
let locus = ctx.rng.gen_range(20, 26);
|
||||
let offset = (dir * dist).map(|e| e as i32);
|
||||
let storeys = ctx.rng.gen_range(1, 5).clamped(2, 3);
|
||||
let storeys = ctx.rng.gen_range(1, 8).clamped(3, 5);
|
||||
|
||||
Keep {
|
||||
offset,
|
||||
@ -244,9 +246,9 @@ impl Castle {
|
||||
let wall_ori = if (tower0.offset.x - tower1.offset.x).abs()
|
||||
< (tower0.offset.y - tower1.offset.y).abs()
|
||||
{
|
||||
Ori::East
|
||||
} else {
|
||||
Ori::North
|
||||
} else {
|
||||
Ori::East
|
||||
};
|
||||
|
||||
(
|
||||
@ -271,13 +273,15 @@ impl Castle {
|
||||
.map(|(dist, _, path, _)| path.head_space(dist))
|
||||
.unwrap_or(0);
|
||||
|
||||
// Apply the dungeon entrance
|
||||
let wall_sample = if let Some(col) = get_column(offs + wall_pos - rpos) {
|
||||
col
|
||||
} else {
|
||||
col_sample
|
||||
};
|
||||
|
||||
// Make sure particularly weird terrain doesn't give us underground walls
|
||||
let wall_alt = wall_alt + (wall_sample.alt as i32 - wall_alt - 10).max(0);
|
||||
|
||||
let keep_archetype = KeepArchetype {
|
||||
flag_color: Rgb::new(200, 80, 40),
|
||||
};
|
||||
@ -294,17 +298,18 @@ impl Castle {
|
||||
let mut mask = keep_archetype.draw(
|
||||
Vec3::from(wall_rpos) + Vec3::unit_z() * wpos.z - wall_alt,
|
||||
wall_dist,
|
||||
Vec2::new(border_pos.reduce_max(), border_pos.reduce_min()),
|
||||
border_pos,
|
||||
rpos - wall_pos,
|
||||
wall_z,
|
||||
wall_ori,
|
||||
4,
|
||||
0,
|
||||
&Attr {
|
||||
storeys: 1,
|
||||
storeys: 2,
|
||||
is_tower: false,
|
||||
ridged: false,
|
||||
rounded: true,
|
||||
has_doors: false,
|
||||
},
|
||||
);
|
||||
|
||||
@ -329,17 +334,22 @@ impl Castle {
|
||||
)
|
||||
},
|
||||
border_pos.reduce_max() - tower_locus,
|
||||
Vec2::new(border_pos.reduce_max(), border_pos.reduce_min()),
|
||||
Vec2::new(border_pos.reduce_min(), border_pos.reduce_max()),
|
||||
(wpos - tower_wpos).xy(),
|
||||
wpos.z - tower.alt,
|
||||
Ori::East,
|
||||
if border_pos.x > border_pos.y {
|
||||
Ori::East
|
||||
} else {
|
||||
Ori::North
|
||||
},
|
||||
tower_locus,
|
||||
0,
|
||||
&Attr {
|
||||
storeys: 2,
|
||||
storeys: 3,
|
||||
is_tower: true,
|
||||
ridged: false,
|
||||
ridged: self.ridged,
|
||||
rounded: self.rounded_towers,
|
||||
has_doors: false,
|
||||
},
|
||||
));
|
||||
}
|
||||
@ -364,17 +374,22 @@ impl Castle {
|
||||
)
|
||||
},
|
||||
border_pos.reduce_max() - keep.locus,
|
||||
Vec2::new(border_pos.reduce_max(), border_pos.reduce_min()),
|
||||
Vec2::new(border_pos.reduce_min(), border_pos.reduce_max()),
|
||||
(wpos - keep_wpos).xy(),
|
||||
wpos.z - keep.alt,
|
||||
Ori::East,
|
||||
if border_pos.x > border_pos.y {
|
||||
Ori::East
|
||||
} else {
|
||||
Ori::North
|
||||
},
|
||||
keep.locus,
|
||||
0,
|
||||
&Attr {
|
||||
storeys: keep.storeys,
|
||||
is_tower: keep.is_tower,
|
||||
ridged: true,
|
||||
ridged: self.ridged,
|
||||
rounded: self.rounded_towers,
|
||||
has_doors: true,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ pub struct Attr {
|
||||
pub is_tower: bool,
|
||||
pub ridged: bool,
|
||||
pub rounded: bool,
|
||||
pub has_doors: bool,
|
||||
}
|
||||
|
||||
impl Archetype for Keep {
|
||||
@ -26,16 +27,18 @@ impl Archetype for Keep {
|
||||
|
||||
fn generate<R: Rng>(rng: &mut R) -> (Self, Skeleton<Self::Attr>) {
|
||||
let len = rng.gen_range(-8, 24).max(0);
|
||||
let storeys = rng.gen_range(1, 3);
|
||||
let skel = Skeleton {
|
||||
offset: -rng.gen_range(0, len + 7).clamped(0, len),
|
||||
ori: if rng.gen() { Ori::East } else { Ori::North },
|
||||
root: Branch {
|
||||
len,
|
||||
attr: Attr {
|
||||
storeys: 1,
|
||||
storeys,
|
||||
is_tower: false,
|
||||
ridged: false,
|
||||
rounded: true,
|
||||
has_doors: true,
|
||||
},
|
||||
locus: 10 + rng.gen_range(0, 5),
|
||||
border: 3,
|
||||
@ -46,10 +49,11 @@ impl Archetype for Keep {
|
||||
Branch {
|
||||
len: 0,
|
||||
attr: Attr {
|
||||
storeys: 2,
|
||||
storeys: storeys + rng.gen_range(1, 3),
|
||||
is_tower: true,
|
||||
ridged: false,
|
||||
rounded: true,
|
||||
has_doors: false,
|
||||
},
|
||||
locus: 6 + rng.gen_range(0, 3),
|
||||
border: 3,
|
||||
@ -89,6 +93,17 @@ impl Archetype for Keep {
|
||||
let important_layer = normal_layer + 1;
|
||||
let internal_layer = important_layer + 1;
|
||||
|
||||
let make_meta = |ori| {
|
||||
Rgb::new(
|
||||
match ori {
|
||||
Ori::East => 0,
|
||||
Ori::North => 2,
|
||||
},
|
||||
0,
|
||||
0,
|
||||
)
|
||||
};
|
||||
|
||||
let make_block = |r, g, b| {
|
||||
BlockMask::new(
|
||||
Block::new(BlockKind::Normal, Rgb::new(r, g, b)),
|
||||
@ -100,6 +115,10 @@ impl Archetype for Keep {
|
||||
let brick_tex = RandomField::new(0).get(brick_tex_pos) as u8 % 24;
|
||||
let foundation = make_block(80 + brick_tex, 80 + brick_tex, 80 + brick_tex);
|
||||
let wall = make_block(100 + brick_tex, 100 + brick_tex, 110 + brick_tex);
|
||||
let window = BlockMask::new(
|
||||
Block::new(BlockKind::Window1, make_meta(ori.flip())),
|
||||
normal_layer,
|
||||
);
|
||||
let floor = make_block(
|
||||
80 + (pos.y.abs() % 2) as u8 * 15,
|
||||
60 + (pos.y.abs() % 2) as u8 * 15,
|
||||
@ -132,23 +151,19 @@ impl Archetype for Keep {
|
||||
}
|
||||
};
|
||||
|
||||
let edge_pos = if (bound_offset.x.abs() > bound_offset.y.abs()) ^ (ori == Ori::East) {
|
||||
pos.y
|
||||
} else {
|
||||
pos.x
|
||||
};
|
||||
|
||||
let ridge_x = (center_offset.map(|e| e.abs()).reduce_min() + 2) % 8;
|
||||
let width = locus
|
||||
+ if (edge_pos + 1000) % 8 < 4 && attr.ridged && !attr.rounded {
|
||||
+ if ridge_x < 4 && attr.ridged && !attr.rounded {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let rampart_width = 2 + width;
|
||||
let storey_height = 16;
|
||||
let storey_height = 9;
|
||||
let roof_height = attr.storeys * storey_height;
|
||||
let storey_y = profile.y % storey_height;
|
||||
let door_height = 6;
|
||||
let rampart_height = roof_height + if edge_pos % 2 == 0 { 3 } else { 4 };
|
||||
let rampart_height = roof_height + if ridge_x % 2 == 0 { 3 } else { 4 };
|
||||
let min_dist = if attr.rounded {
|
||||
bound_offset.map(|e| e.pow(2) as f32).sum().powf(0.5) as i32
|
||||
} else {
|
||||
@ -158,24 +173,32 @@ impl Archetype for Keep {
|
||||
if profile.y <= 0 - (min_dist - width - 1).max(0) && min_dist < width + 3 {
|
||||
// Foundations
|
||||
foundation
|
||||
} else if (0..=roof_height).contains(&profile.y) && profile.y % storey_height == 0 && min_dist < rampart_width {
|
||||
} else if (0..=roof_height).contains(&profile.y) && storey_y == 0 && min_dist <= width + 1 {
|
||||
if min_dist < width { floor } else { wall }
|
||||
} else if !attr.is_tower
|
||||
&& bound_offset.x.abs() == 4
|
||||
&& min_dist == width + 1
|
||||
&& profile.y < roof_height
|
||||
{
|
||||
wall
|
||||
} else if bound_offset.x.abs() < 3
|
||||
&& profile.y < door_height - bound_offset.x.abs()
|
||||
&& profile.y > 0
|
||||
&& min_dist >= width - 2
|
||||
&& min_dist <= width + 1
|
||||
&& attr.has_doors
|
||||
{
|
||||
internal
|
||||
} else if min_dist == width && profile.y <= roof_height {
|
||||
wall
|
||||
} else if (min_dist == width || (!attr.is_tower && min_dist == width + 1))
|
||||
&& profile.y <= roof_height
|
||||
{
|
||||
if attr.is_tower
|
||||
&& (3..7).contains(&storey_y)
|
||||
&& bound_offset.x.abs() < width - 2
|
||||
&& (5..7).contains(&ridge_x)
|
||||
{
|
||||
window
|
||||
} else {
|
||||
wall
|
||||
}
|
||||
} else if profile.y >= roof_height {
|
||||
if profile.y > roof_height && min_dist < rampart_width {
|
||||
if profile.y > roof_height
|
||||
&& (min_dist < rampart_width - 1 || (attr.is_tower && min_dist < rampart_width))
|
||||
{
|
||||
if attr.is_tower && center_offset == Vec2::zero() && profile.y < roof_height + 16 {
|
||||
pole
|
||||
} else if attr.is_tower
|
||||
@ -189,7 +212,7 @@ impl Archetype for Keep {
|
||||
} else {
|
||||
empty
|
||||
}
|
||||
} else if min_dist == rampart_width {
|
||||
} else if min_dist <= rampart_width {
|
||||
if profile.y < rampart_height {
|
||||
wall
|
||||
} else {
|
||||
@ -203,15 +226,17 @@ impl Archetype for Keep {
|
||||
} else {
|
||||
empty
|
||||
}
|
||||
.resolve_with(if attr.is_tower && profile.y > 0 && profile.y <= roof_height {
|
||||
make_staircase(
|
||||
Vec3::new(center_offset.x, center_offset.y, pos.z),
|
||||
7.0f32.min(width as f32 - 1.0),
|
||||
0.5,
|
||||
9.0,
|
||||
)
|
||||
} else {
|
||||
BlockMask::nothing()
|
||||
})
|
||||
.resolve_with(
|
||||
if attr.is_tower && profile.y > 0 && profile.y <= roof_height {
|
||||
make_staircase(
|
||||
Vec3::new(center_offset.x, center_offset.y, pos.z),
|
||||
7.0f32.min(width as f32 - 1.0),
|
||||
0.5,
|
||||
9.0,
|
||||
)
|
||||
} else {
|
||||
BlockMask::nothing()
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user