mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Addressed review issues
This commit is contained in:
parent
388a899a7f
commit
0ca42857fa
@ -16,7 +16,7 @@ fn criterion_benchmark(c: &mut Criterion) {
|
|||||||
// Setup: Create chunk and fill it (dense) for z in [140, 220).
|
// Setup: Create chunk and fill it (dense) for z in [140, 220).
|
||||||
let mut chunk = TerrainChunk::new(
|
let mut chunk = TerrainChunk::new(
|
||||||
MIN_Z,
|
MIN_Z,
|
||||||
Block::new(BlockKind::Rock, Default::default()),
|
Block::new(BlockKind::Rock, Rgb::zero()),
|
||||||
Block::empty(),
|
Block::empty(),
|
||||||
TerrainChunkMeta::void(),
|
TerrainChunkMeta::void(),
|
||||||
);
|
);
|
||||||
@ -29,7 +29,7 @@ fn criterion_benchmark(c: &mut Criterion) {
|
|||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
chunk
|
chunk
|
||||||
.set(pos, Block::new(BlockKind::Rock, Default::default()))
|
.set(pos, Block::new(BlockKind::Rock, Rgb::zero()))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ fn criterion_benchmark(c: &mut Criterion) {
|
|||||||
MAX_Z,
|
MAX_Z,
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
let _ = chunk.set(pos, Block::new(BlockKind::Rock, Default::default()));
|
let _ = chunk.set(pos, Block::new(BlockKind::Rock, Rgb::zero()));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -45,18 +45,32 @@ make_case_elim!(
|
|||||||
// Covers all other cases (we sometimes have bizarrely coloured misc blocks, and also we
|
// Covers all other cases (we sometimes have bizarrely coloured misc blocks, and also we
|
||||||
// often want to experiment with new kinds of block without allocating them a
|
// often want to experiment with new kinds of block without allocating them a
|
||||||
// dedicated block kind.
|
// dedicated block kind.
|
||||||
Misc = 0xFF,
|
Misc = 0xFE,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl BlockKind {
|
impl BlockKind {
|
||||||
|
#[inline]
|
||||||
pub const fn is_air(&self) -> bool { matches!(self, BlockKind::Air) }
|
pub const fn is_air(&self) -> bool { matches!(self, BlockKind::Air) }
|
||||||
|
|
||||||
|
/// Determine whether the block kind is a gas or a liquid. This does not
|
||||||
|
/// consider any sprites that may occupy the block (the definition of
|
||||||
|
/// fluid is 'a substance that deforms to fit containers')
|
||||||
|
#[inline]
|
||||||
pub const fn is_fluid(&self) -> bool { *self as u8 & 0xF0 == 0x00 }
|
pub const fn is_fluid(&self) -> bool { *self as u8 & 0xF0 == 0x00 }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub const fn is_liquid(&self) -> bool { self.is_fluid() && !self.is_air() }
|
pub const fn is_liquid(&self) -> bool { self.is_fluid() && !self.is_air() }
|
||||||
|
|
||||||
|
/// Determine whether the block is filled (i.e: fully solid). Right now,
|
||||||
|
/// this is the opposite of being a fluid.
|
||||||
|
#[inline]
|
||||||
pub const fn is_filled(&self) -> bool { !self.is_fluid() }
|
pub const fn is_filled(&self) -> bool { !self.is_fluid() }
|
||||||
|
|
||||||
|
/// Determine whether the block has an RGB color storaged in the attribute
|
||||||
|
/// fields.
|
||||||
|
#[inline]
|
||||||
|
pub const fn has_color(&self) -> bool { self.is_filled() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for BlockKind {
|
impl fmt::Display for BlockKind {
|
||||||
@ -76,7 +90,6 @@ impl<'a> TryFrom<&'a str> for BlockKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[repr(packed)]
|
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
kind: BlockKind,
|
kind: BlockKind,
|
||||||
attr: [u8; 3],
|
attr: [u8; 3],
|
||||||
@ -114,14 +127,23 @@ impl Block {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn air(sprite: SpriteKind) -> Self {
|
||||||
|
Self {
|
||||||
|
kind: BlockKind::Air,
|
||||||
|
attr: [sprite as u8, 0, 0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_color(&self) -> Option<Rgb<u8>> {
|
pub fn get_color(&self) -> Option<Rgb<u8>> {
|
||||||
if self.is_filled() {
|
if self.has_color() {
|
||||||
Some(self.attr.into())
|
Some(self.attr.into())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_sprite(&self) -> Option<SpriteKind> {
|
pub fn get_sprite(&self) -> Option<SpriteKind> {
|
||||||
if !self.is_filled() {
|
if !self.is_filled() {
|
||||||
SpriteKind::from_u8(self.attr[0])
|
SpriteKind::from_u8(self.attr[0])
|
||||||
@ -130,6 +152,7 @@ impl Block {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_ori(&self) -> Option<u8> {
|
pub fn get_ori(&self) -> Option<u8> {
|
||||||
if self.get_sprite()?.has_ori() {
|
if self.get_sprite()?.has_ori() {
|
||||||
// TODO: Formalise this a bit better
|
// TODO: Formalise this a bit better
|
||||||
@ -139,6 +162,7 @@ impl Block {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_glow(&self) -> Option<u8> {
|
pub fn get_glow(&self) -> Option<u8> {
|
||||||
// TODO: When we have proper volumetric lighting
|
// TODO: When we have proper volumetric lighting
|
||||||
// match self.get_sprite()? {
|
// match self.get_sprite()? {
|
||||||
@ -149,39 +173,46 @@ impl Block {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn is_solid(&self) -> bool {
|
pub fn is_solid(&self) -> bool {
|
||||||
self.get_sprite()
|
self.get_sprite()
|
||||||
.map(|s| s.solid_height().is_some())
|
.map(|s| s.solid_height().is_some())
|
||||||
.unwrap_or(true)
|
.unwrap_or(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn is_explodable(&self) -> bool {
|
pub fn is_explodable(&self) -> bool {
|
||||||
match self.kind() {
|
match self.kind() {
|
||||||
BlockKind::Leaves | BlockKind::Grass | BlockKind::WeakRock => true,
|
BlockKind::Leaves | BlockKind::Grass | BlockKind::WeakRock => true,
|
||||||
// Explodable means that the terrain sprite will get removed anyway, so is good for
|
// Explodable means that the terrain sprite will get removed anyway, so all is good for
|
||||||
// empty fluids TODO: Handle the case of terrain sprites we don't want to
|
// empty fluids.
|
||||||
// have explode
|
// TODO: Handle the case of terrain sprites we don't want to have explode
|
||||||
_ => true,
|
_ => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn is_collectible(&self) -> bool {
|
pub fn is_collectible(&self) -> bool {
|
||||||
self.get_sprite()
|
self.get_sprite()
|
||||||
.map(|s| s.is_collectible())
|
.map(|s| s.is_collectible())
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn is_opaque(&self) -> bool { self.kind().is_filled() }
|
pub fn is_opaque(&self) -> bool { self.kind().is_filled() }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn solid_height(&self) -> f32 {
|
pub fn solid_height(&self) -> f32 {
|
||||||
self.get_sprite()
|
self.get_sprite()
|
||||||
.map(|s| s.solid_height().unwrap_or(0.0))
|
.map(|s| s.solid_height().unwrap_or(0.0))
|
||||||
.unwrap_or(1.0)
|
.unwrap_or(1.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn kind(&self) -> BlockKind { self.kind }
|
pub fn kind(&self) -> BlockKind { self.kind }
|
||||||
|
|
||||||
/// If this block is a fluid, replace its sprite.
|
/// If this block is a fluid, replace its sprite.
|
||||||
|
#[inline]
|
||||||
pub fn with_sprite(mut self, sprite: SpriteKind) -> Self {
|
pub fn with_sprite(mut self, sprite: SpriteKind) -> Self {
|
||||||
if !self.is_filled() {
|
if !self.is_filled() {
|
||||||
self.attr[0] = sprite as u8;
|
self.attr[0] = sprite as u8;
|
||||||
@ -190,14 +221,18 @@ impl Block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// If this block can have orientation, give it a new orientation.
|
/// If this block can have orientation, give it a new orientation.
|
||||||
pub fn with_ori(mut self, ori: u8) -> Self {
|
#[inline]
|
||||||
|
pub fn with_ori(mut self, ori: u8) -> Option<Self> {
|
||||||
if self.get_sprite().map(|s| s.has_ori()).unwrap_or(false) {
|
if self.get_sprite().map(|s| s.has_ori()).unwrap_or(false) {
|
||||||
self.attr[1] = (self.attr[1] & !0b111) | (ori & 0b111);
|
self.attr[1] = (self.attr[1] & !0b111) | (ori & 0b111);
|
||||||
|
Some(self)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove the terrain sprite or solid aspects of a block
|
/// Remove the terrain sprite or solid aspects of a block
|
||||||
|
#[inline]
|
||||||
pub fn into_vacant(self) -> Self {
|
pub fn into_vacant(self) -> Self {
|
||||||
if self.is_fluid() {
|
if self.is_fluid() {
|
||||||
Block::new(self.kind(), Rgb::zero())
|
Block::new(self.kind(), Rgb::zero())
|
||||||
|
@ -14,7 +14,7 @@ use common::{
|
|||||||
sync::{Uid, UidAllocator, WorldSyncExt},
|
sync::{Uid, UidAllocator, WorldSyncExt},
|
||||||
sys::combat::BLOCK_ANGLE,
|
sys::combat::BLOCK_ANGLE,
|
||||||
terrain::{Block, TerrainGrid},
|
terrain::{Block, TerrainGrid},
|
||||||
vol::{ReadVol, Vox},
|
vol::ReadVol,
|
||||||
};
|
};
|
||||||
use comp::item::Reagent;
|
use comp::item::Reagent;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
@ -572,7 +572,7 @@ pub fn handle_explosion(
|
|||||||
.until(|block| block.is_liquid() || rand::random::<f32>() < 0.05)
|
.until(|block| block.is_liquid() || rand::random::<f32>() < 0.05)
|
||||||
.for_each(|block: &Block, pos| {
|
.for_each(|block: &Block, pos| {
|
||||||
if block.is_explodable() {
|
if block.is_explodable() {
|
||||||
block_change.set(pos, Block::empty());
|
block_change.set(pos, block.into_vacant());
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.cast();
|
.cast();
|
||||||
|
@ -506,23 +506,23 @@ pub fn block_from_structure(
|
|||||||
)),
|
)),
|
||||||
// None of these BlockKinds has an orientation, so we just use zero for the other color
|
// None of these BlockKinds has an orientation, so we just use zero for the other color
|
||||||
// bits.
|
// bits.
|
||||||
StructureBlock::Liana => Some(Block::empty().with_sprite(SpriteKind::Liana)),
|
StructureBlock::Liana => Some(Block::air(SpriteKind::Liana)),
|
||||||
StructureBlock::Fruit => Some(if field.get(pos + structure_pos) % 24 == 0 {
|
StructureBlock::Fruit => Some(if field.get(pos + structure_pos) % 24 == 0 {
|
||||||
Block::empty().with_sprite(SpriteKind::Beehive)
|
Block::air(SpriteKind::Beehive)
|
||||||
} else if field.get(pos + structure_pos + 1) % 3 == 0 {
|
} else if field.get(pos + structure_pos + 1) % 3 == 0 {
|
||||||
Block::empty().with_sprite(SpriteKind::Apple)
|
Block::air(SpriteKind::Apple)
|
||||||
} else {
|
} else {
|
||||||
Block::empty()
|
Block::empty()
|
||||||
}),
|
}),
|
||||||
StructureBlock::Coconut => Some(if field.get(pos + structure_pos) % 3 > 0 {
|
StructureBlock::Coconut => Some(if field.get(pos + structure_pos) % 3 > 0 {
|
||||||
Block::empty()
|
Block::empty()
|
||||||
} else {
|
} else {
|
||||||
Block::empty().with_sprite(SpriteKind::Coconut)
|
Block::air(SpriteKind::Coconut)
|
||||||
}),
|
}),
|
||||||
StructureBlock::Chest => Some(if structure_seed % 10 < 7 {
|
StructureBlock::Chest => Some(if structure_seed % 10 < 7 {
|
||||||
Block::empty()
|
Block::empty()
|
||||||
} else {
|
} else {
|
||||||
Block::empty().with_sprite(SpriteKind::Chest)
|
Block::air(SpriteKind::Chest)
|
||||||
}),
|
}),
|
||||||
// We interpolate all these BlockKinds as needed.
|
// We interpolate all these BlockKinds as needed.
|
||||||
StructureBlock::TemperateLeaves
|
StructureBlock::TemperateLeaves
|
||||||
|
@ -593,7 +593,7 @@ impl Floor {
|
|||||||
|
|
||||||
let floor_sprite = if RandomField::new(7331).chance(Vec3::from(pos), 0.00005) {
|
let floor_sprite = if RandomField::new(7331).chance(Vec3::from(pos), 0.00005) {
|
||||||
BlockMask::new(
|
BlockMask::new(
|
||||||
Block::empty().with_sprite(
|
Block::air(
|
||||||
match (RandomField::new(1337).get(Vec3::from(pos)) / 2) % 20 {
|
match (RandomField::new(1337).get(Vec3::from(pos)) / 2) % 20 {
|
||||||
0 => SpriteKind::Apple,
|
0 => SpriteKind::Apple,
|
||||||
1 => SpriteKind::VeloriteFrag,
|
1 => SpriteKind::VeloriteFrag,
|
||||||
@ -609,7 +609,7 @@ impl Floor {
|
|||||||
{
|
{
|
||||||
let room = &self.rooms[*room];
|
let room = &self.rooms[*room];
|
||||||
if RandomField::new(room.seed).chance(Vec3::from(pos), room.loot_density * 0.5) {
|
if RandomField::new(room.seed).chance(Vec3::from(pos), room.loot_density * 0.5) {
|
||||||
BlockMask::new(Block::empty().with_sprite(SpriteKind::Chest), 1)
|
BlockMask::new(Block::air(SpriteKind::Chest), 1)
|
||||||
} else {
|
} else {
|
||||||
empty
|
empty
|
||||||
}
|
}
|
||||||
|
@ -296,16 +296,15 @@ impl Archetype for House {
|
|||||||
let empty = BlockMask::nothing();
|
let empty = BlockMask::nothing();
|
||||||
let internal = BlockMask::new(Block::empty(), internal_layer);
|
let internal = BlockMask::new(Block::empty(), internal_layer);
|
||||||
let end_window = BlockMask::new(
|
let end_window = BlockMask::new(
|
||||||
Block::empty().with_sprite(attr.window).with_ori(match ori {
|
Block::air(attr.window)
|
||||||
Ori::East => 2,
|
.with_ori(match ori {
|
||||||
Ori::North => 0,
|
Ori::East => 2,
|
||||||
}),
|
Ori::North => 0,
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
structural_layer,
|
structural_layer,
|
||||||
);
|
);
|
||||||
let fire = BlockMask::new(
|
let fire = BlockMask::new(Block::air(SpriteKind::Ember), foundation_layer);
|
||||||
Block::empty().with_sprite(SpriteKind::Ember),
|
|
||||||
foundation_layer,
|
|
||||||
);
|
|
||||||
|
|
||||||
let storey_height = 6;
|
let storey_height = 6;
|
||||||
let storey = ((z - 1) / storey_height).min(attr.levels - 1);
|
let storey = ((z - 1) / storey_height).min(attr.levels - 1);
|
||||||
@ -436,16 +435,18 @@ impl Archetype for House {
|
|||||||
// Doors on first floor only
|
// Doors on first floor only
|
||||||
if profile.y == foundation_height + 1 {
|
if profile.y == foundation_height + 1 {
|
||||||
BlockMask::new(
|
BlockMask::new(
|
||||||
Block::empty().with_sprite(SpriteKind::Door).with_ori(
|
Block::air(SpriteKind::Door)
|
||||||
match ori {
|
.with_ori(
|
||||||
Ori::East => 2,
|
match ori {
|
||||||
Ori::North => 0,
|
Ori::East => 2,
|
||||||
} + if bound_offset.x == (width - 1) / 2 {
|
Ori::North => 0,
|
||||||
0
|
} + if bound_offset.x == (width - 1) / 2 {
|
||||||
} else {
|
0
|
||||||
4
|
} else {
|
||||||
},
|
4
|
||||||
),
|
},
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
structural_layer,
|
structural_layer,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@ -558,7 +559,7 @@ impl Archetype for House {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return Some(BlockMask::new(
|
return Some(BlockMask::new(
|
||||||
Block::empty().with_sprite(furniture).with_ori(edge_ori),
|
Block::air(furniture).with_ori(edge_ori).unwrap(),
|
||||||
internal_layer,
|
internal_layer,
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
@ -587,9 +588,7 @@ impl Archetype for House {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Some(BlockMask::new(
|
Some(BlockMask::new(
|
||||||
Block::empty()
|
Block::air(ornament).with_ori((edge_ori + 4) % 8).unwrap(),
|
||||||
.with_sprite(ornament)
|
|
||||||
.with_ori((edge_ori + 4) % 8),
|
|
||||||
internal_layer,
|
internal_layer,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
|
@ -150,12 +150,12 @@ impl Archetype for Keep {
|
|||||||
stone_color.2 + brick_tex,
|
stone_color.2 + brick_tex,
|
||||||
);
|
);
|
||||||
let window = BlockMask::new(
|
let window = BlockMask::new(
|
||||||
Block::empty()
|
Block::air(SpriteKind::Window1)
|
||||||
.with_sprite(SpriteKind::Window1)
|
|
||||||
.with_ori(match ori {
|
.with_ori(match ori {
|
||||||
Ori::East => 2,
|
Ori::East => 2,
|
||||||
Ori::North => 0,
|
Ori::North => 0,
|
||||||
}),
|
})
|
||||||
|
.unwrap(),
|
||||||
normal_layer,
|
normal_layer,
|
||||||
);
|
);
|
||||||
let floor = make_block(
|
let floor = make_block(
|
||||||
|
Loading…
Reference in New Issue
Block a user