This commit is contained in:
33333-33333 2026-06-07 18:06:35 +09:00
commit b454ffbd40
21 changed files with 1349 additions and 712 deletions

View file

@ -1,12 +1,12 @@
import { GRID, THEME, EFFECT_PRIORITY, VERSION } from '../core/config.js';
import { key, parseKey, cellCenter, mixHex, randomBetween } from '../core/utils.js';
import { getConveyorNeighbors, routeFromFarmToScanner, outputRoute, scannerCenter, scannerConnector, scannerOutputs, destinationLabel, destinationColor } from '../systems/routing.js';
import { truckPayoutMultiplier } from '../systems/economy.js';
import { upgradedTruckPrice } from '../systems/economy.js';
const ASSET_PATHS = {
chickMale: './assets/images/chick_male.png',
chickFemale: './assets/images/chick_female.png',
poop: './assets/images/poop.png',
poop: './assets/images/tarinai.png',
conveyor: './assets/images/conveyor.png',
scannerManual: './assets/images/scanner_manual.png',
scannerAuto: './assets/images/scanner_auto.png',
@ -187,12 +187,12 @@ function drawDestinationFlowSegments(ctx, segments) {
const entries = [...dests.entries()].sort((a, b) => order.indexOf(a[0]) - order.indexOf(b[0]));
const count = entries.length;
entries.forEach(([dest, seg], index) => {
const offset = (index - (count - 1) / 2) * 8;
drawColoredFlowSegment(ctx, seg.a, seg.b, destinationColor(dest), offset);
const offset = (index - (count - 1) / 2) * 12;
drawColoredFlowSegment(ctx, seg.a, seg.b, destinationColor(dest), offset, index - (count - 1) / 2);
});
}
}
function drawColoredFlowSegment(ctx, a, b, color, offset) {
function drawColoredFlowSegment(ctx, a, b, color, offset, arrowShift = 0) {
const dx = b.x - a.x, dy = b.y - a.y;
const dist = Math.hypot(dx, dy);
if (dist < 8) return;
@ -203,7 +203,7 @@ function drawColoredFlowSegment(ctx, a, b, color, offset) {
ctx.strokeStyle = color; ctx.lineWidth = 5; ctx.globalAlpha = .9; ctx.lineCap = 'round';
ctx.beginPath(); ctx.moveTo(ax, ay); ctx.lineTo(bx, by); ctx.stroke();
ctx.fillStyle = color; ctx.globalAlpha = .98;
if (dist > 32) drawArrow(ctx, ax + (bx - ax) * .58, ay + (by - ay) * .58, Math.atan2(dy, dx));
if (dist > 32) drawArrow(ctx, ax + (bx - ax) * .58 + arrowShift * 9, ay + (by - ay) * .58, Math.atan2(dy, dx));
ctx.restore();
}
function drawArrow(ctx, x, y, angle) {
@ -387,7 +387,7 @@ function drawTruck(ctx, game) {
if (drawImageIfLoaded(ctx, assets.truck, t.x, t.y, t.w, t.h)) { ctx.restore(); return; }
ctx.fillStyle = THEME.white; ctx.strokeStyle = THEME.ink; ctx.lineWidth = 4; rect(ctx, t.x, t.y, t.w, t.h, true, true);
ctx.fillStyle = THEME.ink; ctx.font = '900 15px ui-monospace, monospace'; ctx.textAlign = 'center'; ctx.fillText(`TRUCK L${t.level}`, t.x + t.w / 2, t.y + 24);
ctx.font = '900 11px ui-monospace, monospace'; ctx.fillText(`EST ${Math.round(truckPayoutMultiplier(game) * 100)}%`, t.x + t.w / 2, t.y + 42);
ctx.font = '900 11px ui-monospace, monospace'; ctx.fillText(`UNIT ${upgradedTruckPrice(game)}`, t.x + t.w / 2, t.y + 42);
const truckTargetType = targetForTruck(game);
drawTargetBadge(ctx, t.x + 15, t.y + 50, t.w - 30, `SEND ${truckTargetType.toUpperCase()}`, truckTargetType, game.contractOffer && !game.contractActive ? 'next event' : 'truck cargo');
ctx.fillStyle = THEME.greenSoft; rect(ctx, t.x + 13, t.y + 88, t.w - 26, t.h - 103, true, false);
@ -409,6 +409,15 @@ function drawChick(ctx, chick, active, game) {
ctx.save();
if (active) { ctx.strokeStyle = THEME.green; ctx.lineWidth = 5; ctx.beginPath(); ctx.arc(chick.x, y, chick.radius + 8, 0, Math.PI * 2); ctx.stroke(); }
if (rage) { ctx.strokeStyle = THEME.danger; ctx.lineWidth = 3; ctx.beginPath(); ctx.arc(chick.x, y, chick.radius + 12 + Math.sin(chick.bob * 2) * 4, 0, Math.PI * 2); ctx.stroke(); }
if (chick.stoppedTimer > 0) {
ctx.strokeStyle = THEME.warn;
ctx.lineWidth = 4;
ctx.setLineDash([5, 4]);
ctx.beginPath();
ctx.arc(chick.x, y, chick.radius + 10, 0, Math.PI * 2);
ctx.stroke();
ctx.setLineDash([]);
}
if (chick.sex === 'poop') drawPoop(ctx, chick.x, y, chick.radius);
else {
const img = chick.sex === 'male' ? assets.chickMale : assets.chickFemale;
@ -420,6 +429,15 @@ function drawChick(ctx, chick, active, game) {
ctx.fillStyle = '#ffaa2e'; ctx.beginPath(); ctx.moveTo(chick.x, y + 2); ctx.lineTo(chick.x + 9, y + 6); ctx.lineTo(chick.x, y + 10); ctx.closePath(); ctx.fill();
}
}
if (chick.stoppedTimer > 0) {
ctx.font = '900 10px ui-monospace, monospace';
ctx.textAlign = 'center';
ctx.lineWidth = 4;
ctx.strokeStyle = THEME.white;
ctx.fillStyle = THEME.warn;
ctx.strokeText('STOPPED', chick.x, y - chick.radius - 13);
ctx.fillText('STOPPED', chick.x, y - chick.radius - 13);
}
ctx.restore();
}
function nearestRatio(game, chick) {