less than half finished block states
This commit is contained in:
@@ -10,6 +10,9 @@ const block = EverythingRegistry.register<BlockRegistry>("blocks", "bworld:hoed_
|
|||||||
toughness: 5,
|
toughness: 5,
|
||||||
requires_tool: false,
|
requires_tool: false,
|
||||||
tool_to_break: "shovel",
|
tool_to_break: "shovel",
|
||||||
|
states: [
|
||||||
|
{ name: "watered", bits: 1, default: 0 },
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
register_block_item(block);
|
register_block_item(block);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Component } from "$/common/ecs/mod.ts";
|
import { Component } from "$/common/ecs/mod.ts";
|
||||||
import { BlockRegistry, EverythingRegistry } from "$/common/everything_registry.ts";
|
import { BlockRegistry, EverythingRegistry } from "$/common/everything_registry.ts";
|
||||||
import { Faces } from "../../common/constants.ts";
|
import { AIR, Faces, ID_MASK, VOID } from "../../common/constants.ts";
|
||||||
import { AssetManager } from "../assets.ts";
|
import { AssetManager } from "../assets.ts";
|
||||||
import { ClientWorld } from "../client_world.ts";
|
import { ClientWorld } from "../client_world.ts";
|
||||||
import { generate_chunk } from "../generation.ts";
|
import { generate_chunk } from "../generation.ts";
|
||||||
@@ -31,7 +31,7 @@ export const CHUNK_AREA = CHUNK_SIZE * CHUNK_SIZE;
|
|||||||
export interface Chunk {
|
export interface Chunk {
|
||||||
x: number;
|
x: number;
|
||||||
z: number;
|
z: number;
|
||||||
blocks: Int16Array;
|
blocks: Uint32Array;
|
||||||
blocks_data: BlockData[];
|
blocks_data: BlockData[];
|
||||||
generated: boolean;
|
generated: boolean;
|
||||||
dirty: boolean;
|
dirty: boolean;
|
||||||
@@ -57,7 +57,7 @@ export class Dimension extends Component {
|
|||||||
const chunk = {
|
const chunk = {
|
||||||
x,
|
x,
|
||||||
z,
|
z,
|
||||||
blocks: new Int16Array(CHUNK_AREA * CHUNK_HEIGHT),
|
blocks: new Uint32Array(CHUNK_AREA * CHUNK_HEIGHT),
|
||||||
blocks_data: [],
|
blocks_data: [],
|
||||||
dirty: true,
|
dirty: true,
|
||||||
generated: false,
|
generated: false,
|
||||||
@@ -100,7 +100,7 @@ export class Dimension extends Component {
|
|||||||
const chunk = this.get_chunk(chunk_x, chunk_z);
|
const chunk = this.get_chunk(chunk_x, chunk_z);
|
||||||
|
|
||||||
if (!chunk) {
|
if (!chunk) {
|
||||||
return -1;
|
return VOID;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lx = x - chunk_x * CHUNK_SIZE;
|
const lx = x - chunk_x * CHUNK_SIZE;
|
||||||
@@ -109,7 +109,7 @@ export class Dimension extends Component {
|
|||||||
|
|
||||||
const index = ly * CHUNK_SIZE * CHUNK_SIZE + lz * CHUNK_SIZE + lx;
|
const index = ly * CHUNK_SIZE * CHUNK_SIZE + lz * CHUNK_SIZE + lx;
|
||||||
|
|
||||||
return chunk.blocks[index];
|
return chunk.blocks[index] & ID_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_block_data(block_data: BlockData) {
|
add_block_data(block_data: BlockData) {
|
||||||
@@ -159,7 +159,7 @@ export class Dimension extends Component {
|
|||||||
const ly = y;
|
const ly = y;
|
||||||
|
|
||||||
const index = ly * CHUNK_SIZE * CHUNK_SIZE + lz * CHUNK_SIZE + lx;
|
const index = ly * CHUNK_SIZE * CHUNK_SIZE + lz * CHUNK_SIZE + lx;
|
||||||
chunk.blocks[index] = 0;
|
chunk.blocks[index] = AIR;
|
||||||
chunk.dirty = true;
|
chunk.dirty = true;
|
||||||
|
|
||||||
if (lx === 0) {
|
if (lx === 0) {
|
||||||
@@ -283,7 +283,7 @@ export class Dimension extends Component {
|
|||||||
|
|
||||||
const block = dimension.get_block(bx, by, bz);
|
const block = dimension.get_block(bx, by, bz);
|
||||||
|
|
||||||
if (block && block !== 0 && block !== -1) {
|
if (block && block !== AIR && block !== VOID) {
|
||||||
let face: Faces;
|
let face: Faces;
|
||||||
|
|
||||||
if (bx > prev_bx) {
|
if (bx > prev_bx) {
|
||||||
@@ -316,7 +316,7 @@ export class Dimension extends Component {
|
|||||||
const cz = chunk.z;
|
const cz = chunk.z;
|
||||||
|
|
||||||
const size = CHUNK_SIZE + 2;
|
const size = CHUNK_SIZE + 2;
|
||||||
const padded = new Int16Array(size * size * CHUNK_HEIGHT);
|
const padded = new Uint32Array(size * size * CHUNK_HEIGHT);
|
||||||
|
|
||||||
for (let y = 0; y < CHUNK_HEIGHT; y++) {
|
for (let y = 0; y < CHUNK_HEIGHT; y++) {
|
||||||
for (let z = -1; z <= CHUNK_SIZE; z++) {
|
for (let z = -1; z <= CHUNK_SIZE; z++) {
|
||||||
@@ -325,11 +325,11 @@ export class Dimension extends Component {
|
|||||||
|
|
||||||
if (x >= 0 && x < CHUNK_SIZE && z >= 0 && z < CHUNK_SIZE) {
|
if (x >= 0 && x < CHUNK_SIZE && z >= 0 && z < CHUNK_SIZE) {
|
||||||
const index = y * CHUNK_SIZE * CHUNK_SIZE + z * CHUNK_SIZE + x;
|
const index = y * CHUNK_SIZE * CHUNK_SIZE + z * CHUNK_SIZE + x;
|
||||||
block = chunk.blocks[index];
|
block = chunk.blocks[index] & ID_MASK;
|
||||||
} else {
|
} else {
|
||||||
const wx = cx * CHUNK_SIZE + x;
|
const wx = cx * CHUNK_SIZE + x;
|
||||||
const wz = cz * CHUNK_SIZE + z;
|
const wz = cz * CHUNK_SIZE + z;
|
||||||
block = this.get_block(wx, y, wz) ?? 0;
|
block = this.get_block(wx, y, wz) ?? AIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
const px = x + 1;
|
const px = x + 1;
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ self.onmessage = (event) => {
|
|||||||
function make_chunk_mesh(
|
function make_chunk_mesh(
|
||||||
chunk_x: number,
|
chunk_x: number,
|
||||||
chunk_z: number,
|
chunk_z: number,
|
||||||
padded_chunk: Int16Array,
|
padded_chunk: Uint32Array,
|
||||||
blocks_registry: BlockRegistry[],
|
blocks_registry: BlockRegistry[],
|
||||||
textures_info: TexturesInfo,
|
textures_info: TexturesInfo,
|
||||||
image: Texture,
|
image: Texture,
|
||||||
|
|||||||
@@ -12,3 +12,9 @@ export interface SpriteRegion {
|
|||||||
|
|
||||||
export const faces = ["west", "east", "bottom", "top", "north", "south"] as const;
|
export const faces = ["west", "east", "bottom", "top", "north", "south"] as const;
|
||||||
export type Faces = typeof faces[number];
|
export type Faces = typeof faces[number];
|
||||||
|
|
||||||
|
export const AIR = 0;
|
||||||
|
export const VOID = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
export const ID_MASK = 0xFFFF;
|
||||||
|
export const STATE_SHIFT = 16;
|
||||||
|
|||||||
@@ -62,6 +62,23 @@ interface TextureFront {
|
|||||||
side: string;
|
side: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface BlockStateDefinition {
|
||||||
|
name: string;
|
||||||
|
bits: number;
|
||||||
|
default: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CompiledStateDefinition {
|
||||||
|
name: string;
|
||||||
|
mask: number;
|
||||||
|
shift: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BlockStateVariant {
|
||||||
|
model: string;
|
||||||
|
y: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface BlockRegistry {
|
export interface BlockRegistry {
|
||||||
id: string;
|
id: string;
|
||||||
textures: string | TextureSideTopBottom | TextureFront;
|
textures: string | TextureSideTopBottom | TextureFront;
|
||||||
@@ -74,12 +91,17 @@ export interface BlockRegistry {
|
|||||||
tool_to_break?: string;
|
tool_to_break?: string;
|
||||||
drop_table?: string;
|
drop_table?: string;
|
||||||
|
|
||||||
|
states?: BlockStateDefinition[];
|
||||||
|
variants?: Record<string, BlockStateVariant>;
|
||||||
|
|
||||||
on_create?(dimension: Dimension, block: Block): void;
|
on_create?(dimension: Dimension, block: Block): void;
|
||||||
on_break?(dimension: Dimension, block: Block): void;
|
on_break?(dimension: Dimension, block: Block): void;
|
||||||
on_click?(dimension: Dimension, block: Block): void;
|
on_click?(dimension: Dimension, block: Block): void;
|
||||||
on_interact?(dimension: Dimension, block: Block): boolean;
|
on_interact?(dimension: Dimension, block: Block): boolean;
|
||||||
on_tick?(dimension: Dimension, block: Block, tick_delta: number): void;
|
on_tick?(dimension: Dimension, block: Block, tick_delta: number): void;
|
||||||
on_second?(dimension: Dimension, block: Block, second_delta: number): void;
|
on_second?(dimension: Dimension, block: Block, second_delta: number): void;
|
||||||
|
|
||||||
|
compiled_states?: CompiledStateDefinition[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ItemRegistry<T = unknown | undefined> {
|
export interface ItemRegistry<T = unknown | undefined> {
|
||||||
|
|||||||
+51
-1
@@ -1,5 +1,5 @@
|
|||||||
import { AssetManager } from "../client/assets.ts";
|
import { AssetManager } from "../client/assets.ts";
|
||||||
import { SpriteRegion } from "./constants.ts";
|
import { ID_MASK, SpriteRegion, STATE_SHIFT } from "./constants.ts";
|
||||||
import { BlockRegistry, EverythingRegistry, ItemRegistry } from "./everything_registry.ts";
|
import { BlockRegistry, EverythingRegistry, ItemRegistry } from "./everything_registry.ts";
|
||||||
|
|
||||||
export function point_inside_rec(
|
export function point_inside_rec(
|
||||||
@@ -56,3 +56,53 @@ export function register_block_item(block: BlockRegistry) {
|
|||||||
block_id: block.id,
|
block_id: block.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function get_state_value(value: number, block_info: BlockRegistry, name: string) {
|
||||||
|
if (!block_info.states) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!block_info.compiled_states) {
|
||||||
|
compile_block_states(block_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
const state_bits = value >>> STATE_SHIFT;
|
||||||
|
|
||||||
|
const s = block_info.compiled_states!.find((s) => s.name === name)!;
|
||||||
|
return (state_bits & s.mask) >>> s.shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function set_state_value(value: number, block_info: BlockRegistry, name: string, new_value: number) {
|
||||||
|
if (!block_info.states) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!block_info.compiled_states) {
|
||||||
|
compile_block_states(block_info);
|
||||||
|
}
|
||||||
|
const id = value & ID_MASK;
|
||||||
|
let state_bits = value >>> 16;
|
||||||
|
|
||||||
|
const s = block_info.compiled_states!.find((s) => s.name === name)!;
|
||||||
|
|
||||||
|
state_bits = (state_bits & ~s.mask) | (new_value << s.shift);
|
||||||
|
|
||||||
|
return (state_bits << 16) | id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function compile_block_states(block_info: BlockRegistry) {
|
||||||
|
if (!block_info.states) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let offset = 0;
|
||||||
|
|
||||||
|
block_info.compiled_states = block_info.states.map((s) => {
|
||||||
|
const shift = offset;
|
||||||
|
const mask = ((1 << s.bits) - 1) << shift;
|
||||||
|
|
||||||
|
offset += s.bits;
|
||||||
|
|
||||||
|
return { name: s.name, mask, shift };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user