Server authority

This commit is contained in:
2026-09-24 19:34:07 -03:00
parent 1bef94ce0c
commit 79faa556de
75 changed files with 2247 additions and 1632 deletions
+119
View File
@@ -0,0 +1,119 @@
import { add_player_hotbar, add_player_inventory, GuiInventoryScreen, Slot } from "./gui_screen.ts";
import { canvas, draw_rect, draw_texture_region, Texture } from "$/client/renderer/mod.ts";
import { AssetManager } from "../assets.ts";
import { SLOT_SIZE, TEXTURE_SIZE } from "$/common/constants.ts";
import { ClientMessage, ScreenLayout } from "$/common/protocol.ts";
import { draw_nine_slice } from "../systems/rendering/render_utils.ts";
import { get_sprite_region } from "$/client/sprites.ts";
import { ClientInventories } from "../inventory.ts";
const PADDING = 10;
// a screen opened by the server (chest, furnace, ...), drawn from the layout it sent
export class GuiContainer extends GuiInventoryScreen {
layout: ScreenLayout;
properties: Record<string, number>;
constructor(
inventories: ClientInventories,
send: (message: ClientMessage) => void,
layout: ScreenLayout,
properties: Record<string, number>,
) {
super(inventories, send);
this.layout = layout;
this.properties = properties;
this.inventory_width = PADDING * 2 + SLOT_SIZE * 9;
this.inventory_height = PADDING * 4 + SLOT_SIZE * (4 + layout.rows);
add_player_hotbar(this, PADDING, PADDING);
add_player_inventory(this, PADDING, PADDING * 2 + SLOT_SIZE);
const area_y = PADDING * 3 + SLOT_SIZE * 4;
for (const slot of layout.slots) {
this.slots.push(
new Slot("screen", slot.index, PADDING + slot.x * SLOT_SIZE, area_y + slot.y * SLOT_SIZE, slot.output),
);
}
}
override on_render(): void {
draw_rect(0, 0, canvas.width, canvas.height, [0, 0, 0, 0.8]);
const ui = AssetManager.instance.get<Texture>("bworld:ui");
draw_nine_slice(
ui,
160,
0,
16,
16,
4,
4,
4,
4,
this.x,
this.y,
this.inventory_width,
this.inventory_height,
);
this.draw_bars();
super.on_render();
}
draw_bars() {
const atlas = AssetManager.instance.get<Texture>("bworld:textures");
const area_y = PADDING * 3 + SLOT_SIZE * 4;
for (const bar of this.layout.bars) {
const x = this.x + PADDING + bar.x * SLOT_SIZE;
const y = this.y + area_y + bar.y * SLOT_SIZE;
const max = this.properties[bar.max] ?? 0;
const pct = max > 0 ? Math.max(0, Math.min(1, (this.properties[bar.value] ?? 0) / max)) : 0;
const empty = get_sprite_region(bar.empty_texture);
draw_texture_region(
atlas,
empty.x * TEXTURE_SIZE,
empty.y * TEXTURE_SIZE,
TEXTURE_SIZE,
TEXTURE_SIZE,
x,
y,
SLOT_SIZE,
SLOT_SIZE,
);
const full = get_sprite_region(bar.full_texture);
if (bar.direction === "right") {
draw_texture_region(
atlas,
full.x * TEXTURE_SIZE,
full.y * TEXTURE_SIZE,
TEXTURE_SIZE * pct,
TEXTURE_SIZE,
x,
y,
SLOT_SIZE * pct,
SLOT_SIZE,
);
} else {
// fills from the bottom up
draw_texture_region(
atlas,
full.x * TEXTURE_SIZE,
full.y * TEXTURE_SIZE + TEXTURE_SIZE * (1 - pct),
TEXTURE_SIZE,
TEXTURE_SIZE * pct,
x,
y + SLOT_SIZE * (1 - pct),
SLOT_SIZE,
SLOT_SIZE * pct,
);
}
}
}
}