mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
More work on castles
This commit is contained in:
parent
f7f7f12a38
commit
c35780d05b
@ -5,7 +5,7 @@ mod tile;
|
||||
use self::{
|
||||
gen::{Fill, Primitive, Structure},
|
||||
plot::{Plot, PlotKind},
|
||||
tile::{HazardKind, Tile, TileGrid, TileKind, TILE_SIZE},
|
||||
tile::{HazardKind, Tile, TileGrid, TileKind, KeepKind, Ori, TILE_SIZE},
|
||||
};
|
||||
use crate::{
|
||||
site::SpawnRules,
|
||||
@ -16,8 +16,7 @@ use common::{
|
||||
astar::Astar,
|
||||
lottery::Lottery,
|
||||
spiral::Spiral2d,
|
||||
store::{Id, Store},
|
||||
terrain::{Block, BlockKind, SpriteKind, TerrainChunkSize},
|
||||
store::{Id, Store}, terrain::{Block, BlockKind, SpriteKind, TerrainChunkSize},
|
||||
vol::RectVolSize,
|
||||
};
|
||||
use hashbrown::hash_map::DefaultHashBuilder;
|
||||
@ -405,12 +404,12 @@ impl Site {
|
||||
|
||||
// Walls
|
||||
site.blit_aabr(aabr, Tile {
|
||||
kind: TileKind::Wall,
|
||||
kind: TileKind::Wall(Ori::North),
|
||||
plot: Some(plot),
|
||||
});
|
||||
|
||||
let tower = Tile {
|
||||
kind: TileKind::Castle,
|
||||
kind: TileKind::Tower,
|
||||
plot: Some(plot),
|
||||
};
|
||||
site.tiles
|
||||
@ -441,10 +440,25 @@ impl Site {
|
||||
max: aabr.center() + 3,
|
||||
},
|
||||
Tile {
|
||||
kind: TileKind::Castle,
|
||||
kind: TileKind::Wall(Ori::North),
|
||||
plot: Some(plot),
|
||||
},
|
||||
);
|
||||
site.tiles.set(Vec2::new(aabr.center().x + 2, aabr.center().y + 2), tower.clone());
|
||||
site.tiles.set(Vec2::new(aabr.center().x + 2, aabr.center().y - 3), tower.clone());
|
||||
site.tiles.set(Vec2::new(aabr.center().x - 3, aabr.center().y + 2), tower.clone());
|
||||
site.tiles.set(Vec2::new(aabr.center().x - 3, aabr.center().y - 3), tower.clone());
|
||||
|
||||
site.blit_aabr(
|
||||
Aabr {
|
||||
min: aabr.center() - 2,
|
||||
max: aabr.center() + 2,
|
||||
},
|
||||
Tile {
|
||||
kind: TileKind::Keep(tile::KeepKind::Middle),
|
||||
plot: Some(plot),
|
||||
},
|
||||
);
|
||||
|
||||
castles += 1;
|
||||
}
|
||||
|
@ -43,57 +43,182 @@ impl Structure for Castle {
|
||||
let parapet_height = 2;
|
||||
let parapet_width = 1;
|
||||
let downwards = 40;
|
||||
|
||||
let tower_height = 12;
|
||||
|
||||
let keep_levels = 3;
|
||||
let keep_level_height = 8;
|
||||
let keep_height = wall_height + keep_levels * keep_level_height + 1;
|
||||
for x in 0..self.tile_aabr.size().w {
|
||||
for y in 0..self.tile_aabr.size().h {
|
||||
let tile_pos = self.tile_aabr.min + Vec2::new(x, y);
|
||||
let wpos_center = site.tile_center_wpos(tile_pos);
|
||||
let wpos = site.tile_wpos(tile_pos);
|
||||
let ori = if x == 0 || x == self.tile_aabr.size().w - 1 {
|
||||
Vec2::new(1, 0)
|
||||
} else {
|
||||
Vec2::new(0, 1)
|
||||
};
|
||||
let ori_tower_x = if x == 0 {
|
||||
Vec2::new(1, 0)
|
||||
} else {
|
||||
Vec2::new(0, 0)
|
||||
};
|
||||
let ori_tower_y = if y == 0 {
|
||||
Vec2::new(0, 1)
|
||||
} else {
|
||||
Vec2::new(0, 0)
|
||||
};
|
||||
let ori_tower = ori_tower_x + ori_tower_y;
|
||||
match site.tiles.get(tile_pos).kind.clone() {
|
||||
TileKind::Wall => {
|
||||
let ori = if x == 0 || x == self.tile_aabr.size().w - 1 {
|
||||
Vec2::new(1, 0)
|
||||
} else {
|
||||
Vec2::new(0, 1)
|
||||
};
|
||||
TileKind::Wall(orientation) => {
|
||||
let wall = prim(Primitive::Aabb(Aabb {
|
||||
min: wpos.with_z(self.alt),
|
||||
max: (wpos + 7).with_z(self.alt + wall_height + parapet_height),
|
||||
max: (wpos + 6).with_z(self.alt + wall_height + parapet_height),
|
||||
}));
|
||||
let cut_path = prim(Primitive::Aabb(Aabb {
|
||||
min: Vec3::new(
|
||||
wpos.x + parapet_width * ori.x,
|
||||
wpos.y + parapet_width * ori.y,
|
||||
self.alt + wall_height,
|
||||
),
|
||||
max: Vec3::new(
|
||||
wpos.x + (7 - parapet_width) * ori.x + 7 * ori.y,
|
||||
wpos.y + (7 - parapet_width) * ori.y + 7 * ori.x,
|
||||
self.alt + wall_height + parapet_height,
|
||||
),
|
||||
min: (wpos + (parapet_width * ori) as Vec2<i32>)
|
||||
.with_z(self.alt + wall_height),
|
||||
max: (wpos
|
||||
+ (6 - parapet_width) * ori as Vec2<i32>
|
||||
+ 6 * ori.yx() as Vec2<i32>)
|
||||
.with_z(self.alt + wall_height + parapet_height),
|
||||
}));
|
||||
let cut_sides1 = prim(Primitive::Aabb(Aabb {
|
||||
min: Vec3::new(wpos.x, wpos.y, self.alt + wall_height + 1),
|
||||
max: Vec3::new(
|
||||
wpos.x + 7 * ori.x + ori.y,
|
||||
wpos.y + 7 * ori.y + ori.x,
|
||||
wpos.x + 6 * ori.x + ori.y,
|
||||
wpos.y + 6 * ori.y + ori.x,
|
||||
self.alt + wall_height + parapet_height,
|
||||
),
|
||||
}));
|
||||
let pillar_start = prim(Primitive::Aabb(Aabb {
|
||||
min: Vec3::new(wpos.x, wpos.y - 1, self.alt),
|
||||
max: Vec3::new(wpos.x + 1, wpos.y + 7, self.alt + wall_height),
|
||||
}));
|
||||
let pillar_end = prim(Primitive::Aabb(Aabb {
|
||||
min: Vec3::new(wpos.x + 5, wpos.y - 1, self.alt),
|
||||
max: Vec3::new(wpos.x + 6, wpos.y + 7, self.alt + wall_height),
|
||||
}));
|
||||
let pillars = prim(Primitive::Or(pillar_start, pillar_end));
|
||||
fill(
|
||||
prim(Primitive::Xor(wall, cut_path)),
|
||||
prim(Primitive::Or(wall, pillars)),
|
||||
Fill::Block(Block::new(BlockKind::Rock, Rgb::new(33, 33, 33))),
|
||||
);
|
||||
fill(cut_sides1, Fill::Block(Block::air(SpriteKind::Empty)));
|
||||
fill(cut_path, Fill::Block(Block::empty()));
|
||||
fill(cut_sides1, Fill::Block(Block::empty()));
|
||||
},
|
||||
_ => {
|
||||
TileKind::Tower => {
|
||||
let tower_lower = prim(Primitive::Aabb(Aabb {
|
||||
min: wpos.with_z(self.alt),
|
||||
max: (wpos + 6).with_z(self.alt + wall_height + tower_height),
|
||||
}));
|
||||
let tower_lower_inner_x = prim(Primitive::Aabb(Aabb {
|
||||
min: Vec3::new(
|
||||
wpos.x + 1 * ori_tower.x,
|
||||
wpos.y + parapet_width,
|
||||
self.alt + wall_height,
|
||||
),
|
||||
max: Vec3::new(
|
||||
wpos.x + 6 + ori_tower.x - 1,
|
||||
wpos.y + 6 - parapet_width,
|
||||
self.alt + wall_height + tower_height / 3,
|
||||
),
|
||||
}));
|
||||
let tower_lower_inner_y = prim(Primitive::Aabb(Aabb {
|
||||
min: Vec3::new(
|
||||
wpos.x + parapet_width,
|
||||
wpos.y + 1 * ori_tower.y,
|
||||
self.alt + wall_height,
|
||||
),
|
||||
max: Vec3::new(
|
||||
wpos.x + 6 - parapet_width,
|
||||
wpos.y + 6 + ori_tower.y - 1,
|
||||
self.alt + wall_height + tower_height / 3,
|
||||
),
|
||||
}));
|
||||
let tower_lower_inner =
|
||||
prim(Primitive::Or(tower_lower_inner_x, tower_lower_inner_y));
|
||||
fill(
|
||||
prim(Primitive::Aabb(Aabb {
|
||||
min: wpos_center.with_z(self.alt + 9),
|
||||
max: (wpos_center + 1).with_z(self.alt + 10),
|
||||
})),
|
||||
Fill::Block(Block::new(BlockKind::Rock, Rgb::new(255, 255, 255))),
|
||||
prim(Primitive::Xor(tower_lower, tower_lower_inner)),
|
||||
Fill::Block(Block::new(BlockKind::Rock, Rgb::new(33, 33, 33))),
|
||||
);
|
||||
let tower_upper = prim(Primitive::Aabb(Aabb {
|
||||
min: Vec3::new(
|
||||
wpos.x - 1,
|
||||
wpos.y - 1,
|
||||
self.alt + wall_height + tower_height - 3 as i32,
|
||||
),
|
||||
max: Vec3::new(
|
||||
wpos.x + 7,
|
||||
wpos.y + 7,
|
||||
self.alt + wall_height + tower_height - 1 as i32,
|
||||
),
|
||||
}));
|
||||
let tower_upper2 = prim(Primitive::Aabb(Aabb {
|
||||
min: Vec3::new(
|
||||
wpos.x - 2,
|
||||
wpos.y - 2,
|
||||
self.alt + wall_height + tower_height - 1 as i32,
|
||||
),
|
||||
max: Vec3::new(
|
||||
wpos.x + 8,
|
||||
wpos.y + 8,
|
||||
self.alt + wall_height + tower_height,
|
||||
),
|
||||
}));
|
||||
|
||||
fill(
|
||||
prim(Primitive::Or(tower_upper, tower_upper2)),
|
||||
Fill::Block(Block::new(BlockKind::Rock, Rgb::new(33, 33, 33))),
|
||||
);
|
||||
|
||||
let roof_lip = 1;
|
||||
let roof_height = 8 / 2 + roof_lip + 1;
|
||||
|
||||
// Roof
|
||||
fill(
|
||||
prim(Primitive::Pyramid {
|
||||
aabb: Aabb {
|
||||
min: (wpos - 2 - roof_lip)
|
||||
.with_z(self.alt + wall_height + tower_height),
|
||||
max: (wpos + 8 + roof_lip).with_z(
|
||||
self.alt + wall_height + tower_height + roof_height,
|
||||
),
|
||||
},
|
||||
inset: roof_height,
|
||||
}),
|
||||
Fill::Block(Block::new(BlockKind::Wood, Rgb::new(116, 20, 20))),
|
||||
);
|
||||
},
|
||||
TileKind::Keep(kind) => {
|
||||
match kind {
|
||||
tile::KeepKind::Middle => {
|
||||
for i in 0..keep_levels + 1 {
|
||||
let height = keep_level_height * i;
|
||||
fill(
|
||||
prim(Primitive::Aabb(Aabb {
|
||||
min: wpos.with_z(self.alt + height),
|
||||
max: (wpos + 6).with_z(self.alt + height + 1),
|
||||
})),
|
||||
Fill::Block(Block::new(
|
||||
BlockKind::Rock,
|
||||
Rgb::new(89, 44, 14),
|
||||
)),
|
||||
);
|
||||
}
|
||||
},
|
||||
tile::KeepKind::Corner => {},
|
||||
tile::KeepKind::Wall(orientation) => {
|
||||
for i in 0..keep_levels + 1 {
|
||||
let height = keep_level_height * i;
|
||||
// TODO clamp value in case of big heights
|
||||
let window_height = keep_level_height - 3;
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -182,7 +182,9 @@ pub enum TileKind {
|
||||
Road { a: u16, b: u16, w: u16 },
|
||||
Building,
|
||||
Castle,
|
||||
Wall,
|
||||
Wall(Ori),
|
||||
Tower,
|
||||
Keep(KeepKind),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
@ -209,7 +211,7 @@ impl Tile {
|
||||
pub fn is_obstacle(&self) -> bool {
|
||||
matches!(
|
||||
self.kind,
|
||||
TileKind::Hazard(_) | TileKind::Building | TileKind::Castle | TileKind::Wall
|
||||
TileKind::Hazard(_) | TileKind::Building | TileKind::Castle | TileKind::Wall(_)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -219,3 +221,23 @@ pub enum HazardKind {
|
||||
Water,
|
||||
Hill { gradient: f32 },
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum KeepKind {
|
||||
Middle,
|
||||
Corner,
|
||||
Wall(Ori),
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum Ori {
|
||||
North = 0,
|
||||
East = 1,
|
||||
South = 2,
|
||||
West = 3,
|
||||
}
|
||||
|
||||
impl Ori {
|
||||
pub fn dir(self) -> Vec2<i32> {CARDINALS[self as u8 as usize]}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user