56 lines
2.2 KiB
TypeScript
56 lines
2.2 KiB
TypeScript
// the box next to the mouse saying what an item is, like minecraft's: its name, then its lore
|
|
import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts";
|
|
import type { ItemStack } from "$/common/inventory.ts";
|
|
import { display_name } from "$/common/utils.ts";
|
|
import { canvas, draw_rect, draw_text, measure_text } from "$/client/renderer/mod.ts";
|
|
import { TEXT_HEIGHT, TEXT_SCALE } from "./widgets.ts";
|
|
|
|
type Color = [number, number, number, number];
|
|
|
|
const NAME_COLOR: Color = [1, 1, 1, 1];
|
|
const LORE_COLOR: Color = [0.66, 0.66, 0.66, 1];
|
|
const BACKGROUND: Color = [0.06, 0.02, 0.1, 0.94];
|
|
const BORDER: Color = [0.31, 0.1, 0.6, 1];
|
|
const BORDER_WIDTH = 2;
|
|
const PADDING = 8;
|
|
const LINE_GAP = 4;
|
|
// from the mouse, so the cursor doesn't cover it
|
|
const OFFSET = 16;
|
|
|
|
export interface TooltipLine {
|
|
text: string;
|
|
color: Color;
|
|
}
|
|
|
|
// its name, the item's lore from its json, then what the server's scripts said about this stack
|
|
export function item_tooltip(item: ItemStack): TooltipLine[] {
|
|
const lines: TooltipLine[] = [{ text: display_name(item.type_id), color: NAME_COLOR }];
|
|
const static_lore = EverythingRegistry.get<ItemRegistry>("items", item.type_id)?.lore;
|
|
for (const lore of [static_lore, item.lore]) {
|
|
for (const text of lore?.split("\n") ?? []) {
|
|
lines.push({ text, color: LORE_COLOR });
|
|
}
|
|
}
|
|
return lines;
|
|
}
|
|
|
|
// below and right of the mouse, moved back inside the window when it would go past its edge
|
|
export function draw_tooltip(lines: TooltipLine[], mouse_x: number, mouse_y: number) {
|
|
const line_height = TEXT_HEIGHT * TEXT_SCALE;
|
|
const width = Math.max(...lines.map((line) => measure_text(line.text, TEXT_SCALE))) + PADDING * 2;
|
|
const height = lines.length * line_height + (lines.length - 1) * LINE_GAP + PADDING * 2;
|
|
|
|
let x = mouse_x + OFFSET;
|
|
let y = mouse_y + OFFSET;
|
|
if (x + width > canvas.width) x = mouse_x - OFFSET - width;
|
|
if (y + height > canvas.height) y = canvas.height - height;
|
|
x = Math.max(0, x);
|
|
y = Math.max(0, y);
|
|
|
|
draw_rect(x, y, width, height, BORDER);
|
|
draw_rect(x + BORDER_WIDTH, y + BORDER_WIDTH, width - BORDER_WIDTH * 2, height - BORDER_WIDTH * 2, BACKGROUND);
|
|
lines.forEach((line, i) => {
|
|
draw_text(line.text, x + PADDING, y + PADDING + i * (line_height + LINE_GAP), TEXT_SCALE, line.color);
|
|
});
|
|
}
|