Files
vending-machine-game/src/game/runtime/mapInteraction.js
T

141 lines
4.6 KiB
JavaScript

import iran from '../../data/iran.json';
import { CATEGORIES, lockedPlaces } from '../../constants/locations.js';
import { catalog, priceAt, isOpen, fa } from '../economy/gameState.js';
import { drawFullMap, drawIran } from '../world/mapRender.js';
import { formatDistance } from '../../utils/geo.js';
/**
* Runs the size canvas operation for this subsystem.
* @param {*} context - context.
* @param {*} c - c.
* @returns {*} Operation result, when applicable.
*/
export function sizeCanvas(context, c) {
const r = c.getBoundingClientRect(),
dpr = Math.min(devicePixelRatio, 2);
c.width = Math.max(1, r.width * dpr);
c.height = Math.max(1, r.height * dpr);
return dpr;
}
/**
* Runs the render map operation for this subsystem.
* @param {*} context - context.
* @returns {*} Operation result, when applicable.
*/
export function renderMap(context) {
if (!context.ui.read('map-dialog').open) return;
if (context.mapTab === 'city') {
const dpr = context.sizeCanvas(context.mapCanvas);
const pos = context.mode === 'drive' ? context.car : context.player;
drawFullMap(context.mapCanvas.getContext('2d'), context.mapAssets, context.mapView, {
dpr,
markers: context.markers(),
route: context.route?.points,
selected: context.selected,
player: {
x: pos.x,
z: pos.z,
heading: context.mode === 'drive' ? context.car.heading : context.player.heading,
},
});
} else {
const dpr = context.sizeCanvas(context.iranCanvas),
c = context.iranCanvas.getContext('2d');
c.setTransform(dpr, 0, 0, dpr, 0, 0);
drawIran(c, iran, {
width: context.iranCanvas.width / dpr,
height: context.iranCanvas.height / dpr,
t: context.elapsed,
cities: context.CITIES,
});
}
}
/**
* Runs the render machine list operation for this subsystem.
* @param {*} context - context.
* @returns {*} Operation result, when applicable.
*/
export function renderMachineList(context) {
const pos = context.mode === 'drive' ? context.car : context.player;
const visited = new Set(context.state.purchases.map((p) => p.machineId));
const items = context.activeStations().map((s) => ({
id: s.def.id,
name: s.def.name,
icon: CATEGORIES[s.def.category].icon,
category: CATEGORIES[s.def.category].label,
visited: visited.has(s.def.id),
open: isOpen(s.def, context.state.minutes),
selected: s.def.id === context.selected,
distance: formatDistance(Math.hypot(s.x - pos.x, s.z - pos.z)),
}));
context.ui.patch('machine-list', {
items: [
...items,
...lockedPlaces.map((p) => ({
...p,
id: p.name,
locked: true,
})),
],
});
}
/**
* Runs the select machine operation for this subsystem.
* @param {*} context - context.
* @param {*} id - id.
* @param {*} center - center.
* @returns {*} Operation result, when applicable.
*/
export function selectMachine(context, id, center = false) {
context.selected = id;
const s = context.stationById(id),
def = s.def;
if (center) {
context.mapView.cx = s.x;
context.mapView.cz = s.z;
context.mapView.mpp = Math.min(context.mapView.mpp, 1.4);
}
context.ui.patch('machine-detail', {
hidden: false,
});
context.ui.patch('detail-name', {
text: `${CATEGORIES[def.category].icon} ${def.name}`,
});
context.ui.patch('detail-address', {
text: `📍 ${def.address}`,
});
context.ui.patch('detail-meta', {
text: `🕒 ${context.hoursText(def)} · ${isOpen(def, context.state.minutes) ? 'الان باز است' : 'الان بسته است'} · ${def.note}`,
});
context.ui.patch('detail-products', {
text: def.products
.map((id) => `${catalog[id].icon} ${catalog[id].name} ${fa(priceAt(def, id))}`)
.join(' · '),
});
context.ui.patch('route-button', {
text: context.waypoint === id ? 'مسیر فعال است ✓' : 'مسیریابی تا اینجا',
});
context.renderMachineList();
context.renderMap();
}
/**
* Runs the open map operation for this subsystem.
* @param {*} context - context.
* @returns {*} Operation result, when applicable.
*/
export function openMap(context) {
if (context.anyDialogOpen()) return;
document.exitPointerLock?.();
context.keys.clear();
const pos = context.mode === 'drive' ? context.car : context.player;
Object.assign(context.mapView, {
cx: pos.x,
cz: pos.z,
mpp: 2.2,
});
context.ui.open('map-dialog');
context.selected ??= context.objectiveStation()?.def.id ?? null;
if (context.selected) context.selectMachine(context.selected);
context.renderMachineList();
context.renderMap();
}