Remove collision from water

This commit is contained in:
2026-09-25 17:21:46 -03:00
parent d07528bd0e
commit 05f80c81ad
9 changed files with 26 additions and 7 deletions
+1 -2
View File
@@ -1,4 +1,3 @@
import { AIR } from "$/common/constants.ts";
import { move_body } from "$/common/physics.ts";
import type { ClientLevel } from "../level/client_level.ts";
@@ -73,7 +72,7 @@ export abstract class Entity {
// falls and moves by its velocity for one tick, see move_body
move() {
const collisions = move_body(this, this.gravity, (x, y, z) => this.level.get_block(x, y, z) !== AIR);
const collisions = move_body(this, this.gravity, (x, y, z) => this.level.has_collision(x, y, z));
this.colliding_x = collisions.x;
this.colliding_y = collisions.y;
this.colliding_z = collisions.z;
+6
View File
@@ -254,6 +254,12 @@ export class ClientLevel {
return chunk.blocks[index] & ID_MASK;
}
// whether entities bump into the block there. unloaded chunks count as solid, so nothing falls out of the world
has_collision(x: number, y: number, z: number) {
const block = this.get_block(x, y, z);
return block === VOID || (block !== AIR && (this.#blocks[block]?.has_collision ?? true));
}
// only changes what this client shows, drops and everything else happen on the server
break_block(x: number, y: number, z: number) {
const block_chunk_x = Math.floor(x / CHUNK_SIZE);
-1
View File
@@ -3,7 +3,6 @@
"block": {
"id": "bworld:chest",
"textures": "bworld:planks",
"collision": false,
"mining": {
"toughness": 8,
"tool": "axe"
-1
View File
@@ -3,7 +3,6 @@
"block": {
"id": "bworld:dirt",
"textures": "bworld:dirt",
"collision": false,
"mining": {
"toughness": 2,
"tool": "shovel"
-1
View File
@@ -7,7 +7,6 @@
"bottom": "bworld:dirt",
"side": "bworld:grass_side"
},
"collision": false,
"mining": {
"toughness": 2,
"tool": "shovel"
-1
View File
@@ -7,7 +7,6 @@
"top": "bworld:hoed_dirt",
"bottom": "bworld:dirt"
},
"collision": false,
"mining": {
"toughness": 5,
"tool": "shovel"
+1 -1
View File
@@ -829,7 +829,7 @@ export class GameServer {
if (this.#entities.size === 0) {
return;
}
const is_solid = (x: number, y: number, z: number) => this.world.get_block_nid(x, y, z) !== AIR;
const is_solid = (x: number, y: number, z: number) => this.world.has_collision(x, y, z);
const active = [...this.#entities.values()].filter((entity) => this.#near_any_player(entity.x, entity.z));
for (const entity of active) {
+5
View File
@@ -113,6 +113,11 @@ export class ServerWorld {
return this.#get_chunk(chunk_x, chunk_z)[index_in_chunk(x, y, z, chunk_x, chunk_z)];
}
// whether entities bump into the block there, water and other blocks with "collision": false don't
has_collision(x: number, y: number, z: number) {
return this.get_block_info(x, y, z)?.has_collision ?? false;
}
get_block_info(x: number, y: number, z: number): BlockRegistry | undefined {
const nid = this.get_block_nid(x, y, z);
return nid === AIR ? undefined : EverythingRegistry.get_by_id<BlockRegistry>("blocks", nid);
+13
View File
@@ -114,3 +114,16 @@ Deno.test("q throws one of an item the way the player looks, ctrl throws the who
send(1, { type: "drop_item", container: "crafting", index: 9, all: true });
assertEquals(game.item_entities().length, 2);
});
Deno.test("water has no collision, items sink through it to the floor", async () => {
const { game, join } = await test_game("mods");
join(1, "alice");
build_floor(game);
for (let y = 100; y <= 102; y++) {
game.set_block(6, y, 0, "bworld:water");
}
const item = game.spawn_item(6.5, 104, 0.5, new ItemStack("bworld:dirt"));
for (let i = 0; i < 40; i++) game.tick();
assert(item.on_ground);
assertEquals(item.y, 100, "on the stone under the water");
});