You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tobspr_shapez.io/src/js/game/systems/zone.js

132 lines
3.7 KiB

/* typehints:start */
import { DrawParameters } from "../../core/draw_parameters";
import { MapChunkView } from "../map_chunk_view";
import { GameRoot } from "../root";
/* typehints:end */
import { globalConfig } from "../../core/config";
import { STOP_PROPAGATION } from "../../core/signal";
import { GameSystem } from "../game_system";
import { THEME } from "../theme";
import { Entity } from "../entity";
import { Vector } from "../../core/vector";
export class ZoneSystem extends GameSystem {
/** @param {GameRoot} root */
constructor(root) {
super(root);
this.drawn = false;
this.root.signals.prePlacementCheck.add(this.prePlacementCheck, this);
this.root.signals.gameFrameStarted.add(() => {
this.drawn = false;
});
}
/**
*
* @param {Entity} entity
* @param {Vector | undefined} tile
* @returns
*/
prePlacementCheck(entity, tile = null) {
const staticComp = entity.components.StaticMapEntity;
if (!staticComp) {
return;
}
const mode = this.root.gameMode;
const zones = mode.getBuildableZones();
if (!zones) {
return;
}
const transformed = staticComp.getTileSpaceBounds();
if (tile) {
transformed.x += tile.x;
transformed.y += tile.y;
}
if (!zones.some(zone => zone.intersectsFully(transformed))) {
return STOP_PROPAGATION;
}
}
/**
* Draws the zone
* @param {DrawParameters} parameters
* @param {MapChunkView} chunk
*/
drawChunk(parameters, chunk) {
if (this.drawn) {
// double oof
return;
}
this.drawn = true;
const mode = this.root.gameMode;
const zones = mode.getBuildableZones();
if (!zones) {
return;
}
const zone = zones[0].allScaled(globalConfig.tileSize);
const context = parameters.context;
context.lineWidth = 2;
context.strokeStyle = THEME.map.zone.borderSolid;
context.beginPath();
context.rect(zone.x - 1, zone.y - 1, zone.w + 2, zone.h + 2);
context.stroke();
const outer = zone;
const padding = 40 * globalConfig.tileSize;
context.fillStyle = THEME.map.zone.outerColor;
context.fillRect(outer.x + outer.w, outer.y, padding, outer.h);
context.fillRect(outer.x - padding, outer.y, padding, outer.h);
context.fillRect(
outer.x - padding - globalConfig.tileSize,
outer.y - padding,
2 * padding + zone.w + 2 * globalConfig.tileSize,
padding
);
context.fillRect(
outer.x - padding - globalConfig.tileSize,
outer.y + outer.h,
2 * padding + zone.w + 2 * globalConfig.tileSize,
padding
);
context.globalAlpha = 1;
// render zone indicators with letters and numbers
context.font = "10px GameFont";
context.fillStyle = "#626262";
context.textAlign = "center";
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const halfTile = globalConfig.halfTileSize;
const pixelGap = 9;
const topLeft = zone.topLeft().add(new Vector(-pixelGap, -pixelGap));
for (let i = 0; i < zones[0].h; ++i) {
const letter = alphabet[i];
const pxOffset = halfTile + i * globalConfig.tileSize + pixelGap;
context.fillText(letter, topLeft.x, topLeft.y + pxOffset + 5);
}
for (let i = 0; i < zones[0].w; ++i) {
const pxOffset = halfTile + i * globalConfig.tileSize + pixelGap;
context.fillText((i + 1).toString(), topLeft.x + pxOffset, topLeft.y + 3);
}
}
}