use super::*;
use crate::{
util::{RandomField, Sampler, CARDINALS, DIAGONALS, NEIGHBORS},
Land,
};
use common::{
generation::{EntityInfo, SpecialEntity},
terrain::{BlockKind, SpriteKind},
};
use rand::prelude::*;
use std::sync::Arc;
use vek::*;
pub struct SavannahPit {
bounds: Aabr<i32>,
pub(crate) alt: i32,
}
impl SavannahPit {
pub fn generate(land: &Land, _rng: &mut impl Rng, site: &Site, tile_aabr: Aabr<i32>) -> Self {
let bounds = Aabr {
min: site.tile_wpos(tile_aabr.min),
max: site.tile_wpos(tile_aabr.max),
};
Self {
bounds,
alt: land.get_alt_approx(site.tile_center_wpos(tile_aabr.center())) as i32 + 2,
}
}
}
impl Structure for SavannahPit {
#[cfg(feature = "use-dyn-lib")]
const UPDATE_FN: &'static [u8] = b"render_savannahpit\0";
#[cfg_attr(feature = "be-dyn-lib", export_name = "render_savannahpit")]
fn render_inner(&self, _site: &Site, _land: &Land, painter: &Painter) {
let base = self.alt + 1;
let center = self.bounds.center();
let sprite_fill = Fill::Sampling(Arc::new(|wpos| {
Some(match (RandomField::new(0).get(wpos)) % 50 {
0 => Block::air(SpriteKind::Bowl),
1 => Block::air(SpriteKind::VialEmpty),
2 => Block::air(SpriteKind::Lantern),
3 => Block::air(SpriteKind::JugArabic),
4 => Block::air(SpriteKind::Crate),
_ => Block::new(BlockKind::Air, Rgb::new(0, 0, 0)),
})
}));
let wood_light = Fill::Brick(BlockKind::Misc, Rgb::new(179, 125, 64), 12);
let wood_dark = Fill::Brick(BlockKind::Misc, Rgb::new(142, 67, 27), 12);
let reed = Fill::Brick(BlockKind::Misc, Rgb::new(72, 55, 46), 22);
let clay = Fill::Brick(BlockKind::Misc, Rgb::new(209, 124, 57), 22);
let color = Fill::Sampling(Arc::new(|center| {
Some(match (RandomField::new(0).get(center)) % 7 {
0 => Block::new(BlockKind::GlowingRock, Rgb::new(153, 82, 40)),
1 => Block::new(BlockKind::GlowingRock, Rgb::new(172, 104, 57)),
2 => Block::new(BlockKind::GlowingRock, Rgb::new(135, 106, 100)),
3 => Block::new(BlockKind::GlowingRock, Rgb::new(198, 164, 139)),
4 => Block::new(BlockKind::GlowingRock, Rgb::new(168, 163, 157)),
5 => Block::new(BlockKind::GlowingRock, Rgb::new(73, 53, 42)),
_ => Block::new(BlockKind::GlowingRock, Rgb::new(178, 124, 90)),
})
}));
let snow_fill = Fill::Block(Block::new(BlockKind::Snow, Rgb::new(255, 255, 255)));
let length = 9;
painter
.superquadric(
Aabb {
min: (center - (4 * length)).with_z(base - (3 * length)),
max: (center + (4 * length)).with_z(base),
},
5.0,
)
.fill(clay.clone());
painter
.cylinder(Aabb {
min: (center - (3 * length) - 2).with_z(base - (1 * length)),
max: (center + (3 * length) + 2).with_z(base),
})
.fill(clay.clone());
painter
.cylinder(Aabb {
min: (center - (7 * length)).with_z(base - (6 * length) - 3),
max: (center + (7 * length)).with_z(base - (1 * length)),
})
.fill(clay.clone());
let decor_var = RandomField::new(0).get(center.with_z(base)) % 5;
for s in 0..3 {
for dir in NEIGHBORS {
let sphere_pos = center + dir * ((2 * length) - (s * length));
let decor1 = Aabb {
min: (sphere_pos - length).with_z(base - ((2 * length) - (s * length))),
max: (sphere_pos + length).with_z(base - (s * length)),
};
let decor2 = Aabb {
min: (sphere_pos - length + 1).with_z(base - ((2 * length) - (s * length))),
max: (sphere_pos + length - 1).with_z(base - (s * length)),
};
match decor_var {
0 => {
painter.cone(decor1).fill(color.clone());
painter.cone(decor2).fill(clay.clone())
},
1 => {
painter.aabb(decor1).fill(color.clone());
painter.aabb(decor2).fill(clay.clone())
},
2 => {
painter.cylinder(decor1).fill(color.clone());
painter.cylinder(decor2).fill(clay.clone())
},
_ => {
painter.sphere(decor1).fill(color.clone());
painter.sphere(decor2).fill(clay.clone())
},
};
}
for dir in CARDINALS {
let sphere_pos = center + dir * ((2 * length) - (s * length));
let decor1 = Aabb {
min: (sphere_pos - (2 * length)).with_z(base - ((4 * length) - (s * length))),
max: (sphere_pos + (2 * length)).with_z(base - (s * length)),
};
let decor2 = Aabb {
min: (sphere_pos - (2 * length) + 1)
.with_z(base - ((4 * length) - (s * length))),
max: (sphere_pos + (2 * length) - 1).with_z(base - (s * length)),
};
match decor_var {
0 => {
painter.cone(decor1).fill(color.clone());
painter.cone(decor2).fill(clay.clone())
},
1 => {
painter.aabb(decor1).fill(color.clone());
painter.aabb(decor2).fill(clay.clone())
},
2 => {
painter.cylinder(decor1).fill(color.clone());
painter.cylinder(decor2).fill(clay.clone())
},
_ => {
painter.sphere(decor1).fill(color.clone());
painter.sphere(decor2).fill(clay.clone())
},
};
}
}
for dir in NEIGHBORS {
let sphere_pos = center + dir * (3 * length);
let decor1 = Aabb {
min: (sphere_pos - length).with_z(base - (5 * length)),
max: (sphere_pos + length).with_z(base - (4 * length)),
};
let decor2 = Aabb {
min: (sphere_pos - length + 1).with_z(base - (5 * length)),
max: (sphere_pos + length - 1).with_z(base - (4 * length)),
};
match decor_var {
0 => {
painter.cone(decor1).fill(color.clone());
painter.cone(decor2).fill(clay.clone())
},
1 => {
painter.aabb(decor1).fill(color.clone());
painter.aabb(decor2).fill(clay.clone())
},
2 => {
painter.cylinder(decor1).fill(color.clone());
painter.cylinder(decor2).fill(clay.clone())
},
_ => {
painter.sphere(decor1).fill(color.clone());
painter.sphere(decor2).fill(clay.clone())
},
};
}
for dir in CARDINALS {
let sphere_pos = center + dir * (3 * length);
let decor1 = Aabb {
min: (sphere_pos - (2 * length)).with_z(base - (5 * length)),
max: (sphere_pos + (2 * length)).with_z(base - (3 * length)),
};
let decor2 = Aabb {
min: (sphere_pos - (2 * length) + 1).with_z(base - (5 * length)),
max: (sphere_pos + (2 * length) - 1).with_z(base - (3 * length)),
};
match decor_var {
0 => {
painter.cone(decor1).fill(color.clone());
painter.cone(decor2).fill(clay.clone())
},
1 => {
painter.aabb(decor1).fill(color.clone());
painter.aabb(decor2).fill(clay.clone())
},
2 => {
painter.cylinder(decor1).fill(color.clone());
painter.cylinder(decor2).fill(clay.clone())
},
_ => {
painter.sphere(decor1).fill(color.clone());
painter.sphere(decor2).fill(clay.clone())
},
};
}
painter
.cylinder(Aabb {
min: (center - (3 * length) - 1).with_z(base - 1),
max: (center + (3 * length) + 1).with_z(base),
})
.fill(wood_light.clone());
painter
.cylinder(Aabb {
min: (center - (2 * length) - 1).with_z(base - length - 1),
max: (center + (2 * length) + 1).with_z(base - length),
})
.fill(wood_light.clone());
painter
.cylinder(Aabb {
min: (center - length - 1).with_z(base - (2 * length) - 1),
max: (center + length + 1).with_z(base - (2 * length)),
})
.fill(wood_light.clone());
painter
.cylinder(Aabb {
min: (center - (3 * length) - 1).with_z(base - length + (length / 2) - 1),
max: (center + (3 * length) + 1).with_z(base - length + (length / 2)),
})
.fill(wood_light.clone());
painter
.cylinder(Aabb {
min: (center - (4 * length) - 1).with_z(base - (2 * length) + (length / 2) - 1),
max: (center + (4 * length) + 1).with_z(base - (2 * length) + (length / 2)),
})
.fill(wood_light.clone());
painter
.cylinder(Aabb {
min: (center - (4 * length) - 1).with_z(base - (3 * length) + (length / 2) - 1),
max: (center + (4 * length) + 1).with_z(base - (3 * length) + (length / 2)),
})
.fill(wood_light.clone());
painter
.cylinder(Aabb {
min: (center - (3 * length)).with_z(base - length),
max: (center + (3 * length)).with_z(base + 25),
})
.clear();
painter
.cylinder(Aabb {
min: (center - (2 * length)).with_z(base - (2 * length)),
max: (center + (2 * length)).with_z(base - length),
})
.clear();
painter
.cylinder(Aabb {
min: (center - length).with_z(base - (3 * length)),
max: (center + length).with_z(base - (2 * length)),
})
.clear();
let rooms_clear = painter
.cylinder(Aabb {
min: (center - (4 * length)).with_z(base - (2 * length)),
max: (center + (4 * length)).with_z(base - length - 1),
})
.union(painter.cylinder(Aabb {
min: (center - (4 * length)).with_z(base - (3 * length)),
max: (center + (4 * length)).with_z(base - (2 * length) - 1),
}));
let rooms = painter
.cylinder(Aabb {
min: (center - (2 * length) - 2).with_z(base - (2 * length)),
max: (center + (2 * length) + 2).with_z(base - length - 1),
})
.union(painter.cylinder(Aabb {
min: (center - length - 2).with_z(base - (3 * length)),
max: (center + length + 2).with_z(base - (2 * length) - 1),
}));
rooms_clear.without(rooms).clear();
painter
.cylinder(Aabb {
min: (center - (3 * length)).with_z(base - length + (length / 2) - 3),
max: (center + (3 * length)).with_z(base - length + (length / 2) - 2),
})
.fill(wood_light.clone());
painter
.cylinder(Aabb {
min: (center - (3 * length) + 1).with_z(base - length + (length / 2) - 3),
max: (center + (3 * length) - 1).with_z(base - length + (length / 2) - 2),
})
.clear();
painter
.cylinder(Aabb {
min: (center - (4 * length)).with_z(base - (2 * length) + (length / 2) - 3),
max: (center + (4 * length)).with_z(base - (2 * length) + (length / 2) - 2),
})
.fill(wood_light.clone());
painter
.cylinder(Aabb {
min: (center - (4 * length) + 1).with_z(base - (2 * length) + (length / 2) - 3),
max: (center + (4 * length) - 1).with_z(base - (2 * length) + (length / 2) - 2),
})
.clear();
painter
.cylinder(Aabb {
min: (center - (4 * length)).with_z(base - (2 * length) + (length / 2) - 2),
max: (center + (4 * length)).with_z(base - (2 * length) + (length / 2) - 1),
})
.fill(sprite_fill.clone());
painter
.cylinder(Aabb {
min: (center - (4 * length) + 1).with_z(base - (2 * length) + (length / 2) - 2),
max: (center + (4 * length) - 1).with_z(base - (2 * length) + (length / 2) - 1),
})
.clear();
painter
.cylinder(Aabb {
min: (center - (2 * length) - 2).with_z(base - (2 * length) + (length / 2) - 3),
max: (center + (2 * length) + 2).with_z(base - (2 * length) + (length / 2) - 1),
})
.fill(color.clone());
painter
.cylinder(Aabb {
min: (center - (2 * length)).with_z(base - (2 * length) + (length / 2) - 3),
max: (center + (2 * length)).with_z(base - (2 * length) + (length / 2) - 1),
})
.clear();
let room1_entry_pos = Vec2::new(center.x, center.y - (2 * length));
painter
.sphere(Aabb {
min: (room1_entry_pos - 5).with_z(base - (2 * length)),
max: (room1_entry_pos + 5).with_z(base - (2 * length) + 5),
})
.clear();
painter
.cylinder(Aabb {
min: (center - (4 * length)).with_z(base - (3 * length) + (length / 2) - 3),
max: (center + (4 * length)).with_z(base - (3 * length) + (length / 2) - 2),
})
.fill(wood_light.clone());
painter
.cylinder(Aabb {
min: (center - (4 * length) + 1).with_z(base - (3 * length) + (length / 2) - 3),
max: (center + (4 * length) - 1).with_z(base - (3 * length) + (length / 2) - 2),
})
.clear();
painter
.cylinder(Aabb {
min: (center - (4 * length)).with_z(base - (3 * length) + (length / 2) - 2),
max: (center + (4 * length)).with_z(base - (3 * length) + (length / 2) - 1),
})
.fill(sprite_fill.clone());
painter
.cylinder(Aabb {
min: (center - (4 * length) + 1).with_z(base - (3 * length) + (length / 2) - 2),
max: (center + (4 * length) - 1).with_z(base - (3 * length) + (length / 2) - 1),
})
.clear();
painter
.cylinder(Aabb {
min: (center - length - 2).with_z(base - (3 * length) + (length / 2) - 3),
max: (center + length + 2).with_z(base - (3 * length) + (length / 2) - 1),
})
.fill(color);
painter
.cylinder(Aabb {
min: (center - length).with_z(base - (3 * length) + (length / 2) - 3),
max: (center + length).with_z(base - (3 * length) + (length / 2) - 1),
})
.clear();
let room2_entry_pos = Vec2::new(center.x, center.y - length);
painter
.sphere(Aabb {
min: (room2_entry_pos - 5).with_z(base - (3 * length)),
max: (room2_entry_pos + 5).with_z(base - (3 * length) + 5),
})
.clear();
for dir in SQUARE_4 {
let corner_pos1 = Vec2::new(center.x - 1, center.y - (3 * length) + 1);
let lamp_pos1 = Vec2::new(
corner_pos1.x + dir.x * 1,
corner_pos1.y + dir.y * ((6 * length) - 3),
);
painter.rotated_sprite(
lamp_pos1.with_z(base - length + 9),
SpriteKind::WallLampSmall,
4 - (4 * dir.y) as u8,
);
let corner_pos2 = Vec2::new(center.x - (3 * length) + 1, center.y - 1);
let lamp_pos2 = Vec2::new(
corner_pos2.x + dir.x * ((6 * length) - 3),
corner_pos2.y + dir.y,
);
painter.rotated_sprite(
lamp_pos2.with_z(base - length + 9),
SpriteKind::WallLampSmall,
2 + (4 * dir.x) as u8,
);
}
for dir in SQUARE_4 {
let corner_pos1 = Vec2::new(center.x - 1, center.y - (2 * length));
let lamp_pos1 = Vec2::new(
corner_pos1.x + dir.x * 1,
corner_pos1.y + dir.y * ((4 * length) - 1),
);
painter.rotated_sprite(
lamp_pos1.with_z(base - (2 * length) + 8),
SpriteKind::WallLampSmall,
4 - (4 * dir.y) as u8,
);
let corner_pos2 = Vec2::new(center.x - (2 * length), center.y - 1);
let lamp_pos2 = Vec2::new(
corner_pos2.x + dir.x * ((4 * length) - 1),
corner_pos2.y + dir.y,
);
painter.rotated_sprite(
lamp_pos2.with_z(base - (2 * length) + 8),
SpriteKind::WallLampSmall,
2 + (4 * dir.x) as u8,
);
}
for dir in SQUARE_4 {
let corner_pos1 = Vec2::new(center.x - 1, center.y - length);
let lamp_pos1 = Vec2::new(
corner_pos1.x + dir.x * 1,
corner_pos1.y + dir.y * ((2 * length) - 1),
);
painter.rotated_sprite(
lamp_pos1.with_z(base - (3 * length) + 8),
SpriteKind::WallLampSmall,
4 - (4 * dir.y) as u8,
);
let corner_pos2 = Vec2::new(center.x - length, center.y - 1);
let lamp_pos2 = Vec2::new(
corner_pos2.x + dir.x * ((2 * length) - 1),
corner_pos2.y + dir.y,
);
painter.rotated_sprite(
lamp_pos2.with_z(base - (3 * length) + 8),
SpriteKind::WallLampSmall,
2 + (4 * dir.x) as u8,
);
}
let stair_radius0 = ((3 * length) + 1) as f32;
let stairs_clear0 = painter.prim(Primitive::Cylinder(Aabb {
min: (center - (3 * length)).with_z(base - length),
max: (center + (3 * length)).with_z(base),
}));
painter
.prim(Primitive::sampling(
stairs_clear0,
dungeon::spiral_staircase(
center.with_z(base - length),
stair_radius0,
2.5,
(2 * length) as f32,
),
))
.fill(wood_dark.clone());
let stair_radius1 = ((2 * length) + 1) as f32;
let stairs_clear1 = painter.prim(Primitive::Cylinder(Aabb {
min: (center - (3 * length)).with_z(base - (2 * length)),
max: (center + (3 * length)).with_z(base - length),
}));
painter
.prim(Primitive::sampling(
stairs_clear1,
dungeon::spiral_staircase(
center.with_z(base - (2 * length)),
stair_radius1,
2.5,
(2 * length) as f32,
),
))
.fill(wood_dark.clone());
let stair_radius2 = ((2 * length) + 1) as f32;
let stairs_clear2 = painter.prim(Primitive::Cylinder(Aabb {
min: (center - length).with_z(base - (3 * length)),
max: (center + length).with_z(base - (2 * length)),
}));
painter
.prim(Primitive::sampling(
stairs_clear2,
dungeon::spiral_staircase(
center.with_z(base - (3 * length)),
stair_radius2,
2.5,
(2 * length) as f32,
),
))
.fill(wood_dark.clone());
painter
.cone(Aabb {
min: (center - (4 * length)).with_z(base + length),
max: (center + (4 * length)).with_z(base + (3 * length)),
})
.fill(reed.clone());
painter
.cone(Aabb {
min: (center - (4 * length)).with_z(base + length - 1),
max: (center + (4 * length)).with_z(base + (3 * length) - 1),
})
.clear();
painter
.cylinder(Aabb {
min: (center - 2).with_z(base),
max: (center + 2).with_z(base + (3 * length) - 1),
})
.fill(wood_dark.clone());
for dir in CARDINALS {
let outer_support = center + dir * ((3 * length) + 2);
painter
.cylinder(Aabb {
min: (outer_support - 3).with_z(base - length),
max: (outer_support + 3).with_z(base + length + 2),
})
.fill(wood_dark.clone());
}
painter
.cylinder(Aabb {
min: (center - length).with_z(base + length + 1),
max: (center + length).with_z(base + length + 2),
})
.fill(wood_light.clone());
let small_stairs_pos = center - 5;
let small_stair_radius = 4.0;
let small_stairs_clear = painter.cylinder(Aabb {
min: (small_stairs_pos + 1 - small_stair_radius as i32).with_z(base),
max: (small_stairs_pos - 1 + small_stair_radius as i32).with_z(base + length + 3),
});
small_stairs_clear.clear();
painter
.prim(Primitive::sampling(
small_stairs_clear,
dungeon::spiral_staircase(
small_stairs_pos.with_z(base),
small_stair_radius,
0.5,
(length - 2) as f32,
),
))
.fill(wood_dark.clone());
for dir in CARDINALS {
let room_center = center + dir * ((4 * length) - (length / 4));
let entries_clear = center + dir * ((3 * length) - (length / 4));
for f in 1..3 {
painter
.cylinder(Aabb {
min: (room_center - length - 1).with_z(base - ((1 + f) * length)),
max: (room_center + length + 1).with_z(base - (length * f) - 1),
})
.fill(clay.clone());
painter
.cylinder(Aabb {
min: (room_center - length).with_z(base - ((1 + f) * length)),
max: (room_center + length).with_z(base - (length * f) - 1),
})
.clear();
painter
.cylinder(Aabb {
min: (room_center - length).with_z(base - ((1 + f) * length) + 1),
max: (room_center + length).with_z(base - ((1 + f) * length) + 2),
})
.fill(wood_light.clone());
painter
.cylinder(Aabb {
min: (room_center - length).with_z(base - ((1 + f) * length) + 2),
max: (room_center + length).with_z(base - ((1 + f) * length) + 3),
})
.fill(sprite_fill.clone());
painter
.cylinder(Aabb {
min: (room_center - length + 1).with_z(base - ((1 + f) * length) + 1),
max: (room_center + length - 1).with_z(base - ((1 + f) * length) + 3),
})
.clear();
painter
.sphere(Aabb {
min: (entries_clear - 2).with_z(base - ((1 + f) * length)),
max: (entries_clear + 2).with_z(base - ((1 + f) * length) + 4),
})
.clear();
}
painter
.cylinder(Aabb {
min: (room_center - length + 1).with_z(base + length),
max: (room_center + length - 1).with_z(base + length + 1),
})
.fill(wood_light.clone());
let top_var = RandomField::new(0).get(room_center.with_z(base)) % 4;
if let 0..=2 = top_var {
painter
.cone(Aabb {
min: (room_center - length)
.with_z(base + (2 * length) + (3 * top_var) as i32),
max: (room_center + length)
.with_z(base + (2 * length) + (length / 2) + 2 + (3 * top_var) as i32),
})
.fill(reed.clone());
painter
.cone(Aabb {
min: (room_center - length)
.with_z(base + (2 * length) - 1 + (3 * top_var) as i32),
max: (room_center + length)
.with_z(base + (2 * length) + (length / 2) + 1 + (3 * top_var) as i32),
})
.clear();
painter
.aabb(Aabb {
min: (room_center - 1).with_z(base + length + 1),
max: (room_center + 1)
.with_z(base + (2 * length) + 5 + (3 * top_var) as i32),
})
.fill(wood_dark.clone());
}
let lantern_pos = center + dir * ((4 * length) - (length / 4) + 4);
painter.sprite(lantern_pos.with_z(base + length + 1), SpriteKind::Lantern);
}
for dir in DIAGONALS {
let room_center = center + dir * ((3 * length) - (length / 3));
let entries_clear = center + dir * (2 * length);
for f in 1..3 {
painter
.cylinder(Aabb {
min: (room_center - length - 1).with_z(base - ((1 + f) * length)),
max: (room_center + length + 1).with_z(base - (length * f) - 1),
})
.fill(clay.clone());
painter
.cylinder(Aabb {
min: (room_center - length).with_z(base - ((1 + f) * length)),
max: (room_center + length).with_z(base - (length * f) - 1),
})
.clear();
painter
.cylinder(Aabb {
min: (room_center - length).with_z(base - ((1 + f) * length) + 1),
max: (room_center + length).with_z(base - ((1 + f) * length) + 2),
})
.fill(wood_light.clone());
painter
.cylinder(Aabb {
min: (room_center - length).with_z(base - ((1 + f) * length) + 2),
max: (room_center + length).with_z(base - ((1 + f) * length) + 3),
})
.fill(sprite_fill.clone());
painter
.cylinder(Aabb {
min: (room_center - length + 1).with_z(base - ((1 + f) * length) + 1),
max: (room_center + length - 1).with_z(base - ((1 + f) * length) + 3),
})
.clear();
painter
.sphere(Aabb {
min: (entries_clear - 3).with_z(base - ((1 + f) * length)),
max: (entries_clear + 3).with_z(base - ((1 + f) * length) + 4),
})
.clear();
match RandomField::new(0).get(room_center.with_z(base)) % 2 {
0 => {
let mut sprites = vec![
SpriteKind::Bowl,
SpriteKind::VialEmpty,
SpriteKind::JugArabic,
SpriteKind::JugAndBowlArabic,
SpriteKind::FountainArabic,
SpriteKind::SepareArabic,
];
'outer3: for d in 0..2 {
for dir in NEIGHBORS {
if sprites.is_empty() {
break 'outer3;
}
let position = room_center + dir * (5 + d);
let sprite = sprites.swap_remove(
RandomField::new(0).get(position.with_z(base)) as usize
% sprites.len(),
);
painter.sprite(position.with_z(base - ((1 + f) * length)), sprite);
}
}
},
1 => {
let mut sprites = vec![
SpriteKind::DrawerSmall,
SpriteKind::ChairSingle,
SpriteKind::CoatRack,
SpriteKind::Bed,
SpriteKind::WardrobeSingle,
SpriteKind::CushionArabic,
SpriteKind::TableArabicSmall,
SpriteKind::DecorSetArabic,
];
'outer4: for d in 0..2 {
for dir in NEIGHBORS {
if sprites.is_empty() {
break 'outer4;
}
let position = room_center + dir * (5 + d);
let sprite = sprites.swap_remove(
RandomField::new(0).get(position.with_z(base)) as usize
% sprites.len(),
);
painter.sprite(position.with_z(base - ((1 + f) * length)), sprite);
}
}
},
_ => {},
}
}
painter
.cylinder(Aabb {
min: (room_center - length + 1).with_z(base + length),
max: (room_center + length - 1).with_z(base + length + 1),
})
.fill(wood_light.clone());
let small_stairs_pos = room_center;
let small_stair_radius = 4.0;
let small_stairs_clear = painter.cylinder(Aabb {
min: (small_stairs_pos + 1 - small_stair_radius as i32).with_z(base - (3 * length)),
max: (small_stairs_pos - 1 + small_stair_radius as i32).with_z(base + length + 3),
});
small_stairs_clear.clear();
painter
.prim(Primitive::sampling(
small_stairs_clear,
dungeon::spiral_staircase(
small_stairs_pos.with_z(base - (3 * length)),
small_stair_radius,
0.5,
(length - 2) as f32,
),
))
.fill(wood_dark.clone());
let top_var = RandomField::new(0).get(room_center.with_z(base)) % 4;
if let 0..=2 = top_var {
painter
.cone(Aabb {
min: (room_center - length)
.with_z(base + (2 * length) + (3 * top_var) as i32),
max: (room_center + length)
.with_z(base + (2 * length) + (length / 2) + 2 + (3 * top_var) as i32),
})
.fill(reed.clone());
painter
.cone(Aabb {
min: (room_center - length)
.with_z(base + (2 * length) - 1 + (3 * top_var) as i32),
max: (room_center + length)
.with_z(base + (2 * length) + (length / 2) + 1 + (3 * top_var) as i32),
})
.clear();
painter
.aabb(Aabb {
min: (room_center - 1).with_z(base + length + 1),
max: (room_center + 1)
.with_z(base + (2 * length) + 5 + (3 * top_var) as i32),
})
.fill(wood_dark.clone());
}
let lantern_pos = center + dir * ((3 * length) - (length / 3) + 4);
painter.sprite(lantern_pos.with_z(base + length + 1), SpriteKind::Lantern);
}
for dir in SQUARE_4 {
for f in 2..4 {
let corner_pos1 = Vec2::new(center.x - 1, center.y - (2 * length) - 6);
let lamp_pos1 = Vec2::new(
corner_pos1.x + dir.x * 1,
corner_pos1.y + dir.y * ((4 * length) + 11),
);
painter.rotated_sprite(
lamp_pos1.with_z(base - (f * length) + 5),
SpriteKind::WallLampSmall,
4 - (4 * dir.y) as u8,
);
let corner_pos2 = Vec2::new(center.x - (2 * length) - 6, center.y - 1);
let lamp_pos2 = Vec2::new(
corner_pos2.x + dir.x * ((4 * length) + 11),
corner_pos2.y + dir.y,
);
painter.rotated_sprite(
lamp_pos2.with_z(base - (f * length) + 5),
SpriteKind::WallLampSmall,
2 + (4 * dir.x) as u8,
);
}
}
for f in 2..4 {
for n in 0..2 {
let ws_center = Vec2::new(
center.x,
center.y - (4 * length) + 2 + (n * ((8 * length) - 4)),
);
painter
.aabb(Aabb {
min: (ws_center - 2).with_z(base - (f * length)),
max: (ws_center + 2).with_z(base - (f * length) + 2),
})
.fill(clay.clone());
painter
.aabb(Aabb {
min: (ws_center - 1).with_z(base - (f * length) + 1),
max: (ws_center + 1).with_z(base - (f * length) + 2),
})
.clear();
painter
.aabb(Aabb {
min: (ws_center - 1).with_z(base - (f * length)),
max: (ws_center + 1).with_z(base - (f * length) + 1),
})
.fill(Fill::Block(Block::air(SpriteKind::Ember)));
let mut stations = vec![
SpriteKind::CraftingBench,
SpriteKind::Forge,
SpriteKind::SpinningWheel,
SpriteKind::TanningRack,
SpriteKind::Loom,
SpriteKind::Anvil,
SpriteKind::DismantlingBench,
SpriteKind::RepairBench,
];
'outer: for d in 0..2 {
for dir in NEIGHBORS {
if stations.is_empty() {
break 'outer;
}
let position = ws_center + dir * (4 + d * 2);
let cr_station = stations.swap_remove(
RandomField::new(0).get(position.with_z(base)) as usize
% stations.len(),
);
painter.sprite(position.with_z(base - (f * length)), cr_station);
}
}
let k_center = Vec2::new(
center.x - (4 * length) + 2 + (n * ((8 * length) - 4)),
center.y,
);
painter
.aabb(Aabb {
min: (k_center - 2).with_z(base - (f * length)),
max: (k_center + 2).with_z(base - (f * length) + 2),
})
.fill(clay.clone());
painter
.aabb(Aabb {
min: (k_center - 1).with_z(base - (f * length) + 1),
max: (k_center + 1).with_z(base - (f * length) + 2),
})
.clear();
painter
.aabb(Aabb {
min: (k_center - 1).with_z(base - (f * length)),
max: (k_center + 1).with_z(base - (f * length) + 1),
})
.fill(Fill::Block(Block::air(SpriteKind::Ember)));
let mut stations = vec![SpriteKind::CookingPot, SpriteKind::Cauldron];
'outer2: for d in 0..2 {
for dir in NEIGHBORS {
if stations.is_empty() {
break 'outer2;
}
let position = k_center + dir * (3 + d);
let cr_station = stations.swap_remove(
RandomField::new(0).get(position.with_z(base)) as usize
% stations.len(),
);
painter.sprite(position.with_z(base - (f * length)), cr_station);
}
}
}
}
let campfire_pos = (center - 10).with_z(base);
painter.spawn(
EntityInfo::at(campfire_pos.map(|e| e as f32)).into_special(SpecialEntity::Waypoint),
);
let stairs_pos = Vec2::new(center.x, center.y - (2 * length) + 1);
let cone_pos = Vec2::new(center.x, center.y - (3 * length) + 3);
let cyl_pos = Vec2::new(center.x, center.y - (4 * length) - 3);
let crates_pos = Vec2::new(center.x, center.y + (2 * length));
painter
.cylinder(Aabb {
min: (stairs_pos - (length / 2) - 1).with_z(base - (5 * length) + 3),
max: (stairs_pos + (length / 2) + 1).with_z(base - (3 * length)),
})
.clear();
painter
.cylinder(Aabb {
min: (center - (4 * length) + 1).with_z(base - (5 * length) + 3),
max: (center + (4 * length) - 1).with_z(base - (3 * length) - 2),
})
.clear();
painter
.cylinder(Aabb {
min: (center - (4 * length) + 1).with_z(base - (5 * length) + 4),
max: (center + (4 * length) - 1).with_z(base - (5 * length) + 5),
})
.fill(wood_light.clone());
painter
.cylinder(Aabb {
min: (center - (4 * length) + 1).with_z(base - (5 * length) + 5),
max: (center + (4 * length) - 1).with_z(base - (5 * length) + 6),
})
.fill(sprite_fill);
painter
.cylinder(Aabb {
min: (center - (4 * length) + 2).with_z(base - (5 * length) + 3),
max: (center + (4 * length) - 2).with_z(base - (5 * length) + 6),
})
.clear();
for dir in SQUARE_4 {
let corner_pos1 = Vec2::new(center.x - 1, center.y - (3 * length) - 4);
let lamp_pos1 = Vec2::new(
corner_pos1.x + dir.x * 1,
corner_pos1.y + dir.y * ((6 * length) + 7),
);
painter.rotated_sprite(
lamp_pos1.with_z(base - (5 * length) + 8),
SpriteKind::WallLampSmall,
4 - (4 * dir.y) as u8,
);
let corner_pos2 = Vec2::new(center.x - (3 * length) - 4, center.y - 1);
let lamp_pos2 = Vec2::new(
corner_pos2.x + dir.x * ((6 * length) + 7),
corner_pos2.y + dir.y,
);
painter.rotated_sprite(
lamp_pos2.with_z(base - (5 * length) + 8),
SpriteKind::WallLampSmall,
2 + (4 * dir.x) as u8,
);
}
painter
.cone(Aabb {
min: (cone_pos - (3 * length)).with_z(base - (5 * length) + 3),
max: (cone_pos + (3 * length)).with_z(base - (3 * length)),
})
.fill(clay.clone());
painter
.cylinder(Aabb {
min: (cyl_pos - (2 * length)).with_z(base - (5 * length) + 3),
max: (cyl_pos + (2 * length)).with_z(base - (3 * length) - 1),
})
.fill(clay.clone());
for dir in CARDINALS {
let crate_pos = crates_pos + dir * length;
painter
.cylinder(Aabb {
min: (crate_pos - 3).with_z(base - (5 * length) + 3),
max: (crate_pos + 3).with_z(base - (5 * length) + 4),
})
.fill(wood_light.clone());
painter
.cylinder(Aabb {
min: (crate_pos - 3).with_z(base - (5 * length) + 4),
max: (crate_pos + 3).with_z(base - (5 * length) + 5),
})
.fill(Fill::Block(Block::air(SpriteKind::Planter)));
painter
.cylinder(Aabb {
min: (crate_pos - 2).with_z(base - (5 * length) + 3),
max: (crate_pos + 2).with_z(base - (5 * length) + 5),
})
.clear();
painter.sprite(
(crate_pos + 1).with_z(base - (5 * length) + 3),
SpriteKind::Lantern,
);
}
for c in 0..2 {
let fridge_pos = Vec2::new(
crates_pos.x - (2 * length) + (c * (4 * length)),
crates_pos.y,
);
painter
.aabb(Aabb {
min: (fridge_pos - 1).with_z(base - (5 * length) + 3),
max: (fridge_pos + 2).with_z(base - (5 * length) + 6),
})
.fill(snow_fill.clone());
painter
.aabb(Aabb {
min: Vec2::new(fridge_pos.x, fridge_pos.y - 1).with_z(base - (5 * length) + 4),
max: Vec2::new(fridge_pos.x + 1, fridge_pos.y + 2)
.with_z(base - (5 * length) + 5),
})
.clear();
painter
.aabb(Aabb {
min: Vec2::new(fridge_pos.x, fridge_pos.y - 1).with_z(base - (5 * length) + 4),
max: Vec2::new(fridge_pos.x + 1, fridge_pos.y + 2).with_z(base - (5 * length) + 5),
})
.fill(Fill::Block(Block::air(SpriteKind::Crate)));
}
for dir in CARDINALS {
let outer_support = center + dir * ((4 * length) - 2);
painter
.cylinder(Aabb {
min: (outer_support - 3).with_z(base - (5 * length) + 3),
max: (outer_support + 3).with_z(base - (3 * length) - 2),
})
.fill(wood_dark.clone());
}
let wall_length = length - 1;
let wall_height = 5;
let wall_size = 1.5;
for w in 0..10 {
painter
.line(
Vec2::new(center.x, center.y - (7 * wall_length))
.with_z(base - ((wall_height / 2) * w)),
(center - (6 * wall_length))
.with_z(base + (wall_height / 2) - ((wall_height / 2) * w)),
wall_size,
)
.fill(wood_light.clone());
painter
.line(
(center - (6 * wall_length)).with_z(base - ((wall_height / 2) * w)),
Vec2::new(center.x - (7 * wall_length), center.y)
.with_z(base + (wall_height / 2) - ((wall_height / 2) * w)),
wall_size,
)
.fill(wood_light.clone());
painter
.line(
Vec2::new(center.x - (7 * wall_length), center.y)
.with_z(base - ((wall_height / 2) * w)),
Vec2::new(center.x - (6 * wall_length), center.y + (6 * wall_length))
.with_z(base + (wall_height / 2) - ((wall_height / 2) * w)),
wall_size,
)
.fill(wood_light.clone());
painter
.line(
Vec2::new(center.x - (6 * wall_length), center.y + (6 * wall_length))
.with_z(base - ((wall_height / 2) * w)),
Vec2::new(center.x, center.y + (7 * wall_length))
.with_z(base + (wall_height / 2) - ((wall_height / 2) * w)),
wall_size,
)
.fill(wood_light.clone());
painter
.line(
Vec2::new(center.x, center.y + (7 * wall_length))
.with_z(base - ((wall_height / 2) * w)),
(center + (6 * wall_length)).with_z(base - ((wall_height / 2) * w)),
wall_size,
)
.fill(wood_light.clone());
painter
.line(
(center + (6 * wall_length)).with_z(base - ((wall_height / 2) * w)),
Vec2::new(center.x + (7 * wall_length), center.y)
.with_z(base + (wall_height / 2) - ((wall_height / 2) * w)),
wall_size,
)
.fill(wood_light.clone());
painter
.line(
Vec2::new(center.x + (7 * wall_length), center.y)
.with_z(base - ((wall_height / 2) * w)),
Vec2::new(center.x + (6 * wall_length), center.y - (6 * wall_length))
.with_z(base + (wall_height / 2) - ((wall_height / 2) * w)),
wall_size,
)
.fill(wood_light.clone());
painter
.line(
Vec2::new(center.x + (6 * wall_length), center.y - (6 * wall_length))
.with_z(base - ((wall_height / 2) * w)),
Vec2::new(center.x, center.y - (7 * wall_length))
.with_z(base + (wall_height / 2) - ((wall_height / 2) * w)),
wall_size,
)
.fill(wood_light.clone());
}
for w in 0..2 {
painter
.line(
Vec2::new(center.x, center.y - (7 * wall_length))
.with_z(base + (wall_height * w)),
(center - (6 * wall_length)).with_z(base + (wall_height * w)),
wall_size + (2 * w) as f32,
)
.fill(wood_light.clone());
painter
.line(
(center - (6 * wall_length)).with_z(base + (wall_height * w)),
Vec2::new(center.x - (7 * wall_length), center.y)
.with_z(base + (wall_height * w)),
wall_size + (2 * w) as f32,
)
.fill(wood_light.clone());
painter
.line(
Vec2::new(center.x - (7 * wall_length), center.y)
.with_z(base + (wall_height * w)),
Vec2::new(center.x - (6 * wall_length), center.y + (6 * wall_length))
.with_z(base + (wall_height * w)),
wall_size + (2 * w) as f32,
)
.fill(wood_light.clone());
painter
.line(
Vec2::new(center.x - (6 * wall_length), center.y + (6 * wall_length))
.with_z(base + (wall_height * w)),
Vec2::new(center.x, center.y + (7 * wall_length))
.with_z(base + (wall_height * w)),
wall_size + (2 * w) as f32,
)
.fill(wood_light.clone());
painter
.line(
Vec2::new(center.x, center.y + (7 * wall_length))
.with_z(base + (wall_height * w)),
(center + (6 * wall_length)).with_z(base + (wall_height * w)),
wall_size + (2 * w) as f32,
)
.fill(wood_light.clone());
painter
.line(
(center + (6 * wall_length)).with_z(base + (wall_height * w)),
Vec2::new(center.x + (7 * wall_length), center.y)
.with_z(base + (wall_height * w)),
wall_size + (2 * w) as f32,
)
.fill(wood_light.clone());
painter
.line(
Vec2::new(center.x + (7 * wall_length), center.y)
.with_z(base + (wall_height * w)),
Vec2::new(center.x + (6 * wall_length), center.y - (6 * wall_length))
.with_z(base + (wall_height * w)),
wall_size + (2 * w) as f32,
)
.fill(wood_light.clone());
painter
.line(
Vec2::new(center.x + (6 * wall_length), center.y - (6 * wall_length))
.with_z(base + (wall_height * w)),
Vec2::new(center.x, center.y - (7 * wall_length))
.with_z(base + (wall_height * w)),
wall_size + (2 * w) as f32,
)
.fill(wood_light.clone());
}
painter
.line(
Vec2::new(center.x, center.y - (7 * wall_length)).with_z(base + 3 + wall_height),
(center - (6 * wall_length)).with_z(base + 3 + wall_height),
wall_size + 3_f32,
)
.clear();
painter
.line(
(center - (6 * wall_length)).with_z(base + 3 + wall_height),
Vec2::new(center.x - (7 * wall_length), center.y).with_z(base + 3 + wall_height),
wall_size + 3_f32,
)
.clear();
painter
.line(
Vec2::new(center.x - (7 * wall_length), center.y).with_z(base + 3 + wall_height),
Vec2::new(center.x - (6 * wall_length), center.y + (6 * wall_length))
.with_z(base + 3 + wall_height),
wall_size + 3_f32,
)
.clear();
painter
.line(
Vec2::new(center.x - (6 * wall_length), center.y + (6 * wall_length))
.with_z(base + 3 + wall_height),
Vec2::new(center.x, center.y + (7 * wall_length)).with_z(base + 3 + wall_height),
wall_size + 3_f32,
)
.clear();
painter
.line(
Vec2::new(center.x, center.y + (7 * wall_length)).with_z(base + 3 + wall_height),
(center + (6 * wall_length)).with_z(base + 3 + wall_height),
wall_size + 3_f32,
)
.clear();
painter
.line(
(center + (6 * wall_length)).with_z(base + 3 + wall_height),
Vec2::new(center.x + (7 * wall_length), center.y).with_z(base + 3 + wall_height),
wall_size + 3_f32,
)
.clear();
painter
.line(
Vec2::new(center.x + (7 * wall_length), center.y).with_z(base + 3 + wall_height),
Vec2::new(center.x + (6 * wall_length), center.y - (6 * wall_length))
.with_z(base + 3 + wall_height),
wall_size + 3_f32,
)
.clear();
painter
.line(
Vec2::new(center.x + (6 * wall_length), center.y - (6 * wall_length))
.with_z(base + 3 + wall_height),
Vec2::new(center.x, center.y - (7 * wall_length)).with_z(base + 3 + wall_height),
wall_size + 3_f32,
)
.clear();
painter
.line(
Vec2::new(center.x, center.y - (7 * wall_length)).with_z(base - (2 * length)),
(center - (6 * wall_length)).with_z(base - (2 * length)),
wall_size * 3_f32,
)
.fill(clay.clone());
painter
.line(
(center - (6 * wall_length)).with_z(base - (2 * length)),
Vec2::new(center.x - (7 * wall_length), center.y).with_z(base - (2 * length)),
wall_size * 3_f32,
)
.fill(clay.clone());
painter
.line(
Vec2::new(center.x - (7 * wall_length), center.y).with_z(base - (2 * length)),
Vec2::new(center.x - (6 * wall_length), center.y + (6 * wall_length))
.with_z(base - (2 * length)),
wall_size * 3_f32,
)
.fill(clay.clone());
painter
.line(
Vec2::new(center.x - (6 * wall_length), center.y + (6 * wall_length))
.with_z(base - (2 * length)),
Vec2::new(center.x, center.y + (7 * wall_length)).with_z(base - (2 * length)),
wall_size * 3_f32,
)
.fill(clay.clone());
painter
.line(
Vec2::new(center.x, center.y + (7 * wall_length)).with_z(base - (2 * length)),
(center + (6 * wall_length)).with_z(base - (2 * length)),
wall_size * 3_f32,
)
.fill(clay.clone());
painter
.line(
(center + (6 * wall_length)).with_z(base - (2 * length)),
Vec2::new(center.x + (7 * wall_length), center.y).with_z(base - (2 * length)),
wall_size * 3_f32,
)
.fill(clay.clone());
painter
.line(
Vec2::new(center.x + (7 * wall_length), center.y).with_z(base - (2 * length)),
Vec2::new(center.x + (6 * wall_length), center.y - (6 * wall_length))
.with_z(base - (2 * length)),
wall_size * 3_f32,
)
.fill(clay.clone());
painter
.line(
Vec2::new(center.x + (6 * wall_length), center.y - (6 * wall_length))
.with_z(base - (2 * length)),
Vec2::new(center.x, center.y - (7 * wall_length)).with_z(base - (2 * length)),
wall_size * 3_f32,
)
.fill(clay.clone());
painter
.line(
Vec2::new(center.x, center.y - (7 * wall_length)).with_z(base - (2 * length)),
(center - (6 * wall_length)).with_z(base - (2 * length)),
wall_size * 2_f32,
)
.clear();
painter
.line(
(center - (6 * wall_length)).with_z(base - (2 * length)),
Vec2::new(center.x - (7 * wall_length), center.y).with_z(base - (2 * length)),
wall_size * 2_f32,
)
.clear();
painter
.line(
Vec2::new(center.x - (7 * wall_length), center.y).with_z(base - (2 * length)),
Vec2::new(center.x - (6 * wall_length), center.y + (6 * wall_length))
.with_z(base - (2 * length)),
wall_size * 2_f32,
)
.clear();
painter
.line(
Vec2::new(center.x - (6 * wall_length), center.y + (6 * wall_length))
.with_z(base - (2 * length)),
Vec2::new(center.x, center.y + (7 * wall_length)).with_z(base - (2 * length)),
wall_size * 2_f32,
)
.clear();
painter
.line(
Vec2::new(center.x, center.y + (7 * wall_length)).with_z(base - (2 * length)),
(center + (6 * wall_length)).with_z(base - (2 * length)),
wall_size * 2_f32,
)
.clear();
painter
.line(
(center + (6 * wall_length)).with_z(base - (2 * length)),
Vec2::new(center.x + (7 * wall_length), center.y).with_z(base - (2 * length)),
wall_size * 2_f32,
)
.clear();
painter
.line(
Vec2::new(center.x + (7 * wall_length), center.y).with_z(base - (2 * length)),
Vec2::new(center.x + (6 * wall_length), center.y - (6 * wall_length))
.with_z(base - (2 * length)),
wall_size * 2_f32,
)
.clear();
painter
.line(
Vec2::new(center.x + (6 * wall_length), center.y - (6 * wall_length))
.with_z(base - (2 * length)),
Vec2::new(center.x, center.y - (7 * wall_length)).with_z(base - (2 * length)),
wall_size * 2_f32,
)
.clear();
painter
.line(
Vec2::new(center.x, center.y - (7 * wall_length)).with_z(base - (2 * length)),
Vec2::new(center.x, center.y - (6 * wall_length) + (length / 2))
.with_z(base - (2 * length) + 2),
wall_size * 2_f32,
)
.clear();
painter
.line(
(center - (6 * wall_length)).with_z(base - (2 * length)),
(center - (4 * wall_length) + 1).with_z(base - (2 * length) + 2),
wall_size * 2_f32,
)
.clear();
painter
.line(
Vec2::new(center.x - (7 * wall_length), center.y).with_z(base - (2 * length)),
Vec2::new(center.x - (6 * wall_length) + (length / 2), center.y)
.with_z(base - (2 * length) + 2),
wall_size * 2_f32,
)
.clear();
painter
.line(
Vec2::new(center.x - (6 * wall_length), center.y + (6 * wall_length))
.with_z(base - (2 * length)),
Vec2::new(
center.x - (4 * wall_length) + 1,
center.y + (4 * wall_length) - 1,
)
.with_z(base - (2 * length) + 2),
wall_size * 2_f32,
)
.clear();
painter
.line(
Vec2::new(center.x, center.y + (7 * wall_length)).with_z(base - (2 * length)),
Vec2::new(center.x, center.y + (6 * wall_length) - (length / 2))
.with_z(base - (2 * length) + 2),
wall_size * 2_f32,
)
.clear();
painter
.line(
(center + (6 * wall_length)).with_z(base - (2 * length)),
(center + (4 * wall_length) - 1).with_z(base - (2 * length) + 2),
wall_size * 2_f32,
)
.clear();
painter
.line(
Vec2::new(center.x + (7 * wall_length), center.y).with_z(base - (2 * length)),
Vec2::new(center.x + (6 * wall_length) - (length / 2), center.y)
.with_z(base - (2 * length) + 2),
wall_size * 2_f32,
)
.clear();
painter
.line(
Vec2::new(center.x + (6 * wall_length), center.y - (6 * wall_length))
.with_z(base - (2 * length)),
Vec2::new(
center.x + (4 * wall_length) - 1,
center.y - (4 * wall_length) + 1,
)
.with_z(base - (2 * length) + 2),
wall_size * 2_f32,
)
.clear();
for dir in DIAGONALS {
let tower_center = center + dir * ((6 * wall_length) - 3);
let small_stairs_pos = tower_center;
let small_stair_radius = 4.0;
let small_stairs_clear = painter.cylinder(Aabb {
min: (small_stairs_pos + 1 - small_stair_radius as i32)
.with_z(base - (2 * length) - 2),
max: (small_stairs_pos - 1 + small_stair_radius as i32)
.with_z(base + (length / 2) + 2),
});
small_stairs_clear.clear();
painter
.prim(Primitive::sampling(
small_stairs_clear,
dungeon::spiral_staircase(
small_stairs_pos.with_z(base - (2 * length) - 2),
small_stair_radius,
0.5,
(length - 2) as f32,
),
))
.fill(wood_dark.clone());
let top_var = RandomField::new(0).get(tower_center.with_z(base)) % 4;
if let 0..=2 = top_var {
painter
.cone(Aabb {
min: (tower_center - length - 2)
.with_z(base + length + (length / 2) + (3 * top_var) as i32),
max: (tower_center + length + 2)
.with_z(base + (2 * length) + (length / 2) + (3 * top_var) as i32),
})
.fill(reed.clone());
painter
.cone(Aabb {
min: (tower_center - length - 2)
.with_z(base + length + (length / 2) - 1 + (3 * top_var) as i32),
max: (tower_center + length + 2)
.with_z(base + (2 * length) + (length / 2) - 1 + (3 * top_var) as i32),
})
.clear();
painter
.cylinder(Aabb {
min: (tower_center - 1).with_z(base + (length / 2) - 1),
max: (tower_center + 1)
.with_z(base + (2 * length) + (length / 2) - 2 + (3 * top_var) as i32),
})
.fill(wood_dark.clone());
}
let lantern_pos = tower_center - 3;
painter.sprite(lantern_pos.with_z(base + (length / 2)), SpriteKind::Lantern);
let tunnel_lantern_pos = tower_center - 3;
painter.sprite(
tunnel_lantern_pos.with_z(base - (2 * length) - 2),
SpriteKind::Lantern,
);
}
for dir in CARDINALS {
let tower_center = center + dir * ((7 * wall_length) - 2);
painter
.cone(Aabb {
min: (tower_center - (2 * length)).with_z(base - length),
max: (tower_center + (2 * length)).with_z(base),
})
.fill(clay.clone());
painter
.cylinder(Aabb {
min: (tower_center - (length / 2) - 2).with_z(base - 1),
max: (tower_center + (length / 2) + 2).with_z(base + 2),
})
.clear();
painter
.cylinder(Aabb {
min: (tower_center - (length / 2)).with_z(base + 2),
max: (tower_center + (length / 2)).with_z(base + 3),
})
.clear();
let top_var = RandomField::new(0).get(tower_center.with_z(base)) % 4;
if let 0..=2 = top_var {
painter
.cone(Aabb {
min: (tower_center - length - 2)
.with_z(base + length + (length / 2) + (3 * top_var) as i32),
max: (tower_center + length + 2)
.with_z(base + (2 * length) + (length / 2) + (3 * top_var) as i32),
})
.fill(reed.clone());
painter
.cone(Aabb {
min: (tower_center - length - 2)
.with_z(base + length + (length / 2) - 1 + (3 * top_var) as i32),
max: (tower_center + length + 2)
.with_z(base + (2 * length) + (length / 2) - 1 + (3 * top_var) as i32),
})
.clear();
painter
.cylinder(Aabb {
min: (tower_center - 1).with_z(base + (length / 2) - 1),
max: (tower_center + 1)
.with_z(base + (2 * length) + (length / 2) - 2 + (3 * top_var) as i32),
})
.fill(wood_dark.clone());
}
let lantern_pos = center + dir * (7 * wall_length);
painter.sprite(lantern_pos.with_z(base + (length / 2)), SpriteKind::Lantern);
let tunnel_lantern_pos = tower_center;
painter.sprite(
tunnel_lantern_pos.with_z(base - (2 * length) - 2),
SpriteKind::Lantern,
);
}
}
}