fixed issues
This commit is contained in:
parent
46258a83eb
commit
aea08dc3fb
25 changed files with 1625 additions and 513 deletions
106
js/render.js
106
js/render.js
|
|
@ -124,6 +124,98 @@ function drawItemGlow(ctx, item, lighting, visibleAlpha = 1) {
|
|||
return;
|
||||
}
|
||||
|
||||
const PLACEABLE_TOOL_TYPES = Object.freeze({
|
||||
zunchi: "zunchi", sweet: "sweet", love_mochi: "love_mochi", fight_mochi: "fight_mochi", sleep_drug: "sleep_drug", water: "water", water_bowl: "water_bowl", grass: "grass",
|
||||
stone: "stone", bed: "bed", nest_box: "nest_box", ball: "ball", firecracker: "firecracker", fence_v: "fence_v", fence_h: "fence_h",
|
||||
});
|
||||
|
||||
function placementPreviewFor(world) {
|
||||
const p = world?.pointer;
|
||||
const type = PLACEABLE_TOOL_TYPES[world?.tool || ""];
|
||||
if (!p?.inside || !type) return null;
|
||||
const pad = CONFIG.worldPadding || 30;
|
||||
let x = clamp(p.x, pad, world.w - pad);
|
||||
let y = clamp(p.y, pad, world.h - pad);
|
||||
const r = {
|
||||
food: 14, sweet: 13, love_mochi: 13, fight_mochi: 13, sleep_drug: 13, water: 12, water_bowl: 20, grass: 17, stone: 20, bed: 37, nest_box: 42, ball: 18, firecracker: 15, fence_v: 42, fence_h: 42, zunchi: 14
|
||||
}[type] || 12;
|
||||
const rectOutside = (rect) => Boolean(rect && (rect.left < pad || rect.top < pad || rect.right > world.w - pad || rect.bottom > world.h - pad));
|
||||
const circleOutside = (cx, cy, radius) => cx - radius < pad || cy - radius < pad || cx + radius > world.w - pad || cy + radius > world.h - pad;
|
||||
let blocked = false;
|
||||
if (type === "grass" && world.findGrassPlantingSpot) {
|
||||
const spot = world.findGrassPlantingSpot(x, y, { allowOriginal: true, minRadius: 22, maxRadius: 128, attempts: 16 });
|
||||
if (!spot) return { type, x, y, r, blocked: true };
|
||||
x = spot.x;
|
||||
y = spot.y;
|
||||
blocked = circleOutside(x, y, Math.max(14, r * 1.55));
|
||||
}
|
||||
if ((type === "fence_v" || type === "fence_h") && world.fenceRect) {
|
||||
const raw = { type, x, y, r };
|
||||
const rawRect = world.fenceRect(raw);
|
||||
blocked = rectOutside(rawRect);
|
||||
const tmp = { type, x, y, r };
|
||||
const rect = world.fenceRect(tmp);
|
||||
if (rect) {
|
||||
const dx = Math.max(pad - rect.left, 0) - Math.max(rect.right - (world.w - pad), 0);
|
||||
const dy = Math.max(pad - rect.top, 0) - Math.max(rect.bottom - (world.h - pad), 0);
|
||||
tmp.x += dx;
|
||||
tmp.y += dy;
|
||||
return { type, x: tmp.x, y: tmp.y, r, rect: world.fenceRect(tmp), blocked: blocked || world.fencePlacementBlocked?.(raw) || world.fencePlacementBlocked?.(tmp) };
|
||||
}
|
||||
}
|
||||
if (type === "nest_box" && world.nestBoxBaseRect) {
|
||||
const tmp = { type, x, y, r, dead: false };
|
||||
const rect = world.nestBoxBaseRect(tmp);
|
||||
return { type, x, y, r, rect, blocked: rectOutside(rect) };
|
||||
}
|
||||
if (!blocked) blocked = circleOutside(x, y, Math.max(14, r * (type === "bed" ? 1.55 : 1.25)));
|
||||
return { type, x, y, r, blocked };
|
||||
}
|
||||
|
||||
function drawPlacementPreview(ctx, world) {
|
||||
const preview = placementPreviewFor(world);
|
||||
if (!preview) return;
|
||||
const { type, x, y, r, rect, blocked } = preview;
|
||||
const pulse = 0.55 + Math.sin((world.time || 0) * 7.0) * 0.10;
|
||||
ctx.save();
|
||||
ctx.globalAlpha = blocked ? 0.44 : 0.72;
|
||||
ctx.lineWidth = blocked ? 2.2 : 2.0;
|
||||
ctx.setLineDash(blocked ? [5, 4] : [7, 5]);
|
||||
ctx.strokeStyle = blocked ? "rgba(194,70,58,0.86)" : "rgba(110,178,55,0.88)";
|
||||
ctx.fillStyle = blocked ? "rgba(232,84,72,0.14)" : "rgba(190,236,92,0.15)";
|
||||
if (rect) {
|
||||
roundedRect(ctx, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 8);
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
if (type === "nest_box" && world.nestBoxSolidRects) {
|
||||
ctx.setLineDash([3, 4]);
|
||||
ctx.strokeStyle = blocked ? "rgba(194,70,58,0.38)" : "rgba(110,178,55,0.42)";
|
||||
for (const part of world.nestBoxSolidRects({ type, x, y, r, dead: false })) {
|
||||
ctx.strokeRect(part.left, part.top, part.right - part.left, part.bottom - part.top);
|
||||
}
|
||||
}
|
||||
} else if (type === "water_bowl" || type === "stone" || type === "ball" || type === "firecracker" || type === "zunchi" || type.includes("mochi") || type === "sweet" || type === "sleep_drug") {
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, Math.max(16, r * (1.18 + pulse * 0.04)), 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
} else {
|
||||
ctx.beginPath();
|
||||
ctx.ellipse(x, y, Math.max(14, r * 1.55), Math.max(9, r * 0.86), 0, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
}
|
||||
ctx.setLineDash([]);
|
||||
ctx.globalAlpha = blocked ? 0.52 : 0.70;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x - 8, y);
|
||||
ctx.lineTo(x + 8, y);
|
||||
ctx.moveTo(x, y - 8);
|
||||
ctx.lineTo(x, y + 8);
|
||||
ctx.stroke();
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
function drawCreatureGlow(ctx, tarinai, drawW, drawH, lighting) {
|
||||
if (tarinai.dead || tarinai.world.selected !== tarinai) return;
|
||||
ctx.save();
|
||||
|
|
@ -580,6 +672,7 @@ function render() {
|
|||
if (perf < 3 || world.weather === "light_rain") drawRain(ctx, screenW, screenH, world.time);
|
||||
|
||||
beginFieldTransform();
|
||||
drawPlacementPreview(ctx, world);
|
||||
for (const it of world.items) {
|
||||
if (it.type === "trace" || it.type === "splat") it.draw(ctx, world.time, lighting);
|
||||
}
|
||||
|
|
@ -680,13 +773,16 @@ function drawNestBoxTooltip(ctx, world) {
|
|||
const info = world.pointerNestBoxInfo?.();
|
||||
if (!info) return;
|
||||
const box = info.box;
|
||||
const names = info.occupants.length ? info.occupants.map(t => t.name).join("\u3001") : "\u4e2d\u306b\u306f\u8ab0\u3082\u3044\u306a\u3044";
|
||||
const title = "\u5de3\u7bb1";
|
||||
const text = `${title}: ${names}`;
|
||||
const lines = info.occupants.length
|
||||
? [title, ...info.occupants.map(t => t.name)]
|
||||
: [title, "\u4e2d\u306b\u306f\u8ab0\u3082\u3044\u306a\u3044"];
|
||||
ctx.save();
|
||||
ctx.font = "12px Yomogi, sans-serif";
|
||||
const w = Math.min(240, Math.max(92, ctx.measureText(text).width + 22));
|
||||
const h = 38;
|
||||
const textW = lines.reduce((m, line) => Math.max(m, ctx.measureText(line).width), 0);
|
||||
const lineH = 17;
|
||||
const w = Math.min(240, Math.max(92, textW + 22));
|
||||
const h = Math.max(38, 16 + lines.length * lineH);
|
||||
const pos = world.worldToScreen ? world.worldToScreen(box.x, box.y) : { x: box.x, y: box.y };
|
||||
const x = clamp(pos.x - w / 2, 8, ctx.canvas.width - w - 8);
|
||||
const y = clamp(pos.y - box.r * 1.8 - h, 8, ctx.canvas.height - h - 8);
|
||||
|
|
@ -699,7 +795,7 @@ function drawNestBoxTooltip(ctx, world) {
|
|||
ctx.fillStyle = "#fff8e6";
|
||||
ctx.textAlign = "left";
|
||||
ctx.textBaseline = "middle";
|
||||
ctx.fillText(text, x + 11, y + h / 2);
|
||||
lines.forEach((line, i) => ctx.fillText(line, x + 11, y + 11 + lineH * i + lineH / 2));
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue