mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'floppy_coastal_town' into 'master'
coastal_town See merge request veloren/veloren!3887
This commit is contained in:
commit
e48ef26952
@ -22,4 +22,5 @@ pub enum SettlementKindMeta {
|
||||
CliffTown,
|
||||
DesertCity,
|
||||
SavannahPit,
|
||||
CoastalTown,
|
||||
}
|
||||
|
@ -85,6 +85,7 @@ impl Data {
|
||||
SiteKind::Refactor(site2)
|
||||
| SiteKind::CliffTown(site2)
|
||||
| SiteKind::SavannahPit(site2)
|
||||
| SiteKind::CoastalTown(site2)
|
||||
| SiteKind::DesertCity(site2) => Some(site2),
|
||||
_ => None,
|
||||
})?)))
|
||||
@ -122,6 +123,8 @@ impl Data {
|
||||
| PlotKind::CliffTower(_)
|
||||
| PlotKind::DesertCityMultiPlot(_)
|
||||
| PlotKind::DesertCityTemple(_)
|
||||
| PlotKind::CoastalHouse(_)
|
||||
| PlotKind::CoastalWorkshop(_)
|
||||
)
|
||||
}) as _;
|
||||
let matches_plazas = (|kind: &PlotKind| matches!(kind, PlotKind::Plaza)) as _;
|
||||
|
@ -25,7 +25,8 @@ impl Site {
|
||||
SiteKind::Refactor(_)
|
||||
| SiteKind::CliffTown(_)
|
||||
| SiteKind::DesertCity(_)
|
||||
| SiteKind::SavannahPit(_) => Some(true),
|
||||
| SiteKind::SavannahPit(_)
|
||||
| SiteKind::CoastalTown(_) => Some(true),
|
||||
// Evil
|
||||
SiteKind::Dungeon(_)
|
||||
| SiteKind::ChapelSite(_)
|
||||
|
@ -74,6 +74,7 @@ impl Rule for Migrate {
|
||||
site.world_site.map_or(false, |ws| matches!(&ctx.index.sites.get(ws).kind, SiteKind::Refactor(_)
|
||||
| SiteKind::CliffTown(_)
|
||||
| SiteKind::SavannahPit(_)
|
||||
| SiteKind::CoastalTown(_)
|
||||
| SiteKind::DesertCity(_)))
|
||||
})
|
||||
.min_by_key(|(_, site)| site.wpos.as_().distance_squared(npc.wpos.xy()) as i32)
|
||||
|
@ -673,6 +673,7 @@ fn adventure() -> impl Action<DefaultState> {
|
||||
SiteKind::Refactor(_)
|
||||
| SiteKind::CliffTown(_)
|
||||
| SiteKind::SavannahPit(_)
|
||||
| SiteKind::CoastalTown(_)
|
||||
| SiteKind::DesertCity(_)
|
||||
),
|
||||
) && ctx.npc.current_site.map_or(true, |cs| *site_id != cs)
|
||||
@ -776,6 +777,7 @@ fn villager(visiting_site: SiteId) -> impl Action<DefaultState> {
|
||||
Some(SiteKind::Refactor(site2)
|
||||
| SiteKind::CliffTown(site2)
|
||||
| SiteKind::SavannahPit(site2)
|
||||
| SiteKind::CoastalTown(site2)
|
||||
| SiteKind::DesertCity(site2)) => site2,
|
||||
_ => return None,
|
||||
};
|
||||
|
@ -79,6 +79,7 @@ fn on_death(ctx: EventCtx<SimulateNpcs, OnDeath>) {
|
||||
SiteKind::Refactor(_)
|
||||
| SiteKind::CliffTown(_)
|
||||
| SiteKind::SavannahPit(_)
|
||||
| SiteKind::CoastalTown(_)
|
||||
| SiteKind::DesertCity(_)
|
||||
)
|
||||
})
|
||||
|
@ -119,6 +119,9 @@ impl ActivityUpdate {
|
||||
Settlement(CliffTown) => format!("Climbing the towers of {chunk_name}"),
|
||||
Settlement(DesertCity) => format!("Hiding from the sun in {chunk_name}"),
|
||||
Settlement(SavannahPit) => format!("Shop at the market down in {chunk_name}"),
|
||||
Settlement(CoastalTown) => {
|
||||
format!("Dip your feet in the water in {chunk_name}")
|
||||
},
|
||||
_ => format!("In {chunk_name}"),
|
||||
};
|
||||
|
||||
|
@ -373,6 +373,7 @@ impl Civs {
|
||||
SiteKind::Refactor => (32i32, 10.0),
|
||||
SiteKind::CliffTown => (64i32, 25.0),
|
||||
SiteKind::SavannahPit => (48i32, 25.0),
|
||||
SiteKind::CoastalTown => (64i32, 35.0),
|
||||
SiteKind::DesertCity => (64i32, 25.0),
|
||||
SiteKind::ChapelSite => (36i32, 10.0),
|
||||
SiteKind::Tree => (12i32, 8.0),
|
||||
@ -482,6 +483,13 @@ impl Civs {
|
||||
wpos,
|
||||
))
|
||||
},
|
||||
SiteKind::CoastalTown => {
|
||||
WorldSite::coastal_town(site2::Site::generate_coastal_town(
|
||||
&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),
|
||||
),
|
||||
@ -809,6 +817,7 @@ impl Civs {
|
||||
0..=10 => SiteKind::CliffTown,
|
||||
11..=12 => SiteKind::DesertCity,
|
||||
13..=18 => SiteKind::SavannahPit,
|
||||
19..=36 => SiteKind::CoastalTown,
|
||||
_ => SiteKind::Refactor,
|
||||
};
|
||||
let world_dims = ctx.sim.get_aabr();
|
||||
@ -1256,6 +1265,7 @@ impl Civs {
|
||||
| SiteKind::Settlement
|
||||
| SiteKind::CliffTown
|
||||
| SiteKind::SavannahPit
|
||||
| SiteKind::CoastalTown
|
||||
| SiteKind::DesertCity
|
||||
| SiteKind::Castle
|
||||
)
|
||||
@ -1269,6 +1279,7 @@ impl Civs {
|
||||
| SiteKind::Settlement
|
||||
| SiteKind::CliffTown
|
||||
| SiteKind::SavannahPit
|
||||
| SiteKind::CoastalTown
|
||||
| SiteKind::DesertCity
|
||||
| SiteKind::Castle = self.sites[site].kind
|
||||
{
|
||||
@ -1755,6 +1766,7 @@ pub enum SiteKind {
|
||||
Refactor,
|
||||
CliffTown,
|
||||
SavannahPit,
|
||||
CoastalTown,
|
||||
DesertCity,
|
||||
ChapelSite,
|
||||
Tree,
|
||||
@ -1829,6 +1841,10 @@ impl SiteKind {
|
||||
&& !chunk.river.near_water()
|
||||
&& suitable_for_town()
|
||||
},
|
||||
SiteKind::CoastalTown => {
|
||||
(2.0..3.5).contains(&(chunk.water_alt - CONFIG.sea_level))
|
||||
&& suitable_for_town()
|
||||
},
|
||||
SiteKind::DesertCity => {
|
||||
(0.9..1.0).contains(&chunk.temp) && !chunk.near_cliffs() && suitable_for_town()
|
||||
},
|
||||
@ -1903,6 +1919,7 @@ impl Site {
|
||||
| SiteKind::CliffTown
|
||||
| SiteKind::DesertCity
|
||||
| SiteKind::SavannahPit
|
||||
| SiteKind::CoastalTown
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ impl World {
|
||||
name: site.site_tmp.map(|id| index.sites[id].name().to_string()),
|
||||
// TODO: Probably unify these, at some point
|
||||
kind: match &site.kind {
|
||||
civ::SiteKind::Settlement | civ::SiteKind::Refactor | civ::SiteKind::CliffTown | civ::SiteKind::SavannahPit | civ::SiteKind::DesertCity => world_msg::SiteKind::Town,
|
||||
civ::SiteKind::Settlement | civ::SiteKind::Refactor | civ::SiteKind::CliffTown | civ::SiteKind::SavannahPit | civ::SiteKind::CoastalTown | civ::SiteKind::DesertCity => world_msg::SiteKind::Town,
|
||||
civ::SiteKind::Dungeon => world_msg::SiteKind::Dungeon {
|
||||
difficulty: match site.site_tmp.map(|id| &index.sites[id].kind) {
|
||||
Some(SiteKind::Dungeon(d)) => d.dungeon_difficulty().unwrap_or(0),
|
||||
|
@ -123,6 +123,7 @@ impl Environment {
|
||||
| SiteKind::Refactor(_)
|
||||
| SiteKind::CliffTown(_)
|
||||
| SiteKind::SavannahPit(_)
|
||||
| SiteKind::CoastalTown(_)
|
||||
| SiteKind::DesertCity(_) => towns += site.economy.pop,
|
||||
SiteKind::Dungeon(_) => dungeons += site.economy.pop,
|
||||
SiteKind::Castle(_) => castles += site.economy.pop,
|
||||
|
@ -72,6 +72,7 @@ pub enum SiteKind {
|
||||
DesertCity(site2::Site),
|
||||
ChapelSite(site2::Site),
|
||||
DwarvenMine(site2::Site),
|
||||
CoastalTown(site2::Site),
|
||||
GiantTree(site2::Site),
|
||||
Gnarling(site2::Site),
|
||||
Bridge(site2::Site),
|
||||
@ -135,6 +136,13 @@ impl Site {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn coastal_town(ct: site2::Site) -> Self {
|
||||
Self {
|
||||
kind: SiteKind::CoastalTown(ct),
|
||||
economy: Economy::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn desert_city(dc: site2::Site) -> Self {
|
||||
Self {
|
||||
kind: SiteKind::DesertCity(dc),
|
||||
@ -185,6 +193,7 @@ impl Site {
|
||||
SiteKind::Refactor(s) => s.radius(),
|
||||
SiteKind::CliffTown(ct) => ct.radius(),
|
||||
SiteKind::SavannahPit(sp) => sp.radius(),
|
||||
SiteKind::CoastalTown(ct) => ct.radius(),
|
||||
SiteKind::DesertCity(dc) => dc.radius(),
|
||||
SiteKind::ChapelSite(p) => p.radius(),
|
||||
SiteKind::DwarvenMine(p) => p.radius(),
|
||||
@ -204,6 +213,7 @@ impl Site {
|
||||
SiteKind::Refactor(s) => s.origin,
|
||||
SiteKind::CliffTown(ct) => ct.origin,
|
||||
SiteKind::SavannahPit(sp) => sp.origin,
|
||||
SiteKind::CoastalTown(ct) => ct.origin,
|
||||
SiteKind::DesertCity(dc) => dc.origin,
|
||||
SiteKind::ChapelSite(p) => p.origin,
|
||||
SiteKind::DwarvenMine(p) => p.origin,
|
||||
@ -223,6 +233,7 @@ impl Site {
|
||||
SiteKind::Refactor(s) => s.spawn_rules(wpos),
|
||||
SiteKind::CliffTown(ct) => ct.spawn_rules(wpos),
|
||||
SiteKind::SavannahPit(sp) => sp.spawn_rules(wpos),
|
||||
SiteKind::CoastalTown(ct) => ct.spawn_rules(wpos),
|
||||
SiteKind::DesertCity(dc) => dc.spawn_rules(wpos),
|
||||
SiteKind::ChapelSite(p) => p.spawn_rules(wpos),
|
||||
SiteKind::DwarvenMine(p) => p.spawn_rules(wpos),
|
||||
@ -242,6 +253,7 @@ impl Site {
|
||||
SiteKind::Refactor(s) => s.name(),
|
||||
SiteKind::CliffTown(ct) => ct.name(),
|
||||
SiteKind::SavannahPit(sp) => sp.name(),
|
||||
SiteKind::CoastalTown(ct) => ct.name(),
|
||||
SiteKind::DesertCity(dc) => dc.name(),
|
||||
SiteKind::ChapelSite(p) => p.name(),
|
||||
SiteKind::DwarvenMine(p) => p.name(),
|
||||
@ -262,6 +274,7 @@ impl Site {
|
||||
| SiteKind::Refactor(_)
|
||||
| SiteKind::CliffTown(_)
|
||||
| SiteKind::SavannahPit(_)
|
||||
| SiteKind::CoastalTown(_)
|
||||
| SiteKind::DesertCity(_) => Some(common::trade::SiteInformation {
|
||||
id: site_id,
|
||||
unconsumed_stock: self.economy.get_available_stock(),
|
||||
@ -280,6 +293,7 @@ impl Site {
|
||||
SiteKind::Refactor(s) => s.render(canvas, dynamic_rng),
|
||||
SiteKind::CliffTown(ct) => ct.render(canvas, dynamic_rng),
|
||||
SiteKind::SavannahPit(sp) => sp.render(canvas, dynamic_rng),
|
||||
SiteKind::CoastalTown(ct) => ct.render(canvas, dynamic_rng),
|
||||
SiteKind::DesertCity(dc) => dc.render(canvas, dynamic_rng),
|
||||
SiteKind::ChapelSite(p) => p.render(canvas, dynamic_rng),
|
||||
SiteKind::DwarvenMine(p) => p.render(canvas, dynamic_rng),
|
||||
@ -312,6 +326,7 @@ impl Site {
|
||||
SiteKind::Refactor(_) => {},
|
||||
SiteKind::CliffTown(_) => {},
|
||||
SiteKind::SavannahPit(_) => {},
|
||||
SiteKind::CoastalTown(_) => {},
|
||||
SiteKind::DesertCity(_) => {},
|
||||
SiteKind::ChapelSite(p) => p.apply_supplement(dynamic_rng, wpos2d, supplement),
|
||||
SiteKind::DwarvenMine(p) => p.apply_supplement(dynamic_rng, wpos2d, supplement),
|
||||
@ -329,6 +344,7 @@ impl Site {
|
||||
SiteKind::Refactor(_)
|
||||
| SiteKind::CliffTown(_)
|
||||
| SiteKind::SavannahPit(_)
|
||||
| SiteKind::CoastalTown(_)
|
||||
| SiteKind::DesertCity(_)
|
||||
| SiteKind::Settlement(_)
|
||||
)
|
||||
@ -344,6 +360,7 @@ impl Site {
|
||||
SiteKind::Refactor(site2) => Some(site2),
|
||||
SiteKind::CliffTown(site2) => Some(site2),
|
||||
SiteKind::SavannahPit(site2) => Some(site2),
|
||||
SiteKind::CoastalTown(site2) => Some(site2),
|
||||
SiteKind::Tree(_) => None,
|
||||
SiteKind::DesertCity(site2) => Some(site2),
|
||||
SiteKind::ChapelSite(site2) => Some(site2),
|
||||
@ -366,6 +383,9 @@ impl SiteKind {
|
||||
SiteKind::SavannahPit(_) => {
|
||||
Some(SiteKindMeta::Settlement(SettlementKindMeta::SavannahPit))
|
||||
},
|
||||
SiteKind::CoastalTown(_) => {
|
||||
Some(SiteKindMeta::Settlement(SettlementKindMeta::CoastalTown))
|
||||
},
|
||||
SiteKind::DesertCity(_) => {
|
||||
Some(SiteKindMeta::Settlement(SettlementKindMeta::DesertCity))
|
||||
},
|
||||
|
@ -1039,6 +1039,98 @@ impl Site {
|
||||
site
|
||||
}
|
||||
|
||||
pub fn generate_coastal_town(land: &Land, rng: &mut impl Rng, origin: Vec2<i32>) -> Self {
|
||||
let mut rng = reseed(rng);
|
||||
let mut site = Site {
|
||||
origin,
|
||||
name: NameGen::location(&mut rng).generate_danari(),
|
||||
..Site::default()
|
||||
};
|
||||
site.demarcate_obstacles(land);
|
||||
|
||||
site.make_plaza(land, &mut rng);
|
||||
let build_chance = Lottery::from(vec![(38.0, 1), (7.0, 2)]);
|
||||
|
||||
for _ in 0..45 {
|
||||
match *build_chance.choose_seeded(rng.gen()) {
|
||||
1 => {
|
||||
// CoastalHouse
|
||||
|
||||
let size = (7.0 + rng.gen::<f32>().powf(5.0) * 1.5).round() as u32;
|
||||
if let Some((aabr, door_tile, door_dir)) = attempt(32, || {
|
||||
site.find_roadside_aabr(
|
||||
&mut rng,
|
||||
7..(size + 1).pow(2),
|
||||
Extent2::broadcast(size),
|
||||
)
|
||||
}) {
|
||||
let coastal_house = plot::CoastalHouse::generate(
|
||||
land,
|
||||
&mut reseed(&mut rng),
|
||||
&site,
|
||||
door_tile,
|
||||
door_dir,
|
||||
aabr,
|
||||
);
|
||||
let coastal_house_alt = coastal_house.alt;
|
||||
let plot = site.create_plot(Plot {
|
||||
kind: PlotKind::CoastalHouse(coastal_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(coastal_house_alt),
|
||||
})
|
||||
} else {
|
||||
site.make_plaza(land, &mut rng);
|
||||
}
|
||||
},
|
||||
2 => {
|
||||
// CoastalWorkshop
|
||||
|
||||
let size = (7.0 + rng.gen::<f32>().powf(5.0) * 1.5).round() as u32;
|
||||
if let Some((aabr, door_tile, door_dir)) = attempt(32, || {
|
||||
site.find_roadside_aabr(
|
||||
&mut rng,
|
||||
7..(size + 1).pow(2),
|
||||
Extent2::broadcast(size),
|
||||
)
|
||||
}) {
|
||||
let coastal_workshop = plot::CoastalWorkshop::generate(
|
||||
land,
|
||||
&mut reseed(&mut rng),
|
||||
&site,
|
||||
door_tile,
|
||||
door_dir,
|
||||
aabr,
|
||||
);
|
||||
let coastal_workshop_alt = coastal_workshop.alt;
|
||||
let plot = site.create_plot(Plot {
|
||||
kind: PlotKind::CoastalWorkshop(coastal_workshop),
|
||||
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(coastal_workshop_alt),
|
||||
})
|
||||
} else {
|
||||
site.make_plaza(land, &mut rng);
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
site
|
||||
}
|
||||
|
||||
pub fn generate_desert_city(land: &Land, rng: &mut impl Rng, origin: Vec2<i32>) -> Self {
|
||||
let mut rng = reseed(rng);
|
||||
|
||||
@ -1494,6 +1586,10 @@ impl Site {
|
||||
for plot in plots_to_render {
|
||||
let (prim_tree, fills, mut entities) = match &self.plots[plot].kind {
|
||||
PlotKind::House(house) => house.render_collect(self, canvas),
|
||||
PlotKind::CoastalHouse(coastal_house) => coastal_house.render_collect(self, canvas),
|
||||
PlotKind::CoastalWorkshop(coastal_workshop) => {
|
||||
coastal_workshop.render_collect(self, canvas)
|
||||
},
|
||||
PlotKind::Workshop(workshop) => workshop.render_collect(self, canvas),
|
||||
PlotKind::Castle(castle) => castle.render_collect(self, canvas),
|
||||
PlotKind::SeaChapel(sea_chapel) => sea_chapel.render_collect(self, canvas),
|
||||
|
@ -3,6 +3,8 @@ mod bridge;
|
||||
mod castle;
|
||||
mod citadel;
|
||||
mod cliff_tower;
|
||||
mod coastal_house;
|
||||
mod coastal_workshop;
|
||||
mod desert_city_multiplot;
|
||||
mod desert_city_temple;
|
||||
pub mod dungeon;
|
||||
@ -18,11 +20,12 @@ mod workshop;
|
||||
|
||||
pub use self::{
|
||||
adlet::AdletStronghold, bridge::Bridge, castle::Castle, citadel::Citadel,
|
||||
cliff_tower::CliffTower, desert_city_multiplot::DesertCityMultiPlot,
|
||||
desert_city_temple::DesertCityTemple, dungeon::Dungeon, dwarven_mine::DwarvenMine,
|
||||
giant_tree::GiantTree, gnarling::GnarlingFortification, house::House,
|
||||
savannah_hut::SavannahHut, savannah_pit::SavannahPit, savannah_workshop::SavannahWorkshop,
|
||||
sea_chapel::SeaChapel, workshop::Workshop,
|
||||
cliff_tower::CliffTower, coastal_house::CoastalHouse, coastal_workshop::CoastalWorkshop,
|
||||
desert_city_multiplot::DesertCityMultiPlot, desert_city_temple::DesertCityTemple,
|
||||
dungeon::Dungeon, dwarven_mine::DwarvenMine, giant_tree::GiantTree,
|
||||
gnarling::GnarlingFortification, house::House, savannah_hut::SavannahHut,
|
||||
savannah_pit::SavannahPit, savannah_workshop::SavannahWorkshop, sea_chapel::SeaChapel,
|
||||
workshop::Workshop,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
@ -64,6 +67,8 @@ impl Plot {
|
||||
|
||||
pub enum PlotKind {
|
||||
House(House),
|
||||
CoastalHouse(CoastalHouse),
|
||||
CoastalWorkshop(CoastalWorkshop),
|
||||
Workshop(Workshop),
|
||||
DesertCityMultiPlot(DesertCityMultiPlot),
|
||||
DesertCityTemple(DesertCityTemple),
|
||||
|
465
world/src/site2/plot/coastal_house.rs
Normal file
465
world/src/site2/plot/coastal_house.rs
Normal file
@ -0,0 +1,465 @@
|
||||
use super::*;
|
||||
use crate::{
|
||||
site2::plot::dungeon::wall_staircase,
|
||||
util::{RandomField, Sampler, CARDINALS, DIAGONALS, NEIGHBORS},
|
||||
Land,
|
||||
};
|
||||
use common::terrain::{BlockKind, SpriteKind};
|
||||
use rand::prelude::*;
|
||||
use std::sync::Arc;
|
||||
use vek::*;
|
||||
|
||||
/// Represents house data generated by the `generate()` method
|
||||
pub struct CoastalHouse {
|
||||
/// Tile position of the door tile
|
||||
pub door_tile: Vec2<i32>,
|
||||
/// Axis aligned bounding region for the house
|
||||
bounds: Aabr<i32>,
|
||||
/// Approximate altitude of the door tile
|
||||
pub(crate) alt: i32,
|
||||
}
|
||||
|
||||
impl CoastalHouse {
|
||||
pub fn generate(
|
||||
land: &Land,
|
||||
_rng: &mut impl Rng,
|
||||
site: &Site,
|
||||
door_tile: Vec2<i32>,
|
||||
door_dir: Vec2<i32>,
|
||||
tile_aabr: Aabr<i32>,
|
||||
) -> Self {
|
||||
let door_tile_pos = site.tile_center_wpos(door_tile);
|
||||
let bounds = Aabr {
|
||||
min: site.tile_wpos(tile_aabr.min),
|
||||
max: site.tile_wpos(tile_aabr.max),
|
||||
};
|
||||
Self {
|
||||
door_tile: door_tile_pos,
|
||||
bounds,
|
||||
alt: land.get_alt_approx(site.tile_center_wpos(door_tile + door_dir)) as i32 + 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Structure for CoastalHouse {
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"render_coastalhouse\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "render_coastalhouse")]
|
||||
fn render_inner(&self, _site: &Site, _land: &Land, painter: &Painter) {
|
||||
let base = self.alt + 1;
|
||||
let center = self.bounds.center();
|
||||
let white = Fill::Sampling(Arc::new(|center| {
|
||||
Some(match (RandomField::new(0).get(center)) % 37 {
|
||||
0..=8 => Block::new(BlockKind::Rock, Rgb::new(251, 251, 227)),
|
||||
9..=17 => Block::new(BlockKind::Rock, Rgb::new(245, 245, 229)),
|
||||
18..=26 => Block::new(BlockKind::Rock, Rgb::new(250, 243, 221)),
|
||||
27..=35 => Block::new(BlockKind::Rock, Rgb::new(240, 240, 230)),
|
||||
_ => Block::new(BlockKind::Rock, Rgb::new(255, 244, 193)),
|
||||
})
|
||||
}));
|
||||
let blue_broken = Fill::Sampling(Arc::new(|center| {
|
||||
Some(match (RandomField::new(0).get(center)) % 20 {
|
||||
0 => Block::new(BlockKind::Rock, Rgb::new(30, 187, 235)),
|
||||
_ => Block::new(BlockKind::Rock, Rgb::new(11, 146, 187)),
|
||||
})
|
||||
}));
|
||||
let length = (14 + RandomField::new(0).get(center.with_z(base)) % 3) as i32;
|
||||
let width = (12 + RandomField::new(0).get((center - 1).with_z(base)) % 3) as i32;
|
||||
let height = (12 + RandomField::new(0).get((center + 1).with_z(base)) % 4) as i32;
|
||||
let storeys = (1 + RandomField::new(0).get(center.with_z(base)) % 2) as i32;
|
||||
|
||||
// fence, blue gates
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length - 6, center.y - width - 6).with_z(base - 1),
|
||||
max: Vec2::new(center.x + length + 7, center.y + width + 7).with_z(base),
|
||||
})
|
||||
.fill(blue_broken.clone());
|
||||
|
||||
for dir in CARDINALS {
|
||||
let frame_pos = Vec2::new(
|
||||
center.x + dir.x * (length + 5),
|
||||
center.y + dir.y * (width + 5),
|
||||
);
|
||||
painter
|
||||
.line(center.with_z(base - 1), frame_pos.with_z(base - 1), 3.0)
|
||||
.fill(blue_broken.clone());
|
||||
}
|
||||
// foundation
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length - 6, center.y - width - 6).with_z(base - height),
|
||||
max: Vec2::new(center.x + length + 7, center.y + width + 7).with_z(base - 1),
|
||||
})
|
||||
.fill(white.clone());
|
||||
for f in 0..8 {
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length - 7 - f, center.y - width - 7 - f)
|
||||
.with_z(base - 3 - f),
|
||||
max: Vec2::new(center.x + length + 8 + f, center.y + width + 8 + f)
|
||||
.with_z(base - 2 - f),
|
||||
})
|
||||
.fill(white.clone());
|
||||
}
|
||||
// clear yard
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length - 5, center.y - width - 5).with_z(base - 2),
|
||||
max: Vec2::new(center.x + length + 6, center.y + width + 6).with_z(base + height),
|
||||
})
|
||||
.clear();
|
||||
// clear entries
|
||||
for dir in CARDINALS {
|
||||
let clear_pos = Vec2::new(
|
||||
center.x + dir.x * (length + 7),
|
||||
center.y + dir.y * (width + 7),
|
||||
);
|
||||
painter
|
||||
.line(center.with_z(base - 1), clear_pos.with_z(base - 1), 2.0)
|
||||
.clear();
|
||||
}
|
||||
for s in 0..storeys {
|
||||
// roof terrace
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(
|
||||
center.x - length - 3 + (2 * s),
|
||||
center.y - width - 3 + (2 * s),
|
||||
)
|
||||
.with_z(base - 3 + height + (s * height)),
|
||||
max: Vec2::new(
|
||||
center.x + length + 2 - (2 * s),
|
||||
center.y + width + 2 - (2 * s),
|
||||
)
|
||||
.with_z(base - 2 + height + (s * height)),
|
||||
})
|
||||
.fill(white.clone());
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(
|
||||
center.x - length - 3 + (2 * s),
|
||||
center.y - width - 3 + (2 * s),
|
||||
)
|
||||
.with_z(base - 2 + height + (s * height)),
|
||||
max: Vec2::new(
|
||||
center.x + length + 2 - (2 * s),
|
||||
center.y + width + 2 - (2 * s),
|
||||
)
|
||||
.with_z(base - 1 + height + (s * height)),
|
||||
})
|
||||
.fill(blue_broken.clone());
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(
|
||||
center.x - length - 2 + (2 * s),
|
||||
center.y - width - 2 + (2 * s),
|
||||
)
|
||||
.with_z(base - 2 + height + (s * height)),
|
||||
max: Vec2::new(
|
||||
center.x + length + 1 - (2 * s),
|
||||
center.y + width + 1 - (2 * s),
|
||||
)
|
||||
.with_z(base - 1 + height + (s * height)),
|
||||
})
|
||||
.clear();
|
||||
// room
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length + (2 * s), center.y - width + (2 * s))
|
||||
.with_z(base - 2 + (s * height)),
|
||||
max: Vec2::new(center.x + length - (2 * s), center.y + width - (2 * s))
|
||||
.with_z(base - 1 + (s * height)),
|
||||
})
|
||||
.fill(blue_broken.clone());
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(
|
||||
center.x - length + 1 + (2 * s),
|
||||
center.y - width + 1 + (2 * s),
|
||||
)
|
||||
.with_z(base - 2 + (s * height)),
|
||||
max: Vec2::new(
|
||||
center.x + length - 1 - (2 * s),
|
||||
center.y + width - 1 - (2 * s),
|
||||
)
|
||||
.with_z(base - 1 + height - 1 + (s * height)),
|
||||
})
|
||||
.fill(white.clone());
|
||||
|
||||
// entries
|
||||
painter
|
||||
.line(
|
||||
Vec2::new(center.x, center.y + 1 - width + (2 * s))
|
||||
.with_z(base - 1 + (s * height)),
|
||||
Vec2::new(center.x, center.y - 2 + width - (2 * s))
|
||||
.with_z(base - 1 + (s * height)),
|
||||
3.0,
|
||||
)
|
||||
.fill(blue_broken.clone());
|
||||
painter
|
||||
.line(
|
||||
Vec2::new(center.x, center.y - width + (2 * s)).with_z(base - 1 + (s * height)),
|
||||
Vec2::new(center.x, center.y + width - (2 * s)).with_z(base - 1 + (s * height)),
|
||||
2.0,
|
||||
)
|
||||
.clear();
|
||||
painter
|
||||
.line(
|
||||
Vec2::new(center.x + 1 - length + (2 * s), center.y)
|
||||
.with_z(base - 1 + (s * height)),
|
||||
Vec2::new(center.x - 2 + length - (2 * s), center.y)
|
||||
.with_z(base - 1 + (s * height)),
|
||||
3.0,
|
||||
)
|
||||
.fill(blue_broken.clone());
|
||||
painter
|
||||
.line(
|
||||
Vec2::new(center.x - length + (2 * s), center.y)
|
||||
.with_z(base - 1 + (s * height)),
|
||||
Vec2::new(center.x + length - (2 * s), center.y)
|
||||
.with_z(base - 1 + (s * height)),
|
||||
2.0,
|
||||
)
|
||||
.clear();
|
||||
// windows length
|
||||
painter
|
||||
.line(
|
||||
Vec2::new(center.x - (length / 3), center.y + 1 - width + (2 * s))
|
||||
.with_z(base - 1 + (s * height) + (height / 2)),
|
||||
Vec2::new(center.x - (length / 3), center.y - 2 + width - (2 * s))
|
||||
.with_z(base - 1 + (s * height) + (height / 2)),
|
||||
3.0,
|
||||
)
|
||||
.fill(blue_broken.clone());
|
||||
painter
|
||||
.line(
|
||||
Vec2::new(center.x - (length / 3), center.y - width - 2 + (2 * s))
|
||||
.with_z(base - 1 + (s * height) + (height / 2)),
|
||||
Vec2::new(center.x - (length / 3), center.y + width + 2 - (2 * s))
|
||||
.with_z(base - 1 + (s * height) + (height / 2)),
|
||||
2.0,
|
||||
)
|
||||
.clear();
|
||||
|
||||
painter
|
||||
.line(
|
||||
Vec2::new(center.x + (length / 3), center.y + 1 - width + (2 * s))
|
||||
.with_z(base - 1 + (s * height) + (height / 2)),
|
||||
Vec2::new(center.x + (length / 3), center.y - 2 + width - (2 * s))
|
||||
.with_z(base - 1 + (s * height) + (height / 2)),
|
||||
3.0,
|
||||
)
|
||||
.fill(blue_broken.clone());
|
||||
painter
|
||||
.line(
|
||||
Vec2::new(center.x + (length / 3), center.y - width - 2 + (2 * s))
|
||||
.with_z(base - 1 + (s * height) + (height / 2)),
|
||||
Vec2::new(center.x + (length / 3), center.y + width + 2 - (2 * s))
|
||||
.with_z(base - 1 + (s * height) + (height / 2)),
|
||||
2.0,
|
||||
)
|
||||
.clear();
|
||||
|
||||
// windows width
|
||||
painter
|
||||
.line(
|
||||
Vec2::new(center.x + 1 - length + (2 * s), center.y)
|
||||
.with_z(base - 1 + (s * height) + (height / 2)),
|
||||
Vec2::new(center.x - 2 + length - (2 * s), center.y)
|
||||
.with_z(base - 1 + (s * height) + (height / 2)),
|
||||
3.0,
|
||||
)
|
||||
.fill(blue_broken.clone());
|
||||
painter
|
||||
.line(
|
||||
Vec2::new(center.x - length - 2 + (2 * s), center.y)
|
||||
.with_z(base - 1 + (s * height) + (height / 2)),
|
||||
Vec2::new(center.x + length + 2 - (2 * s), center.y)
|
||||
.with_z(base - 1 + (s * height) + (height / 2)),
|
||||
2.0,
|
||||
)
|
||||
.clear();
|
||||
|
||||
// clear room
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(
|
||||
center.x - length + 2 + (2 * s),
|
||||
center.y - width + 2 + (2 * s),
|
||||
)
|
||||
.with_z(base - 2 + (s * height)),
|
||||
max: Vec2::new(
|
||||
center.x + length - 2 - (2 * s),
|
||||
center.y + width - 2 - (2 * s),
|
||||
)
|
||||
.with_z(base - 2 + height - 1 + (s * height)),
|
||||
})
|
||||
.clear();
|
||||
|
||||
// room floors
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(
|
||||
center.x - length + 5 + (2 * s),
|
||||
center.y - width + 5 + (2 * s),
|
||||
)
|
||||
.with_z(base - 3 + (s * height)),
|
||||
max: Vec2::new(
|
||||
center.x + length - 5 - (2 * s),
|
||||
center.y + width - 5 - (2 * s),
|
||||
)
|
||||
.with_z(base - 2 + (s * height)),
|
||||
})
|
||||
.fill(blue_broken.clone());
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(
|
||||
center.x - length + 6 + (2 * s),
|
||||
center.y - width + 6 + (2 * s),
|
||||
)
|
||||
.with_z(base - 3 + (s * height)),
|
||||
max: Vec2::new(
|
||||
center.x + length - 6 - (2 * s),
|
||||
center.y + width - 6 - (2 * s),
|
||||
)
|
||||
.with_z(base - 2 + (s * height)),
|
||||
})
|
||||
.fill(white.clone());
|
||||
// furniture
|
||||
let mut sprites = vec![
|
||||
SpriteKind::DrawerSmall,
|
||||
SpriteKind::DrawerMedium,
|
||||
SpriteKind::DrawerMedium,
|
||||
SpriteKind::ChairSingle,
|
||||
SpriteKind::ChairDouble,
|
||||
SpriteKind::CoatRack,
|
||||
SpriteKind::Bed,
|
||||
SpriteKind::WardrobeDouble,
|
||||
SpriteKind::WardrobeSingle,
|
||||
SpriteKind::TableSide,
|
||||
SpriteKind::Bowl,
|
||||
SpriteKind::VialEmpty,
|
||||
SpriteKind::SepareArabic,
|
||||
SpriteKind::FountainArabic,
|
||||
SpriteKind::JugAndBowlArabic,
|
||||
SpriteKind::Crate,
|
||||
SpriteKind::Pot,
|
||||
SpriteKind::Lantern,
|
||||
SpriteKind::TableArabicSmall,
|
||||
SpriteKind::CushionArabic,
|
||||
SpriteKind::JugArabic,
|
||||
SpriteKind::DecorSetArabic,
|
||||
];
|
||||
'outer: for dir in DIAGONALS {
|
||||
let furniture_pos = Vec2::new(
|
||||
center.x + dir.x * ((length / 2) - 2),
|
||||
center.y + dir.y * ((width / 2) - 2),
|
||||
);
|
||||
for dir in NEIGHBORS {
|
||||
if sprites.is_empty() {
|
||||
break 'outer;
|
||||
}
|
||||
let position = furniture_pos + dir * 3;
|
||||
let sprite = sprites.swap_remove(
|
||||
RandomField::new(0).get(position.with_z(base)) as usize % sprites.len(),
|
||||
);
|
||||
painter.sprite(position.with_z(base - 2 + (s * height)), sprite);
|
||||
}
|
||||
}
|
||||
// clear floor center if stairs
|
||||
if storeys > 1 {
|
||||
painter
|
||||
.cylinder(Aabb {
|
||||
min: (center - 6).with_z(base - 2 + (s * height)),
|
||||
max: (center + 6).with_z(base + (s * height)),
|
||||
})
|
||||
.clear();
|
||||
};
|
||||
// wall lamps
|
||||
for d in 0..2 {
|
||||
let door_lamp_pos = Vec2::new(
|
||||
center.x - length + 2 + (2 * s) + (d * ((2 * (length - (2 * s))) - 5)),
|
||||
center.y,
|
||||
)
|
||||
.with_z(base + 1 + (s * height));
|
||||
painter.rotated_sprite(
|
||||
door_lamp_pos,
|
||||
SpriteKind::WallLampSmall,
|
||||
2 + ((d * 4) as u8),
|
||||
);
|
||||
|
||||
let lamp_pos = Vec2::new(
|
||||
center.x,
|
||||
center.y - width + 2 + (2 * s) + (d * ((2 * (width - (2 * s))) - 5)),
|
||||
)
|
||||
.with_z(base + 1 + (s * height));
|
||||
painter.rotated_sprite(lamp_pos, SpriteKind::WallLampSmall, 4 - ((d * 4) as u8));
|
||||
}
|
||||
for d in 0..2 {
|
||||
let door_lamp_pos = Vec2::new(
|
||||
center.x - length - 1 + (2 * s) + (d * ((2 * (length - (2 * s))) + 1)),
|
||||
center.y,
|
||||
)
|
||||
.with_z(base + 1 + (s * height));
|
||||
painter.rotated_sprite(
|
||||
door_lamp_pos,
|
||||
SpriteKind::WallLampSmall,
|
||||
6 + ((d * 4) as u8),
|
||||
);
|
||||
|
||||
let lamp_pos = Vec2::new(
|
||||
center.x,
|
||||
center.y - width - 1 + (2 * s) + (d * ((2 * (width - (2 * s))) + 1)),
|
||||
)
|
||||
.with_z(base + 1 + (s * height));
|
||||
painter.rotated_sprite(lamp_pos, SpriteKind::WallLampSmall, 8 - ((d * 4) as u8));
|
||||
}
|
||||
}
|
||||
let top_limit = painter.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length, center.y - width)
|
||||
.with_z(base + (storeys * height) - 2),
|
||||
max: Vec2::new(center.x + length, center.y + width)
|
||||
.with_z(base - 2 + (storeys * height) + (height / 2)),
|
||||
});
|
||||
painter
|
||||
.superquadric(
|
||||
Aabb {
|
||||
min: Vec2::new(center.x - length - 1, center.y - width - 1)
|
||||
.with_z(base + (storeys * height) - (height / 2)),
|
||||
max: Vec2::new(center.x + length, center.y + width)
|
||||
.with_z(base - 2 + (storeys * height) + (height / 2)),
|
||||
},
|
||||
1.5,
|
||||
)
|
||||
.intersect(top_limit)
|
||||
.fill(white.clone());
|
||||
|
||||
// stairway1 stairs
|
||||
let stair_radius1 = 3.0;
|
||||
let stairs_clear1 = painter.cylinder(Aabb {
|
||||
min: (center - 1 - stair_radius1 as i32).with_z(base - 2),
|
||||
max: (center + 2 + stair_radius1 as i32).with_z(base + ((storeys - 1) * height) - 2),
|
||||
});
|
||||
let stairs_clear2 = painter.cylinder(Aabb {
|
||||
min: (center - 2 - stair_radius1 as i32).with_z(base - 2),
|
||||
max: (center + 3 + stair_radius1 as i32).with_z(base + ((storeys - 1) * height) - 2),
|
||||
});
|
||||
stairs_clear1.clear();
|
||||
painter
|
||||
.cylinder(Aabb {
|
||||
min: (center - 1).with_z(base - 2),
|
||||
max: (center + 2).with_z(base + ((storeys - 1) * height) - 2),
|
||||
})
|
||||
.fill(white.clone());
|
||||
|
||||
stairs_clear2
|
||||
.sample(wall_staircase(
|
||||
center.with_z(base + ((storeys - 1) * height) - 2),
|
||||
stair_radius1,
|
||||
(height / 2) as f32,
|
||||
))
|
||||
.fill(white);
|
||||
}
|
||||
}
|
332
world/src/site2/plot/coastal_workshop.rs
Normal file
332
world/src/site2/plot/coastal_workshop.rs
Normal file
@ -0,0 +1,332 @@
|
||||
use super::*;
|
||||
use crate::{
|
||||
util::{RandomField, Sampler, CARDINALS},
|
||||
Land,
|
||||
};
|
||||
use common::terrain::{BlockKind, SpriteKind};
|
||||
use rand::prelude::*;
|
||||
use std::sync::Arc;
|
||||
use vek::*;
|
||||
|
||||
/// Represents house data generated by the `generate()` method
|
||||
pub struct CoastalWorkshop {
|
||||
/// Tile position of the door tile
|
||||
pub door_tile: Vec2<i32>,
|
||||
/// Axis aligned bounding region for the house
|
||||
bounds: Aabr<i32>,
|
||||
/// Approximate altitude of the door tile
|
||||
pub(crate) alt: i32,
|
||||
}
|
||||
|
||||
impl CoastalWorkshop {
|
||||
pub fn generate(
|
||||
land: &Land,
|
||||
_rng: &mut impl Rng,
|
||||
site: &Site,
|
||||
door_tile: Vec2<i32>,
|
||||
door_dir: Vec2<i32>,
|
||||
tile_aabr: Aabr<i32>,
|
||||
) -> Self {
|
||||
let door_tile_pos = site.tile_center_wpos(door_tile);
|
||||
let bounds = Aabr {
|
||||
min: site.tile_wpos(tile_aabr.min),
|
||||
max: site.tile_wpos(tile_aabr.max),
|
||||
};
|
||||
Self {
|
||||
door_tile: door_tile_pos,
|
||||
bounds,
|
||||
alt: land.get_alt_approx(site.tile_center_wpos(door_tile + door_dir)) as i32 + 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Structure for CoastalWorkshop {
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"render_coastalworkshop\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "render_coastalworkshop")]
|
||||
fn render_inner(&self, _site: &Site, _land: &Land, painter: &Painter) {
|
||||
let base = self.alt + 1;
|
||||
let center = self.bounds.center();
|
||||
let white = Fill::Sampling(Arc::new(|center| {
|
||||
Some(match (RandomField::new(0).get(center)) % 37 {
|
||||
0..=8 => Block::new(BlockKind::Rock, Rgb::new(251, 251, 227)),
|
||||
9..=17 => Block::new(BlockKind::Rock, Rgb::new(245, 245, 229)),
|
||||
18..=26 => Block::new(BlockKind::Rock, Rgb::new(250, 243, 221)),
|
||||
27..=35 => Block::new(BlockKind::Rock, Rgb::new(240, 240, 230)),
|
||||
_ => Block::new(BlockKind::Rock, Rgb::new(255, 244, 193)),
|
||||
})
|
||||
}));
|
||||
let blue_broken = Fill::Sampling(Arc::new(|center| {
|
||||
Some(match (RandomField::new(0).get(center)) % 20 {
|
||||
0 => Block::new(BlockKind::Rock, Rgb::new(30, 187, 235)),
|
||||
_ => Block::new(BlockKind::Rock, Rgb::new(11, 146, 187)),
|
||||
})
|
||||
}));
|
||||
let length = (14 + RandomField::new(0).get(center.with_z(base)) % 3) as i32;
|
||||
let width = (12 + RandomField::new(0).get((center - 1).with_z(base)) % 3) as i32;
|
||||
let height = (12 + RandomField::new(0).get((center + 1).with_z(base)) % 4) as i32;
|
||||
|
||||
// fence, blue gates
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length - 6, center.y - width - 6).with_z(base - 1),
|
||||
max: Vec2::new(center.x + length + 7, center.y + width + 7).with_z(base),
|
||||
})
|
||||
.fill(blue_broken.clone());
|
||||
|
||||
for dir in CARDINALS {
|
||||
let frame_pos = Vec2::new(
|
||||
center.x + dir.x * (length + 5),
|
||||
center.y + dir.y * (width + 5),
|
||||
);
|
||||
painter
|
||||
.line(center.with_z(base - 1), frame_pos.with_z(base - 1), 3.0)
|
||||
.fill(blue_broken.clone());
|
||||
}
|
||||
// foundation
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length - 6, center.y - width - 6).with_z(base - height),
|
||||
max: Vec2::new(center.x + length + 7, center.y + width + 7).with_z(base - 1),
|
||||
})
|
||||
.fill(white.clone());
|
||||
for f in 0..8 {
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length - 7 - f, center.y - width - 7 - f)
|
||||
.with_z(base - 3 - f),
|
||||
max: Vec2::new(center.x + length + 8 + f, center.y + width + 8 + f)
|
||||
.with_z(base - 2 - f),
|
||||
})
|
||||
.fill(white.clone());
|
||||
}
|
||||
// clear yard
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length - 5, center.y - width - 5).with_z(base - 2),
|
||||
max: Vec2::new(center.x + length + 6, center.y + width + 6).with_z(base + height),
|
||||
})
|
||||
.clear();
|
||||
// clear entries
|
||||
for dir in CARDINALS {
|
||||
let clear_pos = Vec2::new(
|
||||
center.x + dir.x * (length + 7),
|
||||
center.y + dir.y * (width + 7),
|
||||
);
|
||||
painter
|
||||
.line(center.with_z(base - 1), clear_pos.with_z(base - 1), 2.0)
|
||||
.clear();
|
||||
}
|
||||
// roof terrace
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length - 3, center.y - width - 3)
|
||||
.with_z(base - 3 + height),
|
||||
max: Vec2::new(center.x + length + 2, center.y + width + 2)
|
||||
.with_z(base - 2 + height),
|
||||
})
|
||||
.fill(white.clone());
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length - 3, center.y - width - 3)
|
||||
.with_z(base - 2 + height),
|
||||
max: Vec2::new(center.x + length + 2, center.y + width + 2)
|
||||
.with_z(base - 1 + height),
|
||||
})
|
||||
.fill(blue_broken.clone());
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length - 2, center.y - width - 2)
|
||||
.with_z(base - 2 + height),
|
||||
max: Vec2::new(center.x + length + 1, center.y + width + 1)
|
||||
.with_z(base - 1 + height),
|
||||
})
|
||||
.clear();
|
||||
// room
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length, center.y - width).with_z(base - 2),
|
||||
max: Vec2::new(center.x + length, center.y + width).with_z(base - 1),
|
||||
})
|
||||
.fill(blue_broken.clone());
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length + 1, center.y - width + 1).with_z(base - 2),
|
||||
max: Vec2::new(center.x + length - 1, center.y + width - 1)
|
||||
.with_z(base - 1 + height - 1),
|
||||
})
|
||||
.fill(white.clone());
|
||||
|
||||
// entries
|
||||
let entry_limit = painter.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length, center.y - width).with_z(base - 2),
|
||||
max: Vec2::new(center.x + length, center.y + width).with_z(base - 1 + height - 1),
|
||||
});
|
||||
painter
|
||||
.line(
|
||||
Vec2::new(center.x, center.y + 1 - width).with_z(base - 1),
|
||||
Vec2::new(center.x, center.y - 2 + width).with_z(base - 1),
|
||||
8.0,
|
||||
)
|
||||
.intersect(entry_limit)
|
||||
.fill(blue_broken.clone());
|
||||
painter
|
||||
.line(
|
||||
Vec2::new(center.x, center.y - width).with_z(base - 1),
|
||||
Vec2::new(center.x, center.y + width).with_z(base - 1),
|
||||
7.0,
|
||||
)
|
||||
.intersect(entry_limit)
|
||||
.clear();
|
||||
painter
|
||||
.line(
|
||||
Vec2::new(center.x + 1 - length, center.y).with_z(base - 1),
|
||||
Vec2::new(center.x - 2 + length, center.y).with_z(base - 1),
|
||||
8.0,
|
||||
)
|
||||
.intersect(entry_limit)
|
||||
.fill(blue_broken.clone());
|
||||
painter
|
||||
.line(
|
||||
Vec2::new(center.x - length, center.y).with_z(base - 1),
|
||||
Vec2::new(center.x + length, center.y).with_z(base - 1),
|
||||
7.0,
|
||||
)
|
||||
.intersect(entry_limit)
|
||||
.clear();
|
||||
// clear room
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length + 2, center.y - width + 2).with_z(base - 2),
|
||||
max: Vec2::new(center.x + length - 2, center.y + width - 2)
|
||||
.with_z(base - 2 + height - 1),
|
||||
})
|
||||
.clear();
|
||||
|
||||
// room floors
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length + 5, center.y - width + 5).with_z(base - 3),
|
||||
max: Vec2::new(center.x + length - 5, center.y + width - 5).with_z(base - 2),
|
||||
})
|
||||
.fill(blue_broken.clone());
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length + 6, center.y - width + 6).with_z(base - 3),
|
||||
max: Vec2::new(center.x + length - 6, center.y + width - 6).with_z(base - 2),
|
||||
})
|
||||
.fill(white.clone());
|
||||
|
||||
// wall lamps
|
||||
for d in 0..2 {
|
||||
let door_lamp_pos =
|
||||
Vec2::new(center.x - length + 2 + (d * ((2 * (length)) - 5)), center.y)
|
||||
.with_z(base + 6);
|
||||
painter.rotated_sprite(
|
||||
door_lamp_pos,
|
||||
SpriteKind::WallLampSmall,
|
||||
2 + ((d * 4) as u8),
|
||||
);
|
||||
|
||||
let lamp_pos = Vec2::new(center.x, center.y - width + 2 + (d * ((2 * (width)) - 5)))
|
||||
.with_z(base + 6);
|
||||
painter.rotated_sprite(lamp_pos, SpriteKind::WallLampSmall, 4 - ((d * 4) as u8));
|
||||
}
|
||||
for d in 0..2 {
|
||||
let door_lamp_pos =
|
||||
Vec2::new(center.x - length - 1 + (d * ((2 * (length)) + 1)), center.y)
|
||||
.with_z(base + 6);
|
||||
painter.rotated_sprite(
|
||||
door_lamp_pos,
|
||||
SpriteKind::WallLampSmall,
|
||||
6 + ((d * 4) as u8),
|
||||
);
|
||||
|
||||
let lamp_pos = Vec2::new(center.x, center.y - width - 1 + (d * ((2 * (width)) + 1)))
|
||||
.with_z(base + 6);
|
||||
painter.rotated_sprite(lamp_pos, SpriteKind::WallLampSmall, 8 - ((d * 4) as u8));
|
||||
}
|
||||
|
||||
// chimney
|
||||
painter
|
||||
.cylinder(Aabb {
|
||||
min: (center - 4).with_z(base + height - 4),
|
||||
max: (center + 2).with_z(base - 2 + height + (height / 2)),
|
||||
})
|
||||
.fill(blue_broken);
|
||||
|
||||
let top_limit = painter.aabb(Aabb {
|
||||
min: Vec2::new(center.x - length, center.y - width).with_z(base + height - 2),
|
||||
max: Vec2::new(center.x + length, center.y + width)
|
||||
.with_z(base - 2 + height + (height / 2)),
|
||||
});
|
||||
painter
|
||||
.superquadric(
|
||||
Aabb {
|
||||
min: Vec2::new(center.x - length - 1, center.y - width - 1)
|
||||
.with_z(base + height - (height / 2)),
|
||||
max: Vec2::new(center.x + length, center.y + width)
|
||||
.with_z(base - 2 + height + (height / 2)),
|
||||
},
|
||||
1.5,
|
||||
)
|
||||
.intersect(top_limit)
|
||||
.fill(white.clone());
|
||||
// clear chimney
|
||||
painter
|
||||
.cylinder(Aabb {
|
||||
min: (center - 3).with_z(base + height - 4),
|
||||
max: (center + 1).with_z(base - 2 + height + (height / 2)),
|
||||
})
|
||||
.clear();
|
||||
|
||||
painter
|
||||
.cylinder(Aabb {
|
||||
min: (center - 3).with_z(base - 2),
|
||||
max: (center + 1).with_z(base - 1),
|
||||
})
|
||||
.fill(white);
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: (center - 2).with_z(base - 2),
|
||||
max: (center).with_z(base - 1),
|
||||
})
|
||||
.clear();
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: (center - 2).with_z(base - 3),
|
||||
max: (center).with_z(base - 2),
|
||||
})
|
||||
.fill(Fill::Block(Block::air(SpriteKind::Ember)));
|
||||
|
||||
let mut stations = vec![
|
||||
SpriteKind::CraftingBench,
|
||||
SpriteKind::Forge,
|
||||
SpriteKind::SpinningWheel,
|
||||
SpriteKind::TanningRack,
|
||||
SpriteKind::CookingPot,
|
||||
SpriteKind::Cauldron,
|
||||
SpriteKind::Loom,
|
||||
SpriteKind::Anvil,
|
||||
SpriteKind::DismantlingBench,
|
||||
SpriteKind::RepairBench,
|
||||
];
|
||||
'outer: for d in 0..3 {
|
||||
for dir in CARDINALS {
|
||||
if stations.is_empty() {
|
||||
break 'outer;
|
||||
}
|
||||
let position = 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 - 2), cr_station);
|
||||
}
|
||||
}
|
||||
|
||||
painter.spawn(
|
||||
EntityInfo::at((center - 2).with_z(base - 2).map(|e| e as f32 + 0.5)).into_waypoint(),
|
||||
);
|
||||
}
|
||||
}
|
@ -39,6 +39,8 @@ struct WatchTower {
|
||||
|
||||
/// Represents house data generated by the `generate()` method
|
||||
pub struct DesertCityMultiPlot {
|
||||
/// Tile position of the door tile
|
||||
pub door_tile: Vec2<i32>,
|
||||
/// Axis aligned bounding region for the house
|
||||
bounds: Aabr<i32>,
|
||||
/// Approximate altitude of the door tile
|
||||
@ -58,6 +60,7 @@ impl DesertCityMultiPlot {
|
||||
tile_aabr: Aabr<i32>,
|
||||
campfire: bool,
|
||||
) -> Self {
|
||||
let door_tile_pos = site.tile_center_wpos(door_tile);
|
||||
let bounds = Aabr {
|
||||
min: site.tile_wpos(tile_aabr.min),
|
||||
max: site.tile_wpos(tile_aabr.max),
|
||||
@ -120,6 +123,7 @@ impl DesertCityMultiPlot {
|
||||
};
|
||||
Self {
|
||||
bounds,
|
||||
door_tile: door_tile_pos,
|
||||
alt: land.get_alt_approx(site.tile_center_wpos(door_tile + door_dir)) as i32,
|
||||
diameter,
|
||||
plot_kind,
|
||||
@ -159,14 +163,23 @@ impl Structure for DesertCityMultiPlot {
|
||||
// Fence
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: (self.bounds.min + 1).with_z(base - 20),
|
||||
max: (self.bounds.max).with_z(base + 2),
|
||||
min: Vec2::new(self.bounds.min.x + 1, self.bounds.min.y + 1).with_z(base - 20),
|
||||
max: Vec2::new(self.bounds.min.x + 2, self.bounds.max.y).with_z(base + 2),
|
||||
})
|
||||
.without(painter.aabb(Aabb {
|
||||
min: (self.bounds.min + 2).with_z(base - 20),
|
||||
max: (self.bounds.max - 1).with_z(base + 2),
|
||||
.union(painter.aabb(Aabb {
|
||||
min: Vec2::new(self.bounds.max.x - 1, self.bounds.min.y + 1).with_z(base - 20),
|
||||
max: Vec2::new(self.bounds.max.x, self.bounds.max.y).with_z(base + 2),
|
||||
}))
|
||||
.union(painter.aabb(Aabb {
|
||||
min: Vec2::new(self.bounds.min.x + 1, self.bounds.min.y + 1).with_z(base - 20),
|
||||
max: Vec2::new(self.bounds.max.x, self.bounds.min.y + 2).with_z(base + 2),
|
||||
}))
|
||||
.union(painter.aabb(Aabb {
|
||||
min: Vec2::new(self.bounds.min.x + 1, self.bounds.max.y - 1).with_z(base - 20),
|
||||
max: Vec2::new(self.bounds.max.x, self.bounds.max.y).with_z(base + 2),
|
||||
}))
|
||||
.fill(sandstone_broken.clone());
|
||||
|
||||
// Gate1
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
@ -429,17 +442,20 @@ impl Structure for DesertCityMultiPlot {
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - 1, center.y - (2 * room_length / 3) + 5)
|
||||
.with_z(floor_level + 4),
|
||||
max: Vec2::new(center.x + 1, center.y - (2 * room_length / 3) + 6)
|
||||
.with_z(floor_level + 5),
|
||||
})
|
||||
.fill(Fill::Block(
|
||||
Block::air(SpriteKind::WallLampSmall).with_ori(4).unwrap(),
|
||||
));
|
||||
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - 1, center.y + (2 * room_length / 3) - 2)
|
||||
.with_z(floor_level + 4),
|
||||
max: Vec2::new(center.x + 1, center.y + (2 * room_length / 3) - 1)
|
||||
.with_z(floor_level + 5),
|
||||
})
|
||||
.without(
|
||||
painter.aabb(Aabb {
|
||||
min: Vec2::new(center.x - 1, center.y - (2 * room_length / 3) + 6)
|
||||
.with_z(floor_level + 4),
|
||||
max: Vec2::new(center.x + 1, center.y + (2 * room_length / 3) - 2)
|
||||
.with_z(floor_level + 5),
|
||||
}),
|
||||
)
|
||||
.fill(Fill::Block(
|
||||
Block::air(SpriteKind::WallLampSmall).with_ori(4).unwrap(),
|
||||
));
|
||||
@ -449,17 +465,20 @@ impl Structure for DesertCityMultiPlot {
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - 1, center.y - room_length + 4)
|
||||
.with_z(floor_level + 4),
|
||||
max: Vec2::new(center.x + 1, center.y - room_length + 5)
|
||||
.with_z(floor_level + 5),
|
||||
})
|
||||
.fill(Fill::Block(
|
||||
Block::air(SpriteKind::WallLampSmall).with_ori(4).unwrap(),
|
||||
));
|
||||
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - 1, center.y + room_length)
|
||||
.with_z(floor_level + 4),
|
||||
max: Vec2::new(center.x + 1, center.y + room_length + 1)
|
||||
.with_z(floor_level + 5),
|
||||
})
|
||||
.without(
|
||||
painter.aabb(Aabb {
|
||||
min: Vec2::new(center.x - 1, center.y - room_length + 5)
|
||||
.with_z(floor_level + 4),
|
||||
max: Vec2::new(center.x + 1, center.y + room_length)
|
||||
.with_z(floor_level + 5),
|
||||
}),
|
||||
)
|
||||
.fill(Fill::Block(
|
||||
Block::air(SpriteKind::WallLampSmall).with_ori(4).unwrap(),
|
||||
));
|
||||
@ -757,6 +776,13 @@ impl Structure for DesertCityMultiPlot {
|
||||
.with_z(base + 4),
|
||||
})
|
||||
.clear();
|
||||
// clear Tower base
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: (tower_center - tower.length).with_z(base),
|
||||
max: (tower_center + tower.length).with_z(base + 5),
|
||||
})
|
||||
.clear();
|
||||
// Tower Entry Lamps
|
||||
for d in 0..2 {
|
||||
painter
|
||||
@ -832,28 +858,6 @@ impl Structure for DesertCityMultiPlot {
|
||||
))
|
||||
.intersect(tower_clear)
|
||||
.fill(sandstone.clone());
|
||||
//make some room for base entries
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: (tower_center - tower.length).with_z(base),
|
||||
max: (tower_center + tower.length).with_z(base + 5),
|
||||
})
|
||||
.without(painter.aabb(Aabb {
|
||||
min: (tower_center - tower.length + 1).with_z(base),
|
||||
max: (tower_center + tower.length - 1).with_z(base + 5),
|
||||
}))
|
||||
.clear();
|
||||
// clear some steps at the bottom for tower entries
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: (tower_center - tower.length + 1).with_z(base + 1),
|
||||
max: (tower_center + tower.length - 1).with_z(base + 2),
|
||||
})
|
||||
.without(painter.aabb(Aabb {
|
||||
min: (tower_center - tower.length + 2).with_z(base + 1),
|
||||
max: (tower_center + tower.length - 2).with_z(base + 2),
|
||||
}))
|
||||
.clear();
|
||||
}
|
||||
},
|
||||
PlotKind::Multiple { subplots } => {
|
||||
@ -1150,7 +1154,6 @@ impl Structure for DesertCityMultiPlot {
|
||||
SpriteKind::Loom,
|
||||
SpriteKind::Anvil,
|
||||
SpriteKind::DismantlingBench,
|
||||
SpriteKind::RepairBench,
|
||||
];
|
||||
'outer: for d in 0..2 {
|
||||
for dir in NEIGHBORS {
|
||||
@ -1328,26 +1331,28 @@ impl Structure for DesertCityMultiPlot {
|
||||
subplot_center.y - room_length + 4,
|
||||
)
|
||||
.with_z(floor_level + 4),
|
||||
max: Vec2::new(
|
||||
subplot_center.x + 1,
|
||||
subplot_center.y - room_length + 5,
|
||||
)
|
||||
.with_z(floor_level + 5),
|
||||
})
|
||||
.fill(Fill::Block(
|
||||
Block::air(SpriteKind::WallLampSmall).with_ori(4).unwrap(),
|
||||
));
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(
|
||||
subplot_center.x - 1,
|
||||
subplot_center.y + room_length,
|
||||
)
|
||||
.with_z(floor_level + 4),
|
||||
max: Vec2::new(
|
||||
subplot_center.x + 1,
|
||||
subplot_center.y + room_length + 1,
|
||||
)
|
||||
.with_z(floor_level + 5),
|
||||
})
|
||||
.without(
|
||||
painter.aabb(Aabb {
|
||||
min: Vec2::new(
|
||||
subplot_center.x - 1,
|
||||
subplot_center.y - room_length + 5,
|
||||
)
|
||||
.with_z(floor_level + 4),
|
||||
max: Vec2::new(
|
||||
subplot_center.x + 1,
|
||||
subplot_center.y + room_length,
|
||||
)
|
||||
.with_z(floor_level + 5),
|
||||
}),
|
||||
)
|
||||
.fill(Fill::Block(
|
||||
Block::air(SpriteKind::WallLampSmall).with_ori(4).unwrap(),
|
||||
));
|
||||
@ -1462,30 +1467,30 @@ impl Structure for DesertCityMultiPlot {
|
||||
bldg_b_center.y - 4,
|
||||
)
|
||||
.with_z(base + 2 + (n * (tower_height / 2)) + (h * 4)),
|
||||
max: Vec2::new(
|
||||
bldg_b_center.x + (2 * tower_length),
|
||||
bldg_b_center.y - 2,
|
||||
)
|
||||
.with_z(base + 5 + (n * (tower_height / 2)) + (h * 4)),
|
||||
})
|
||||
.fill(Fill::Block(
|
||||
Block::air(SpriteKind::WindowArabic)
|
||||
.with_ori(4)
|
||||
.unwrap(),
|
||||
));
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(
|
||||
bldg_b_center.x + (2 * tower_length) - 1,
|
||||
bldg_b_center.y + 2,
|
||||
)
|
||||
.with_z(base + 2 + (n * (tower_height / 2)) + (h * 4)),
|
||||
max: Vec2::new(
|
||||
bldg_b_center.x + (2 * tower_length),
|
||||
bldg_b_center.y + 4,
|
||||
)
|
||||
.with_z(base + 5 + (n * (tower_height / 2)) + (h * 4)),
|
||||
})
|
||||
.without(
|
||||
painter.aabb(Aabb {
|
||||
min: Vec2::new(
|
||||
bldg_b_center.x + (2 * tower_length) - 1,
|
||||
bldg_b_center.y - 2,
|
||||
)
|
||||
.with_z(
|
||||
base + 2 + (n * (tower_height / 2)) + (h * 4),
|
||||
),
|
||||
max: Vec2::new(
|
||||
bldg_b_center.x + (2 * tower_length),
|
||||
bldg_b_center.y + 2,
|
||||
)
|
||||
.with_z(
|
||||
base + 5 + (n * (tower_height / 2)) + (h * 4),
|
||||
),
|
||||
}),
|
||||
)
|
||||
.fill(Fill::Block(
|
||||
Block::air(SpriteKind::WindowArabic)
|
||||
.with_ori(4)
|
||||
@ -1864,6 +1869,13 @@ impl Structure for DesertCityMultiPlot {
|
||||
.with_z(base + 4),
|
||||
})
|
||||
.clear();
|
||||
// clear Stairway Tower base
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: (bldg_a_center - tower_length).with_z(base),
|
||||
max: (bldg_a_center + tower_length).with_z(base + 6),
|
||||
})
|
||||
.clear();
|
||||
// Stairway Tower Entry Lamps
|
||||
for d in 0..2 {
|
||||
painter
|
||||
@ -1959,17 +1971,6 @@ impl Structure for DesertCityMultiPlot {
|
||||
))
|
||||
.intersect(tower_clear)
|
||||
.fill(sandstone.clone());
|
||||
// make some room for base entries
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: (bldg_a_center - tower_length).with_z(base),
|
||||
max: (bldg_a_center + tower_length).with_z(base + 5),
|
||||
})
|
||||
.without(painter.aabb(Aabb {
|
||||
min: (bldg_a_center - tower_length + 1).with_z(base),
|
||||
max: (bldg_a_center + tower_length - 1).with_z(base + 5),
|
||||
}))
|
||||
.clear();
|
||||
},
|
||||
SubPlotKind::WatchTower(tower) => {
|
||||
// WatchTower Windowsills
|
||||
@ -2086,6 +2087,13 @@ impl Structure for DesertCityMultiPlot {
|
||||
.with_z(base + 4),
|
||||
})
|
||||
.clear();
|
||||
// clear Watch Tower base
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: (subplot_center - tower.length).with_z(base),
|
||||
max: (subplot_center + tower.length).with_z(base + 5),
|
||||
})
|
||||
.clear();
|
||||
// WatchTower Entry Lamps
|
||||
for d in 0..2 {
|
||||
painter
|
||||
@ -2180,28 +2188,6 @@ impl Structure for DesertCityMultiPlot {
|
||||
))
|
||||
.intersect(tower_clear)
|
||||
.fill(sandstone.clone());
|
||||
//make some room for base entries
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: (subplot_center - tower.length).with_z(base),
|
||||
max: (subplot_center + tower.length).with_z(base + 5),
|
||||
})
|
||||
.without(painter.aabb(Aabb {
|
||||
min: (subplot_center - tower.length + 1).with_z(base),
|
||||
max: (subplot_center + tower.length - 1).with_z(base + 5),
|
||||
}))
|
||||
.clear();
|
||||
// clear some steps at the bottom for tower entries
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: (subplot_center - tower.length + 1).with_z(base + 1),
|
||||
max: (subplot_center + tower.length - 1).with_z(base + 2),
|
||||
})
|
||||
.without(painter.aabb(Aabb {
|
||||
min: (subplot_center - tower.length + 2).with_z(base + 1),
|
||||
max: (subplot_center + tower.length - 2).with_z(base + 2),
|
||||
}))
|
||||
.clear();
|
||||
},
|
||||
SubPlotKind::AnimalShed => {
|
||||
// fenced animal shed
|
||||
@ -2215,22 +2201,50 @@ impl Structure for DesertCityMultiPlot {
|
||||
)
|
||||
.with_z(base),
|
||||
max: Vec2::new(
|
||||
subplot_center.x + (2 * shed_length) + 2,
|
||||
subplot_center.x - (2 * shed_length) + 1,
|
||||
subplot_center.y + (2 * shed_length) + 1,
|
||||
)
|
||||
.with_z(base + 2),
|
||||
})
|
||||
.without(
|
||||
.union(
|
||||
painter.aabb(Aabb {
|
||||
min: Vec2::new(
|
||||
subplot_center.x - (2 * shed_length) + 1,
|
||||
subplot_center.y - (2 * shed_length),
|
||||
subplot_center.x + (2 * shed_length) + 1,
|
||||
subplot_center.y - (2 * shed_length) - 1,
|
||||
)
|
||||
.with_z(base),
|
||||
max: Vec2::new(
|
||||
subplot_center.x + (2 * shed_length) + 1,
|
||||
subplot_center.x + (2 * shed_length) + 2,
|
||||
subplot_center.y + (2 * shed_length) + 1,
|
||||
)
|
||||
.with_z(base + 2),
|
||||
}),
|
||||
)
|
||||
.union(
|
||||
painter.aabb(Aabb {
|
||||
min: Vec2::new(
|
||||
subplot_center.x - (2 * shed_length),
|
||||
subplot_center.y - (2 * shed_length) - 1,
|
||||
)
|
||||
.with_z(base),
|
||||
max: Vec2::new(
|
||||
subplot_center.x + (2 * shed_length) + 2,
|
||||
subplot_center.y - (2 * shed_length),
|
||||
)
|
||||
.with_z(base + 2),
|
||||
}),
|
||||
)
|
||||
.union(
|
||||
painter.aabb(Aabb {
|
||||
min: Vec2::new(
|
||||
subplot_center.x - (2 * shed_length),
|
||||
subplot_center.y + (2 * shed_length),
|
||||
)
|
||||
.with_z(base),
|
||||
max: Vec2::new(
|
||||
subplot_center.x + (2 * shed_length) + 2,
|
||||
subplot_center.y + (2 * shed_length) + 1,
|
||||
)
|
||||
.with_z(base + 2),
|
||||
}),
|
||||
)
|
||||
|
@ -10,6 +10,8 @@ use vek::*;
|
||||
|
||||
/// Represents house data generated by the `generate()` method
|
||||
pub struct DesertCityTemple {
|
||||
/// Tile position of the door tile
|
||||
pub door_tile: Vec2<i32>,
|
||||
/// Axis aligned bounding region for the house
|
||||
bounds: Aabr<i32>,
|
||||
/// Approximate altitude of the door tile
|
||||
@ -25,6 +27,7 @@ impl DesertCityTemple {
|
||||
door_dir: Vec2<i32>,
|
||||
tile_aabr: Aabr<i32>,
|
||||
) -> Self {
|
||||
let door_tile_pos = site.tile_center_wpos(door_tile);
|
||||
let bounds = Aabr {
|
||||
min: site.tile_wpos(tile_aabr.min),
|
||||
max: site.tile_wpos(tile_aabr.max),
|
||||
@ -32,6 +35,7 @@ impl DesertCityTemple {
|
||||
|
||||
Self {
|
||||
bounds,
|
||||
door_tile: door_tile_pos,
|
||||
alt: land.get_alt_approx(site.tile_center_wpos(door_tile + door_dir)) as i32,
|
||||
}
|
||||
}
|
||||
@ -69,12 +73,20 @@ impl Structure for DesertCityTemple {
|
||||
// Fence
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: (self.bounds.min + 1).with_z(base - 20),
|
||||
max: (self.bounds.max).with_z(base + 2),
|
||||
min: Vec2::new(self.bounds.min.x + 1, self.bounds.min.y + 1).with_z(base - 20),
|
||||
max: Vec2::new(self.bounds.min.x + 2, self.bounds.max.y).with_z(base + 2),
|
||||
})
|
||||
.without(painter.aabb(Aabb {
|
||||
min: (self.bounds.min + 2).with_z(base - 20),
|
||||
max: (self.bounds.max - 1).with_z(base + 2),
|
||||
.union(painter.aabb(Aabb {
|
||||
min: Vec2::new(self.bounds.max.x - 1, self.bounds.min.y + 1).with_z(base - 20),
|
||||
max: Vec2::new(self.bounds.max.x, self.bounds.max.y).with_z(base + 2),
|
||||
}))
|
||||
.union(painter.aabb(Aabb {
|
||||
min: Vec2::new(self.bounds.min.x + 1, self.bounds.min.y + 1).with_z(base - 20),
|
||||
max: Vec2::new(self.bounds.max.x, self.bounds.min.y + 2).with_z(base + 2),
|
||||
}))
|
||||
.union(painter.aabb(Aabb {
|
||||
min: Vec2::new(self.bounds.min.x + 1, self.bounds.max.y - 1).with_z(base - 20),
|
||||
max: Vec2::new(self.bounds.max.x, self.bounds.max.y).with_z(base + 2),
|
||||
}))
|
||||
.fill(sandstone_broken);
|
||||
painter
|
||||
@ -273,105 +285,86 @@ impl Structure for DesertCityTemple {
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - temple_size + 2, center.y - temple_size + 2)
|
||||
.with_z(base + 2),
|
||||
max: Vec2::new(center.x + temple_size - 3, center.y - temple_size + 3)
|
||||
.with_z(base + temple_size - 1),
|
||||
})
|
||||
.fill(temple_color.clone());
|
||||
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - temple_size + 2, center.y + temple_size - 4)
|
||||
.with_z(base + 2),
|
||||
max: Vec2::new(center.x + temple_size - 3, center.y + temple_size - 3)
|
||||
.with_z(base + temple_size - 1),
|
||||
})
|
||||
.without(
|
||||
painter.aabb(Aabb {
|
||||
min: Vec2::new(center.x - temple_size + 2, center.y - temple_size + 3)
|
||||
.with_z(base + 2),
|
||||
max: Vec2::new(center.x + temple_size - 3, center.y + temple_size - 4)
|
||||
.with_z(base + temple_size - 1),
|
||||
}),
|
||||
)
|
||||
.fill(temple_color.clone());
|
||||
// color inlays2
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - temple_size + 2, center.y - temple_size + 2)
|
||||
.with_z(base + 2),
|
||||
max: Vec2::new(center.x - temple_size + 3, center.y + temple_size - 3)
|
||||
.with_z(base + temple_size - 1),
|
||||
})
|
||||
.fill(temple_color.clone());
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x + temple_size - 4, center.y - temple_size + 2)
|
||||
.with_z(base + 2),
|
||||
max: Vec2::new(center.x + temple_size - 3, center.y + temple_size - 3)
|
||||
.with_z(base + temple_size - 1),
|
||||
})
|
||||
.without(
|
||||
painter.aabb(Aabb {
|
||||
min: Vec2::new(center.x - temple_size + 3, center.y - temple_size + 2)
|
||||
.with_z(base + 2),
|
||||
max: Vec2::new(center.x + temple_size - 4, center.y + temple_size - 3)
|
||||
.with_z(base + temple_size - 1),
|
||||
}),
|
||||
)
|
||||
.fill(temple_color.clone());
|
||||
// carve outside plane1
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - temple_size + 6, center.y - temple_size).with_z(base + 3),
|
||||
max: Vec2::new(center.x + temple_size - 7, center.y - temple_size + 1)
|
||||
.with_z(base + temple_size - 2),
|
||||
})
|
||||
.clear();
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - temple_size + 6, center.y + temple_size - 2)
|
||||
.with_z(base + 3),
|
||||
max: Vec2::new(center.x + temple_size - 7, center.y + temple_size - 1)
|
||||
.with_z(base + temple_size - 2),
|
||||
})
|
||||
.without(
|
||||
painter.aabb(Aabb {
|
||||
min: Vec2::new(center.x - temple_size + 6, center.y - temple_size + 1)
|
||||
.with_z(base + 3),
|
||||
max: Vec2::new(center.x + temple_size - 7, center.y + temple_size - 2)
|
||||
.with_z(base + temple_size - 2),
|
||||
}),
|
||||
)
|
||||
.clear();
|
||||
// carve outside plane2
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x - temple_size, center.y - temple_size + 6).with_z(base + 3),
|
||||
max: Vec2::new(center.x - temple_size + 1, center.y + temple_size - 7)
|
||||
.with_z(base + temple_size - 2),
|
||||
})
|
||||
.clear();
|
||||
painter
|
||||
.aabb(Aabb {
|
||||
min: Vec2::new(center.x + temple_size - 2, center.y - temple_size + 6)
|
||||
.with_z(base + 3),
|
||||
max: Vec2::new(center.x + temple_size - 1, center.y + temple_size - 7)
|
||||
.with_z(base + temple_size - 2),
|
||||
})
|
||||
.without(
|
||||
painter.aabb(Aabb {
|
||||
min: Vec2::new(center.x - temple_size + 1, center.y - temple_size + 6)
|
||||
.with_z(base + 3),
|
||||
max: Vec2::new(center.x + temple_size - 2, center.y + temple_size - 7)
|
||||
.with_z(base + temple_size - 2),
|
||||
}),
|
||||
)
|
||||
.clear();
|
||||
// Temple top
|
||||
// Temple Top Socket
|
||||
painter
|
||||
.sphere(Aabb {
|
||||
min: (center - temple_size + 3).with_z(base),
|
||||
max: (center + temple_size - 4).with_z(base + (2 * temple_size) - 6),
|
||||
})
|
||||
.without(painter.aabb(Aabb {
|
||||
min: (center - temple_size + 2).with_z(base + 1),
|
||||
max: (center + temple_size - 3).with_z(base + temple_size - 3),
|
||||
}))
|
||||
.without(painter.aabb(Aabb {
|
||||
min: (center - temple_size + 1).with_z(base),
|
||||
max: (center + temple_size - 1).with_z(base + temple_size),
|
||||
}))
|
||||
// carve temple top
|
||||
.without(painter.sphere(Aabb {
|
||||
min: (center - temple_size + 5).with_z(base + 2),
|
||||
max: (center + temple_size - 6).with_z(base + (2 * temple_size) - 8),
|
||||
}))
|
||||
.fill(sandstone.clone());
|
||||
.cylinder(Aabb {
|
||||
min: (center - temple_size + 3).with_z(base + temple_size),
|
||||
max: (center + temple_size - 4).with_z(base + temple_size + 1),
|
||||
})
|
||||
.fill(sandstone.clone());
|
||||
// Temple Top
|
||||
let top = painter.sphere(Aabb {
|
||||
min: (center - temple_size + 3).with_z(base),
|
||||
max: (center + temple_size - 4).with_z(base + (2 * temple_size) - 7),
|
||||
});
|
||||
top.fill(sandstone.clone());
|
||||
|
||||
// temple top decoration
|
||||
// apply two decoration options (horizontal, vertical, none) with two spread
|
||||
// options for hor/ver options
|
||||
for s in 0..2 {
|
||||
let top = painter
|
||||
.sphere(Aabb {
|
||||
min: (center - temple_size + 3).with_z(base),
|
||||
max: (center + temple_size - 4).with_z(base + (2 * temple_size) - 6),
|
||||
})
|
||||
.without(painter.sphere(Aabb {
|
||||
min: (center - temple_size + 5).with_z(base + 2),
|
||||
max: (center + temple_size - 6).with_z(base + (2 * temple_size) - 8),
|
||||
}))
|
||||
.without(painter.aabb(Aabb {
|
||||
min: (center - temple_size + 1).with_z(base),
|
||||
max: (center + temple_size - 2).with_z(base + temple_size + 1),
|
||||
}));
|
||||
// decor carve out style
|
||||
let spread_select =
|
||||
((RandomField::new(0).get((center - 1 - s).with_z(base))) % 2) as i32;
|
||||
@ -421,6 +414,20 @@ impl Structure for DesertCityTemple {
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
// Temple Top Socket
|
||||
painter
|
||||
.cylinder(Aabb {
|
||||
min: (center - temple_size + 3).with_z(base + temple_size),
|
||||
max: (center + temple_size - 4).with_z(base + temple_size + 1),
|
||||
})
|
||||
.fill(sandstone.clone());
|
||||
// clear top
|
||||
painter
|
||||
.sphere(Aabb {
|
||||
min: (center - temple_size + 4).with_z(base + 1),
|
||||
max: (center + temple_size - 5).with_z(base + (2 * temple_size) - 8),
|
||||
})
|
||||
.clear();
|
||||
|
||||
// round or rectangle entries
|
||||
let entry_select = ((RandomField::new(0).get((center + 1).with_z(base))) % 2) as i32;
|
||||
@ -550,17 +557,6 @@ impl Structure for DesertCityTemple {
|
||||
.clear();
|
||||
},
|
||||
}
|
||||
// Temple Top Socket
|
||||
painter
|
||||
.cylinder(Aabb {
|
||||
min: (center - temple_size + 3).with_z(base + temple_size),
|
||||
max: (center + temple_size - 4).with_z(base + temple_size + 1),
|
||||
})
|
||||
.without(painter.cylinder(Aabb {
|
||||
min: (center - temple_size + 5).with_z(base + temple_size),
|
||||
max: (center + temple_size - 6).with_z(base + temple_size + 1),
|
||||
}))
|
||||
.fill(sandstone.clone());
|
||||
|
||||
// carve temple
|
||||
painter
|
||||
@ -569,13 +565,6 @@ impl Structure for DesertCityTemple {
|
||||
max: (center + temple_size - 5).with_z(base + temple_size - 1),
|
||||
})
|
||||
.clear();
|
||||
// carve round opening to dome
|
||||
painter
|
||||
.cylinder(Aabb {
|
||||
min: (center - temple_size + 6).with_z(base + temple_size - 1),
|
||||
max: (center + temple_size - 7).with_z(base + temple_size),
|
||||
})
|
||||
.clear();
|
||||
|
||||
// floating sculpture, placeholder for sun god
|
||||
|
||||
@ -593,8 +582,8 @@ impl Structure for DesertCityTemple {
|
||||
.fill(sandstone.clone());
|
||||
painter
|
||||
.sphere(Aabb {
|
||||
min: (center - 4).with_z(base + 8),
|
||||
max: (center + 3).with_z(base + 13),
|
||||
min: (center - 3).with_z(base + 8),
|
||||
max: (center + 2).with_z(base + 13),
|
||||
})
|
||||
.fill(sandstone.clone());
|
||||
painter
|
||||
@ -646,38 +635,5 @@ impl Structure for DesertCityTemple {
|
||||
})
|
||||
.fill(floaty_block.clone());
|
||||
}
|
||||
|
||||
// floating sculpture, placeholder for sun god
|
||||
|
||||
painter
|
||||
.sphere(Aabb {
|
||||
min: (center - 3).with_z(base),
|
||||
max: (center + 2).with_z(base + 5),
|
||||
})
|
||||
.fill(sandstone.clone());
|
||||
painter
|
||||
.sphere(Aabb {
|
||||
min: (center - 3).with_z(base + 4),
|
||||
max: (center + 2).with_z(base + 9),
|
||||
})
|
||||
.fill(sandstone.clone());
|
||||
painter
|
||||
.sphere(Aabb {
|
||||
min: (center - 4).with_z(base + 8),
|
||||
max: (center + 3).with_z(base + 13),
|
||||
})
|
||||
.fill(sandstone.clone());
|
||||
painter
|
||||
.sphere(Aabb {
|
||||
min: (center - 4).with_z(base + 14),
|
||||
max: (center + 3).with_z(base + 15),
|
||||
})
|
||||
.fill(sandstone);
|
||||
painter
|
||||
.sphere(Aabb {
|
||||
min: (center - 3).with_z(base + 16),
|
||||
max: (center + 2).with_z(base + 21),
|
||||
})
|
||||
.fill(floaty_block);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user