airship dock

This commit is contained in:
jshipsey 2023-10-11 20:27:39 -04:00
parent 204834c984
commit 567b6535af
3 changed files with 601 additions and 6 deletions

View File

@ -585,12 +585,20 @@ impl Site {
site.make_plaza(land, &mut rng);
let build_chance = Lottery::from(vec![(64.0, 1), (5.0, 2), (8.0, 3), (5.0, 4), (5.0, 5)]);
let build_chance = Lottery::from(vec![
(64.0, 1),
(5.0, 2),
(8.0, 3),
(5.0, 4),
(5.0, 5),
(30.0, 6),
]);
let mut castles = 0;
let mut workshops = 0;
let mut airship_docks = 0;
for _ in 0..(size * 200.0) as i32 {
match *build_chance.choose_seeded(rng.gen()) {
// Workshop
@ -868,6 +876,46 @@ impl Site {
castles += 1;
}
},
//airship dock
n if (n == 6 && size > 0.125 && airship_docks == 0) => {
if let Some((_aabr, _, _door_dir)) = attempt(10, || {
site.find_roadside_aabr(&mut rng, 4..4, Extent2::new(2, 2))
}) {
let size = 3.0 as u32;
if let Some((aabr, door_tile, door_dir)) = attempt(32, || {
site.find_roadside_aabr(
&mut rng,
4..(size + 1).pow(2),
Extent2::broadcast(size),
)
}) {
let airship_dock = plot::AirshipDock::generate(
land,
&mut reseed(&mut rng),
&site,
door_tile,
door_dir,
aabr,
);
let airship_dock_alt = airship_dock.alt;
let plot = site.create_plot(Plot {
kind: PlotKind::AirshipDock(airship_dock),
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(airship_dock_alt),
});
airship_docks += 1;
} else {
site.make_plaza(land, &mut rng);
}
}
},
_ => {},
}
}
@ -1672,6 +1720,7 @@ 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::AirshipDock(airship_dock) => airship_dock.render_collect(self, canvas),
PlotKind::CoastalHouse(coastal_house) => coastal_house.render_collect(self, canvas),
PlotKind::CoastalWorkshop(coastal_workshop) => {
coastal_workshop.render_collect(self, canvas)

View File

@ -1,4 +1,5 @@
mod adlet;
mod airship_dock;
mod bridge;
mod castle;
mod citadel;
@ -22,11 +23,12 @@ mod sea_chapel;
mod workshop;
pub use self::{
adlet::AdletStronghold, bridge::Bridge, castle::Castle, citadel::Citadel,
cliff_tower::CliffTower, coastal_house::CoastalHouse, coastal_workshop::CoastalWorkshop,
desert_city_arena::DesertCityArena, desert_city_multiplot::DesertCityMultiPlot,
desert_city_temple::DesertCityTemple, dungeon::Dungeon, dwarven_mine::DwarvenMine,
giant_tree::GiantTree, gnarling::GnarlingFortification, house::House, jungle_ruin::JungleRuin,
adlet::AdletStronghold, airship_dock::AirshipDock, bridge::Bridge, castle::Castle,
citadel::Citadel, cliff_tower::CliffTower, coastal_house::CoastalHouse,
coastal_workshop::CoastalWorkshop, desert_city_arena::DesertCityArena,
desert_city_multiplot::DesertCityMultiPlot, desert_city_temple::DesertCityTemple,
dungeon::Dungeon, dwarven_mine::DwarvenMine, giant_tree::GiantTree,
gnarling::GnarlingFortification, house::House, jungle_ruin::JungleRuin,
pirate_hideout::PirateHideout, savannah_hut::SavannahHut, savannah_pit::SavannahPit,
savannah_workshop::SavannahWorkshop, sea_chapel::SeaChapel, workshop::Workshop,
};
@ -70,6 +72,7 @@ impl Plot {
pub enum PlotKind {
House(House),
AirshipDock(AirshipDock),
CoastalHouse(CoastalHouse),
CoastalWorkshop(CoastalWorkshop),
Workshop(Workshop),

View File

@ -0,0 +1,543 @@
use super::*;
use crate::Land;
use common::terrain::{Block, BlockKind, SpriteKind};
use rand::prelude::*;
use vek::*;
/// Represents house data generated by the `generate()` method
pub struct AirshipDock {
/// Axis aligned bounding region for the house
bounds: Aabr<i32>,
/// Approximate altitude of the door tile
pub(crate) alt: i32,
}
impl AirshipDock {
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 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(door_tile + door_dir)) as i32,
}
}
}
impl Structure for AirshipDock {
#[cfg(feature = "use-dyn-lib")]
const UPDATE_FN: &'static [u8] = b"render_airshipdock\0";
#[cfg_attr(feature = "be-dyn-lib", export_name = "render_airshipdock")]
fn render_inner(&self, _site: &Site, _land: &Land, painter: &Painter) {
let brick = Fill::Brick(BlockKind::Rock, Rgb::new(80, 75, 85), 24);
let wood = Fill::Brick(BlockKind::Rock, Rgb::new(45, 28, 21), 24);
let woodalt = Fill::Brick(BlockKind::Rock, Rgb::new(30, 22, 15), 24);
let base = self.alt + 3;
let center = self.bounds.center();
let height = base + 28;
// Base
painter
.aabb(Aabb {
min: (self.bounds.min + 1).with_z(base - 16),
max: Vec2::new(self.bounds.max.x, self.bounds.max.y).with_z(base),
})
.fill(brick.clone());
//bracing
painter
.cylinder_with_radius(center.with_z(height), 7.0, 7.0)
.fill(wood.clone());
painter
.cylinder_with_radius(center.with_z(height + 1), 7.0, 5.0)
.clear();
painter
.cylinder_with_radius(center.with_z(height + 7), 8.0, 1.0)
.fill(wood.clone());
//platform edging
painter
.superquadric(
Aabb {
min: Vec2::new(center.x - 13, center.y - 16).with_z(base + 35),
max: Vec2::new(center.x + 17, center.y + 11).with_z(height + 11),
},
5.0,
)
.fill(woodalt.clone());
//platforrm
painter
.superquadric(
Aabb {
min: Vec2::new(center.x - 12, center.y - 15).with_z(base + 36),
max: Vec2::new(center.x + 16, center.y + 10).with_z(height + 11),
},
5.0,
)
.fill(wood.clone());
painter
.superquadric(
Aabb {
min: Vec2::new(center.x - 12, center.y - 15).with_z(base + 37),
max: Vec2::new(center.x + 16, center.y + 10).with_z(height + 12),
},
5.0,
)
.clear();
//platform walkway bits
painter
.aabb(Aabb {
min: Vec2::new(center.x - 2, center.y - 22).with_z(height + 8),
max: Vec2::new(center.x + 2, center.y + 16).with_z(height + 10),
})
.fill(woodalt.clone());
painter
.aabb(Aabb {
min: Vec2::new(center.x - 1, center.y - 22).with_z(height + 8),
max: Vec2::new(center.x + 1, center.y + 16).with_z(height + 10),
})
.fill(wood.clone());
painter
.aabb(Aabb {
min: Vec2::new(center.x - 2, center.y - 16).with_z(height + 9),
max: Vec2::new(center.x + 2, center.y + 10).with_z(height + 10),
})
.clear();
painter
.aabb(Aabb {
min: Vec2::new(center.x - 1, center.y - 22).with_z(height + 9),
max: Vec2::new(center.x + 1, center.y + 16).with_z(height + 10),
})
.clear();
//column
painter
.cylinder_with_radius(center.with_z(base), 6.0, 45.0)
.fill(brick.clone());
//column thick bits
painter
.cylinder_with_radius(center.with_z(base + 35), 7.0, 3.0)
.fill(brick.clone());
painter
.cylinder_with_radius(center.with_z(base), 7.0, 1.0)
.fill(brick.clone());
painter
.cylinder_with_radius(center.with_z(base), 5.0, 45.0)
.clear();
//cone
painter
.cone_with_radius(center.with_z(base + 45), 8.0, 18.0)
.fill(wood.clone());
//remove 1/4 cyl
painter
.aabb(Aabb {
min: Vec2::new(center.x - 1, center.y + 1).with_z(height + 9),
max: Vec2::new(center.x + 6, center.y + 6).with_z(height + 17),
})
.fill(brick.clone());
painter
.aabb(Aabb {
min: Vec2::new(center.x, center.y + 2).with_z(height + 9),
max: Vec2::new(center.x + 6, center.y + 7).with_z(height + 17),
})
.clear();
//platform cleanup
painter
.aabb(Aabb {
min: Vec2::new(center.x - 2, center.y - 15).with_z(height + 8),
max: Vec2::new(center.x + 6, center.y + 9).with_z(height + 9),
})
.fill(wood.clone());
//upper door
painter
.aabb(Aabb {
min: Vec2::new(center.x + 5, center.y - 2).with_z(height + 10),
max: Vec2::new(center.x + 7, center.y + 2).with_z(height + 13),
})
.fill(brick.clone());
painter
.aabb(Aabb {
min: Vec2::new(center.x + 5, center.y - 1).with_z(height + 10),
max: Vec2::new(center.x + 7, center.y + 1).with_z(height + 15),
})
.fill(brick.clone());
painter
.aabb(Aabb {
min: Vec2::new(center.x + 5, center.y - 1).with_z(height + 10),
max: Vec2::new(center.x + 7, center.y + 1).with_z(height + 13),
})
.clear();
//door sprites
painter.rotated_sprite(
Vec2::new(center.x + 6, center.y - 1).with_z(height + 10),
SpriteKind::Door,
2,
);
painter.rotated_sprite(
Vec2::new(center.x + 6, center.y).with_z(height + 10),
SpriteKind::Door,
6,
);
//bracing diagonal bits
painter
.line(
Vec2::new(center.x + 5, center.y - 3).with_z(height),
Vec2::new(center.x + 11, center.y - 3).with_z(height + 8),
0.8,
)
.fill(wood.clone());
painter
.line(
Vec2::new(center.x + 5, center.y + 2).with_z(height),
Vec2::new(center.x + 11, center.y + 2).with_z(height + 8),
0.8,
)
.fill(wood.clone());
//
painter
.line(
Vec2::new(center.x - 11, center.y - 3).with_z(height + 8),
Vec2::new(center.x - 6, center.y - 3).with_z(height),
0.8,
)
.fill(wood.clone());
painter
.line(
Vec2::new(center.x - 11, center.y + 2).with_z(height + 8),
Vec2::new(center.x - 6, center.y + 2).with_z(height),
0.8,
)
.fill(wood.clone());
//
painter
.line(
Vec2::new(center.x - 3, center.y - 12).with_z(height + 7),
Vec2::new(center.x - 3, center.y - 6).with_z(height),
0.8,
)
.fill(wood.clone());
painter
.line(
Vec2::new(center.x + 2, center.y - 12).with_z(height + 7),
Vec2::new(center.x + 2, center.y - 6).with_z(height),
0.8,
)
.fill(wood.clone());
//
painter
.line(
Vec2::new(center.x - 3, center.y + 5).with_z(height),
Vec2::new(center.x - 3, center.y + 9).with_z(height + 7),
0.8,
)
.fill(wood.clone());
painter
.line(
Vec2::new(center.x + 2, center.y + 5).with_z(height),
Vec2::new(center.x + 2, center.y + 9).with_z(height + 7),
0.8,
)
.fill(wood.clone());
//stairs
painter
.cylinder_with_radius(center.with_z(height + 8), 5.0, 1.0)
.clear();
let stairs_clear1 = painter.cylinder_with_radius(center.with_z(base), 5.0, 38.0);
painter
.prim(Primitive::sampling(
stairs_clear1,
dungeon::spiral_staircase(center.with_z(base + 3), 6.0, 0.5, 9.0),
))
.fill(brick.clone());
//clean up interface at top
painter
.aabb(Aabb {
min: Vec2::new(center.x + 1, center.y + 3).with_z(height + 8),
max: Vec2::new(center.x + 4, center.y + 5).with_z(height + 9),
})
.fill(wood.clone());
painter
.aabb(Aabb {
min: Vec2::new(center.x + 0, center.y + 2).with_z(height + 9),
max: Vec2::new(center.x + 6, center.y + 7).with_z(height + 10),
})
.fill(brick.clone());
painter
.aabb(Aabb {
min: Vec2::new(center.x + 1, center.y + 3).with_z(height + 9),
max: Vec2::new(center.x + 6, center.y + 7).with_z(height + 10),
})
.clear();
painter
.aabb(Aabb {
min: Vec2::new(center.x + 0, center.y + 2).with_z(height + 9),
max: Vec2::new(center.x + 1, center.y + 3).with_z(height + 17),
})
.fill(brick.clone());
//windows
painter.fill(
painter.aabb(Aabb {
min: Vec2::new(center.x - 6, center.y - 1).with_z(height + 12),
max: Vec2::new(center.x - 5, center.y + 1).with_z(height + 15),
}),
Fill::Block(Block::air(SpriteKind::Window1).with_ori(2).unwrap()),
);
//lower windows
painter.fill(
painter.aabb(Aabb {
min: Vec2::new(center.x - 6, center.y - 1).with_z(base + 19),
max: Vec2::new(center.x - 5, center.y + 1).with_z(base + 22),
}),
Fill::Block(Block::air(SpriteKind::Window1).with_ori(2).unwrap()),
);
painter.fill(
painter.aabb(Aabb {
min: Vec2::new(center.x - 6, center.y - 1).with_z(base + 1),
max: Vec2::new(center.x - 5, center.y + 1).with_z(base + 4),
}),
Fill::Block(Block::air(SpriteKind::Window1).with_ori(2).unwrap()),
);
painter.fill(
painter.aabb(Aabb {
min: Vec2::new(center.x + 5, center.y - 1).with_z(base + 4),
max: Vec2::new(center.x + 6, center.y + 1).with_z(base + 7),
}),
Fill::Block(Block::air(SpriteKind::Window1).with_ori(2).unwrap()),
);
painter.fill(
painter.aabb(Aabb {
min: Vec2::new(center.x + 5, center.y - 1).with_z(base + 22),
max: Vec2::new(center.x + 6, center.y + 1).with_z(base + 25),
}),
Fill::Block(Block::air(SpriteKind::Window1).with_ori(2).unwrap()),
);
painter.fill(
painter.aabb(Aabb {
min: Vec2::new(center.x + 5, center.y - 1).with_z(base + 30),
max: Vec2::new(center.x + 6, center.y + 1).with_z(base + 33),
}),
Fill::Block(Block::air(SpriteKind::Window1).with_ori(2).unwrap()),
);
//side windows
painter.fill(
painter.aabb(Aabb {
min: Vec2::new(center.x - 1, center.y + 5).with_z(base + 17),
max: Vec2::new(center.x + 1, center.y + 6).with_z(base + 20),
}),
Fill::Block(Block::air(SpriteKind::Window1).with_ori(4).unwrap()),
);
painter.fill(
painter.aabb(Aabb {
min: Vec2::new(center.x - 1, center.y - 6).with_z(base + 13),
max: Vec2::new(center.x + 1, center.y - 5).with_z(base + 16),
}),
Fill::Block(Block::air(SpriteKind::Window1).with_ori(4).unwrap()),
);
//lower doorway
painter
.aabb(Aabb {
min: Vec2::new(center.x - 4, center.y + 4).with_z(base + 0),
max: Vec2::new(center.x + 1, center.y + 7).with_z(base + 4),
})
.clear();
painter
.aabb(Aabb {
min: Vec2::new(center.x - 4, center.y + 8).with_z(base),
max: Vec2::new(center.x + 1, center.y + 9).with_z(base + 1),
})
.clear();
//lights
painter.rotated_sprite(
Vec2::new(center.x - 3, center.y + 5).with_z(base + 8),
SpriteKind::WallLampSmall,
4,
);
painter.rotated_sprite(
Vec2::new(center.x + 2, center.y + 5).with_z(base + 8),
SpriteKind::WallLampSmall,
4,
);
painter.rotated_sprite(
Vec2::new(center.x - 3, center.y + 5).with_z(base + 18),
SpriteKind::WallLampSmall,
4,
);
painter.rotated_sprite(
Vec2::new(center.x + 2, center.y + 5).with_z(base + 18),
SpriteKind::WallLampSmall,
4,
);
painter.rotated_sprite(
Vec2::new(center.x - 3, center.y - 6).with_z(base + 8),
SpriteKind::WallLampSmall,
0,
);
painter.rotated_sprite(
Vec2::new(center.x + 2, center.y - 6).with_z(base + 8),
SpriteKind::WallLampSmall,
0,
);
painter.rotated_sprite(
Vec2::new(center.x - 3, center.y - 6).with_z(base + 18),
SpriteKind::WallLampSmall,
0,
);
painter.rotated_sprite(
Vec2::new(center.x + 2, center.y - 6).with_z(base + 18),
SpriteKind::WallLampSmall,
0,
);
painter.rotated_sprite(
Vec2::new(center.x + 5, center.y - 3).with_z(base + 13),
SpriteKind::WallLampSmall,
2,
);
painter.rotated_sprite(
Vec2::new(center.x + 5, center.y + 2).with_z(base + 13),
SpriteKind::WallLampSmall,
2,
);
painter.rotated_sprite(
Vec2::new(center.x + 5, center.y - 3).with_z(base + 25),
SpriteKind::WallLampSmall,
2,
);
painter.rotated_sprite(
Vec2::new(center.x + 5, center.y + 2).with_z(base + 25),
SpriteKind::WallLampSmall,
2,
);
painter.rotated_sprite(
Vec2::new(center.x - 6, center.y - 3).with_z(base + 13),
SpriteKind::WallLampSmall,
6,
);
painter.rotated_sprite(
Vec2::new(center.x - 6, center.y + 2).with_z(base + 13),
SpriteKind::WallLampSmall,
6,
);
painter.rotated_sprite(
Vec2::new(center.x - 6, center.y - 3).with_z(base + 25),
SpriteKind::WallLampSmall,
6,
);
painter.rotated_sprite(
Vec2::new(center.x - 6, center.y + 2).with_z(base + 25),
SpriteKind::WallLampSmall,
6,
);
//upper lighting
painter.rotated_sprite(
Vec2::new(center.x + 14, center.y + 8).with_z(base + 35),
SpriteKind::Lantern,
6,
);
painter.rotated_sprite(
Vec2::new(center.x + 14, center.y - 15).with_z(base + 35),
SpriteKind::Lantern,
6,
);
painter.rotated_sprite(
Vec2::new(center.x - 11, center.y + 8).with_z(base + 35),
SpriteKind::Lantern,
6,
);
painter.rotated_sprite(
Vec2::new(center.x - 11, center.y - 15).with_z(base + 35),
SpriteKind::Lantern,
6,
);
painter.rotated_sprite(
Vec2::new(center.x + 4, center.y + 5).with_z(base + 44),
SpriteKind::Lantern,
6,
);
painter.rotated_sprite(
Vec2::new(center.x + 4, center.y - 5).with_z(base + 44),
SpriteKind::Lantern,
6,
);
painter.rotated_sprite(
Vec2::new(center.x - 5, center.y + 4).with_z(base + 44),
SpriteKind::Lantern,
6,
);
painter.rotated_sprite(
Vec2::new(center.x - 5, center.y - 5).with_z(base + 44),
SpriteKind::Lantern,
6,
);
painter.rotated_sprite(
Vec2::new(center.x + 1, center.y + 15).with_z(base + 35),
SpriteKind::Lantern,
6,
);
painter.rotated_sprite(
Vec2::new(center.x + 1, center.y - 22).with_z(base + 35),
SpriteKind::Lantern,
6,
);
painter.rotated_sprite(
Vec2::new(center.x - 2, center.y + 15).with_z(base + 35),
SpriteKind::Lantern,
6,
);
painter.rotated_sprite(
Vec2::new(center.x - 2, center.y - 22).with_z(base + 35),
SpriteKind::Lantern,
6,
);
//interior
painter.rotated_sprite(
Vec2::new(center.x - 2, center.y - 3).with_z(base + 5),
SpriteKind::Lantern,
6,
);
painter.rotated_sprite(
Vec2::new(center.x - 2, center.y - 3).with_z(base + 15),
SpriteKind::Lantern,
6,
);
painter.rotated_sprite(
Vec2::new(center.x - 2, center.y - 3).with_z(base + 24),
SpriteKind::Lantern,
6,
);
painter.rotated_sprite(
Vec2::new(center.x - 2, center.y - 3).with_z(base + 33),
SpriteKind::Lantern,
6,
);
painter.rotated_sprite(
Vec2::new(center.x - 2, center.y - 3).with_z(base + 44),
SpriteKind::Lantern,
6,
);
}
}