Castle and cave tweaks

This commit is contained in:
Joshua Barretto 2020-07-30 16:46:17 +01:00
parent dfecf0dad6
commit a966841c5a
3 changed files with 96 additions and 48 deletions

View File

@ -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;
}
}
}

View File

@ -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,
},
));
}

View File

@ -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()
},
)
}
}