feat(core): add block type enum and per-block properties
This commit is contained in:
1 parent
e1d76bdc42
commit
e0f48fad20
1 file changed
+307
@@ -0,0 +1,307 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace vf {
|
||||
|
||||
enum class Block : uint8_t {
|
||||
Air = 0,
|
||||
Grass = 1,
|
||||
Dirt = 2,
|
||||
Stone = 3,
|
||||
Sand = 4,
|
||||
Wood = 5,
|
||||
Leaves = 6,
|
||||
Water = 7,
|
||||
Snow = 8,
|
||||
CoalOre = 9,
|
||||
IronOre = 10,
|
||||
GoldOre = 11,
|
||||
Gravel = 12,
|
||||
Glowstone = 13,
|
||||
// --- extended palette (wave 1, additive; values above are frozen) ---
|
||||
Cobblestone = 14,
|
||||
Planks = 15,
|
||||
Sandstone = 16,
|
||||
Ice = 17,
|
||||
Bedrock = 18,
|
||||
Obsidian = 19,
|
||||
Lava = 20,
|
||||
DiamondOre = 21,
|
||||
RedstoneOre = 22,
|
||||
EmeraldOre = 23,
|
||||
LapisOre = 24,
|
||||
CraftingTable = 25,
|
||||
Furnace = 26,
|
||||
FurnaceLit = 27,
|
||||
Chest = 28,
|
||||
Torch = 29,
|
||||
RedstoneWire = 30,
|
||||
RedstoneTorch = 31,
|
||||
RedstoneLamp = 32,
|
||||
RedstoneLampLit = 33,
|
||||
Lever = 34,
|
||||
Button = 35,
|
||||
RedstoneBlock = 36,
|
||||
Repeater = 37,
|
||||
Comparator = 38,
|
||||
Piston = 39,
|
||||
PistonSticky = 40,
|
||||
PistonHead = 41,
|
||||
Tnt = 42,
|
||||
Ladder = 43,
|
||||
// --- extended palette (wave 2, additive; values above are frozen) ---
|
||||
// Automation & logistics (agent A).
|
||||
Rail = 44,
|
||||
PoweredRail = 45,
|
||||
DetectorRail = 46,
|
||||
ActivatorRail = 47,
|
||||
Hopper = 48,
|
||||
Dropper = 49,
|
||||
Dispenser = 50,
|
||||
Observer = 51,
|
||||
TargetBlock = 52,
|
||||
SlimeBlock = 53,
|
||||
NoteBlock = 54,
|
||||
// Environment, farming & climate (agent B).
|
||||
Farmland = 55,
|
||||
Wheat = 56,
|
||||
Carrot = 57,
|
||||
Potato = 58,
|
||||
Pumpkin = 59,
|
||||
Melon = 60,
|
||||
PumpkinStem = 61,
|
||||
MelonStem = 62,
|
||||
SugarCane = 63,
|
||||
Cactus = 64,
|
||||
Sapling = 65,
|
||||
Vine = 66,
|
||||
SnowLayer = 67,
|
||||
PackedIce = 68,
|
||||
Count
|
||||
};
|
||||
|
||||
enum class Face : uint8_t {
|
||||
PosX = 0,
|
||||
NegX = 1,
|
||||
PosY = 2,
|
||||
NegY = 3,
|
||||
PosZ = 4,
|
||||
NegZ = 5,
|
||||
};
|
||||
|
||||
inline bool isAir(Block b) { return b == Block::Air; }
|
||||
|
||||
// Non-solid blocks are walked through: fluids and thin redstone/utility parts.
|
||||
inline bool isSolid(Block b) {
|
||||
switch (b) {
|
||||
case Block::Air:
|
||||
case Block::Water:
|
||||
case Block::Lava:
|
||||
case Block::Torch:
|
||||
case Block::RedstoneTorch:
|
||||
case Block::RedstoneWire:
|
||||
case Block::Lever:
|
||||
case Block::Button:
|
||||
case Block::Repeater:
|
||||
case Block::Comparator:
|
||||
case Block::Ladder:
|
||||
case Block::Rail:
|
||||
case Block::PoweredRail:
|
||||
case Block::DetectorRail:
|
||||
case Block::ActivatorRail:
|
||||
case Block::Wheat:
|
||||
case Block::Carrot:
|
||||
case Block::Potato:
|
||||
case Block::PumpkinStem:
|
||||
case Block::MelonStem:
|
||||
case Block::SugarCane:
|
||||
case Block::Sapling:
|
||||
case Block::Vine:
|
||||
case Block::SnowLayer:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Opaque blocks fully hide the neighbouring face. Leaves, fluids, ice and the
|
||||
// thin redstone/utility blocks do not.
|
||||
inline bool isOpaque(Block b) {
|
||||
switch (b) {
|
||||
case Block::Air:
|
||||
case Block::Leaves:
|
||||
case Block::Water:
|
||||
case Block::Ice:
|
||||
case Block::Torch:
|
||||
case Block::RedstoneWire:
|
||||
case Block::RedstoneTorch:
|
||||
case Block::Lever:
|
||||
case Block::Button:
|
||||
case Block::Repeater:
|
||||
case Block::Comparator:
|
||||
case Block::Ladder:
|
||||
case Block::Rail:
|
||||
case Block::PoweredRail:
|
||||
case Block::DetectorRail:
|
||||
case Block::ActivatorRail:
|
||||
case Block::Hopper:
|
||||
case Block::Cactus:
|
||||
case Block::Wheat:
|
||||
case Block::Carrot:
|
||||
case Block::Potato:
|
||||
case Block::PumpkinStem:
|
||||
case Block::MelonStem:
|
||||
case Block::SugarCane:
|
||||
case Block::Sapling:
|
||||
case Block::Vine:
|
||||
case Block::SnowLayer:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Whether a face of `self` should be emitted given the neighbour `other`.
|
||||
// A face is visible when the neighbour does not opaquely cover it, and the
|
||||
// two blocks are not the same translucent type (so water/leaves/ice do not
|
||||
// draw internal seams against their own kind).
|
||||
inline bool faceVisible(Block self, Block other) {
|
||||
if (isAir(self)) return false;
|
||||
if (isOpaque(other)) return false;
|
||||
if (self == other) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Texture-array layer for a given block face. Sided blocks vary by face.
|
||||
inline int faceTile(Block block, Face face) {
|
||||
switch (block) {
|
||||
case Block::Grass:
|
||||
if (face == Face::PosY) return 0; // grass top
|
||||
if (face == Face::NegY) return 2; // dirt bottom
|
||||
return 1; // grass side
|
||||
case Block::Dirt: return 2;
|
||||
case Block::Stone: return 3;
|
||||
case Block::Sand: return 4;
|
||||
case Block::Wood:
|
||||
if (face == Face::PosY || face == Face::NegY) return 6; // rings
|
||||
return 5; // bark
|
||||
case Block::Leaves: return 7;
|
||||
case Block::Water: return 8;
|
||||
case Block::Snow: return 9;
|
||||
case Block::CoalOre: return 10;
|
||||
case Block::IronOre: return 11;
|
||||
case Block::GoldOre: return 12;
|
||||
case Block::Gravel: return 13;
|
||||
case Block::Glowstone: return 14;
|
||||
case Block::Cobblestone: return 15;
|
||||
case Block::Planks: return 16;
|
||||
case Block::Sandstone:
|
||||
if (face == Face::PosY || face == Face::NegY) return 17; // top/bottom
|
||||
return 18; // side
|
||||
case Block::Ice: return 19;
|
||||
case Block::Bedrock: return 20;
|
||||
case Block::Obsidian: return 21;
|
||||
case Block::Lava: return 22;
|
||||
case Block::DiamondOre: return 23;
|
||||
case Block::RedstoneOre: return 24;
|
||||
case Block::EmeraldOre: return 25;
|
||||
case Block::LapisOre: return 26;
|
||||
case Block::CraftingTable:
|
||||
if (face == Face::PosY) return 27; // grid top
|
||||
if (face == Face::NegY) return 16; // planks bottom
|
||||
return 28; // tools side
|
||||
case Block::Furnace:
|
||||
if (face == Face::PosZ) return 29; // cold front
|
||||
if (face == Face::PosY || face == Face::NegY) return 30;
|
||||
return 30; // side
|
||||
case Block::FurnaceLit:
|
||||
if (face == Face::PosZ) return 31; // burning front
|
||||
return 30;
|
||||
case Block::Chest: return 32;
|
||||
case Block::Torch: return 33;
|
||||
case Block::RedstoneWire: return 34;
|
||||
case Block::RedstoneTorch: return 35;
|
||||
case Block::RedstoneLamp: return 36;
|
||||
case Block::RedstoneLampLit: return 37;
|
||||
case Block::Lever: return 38;
|
||||
case Block::Button: return 39;
|
||||
case Block::RedstoneBlock: return 40;
|
||||
case Block::Repeater: return 41;
|
||||
case Block::Comparator: return 42;
|
||||
case Block::Piston:
|
||||
if (face == Face::PosZ) return 43; // face plate
|
||||
if (face == Face::NegZ) return 45; // back
|
||||
return 44; // side
|
||||
case Block::PistonSticky:
|
||||
if (face == Face::PosZ) return 46; // sticky face
|
||||
if (face == Face::NegZ) return 45;
|
||||
return 44;
|
||||
case Block::PistonHead: return 47;
|
||||
case Block::Tnt:
|
||||
if (face == Face::PosY || face == Face::NegY) return 48; // caps
|
||||
return 49; // fuse band
|
||||
case Block::Ladder: return 50;
|
||||
case Block::Rail: return 51;
|
||||
case Block::PoweredRail: return 52;
|
||||
case Block::DetectorRail: return 53;
|
||||
case Block::ActivatorRail: return 54;
|
||||
case Block::Hopper: return 55;
|
||||
case Block::Dropper: return 56;
|
||||
case Block::Dispenser: return 57;
|
||||
case Block::Observer: return 58;
|
||||
case Block::TargetBlock: return 59;
|
||||
case Block::SlimeBlock: return 60;
|
||||
case Block::NoteBlock: return 61;
|
||||
case Block::Farmland:
|
||||
if (face == Face::PosY) return 62; // tilled top
|
||||
return 2; // dirt sides/bottom
|
||||
case Block::Wheat: return 63;
|
||||
case Block::Carrot: return 64;
|
||||
case Block::Potato: return 65;
|
||||
case Block::Pumpkin:
|
||||
if (face == Face::PosY || face == Face::NegY) return 66;
|
||||
return 67;
|
||||
case Block::Melon:
|
||||
if (face == Face::PosY || face == Face::NegY) return 68;
|
||||
return 69;
|
||||
case Block::PumpkinStem: return 70;
|
||||
case Block::MelonStem: return 71;
|
||||
case Block::SugarCane: return 72;
|
||||
case Block::Cactus:
|
||||
if (face == Face::PosY) return 73;
|
||||
if (face == Face::NegY) return 74;
|
||||
return 75;
|
||||
case Block::Sapling: return 76;
|
||||
case Block::Vine: return 77;
|
||||
case Block::SnowLayer: return 78;
|
||||
case Block::PackedIce: return 79;
|
||||
default: return 3;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr int tileCount = 80;
|
||||
|
||||
// Block light emitted by a block itself, 0..15.
|
||||
inline int blockLightEmission(Block b) {
|
||||
switch (b) {
|
||||
case Block::Glowstone: return 15;
|
||||
case Block::Lava: return 15;
|
||||
case Block::RedstoneLampLit: return 15;
|
||||
case Block::Torch: return 14;
|
||||
case Block::FurnaceLit: return 13;
|
||||
case Block::RedstoneTorch: return 7;
|
||||
case Block::RedstoneOre: return 0; // lit only on touch, handled by gameplay
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// A block that ambient-occludes its neighbours and blocks light propagation.
|
||||
inline bool occludesLight(Block b) { return isOpaque(b); }
|
||||
|
||||
// Meshed in the transparent pass (depth write off, back-to-front): fluids + ice.
|
||||
inline bool isTransparent(Block b) {
|
||||
return b == Block::Water || b == Block::Ice;
|
||||
}
|
||||
|
||||
} // namespace vf
|
||||
Reference in new issue
Block a user