mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
move some details to generate
This commit is contained in:
parent
4fa52db71d
commit
c1aa9bd1b6
5
Cargo.lock
generated
5
Cargo.lock
generated
@ -1880,9 +1880,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "enumset"
|
name = "enumset"
|
||||||
version = "1.1.2"
|
version = "1.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e875f1719c16de097dee81ed675e2d9bb63096823ed3f0ca827b7dea3028bbbb"
|
checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"enumset_derive",
|
"enumset_derive",
|
||||||
]
|
]
|
||||||
@ -7430,6 +7430,7 @@ dependencies = [
|
|||||||
"csv",
|
"csv",
|
||||||
"deflate",
|
"deflate",
|
||||||
"enum-map",
|
"enum-map",
|
||||||
|
"enumset",
|
||||||
"fallible-iterator",
|
"fallible-iterator",
|
||||||
"flate2",
|
"flate2",
|
||||||
"fxhash",
|
"fxhash",
|
||||||
|
@ -21,6 +21,7 @@ common-dynlib = {package = "veloren-common-dynlib", path = "../common/dynlib", o
|
|||||||
bincode = { workspace = true }
|
bincode = { workspace = true }
|
||||||
bitvec = "1.0.1"
|
bitvec = "1.0.1"
|
||||||
enum-map = { workspace = true }
|
enum-map = { workspace = true }
|
||||||
|
enumset = "1.1.3"
|
||||||
fxhash = { workspace = true }
|
fxhash = { workspace = true }
|
||||||
image = { workspace = true }
|
image = { workspace = true }
|
||||||
itertools = { workspace = true }
|
itertools = { workspace = true }
|
||||||
|
@ -7,8 +7,9 @@ use common::{
|
|||||||
terrain::{Block, BlockKind, SpriteCfg, SpriteKind},
|
terrain::{Block, BlockKind, SpriteCfg, SpriteKind},
|
||||||
};
|
};
|
||||||
use enum_map::EnumMap;
|
use enum_map::EnumMap;
|
||||||
|
use enumset::EnumSet;
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
use rand::Rng;
|
use rand::{seq::IteratorRandom, Rng};
|
||||||
use strum::{EnumIter, IntoEnumIterator};
|
use strum::{EnumIter, IntoEnumIterator};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
@ -52,13 +53,41 @@ impl RoomKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
enum Detail {
|
||||||
|
Bar {
|
||||||
|
aabr: Aabr<i32>,
|
||||||
|
},
|
||||||
|
Table {
|
||||||
|
pos: Vec2<i32>,
|
||||||
|
chairs: EnumSet<Dir>,
|
||||||
|
},
|
||||||
|
Stage {
|
||||||
|
aabr: Aabr<i32>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
struct Room {
|
struct Room {
|
||||||
/// Inclusive
|
/// Inclusive
|
||||||
bounds: Aabb<i32>,
|
bounds: Aabb<i32>,
|
||||||
kind: RoomKind,
|
kind: RoomKind,
|
||||||
// stairs: Option<Id<Stairs>>,
|
// stairs: Option<Id<Stairs>>,
|
||||||
walls: EnumMap<Dir, Vec<Id<Wall>>>,
|
walls: EnumMap<Dir, Vec<Id<Wall>>>,
|
||||||
|
// TODO: Remove this, used for debugging
|
||||||
detail_areas: Vec<Aabr<i32>>,
|
detail_areas: Vec<Aabr<i32>>,
|
||||||
|
details: Vec<Detail>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Room {
|
||||||
|
fn new(bounds: Aabb<i32>, kind: RoomKind) -> Self {
|
||||||
|
Self {
|
||||||
|
bounds,
|
||||||
|
kind,
|
||||||
|
walls: Default::default(),
|
||||||
|
detail_areas: Default::default(),
|
||||||
|
details: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Stairs {
|
struct Stairs {
|
||||||
@ -90,6 +119,7 @@ impl Tavern {
|
|||||||
door_dir: Dir,
|
door_dir: Dir,
|
||||||
tile_aabr: Aabr<i32>,
|
tile_aabr: Aabr<i32>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let start = std::time::Instant::now();
|
||||||
let mut rooms = Store::default();
|
let mut rooms = Store::default();
|
||||||
let stairs = Store::default();
|
let stairs = Store::default();
|
||||||
let mut walls = Store::default();
|
let mut walls = Store::default();
|
||||||
@ -163,7 +193,7 @@ impl Tavern {
|
|||||||
}
|
}
|
||||||
struct RoomMeta {
|
struct RoomMeta {
|
||||||
id: Id<Room>,
|
id: Id<Room>,
|
||||||
walls: Vec<Dir>,
|
walls: EnumSet<Dir>,
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut room_metas = Vec::new();
|
let mut room_metas = Vec::new();
|
||||||
@ -185,12 +215,7 @@ impl Tavern {
|
|||||||
}
|
}
|
||||||
.made_valid();
|
.made_valid();
|
||||||
|
|
||||||
let entrance_id = rooms.insert(Room {
|
let entrance_id = rooms.insert(Room::new(entrance_room_aabb, entrance_room));
|
||||||
bounds: entrance_room_aabb,
|
|
||||||
kind: entrance_room,
|
|
||||||
walls: EnumMap::default(),
|
|
||||||
detail_areas: Vec::new(),
|
|
||||||
});
|
|
||||||
|
|
||||||
let start = door_dir.select_aabr_with(
|
let start = door_dir.select_aabr_with(
|
||||||
entrance_room_aabr,
|
entrance_room_aabr,
|
||||||
@ -242,9 +267,11 @@ impl Tavern {
|
|||||||
if room_meta.walls.is_empty() {
|
if room_meta.walls.is_empty() {
|
||||||
continue 'room_gen;
|
continue 'room_gen;
|
||||||
}
|
}
|
||||||
let in_dir = room_meta
|
|
||||||
.walls
|
let Some(in_dir) = room_meta.walls.into_iter().choose(rng) else {
|
||||||
.swap_remove(rng.gen_range(0..room_meta.walls.len()));
|
continue 'room_gen;
|
||||||
|
};
|
||||||
|
room_meta.walls.remove(in_dir);
|
||||||
|
|
||||||
let right = in_dir.orthogonal();
|
let right = in_dir.orthogonal();
|
||||||
let left = -right;
|
let left = -right;
|
||||||
@ -377,12 +404,7 @@ impl Tavern {
|
|||||||
min: bounds.min.with_z(from_room.bounds.min.z),
|
min: bounds.min.with_z(from_room.bounds.min.z),
|
||||||
max: bounds.max.with_z(from_room.bounds.min.z + room_hgt),
|
max: bounds.max.with_z(from_room.bounds.min.z + room_hgt),
|
||||||
};
|
};
|
||||||
let id = rooms.insert(Room {
|
let id = rooms.insert(Room::new(bounds3, room));
|
||||||
bounds: bounds3,
|
|
||||||
kind: room,
|
|
||||||
walls: EnumMap::default(),
|
|
||||||
detail_areas: Vec::new(),
|
|
||||||
});
|
|
||||||
|
|
||||||
let start = in_dir.select_aabr_with(
|
let start = in_dir.select_aabr_with(
|
||||||
from_bounds,
|
from_bounds,
|
||||||
@ -606,8 +628,82 @@ impl Tavern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Place details in detail areas.
|
||||||
|
|
||||||
|
for room in rooms.values_mut() {
|
||||||
|
let room_aabr = to_aabr(room.bounds);
|
||||||
|
let table = |pos: Vec2<i32>, aabr: Aabr<i32>| Detail::Table {
|
||||||
|
pos,
|
||||||
|
chairs: Dir::iter()
|
||||||
|
.filter(|dir| aabr.contains_point(pos + dir.to_vec2()))
|
||||||
|
.collect(),
|
||||||
|
};
|
||||||
|
match room.kind {
|
||||||
|
RoomKind::Garden => room.detail_areas.retain(|&aabr| {
|
||||||
|
if aabr.size().reduce_max() > 1 && rng.gen_bool(0.7) {
|
||||||
|
room.details.push(table(aabr.center(), aabr));
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
RoomKind::StageRoom => {
|
||||||
|
let mut best = None;
|
||||||
|
let mut best_score = 0;
|
||||||
|
for (i, aabr) in room.detail_areas.iter().enumerate() {
|
||||||
|
let edges = Dir::iter()
|
||||||
|
.filter(|dir| dir.select_aabr(*aabr) == dir.select_aabr(room_aabr))
|
||||||
|
.count() as i32;
|
||||||
|
let test_score = edges * aabr.size().product();
|
||||||
|
if best_score < test_score {
|
||||||
|
best_score = test_score;
|
||||||
|
best = Some(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(aabr) = best.map(|i| room.detail_areas.swap_remove(i)) {
|
||||||
|
room.details.push(Detail::Stage { aabr })
|
||||||
|
}
|
||||||
|
room.detail_areas.retain(|&aabr| {
|
||||||
|
if aabr.size().reduce_max() > 1 && rng.gen_bool(0.8) {
|
||||||
|
room.details.push(table(aabr.center(), aabr));
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
RoomKind::BarRoom => {
|
||||||
|
let mut best = None;
|
||||||
|
let mut best_score = 0;
|
||||||
|
for (i, aabr) in room.detail_areas.iter().enumerate() {
|
||||||
|
let test_score = Dir::iter()
|
||||||
|
.any(|dir| dir.select_aabr(*aabr) == dir.select_aabr(room_aabr))
|
||||||
|
as i32
|
||||||
|
* aabr.size().product();
|
||||||
|
if best_score < test_score {
|
||||||
|
best_score = test_score;
|
||||||
|
best = Some(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(aabr) = best.map(|i| room.detail_areas.swap_remove(i)) {
|
||||||
|
room.details.push(Detail::Bar { aabr })
|
||||||
|
}
|
||||||
|
room.detail_areas.retain(|&aabr| {
|
||||||
|
if aabr.size().reduce_max() > 1 && rng.gen_bool(0.1) {
|
||||||
|
room.details.push(table(aabr.center(), aabr));
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
RoomKind::EntranceRoom => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let name = namegen::NameGen::location(rng).generate_tavern();
|
let name = namegen::NameGen::location(rng).generate_tavern();
|
||||||
|
|
||||||
|
println!("GENERATION TIME: {}μs", start.elapsed().as_micros());
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
rooms,
|
rooms,
|
||||||
@ -662,25 +758,6 @@ impl Structure for Tavern {
|
|||||||
min: room.bounds.min.xy(),
|
min: room.bounds.min.xy(),
|
||||||
max: room.bounds.max.xy(),
|
max: room.bounds.max.xy(),
|
||||||
};
|
};
|
||||||
let table_set = |pos, bounds: Aabr<i32>| -> bool {
|
|
||||||
if bounds.size().reduce_min() >= 1 {
|
|
||||||
painter.sprite(pos, SpriteKind::TableDining);
|
|
||||||
|
|
||||||
for dir in Dir::iter() {
|
|
||||||
let pos = pos + dir.to_vec2();
|
|
||||||
if bounds.contains_point(pos.xy()) {
|
|
||||||
painter.rotated_sprite(
|
|
||||||
pos,
|
|
||||||
SpriteKind::ChairSingle,
|
|
||||||
dir.opposite().sprite_ori(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
for (i, aabr) in room.detail_areas.iter().enumerate() {
|
for (i, aabr) in room.detail_areas.iter().enumerate() {
|
||||||
let color = fxhash::hash32(&i).to_le_bytes();
|
let color = fxhash::hash32(&i).to_le_bytes();
|
||||||
|
|
||||||
@ -696,14 +773,6 @@ impl Structure for Tavern {
|
|||||||
}
|
}
|
||||||
match room.kind {
|
match room.kind {
|
||||||
RoomKind::Garden => {
|
RoomKind::Garden => {
|
||||||
for aabr in room.detail_areas.iter() {
|
|
||||||
let pos = aabr.center().with_z(room.bounds.min.z);
|
|
||||||
|
|
||||||
if field.chance(pos, 0.6) {
|
|
||||||
table_set(pos, *aabr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let dir = Dir::from_vec2(room_aabr.size().into());
|
let dir = Dir::from_vec2(room_aabr.size().into());
|
||||||
|
|
||||||
painter
|
painter
|
||||||
@ -722,23 +791,7 @@ impl Structure for Tavern {
|
|||||||
.fill(dark_wood.clone())
|
.fill(dark_wood.clone())
|
||||||
},
|
},
|
||||||
RoomKind::StageRoom => {
|
RoomKind::StageRoom => {
|
||||||
let mut stage = None;
|
for aabr in room.detail_areas.iter().copied() {
|
||||||
let mut stage_score = 0;
|
|
||||||
for aabr in room.detail_areas.iter() {
|
|
||||||
let edges = Dir::iter()
|
|
||||||
.filter(|dir| dir.select_aabr(*aabr) == dir.select_aabr(room_aabr))
|
|
||||||
.count() as i32;
|
|
||||||
let test_stage_score = edges * aabr.size().product();
|
|
||||||
let Some(aabr) = (if stage_score < test_stage_score {
|
|
||||||
stage_score = test_stage_score;
|
|
||||||
stage.replace(*aabr)
|
|
||||||
} else {
|
|
||||||
Some(*aabr)
|
|
||||||
}) else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
table_set(aabr.center().with_z(room.bounds.min.z), aabr);
|
|
||||||
for dir in Dir::iter().filter(|dir| {
|
for dir in Dir::iter().filter(|dir| {
|
||||||
dir.select_aabr(aabr) == dir.select_aabr(room_aabr)
|
dir.select_aabr(aabr) == dir.select_aabr(room_aabr)
|
||||||
&& dir.rotated_cw().select_aabr(aabr)
|
&& dir.rotated_cw().select_aabr(aabr)
|
||||||
@ -751,59 +804,9 @@ impl Structure for Tavern {
|
|||||||
painter.sprite(pos.with_z(room.bounds.min.z), SpriteKind::StreetLamp);
|
painter.sprite(pos.with_z(room.bounds.min.z), SpriteKind::StreetLamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(aabr) = stage {
|
|
||||||
painter
|
|
||||||
.aabb(aabb(Aabb {
|
|
||||||
min: aabr.min.with_z(room.bounds.min.z),
|
|
||||||
max: aabr.max.with_z(room.bounds.min.z),
|
|
||||||
}))
|
|
||||||
.fill(stone.clone());
|
|
||||||
painter
|
|
||||||
.aabb(aabb(Aabb {
|
|
||||||
min: (aabr.min + 1).with_z(room.bounds.min.z),
|
|
||||||
max: (aabr.max - 1).with_z(room.bounds.min.z),
|
|
||||||
}))
|
|
||||||
.fill(wood.clone());
|
|
||||||
for dir in Dir::iter().filter(|dir| {
|
|
||||||
dir.select_aabr(aabr) != dir.select_aabr(room_aabr)
|
|
||||||
&& dir.rotated_cw().select_aabr(aabr)
|
|
||||||
!= dir.rotated_cw().select_aabr(room_aabr)
|
|
||||||
}) {
|
|
||||||
let pos = dir.select_aabr_with(
|
|
||||||
aabr,
|
|
||||||
Vec2::broadcast(dir.rotated_cw().select_aabr(aabr)),
|
|
||||||
);
|
|
||||||
painter
|
|
||||||
.column(pos, room.bounds.min.z..=room.bounds.max.z)
|
|
||||||
.fill(dark_wood.clone());
|
|
||||||
|
|
||||||
for dir in Dir::iter() {
|
|
||||||
painter.rotated_sprite(
|
|
||||||
pos.with_z(room.bounds.center().z + 1) + dir.to_vec2(),
|
|
||||||
SpriteKind::WallSconce,
|
|
||||||
dir.sprite_ori(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
RoomKind::BarRoom => {
|
RoomKind::BarRoom => {
|
||||||
let mut bar = None;
|
for aabr in room.detail_areas.iter().copied() {
|
||||||
let mut bar_score = 0;
|
|
||||||
for aabr in room.detail_areas.iter() {
|
|
||||||
let test_stage_score = Dir::iter()
|
|
||||||
.any(|dir| dir.select_aabr(*aabr) == dir.select_aabr(room_aabr))
|
|
||||||
as i32
|
|
||||||
* aabr.size().product();
|
|
||||||
let Some(aabr) = (if bar_score < test_stage_score {
|
|
||||||
bar_score = test_stage_score;
|
|
||||||
bar.replace(*aabr)
|
|
||||||
} else {
|
|
||||||
Some(*aabr)
|
|
||||||
}) else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
for dir in Dir::iter()
|
for dir in Dir::iter()
|
||||||
.filter(|dir| dir.select_aabr(aabr) == dir.select_aabr(room_aabr))
|
.filter(|dir| dir.select_aabr(aabr) == dir.select_aabr(room_aabr))
|
||||||
{
|
{
|
||||||
@ -818,7 +821,40 @@ impl Structure for Tavern {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(aabr) = bar {
|
},
|
||||||
|
RoomKind::EntranceRoom => {
|
||||||
|
for aabr in room.detail_areas.iter() {
|
||||||
|
let edges = Dir::iter()
|
||||||
|
.filter(|dir| dir.select_aabr(*aabr) == dir.select_aabr(room_aabr))
|
||||||
|
.count();
|
||||||
|
let hanger_pos = if edges == 2 {
|
||||||
|
let pos = aabr.center().with_z(room.bounds.min.z);
|
||||||
|
painter.sprite(pos, SpriteKind::CoatRack);
|
||||||
|
Some(pos)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
for dir in Dir::iter()
|
||||||
|
.filter(|dir| dir.select_aabr(*aabr) == dir.select_aabr(room_aabr))
|
||||||
|
{
|
||||||
|
let pos = dir
|
||||||
|
.select_aabr_with(*aabr, aabr.center())
|
||||||
|
.with_z(room.bounds.center().z + 1);
|
||||||
|
if hanger_pos.map_or(false, |p| p.xy() != pos.xy()) {
|
||||||
|
painter.rotated_sprite(
|
||||||
|
pos,
|
||||||
|
SpriteKind::WallLampSmall,
|
||||||
|
dir.opposite().sprite_ori(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for detail in room.details.iter() {
|
||||||
|
match *detail {
|
||||||
|
Detail::Bar { aabr } => {
|
||||||
for dir in Dir::iter() {
|
for dir in Dir::iter() {
|
||||||
let edge = dir.select_aabr(aabr);
|
let edge = dir.select_aabr(aabr);
|
||||||
let rot_dir = if field.chance(aabr.center().with_z(0), 0.5) {
|
let rot_dir = if field.chance(aabr.center().with_z(0), 0.5) {
|
||||||
@ -865,37 +901,54 @@ impl Structure for Tavern {
|
|||||||
(true, false) => {},
|
(true, false) => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
Detail::Stage { aabr } => {
|
||||||
RoomKind::EntranceRoom => {
|
painter
|
||||||
for aabr in room.detail_areas.iter() {
|
.aabb(aabb(Aabb {
|
||||||
let edges = Dir::iter()
|
min: aabr.min.with_z(room.bounds.min.z),
|
||||||
.filter(|dir| dir.select_aabr(*aabr) == dir.select_aabr(room_aabr))
|
max: aabr.max.with_z(room.bounds.min.z),
|
||||||
.count();
|
}))
|
||||||
let hanger_pos = if edges == 2 {
|
.fill(stone.clone());
|
||||||
let pos = aabr.center().with_z(room.bounds.min.z);
|
painter
|
||||||
painter.sprite(pos, SpriteKind::CoatRack);
|
.aabb(aabb(Aabb {
|
||||||
Some(pos)
|
min: (aabr.min + 1).with_z(room.bounds.min.z),
|
||||||
} else {
|
max: (aabr.max - 1).with_z(room.bounds.min.z),
|
||||||
None
|
}))
|
||||||
};
|
.fill(wood.clone());
|
||||||
|
for dir in Dir::iter().filter(|dir| {
|
||||||
|
dir.select_aabr(aabr) != dir.select_aabr(room_aabr)
|
||||||
|
&& dir.rotated_cw().select_aabr(aabr)
|
||||||
|
!= dir.rotated_cw().select_aabr(room_aabr)
|
||||||
|
}) {
|
||||||
|
let pos = dir.select_aabr_with(
|
||||||
|
aabr,
|
||||||
|
Vec2::broadcast(dir.rotated_cw().select_aabr(aabr)),
|
||||||
|
);
|
||||||
|
painter
|
||||||
|
.column(pos, room.bounds.min.z..=room.bounds.max.z)
|
||||||
|
.fill(dark_wood.clone());
|
||||||
|
|
||||||
for dir in Dir::iter()
|
for dir in Dir::iter() {
|
||||||
.filter(|dir| dir.select_aabr(*aabr) == dir.select_aabr(room_aabr))
|
|
||||||
{
|
|
||||||
let pos = dir
|
|
||||||
.select_aabr_with(*aabr, aabr.center())
|
|
||||||
.with_z(room.bounds.center().z + 1);
|
|
||||||
if hanger_pos.map_or(false, |p| p.xy() != pos.xy()) {
|
|
||||||
painter.rotated_sprite(
|
painter.rotated_sprite(
|
||||||
pos,
|
pos.with_z(room.bounds.center().z + 1) + dir.to_vec2(),
|
||||||
SpriteKind::WallLampSmall,
|
SpriteKind::WallSconce,
|
||||||
dir.opposite().sprite_ori(),
|
dir.sprite_ori(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
Detail::Table { pos, chairs } => {
|
||||||
|
let pos = pos.with_z(room.bounds.min.z);
|
||||||
|
painter.sprite(pos, SpriteKind::TableDining);
|
||||||
|
for dir in chairs.into_iter() {
|
||||||
|
painter.rotated_sprite(
|
||||||
|
pos + dir.to_vec2(),
|
||||||
|
SpriteKind::ChairSingle,
|
||||||
|
dir.opposite().sprite_ori(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ use rand::Rng;
|
|||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
/// A 2d direction.
|
/// A 2d direction.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, enum_map::Enum, strum::EnumIter)]
|
#[derive(Debug, enum_map::Enum, strum::EnumIter, enumset::EnumSetType)]
|
||||||
pub enum Dir {
|
pub enum Dir {
|
||||||
X,
|
X,
|
||||||
Y,
|
Y,
|
||||||
|
Loading…
Reference in New Issue
Block a user