This commit is contained in:
2026-03-27 12:00:16 -03:00
parent 89b23582fa
commit a736b9c5c0
11 changed files with 211 additions and 52 deletions
+131
View File
@@ -0,0 +1,131 @@
import { GuiScreen } from "./gui_screen.ts";
import { canvas, draw_rect, draw_text, measure_text } from "$/client/renderer/mod.ts";
import { InputManager } from "../input_manager.ts";
import { ClientWorld } from "../client_world.ts";
import { PlayerComponent } from "../player.ts";
import { ItemStack } from "../inventory.ts";
export class GuiChat extends GuiScreen {
world: ClientWorld;
text_typed = "";
caret = 0;
key_repeat_timer = 0;
show_caret = true;
constructor(world: ClientWorld) {
super();
this.world = world;
}
override on_render(): void {
draw_rect(0, 0, canvas.width, canvas.height, [0, 0, 0, 0.8]);
const y = canvas.height - 32;
draw_rect(0, y, canvas.width, canvas.height, [0, 0, 0, 0.4]);
draw_text(this.text_typed, 0, y, 2, [1, 1, 1]);
if (this.show_caret) {
const before_text = this.text_typed.substring(0, this.caret);
const caret_x = 0 + measure_text(before_text, 2);
draw_rect(caret_x, y + 4, 1, 32 - 4);
}
}
override on_tick(_delta: number): void {
const now = performance.now();
const repeat_delay = 400;
const repeat_rate = 40;
const allow_repeat = () => {
if (InputManager.is_key_pressed("Backspace")) {
this.key_repeat_timer = now;
return true;
}
if (InputManager.is_key_down("Backspace")) {
if (now - this.key_repeat_timer > repeat_delay) {
this.key_repeat_timer = now - (repeat_delay - repeat_rate);
return true;
}
}
return false;
};
if (allow_repeat()) {
if (this.caret > 0) {
this.text_typed = this.text_typed.slice(0, this.caret - 1) + this.text_typed.slice(this.caret);
this.caret -= 1;
}
}
if (InputManager.is_key_pressed("Delete")) {
this.text_typed = this.text_typed.slice(0, this.caret) + this.text_typed.slice(this.caret + 1);
}
if (InputManager.is_key_pressed("ArrowLeft")) {
this.caret = Math.max(0, this.caret - 1);
}
if (InputManager.is_key_pressed("ArrowRight")) {
this.caret = Math.min(this.text_typed.length, this.caret + 1);
}
if (InputManager.is_key_pressed("Home")) {
this.caret = 0;
}
if (InputManager.is_key_pressed("End")) {
this.caret = this.text_typed.length;
}
const typed = InputManager.get_typed_characters();
for (const char of typed) {
this.text_typed = this.text_typed.slice(0, this.caret) + char + this.text_typed.slice(this.caret);
this.caret += 1;
}
if (InputManager.is_key_pressed("Enter")) {
this.submit();
}
}
override on_close(): void {}
submit() {
if (this.text_typed.startsWith("/")) {
this.command();
} else {
// we dont have multiplayer lol?
}
this.text_typed = "";
const [player] = this.world.get_tag("player")!;
const player_component = player.get(PlayerComponent);
if (player_component) {
player_component.pop_screen();
}
}
command() {
if (this.text_typed.startsWith("/give")) {
let [_, item_id, quantity] = this.text_typed.split(" ");
if (!item_id.includes(":")) {
item_id = `bworld:${item_id}`;
}
if (quantity === undefined) {
quantity = "1";
}
const [player] = this.world.get_tag("player")!;
const player_component = player.get(PlayerComponent);
if (player_component) {
player_component.player_inventory.container.add_item(new ItemStack(item_id, Number(quantity)));
}
}
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
import { Inventory, PlayerInventory } from "../inventory.ts";
import { add_player_hotbar, add_player_inventory, GuiScreen, Slot } from "./gui_screen.ts";
import { add_player_hotbar, add_player_inventory, GuiInventoryScreen, Slot } from "./gui_screen.ts";
import { canvas, draw_rect, Texture } from "$/client/renderer/mod.ts";
import { AssetManager } from "../assets.ts";
import { SLOT_SIZE } from "../../common/constants.ts";
@@ -7,7 +7,7 @@ import { draw_nine_slice } from "../systems/rendering/render_utils.ts";
const PADDING = 10;
export class GuiChest extends GuiScreen {
export class GuiChest extends GuiInventoryScreen {
override inventory_width = PADDING * 2 + SLOT_SIZE * 9;
override inventory_height = PADDING * 4 + SLOT_SIZE * 7;
+2 -2
View File
@@ -1,5 +1,5 @@
import { Inventory, PlayerInventory } from "../inventory.ts";
import { add_player_hotbar, add_player_inventory, GuiScreen, Slot } from "./gui_screen.ts";
import { add_player_hotbar, add_player_inventory, GuiInventoryScreen, Slot } from "./gui_screen.ts";
import { canvas, draw_rect, draw_text, Texture } from "$/client/renderer/mod.ts";
import { AssetManager } from "../assets.ts";
import { SLOT_SIZE } from "../../common/constants.ts";
@@ -7,7 +7,7 @@ import { draw_nine_slice } from "../systems/rendering/render_utils.ts";
const PADDING = 10;
export class GuiFurnace extends GuiScreen<Inventory, { fuel: number; progress: number }> {
export class GuiFurnace extends GuiInventoryScreen<Inventory, { fuel: number; progress: number }> {
override inventory_width = PADDING * 2 + SLOT_SIZE * 9;
override inventory_height = PADDING * 4 + SLOT_SIZE * 7;
+2 -2
View File
@@ -1,5 +1,5 @@
import { Container, Inventory, ItemStack, PlayerInventory } from "../inventory.ts";
import { add_player_hotbar, add_player_inventory, GuiScreen, Slot } from "./gui_screen.ts";
import { add_player_hotbar, add_player_inventory, GuiInventoryScreen, Slot } from "./gui_screen.ts";
import { canvas, draw_rect, Texture } from "$/client/renderer/mod.ts";
import { AssetManager } from "../assets.ts";
import { SLOT_SIZE } from "../../common/constants.ts";
@@ -33,7 +33,7 @@ const recipes: CraftingRecipe[] = [
const PADDING = 10;
export class GuiPlayerInventory extends GuiScreen {
export class GuiPlayerInventory extends GuiInventoryScreen {
override inventory_width = PADDING * 2 + SLOT_SIZE * 9;
override inventory_height = PADDING * 2 + SLOT_SIZE * 4 + PADDING + SLOT_SIZE * 3 + PADDING;
+14 -5
View File
@@ -25,14 +25,22 @@ export class Slot {
}
}
export class GuiScreen<Inv extends Inventory = Inventory, Properties = Record<string, unknown> | undefined> {
export abstract class GuiScreen {
x: number = 0;
y: number = 0;
abstract on_tick(_delta: number): void;
abstract on_render(): void;
abstract on_close(): void;
}
export class GuiInventoryScreen<Inv extends Inventory = Inventory, Properties = Record<string, unknown> | undefined>
extends GuiScreen {
inventory: Inv;
player_inventory: PlayerInventory;
properties: Properties;
slots: Slot[] = [];
x: number = 0;
y: number = 0;
inventory_width: number = 500;
inventory_height: number = 500;
@@ -41,6 +49,7 @@ export class GuiScreen<Inv extends Inventory = Inventory, Properties = Record<st
player_inventory: PlayerInventory,
properties: Properties,
) {
super();
this.inventory = inventory;
this.player_inventory = player_inventory;
this.properties = properties;
@@ -245,7 +254,7 @@ export class GuiScreen<Inv extends Inventory = Inventory, Properties = Record<st
// generic methods that is often needed
export function add_player_inventory(
handler: GuiScreen,
handler: GuiInventoryScreen,
player_inventory: PlayerInventory,
offset_x: number,
offset_y: number,
@@ -265,7 +274,7 @@ export function add_player_inventory(
}
export function add_player_hotbar(
handler: GuiScreen,
handler: GuiInventoryScreen,
player_inventory: PlayerInventory,
offset_x: number,
offset_y: number,