mirror of
https://github.com/tobspr/shapez.io.git
synced 2026-03-02 03:39:21 +00:00
Unify assets, refactor waypoints
This commit is contained in:
@@ -4,7 +4,7 @@ import { round3Digits } from "./utils";
|
||||
|
||||
const floorSpriteCoordinates = false;
|
||||
|
||||
const ORIGINAL_SCALE = "1";
|
||||
export const ORIGINAL_SPRITE_SCALE = "0.5";
|
||||
|
||||
export class BaseSprite {
|
||||
/**
|
||||
@@ -73,7 +73,7 @@ export class AtlasSprite extends BaseSprite {
|
||||
}
|
||||
|
||||
getRawTexture() {
|
||||
return this.linksByResolution[ORIGINAL_SCALE].atlas;
|
||||
return this.linksByResolution[ORIGINAL_SPRITE_SCALE].atlas;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,11 +85,15 @@ export class AtlasSprite extends BaseSprite {
|
||||
assert(context instanceof CanvasRenderingContext2D, "Not a valid context");
|
||||
}
|
||||
|
||||
const link = this.linksByResolution[ORIGINAL_SCALE];
|
||||
const link = this.linksByResolution[ORIGINAL_SPRITE_SCALE];
|
||||
|
||||
assert(
|
||||
link,
|
||||
"Link not known: " + ORIGINAL_SCALE + " (having " + Object.keys(this.linksByResolution) + ")"
|
||||
"Link not known: " +
|
||||
ORIGINAL_SPRITE_SCALE +
|
||||
" (having " +
|
||||
Object.keys(this.linksByResolution) +
|
||||
")"
|
||||
);
|
||||
|
||||
const width = w || link.w;
|
||||
|
||||
@@ -9,7 +9,7 @@ import { DrawParameters } from "../core/draw_parameters";
|
||||
import { gMetaBuildingRegistry } from "../core/global_registries";
|
||||
import { createLogger } from "../core/logging";
|
||||
import { Rectangle } from "../core/rectangle";
|
||||
import { randomInt } from "../core/utils";
|
||||
import { randomInt, round2Digits } from "../core/utils";
|
||||
import { Vector } from "../core/vector";
|
||||
import { Savegame } from "../savegame/savegame";
|
||||
import { SavegameSerializer } from "../savegame/savegame_serializer";
|
||||
@@ -31,6 +31,7 @@ import { enumLayer, GameRoot } from "./root";
|
||||
import { ShapeDefinitionManager } from "./shape_definition_manager";
|
||||
import { SoundProxy } from "./sound_proxy";
|
||||
import { GameTime } from "./time/game_time";
|
||||
import { ORIGINAL_SPRITE_SCALE } from "../core/sprites";
|
||||
|
||||
const logger = createLogger("ingame/core");
|
||||
|
||||
@@ -348,15 +349,11 @@ export class GameCore {
|
||||
const effectiveZoomLevel =
|
||||
(zoomLevel / globalConfig.assetsDpi) * getDeviceDPI() * globalConfig.assetsSharpness;
|
||||
|
||||
let desiredAtlasScale = "0.1";
|
||||
if (effectiveZoomLevel > 0.75 && !lowQuality) {
|
||||
desiredAtlasScale = "1";
|
||||
} else if (effectiveZoomLevel > 0.5 && !lowQuality) {
|
||||
desiredAtlasScale = "0.75";
|
||||
} else if (effectiveZoomLevel > 0.25 && !lowQuality) {
|
||||
let desiredAtlasScale = "0.25";
|
||||
if (effectiveZoomLevel > 0.8 && !lowQuality) {
|
||||
desiredAtlasScale = ORIGINAL_SPRITE_SCALE;
|
||||
} else if (effectiveZoomLevel > 0.4 && !lowQuality) {
|
||||
desiredAtlasScale = "0.5";
|
||||
} else if (effectiveZoomLevel > 0.1) {
|
||||
desiredAtlasScale = "0.25";
|
||||
}
|
||||
|
||||
// Construct parameters required for drawing
|
||||
@@ -441,7 +438,7 @@ export class GameCore {
|
||||
|
||||
// Restore parameters
|
||||
params.zoomLevel = 1;
|
||||
params.desiredAtlasScale = "1";
|
||||
params.desiredAtlasScale = ORIGINAL_SPRITE_SCALE;
|
||||
params.visibleRect = new Rectangle(0, 0, this.root.gameWidth, this.root.gameHeight);
|
||||
|
||||
// Draw overlays, those are screen space
|
||||
@@ -458,5 +455,20 @@ export class GameCore {
|
||||
console.log(sum);
|
||||
}
|
||||
}
|
||||
|
||||
if (G_IS_DEV && globalConfig.debug.showAtlasInfo) {
|
||||
context.font = "13px GameFont";
|
||||
context.fillStyle = "yellow";
|
||||
context.fillText(
|
||||
"Atlas: " +
|
||||
desiredAtlasScale +
|
||||
" / Zoom: " +
|
||||
round2Digits(zoomLevel) +
|
||||
" / Effective Zoom: " +
|
||||
round2Digits(effectiveZoomLevel),
|
||||
200,
|
||||
20
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,6 +161,7 @@ export class Entity extends BasicSerializableObject {
|
||||
context.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
if (G_IS_DEV && staticComp && globalConfig.debug.showAcceptorEjectors) {
|
||||
const ejectorComp = this.components.ItemEjector;
|
||||
|
||||
@@ -187,7 +188,7 @@ export class Entity extends BasicSerializableObject {
|
||||
const acceptorComp = this.components.ItemAcceptor;
|
||||
|
||||
if (acceptorComp) {
|
||||
const acceptorSprite = Loader.getSprite("sprites/debug/acceptor_slot.png");
|
||||
const acceptorSprite = Loader.getSprite("sprites/misc/acceptor_slot.png");
|
||||
for (let i = 0; i < acceptorComp.slots.length; ++i) {
|
||||
const slot = acceptorComp.slots[i];
|
||||
const slotTile = staticComp.localTileToWorld(slot.pos);
|
||||
|
||||
@@ -232,7 +232,6 @@ export class GameHUD {
|
||||
*/
|
||||
draw(parameters) {
|
||||
const partsOrder = [
|
||||
"waypoints",
|
||||
"massSelector",
|
||||
"buildingPlacer",
|
||||
"blueprintPlacer",
|
||||
@@ -252,7 +251,7 @@ export class GameHUD {
|
||||
* @param {DrawParameters} parameters
|
||||
*/
|
||||
drawOverlays(parameters) {
|
||||
const partsOrder = ["watermark", "wireInfo"];
|
||||
const partsOrder = ["waypoints", "watermark", "wireInfo"];
|
||||
|
||||
for (let i = 0; i < partsOrder.length; ++i) {
|
||||
if (this.parts[partsOrder[i]]) {
|
||||
|
||||
@@ -21,8 +21,6 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||
createElements(parent) {}
|
||||
|
||||
initialize() {
|
||||
this.deletionMarker = Loader.getSprite("sprites/misc/deletion_marker.png");
|
||||
|
||||
this.currentSelectionStartWorld = null;
|
||||
this.currentSelectionEnd = null;
|
||||
this.selectedUids = new Set();
|
||||
|
||||
@@ -15,6 +15,8 @@ import { BaseHUDPart } from "../base_hud_part";
|
||||
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||
import { enumNotificationType } from "./notifications";
|
||||
import { ShapeDefinition } from "../../shape_definition";
|
||||
import { BaseItem } from "../../base_item";
|
||||
import { ShapeItem } from "../../items/shape_item";
|
||||
|
||||
/** @typedef {{
|
||||
* label: string | null,
|
||||
@@ -25,8 +27,6 @@ import { ShapeDefinition } from "../../shape_definition";
|
||||
/**
|
||||
* Used when a shape icon is rendered instead
|
||||
*/
|
||||
const SHAPE_LABEL_PLACEHOLDER = " ";
|
||||
|
||||
const MAX_LABEL_LENGTH = 71;
|
||||
|
||||
export class HUDWaypoints extends BaseHUDPart {
|
||||
@@ -133,10 +133,44 @@ export class HUDWaypoints extends BaseHUDPart {
|
||||
*/
|
||||
this.cachedKeyToCanvas = {};
|
||||
|
||||
/**
|
||||
* Store cached text widths
|
||||
* @type {Object<string, number>}
|
||||
*/
|
||||
this.cachedTextWidths = {};
|
||||
|
||||
// Initial render
|
||||
this.rerenderWaypointList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how long a text will be rendered
|
||||
* @param {string} text
|
||||
* @returns {number}
|
||||
*/
|
||||
getTextWidth(text) {
|
||||
if (this.cachedTextWidths[text]) {
|
||||
return this.cachedTextWidths[text];
|
||||
}
|
||||
|
||||
this.dummyBuffer.font = "bold " + this.getTextScale() + "px GameFont";
|
||||
return (this.cachedTextWidths[text] = this.dummyBuffer.measureText(text).width);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how big the text should be rendered
|
||||
*/
|
||||
getTextScale() {
|
||||
return this.getWaypointUiScale() * 12;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scale for rendering waypoints
|
||||
*/
|
||||
getWaypointUiScale() {
|
||||
return this.root.app.getEffectiveUiScale();
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-renders the waypoint list to account for changes
|
||||
*/
|
||||
@@ -214,7 +248,7 @@ export class HUDWaypoints extends BaseHUDPart {
|
||||
}
|
||||
|
||||
assert(ShapeDefinition.isValidShortKey(key), "Invalid short key: " + key);
|
||||
const definition = ShapeDefinition.fromShortKey(key);
|
||||
const definition = this.root.shapeDefinitionMgr.getShapeFromShortKey(key);
|
||||
const preRendered = definition.generateAsCanvas(48);
|
||||
return (this.cachedKeyToCanvas[key] = preRendered);
|
||||
}
|
||||
@@ -367,6 +401,51 @@ export class HUDWaypoints extends BaseHUDPart {
|
||||
return waypoint.label !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the screen space bounds of the given waypoint or null
|
||||
* if it couldn't be determined. Also returns wheter its a shape or not
|
||||
* @param {Waypoint} waypoint
|
||||
* @return {{
|
||||
* screenBounds: Rectangle
|
||||
* item: BaseItem|null,
|
||||
* text: string
|
||||
* }}
|
||||
*/
|
||||
getWaypointScreenParams(waypoint) {
|
||||
if (!this.root.camera.getIsMapOverlayActive()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Find parameters
|
||||
const scale = this.getWaypointUiScale();
|
||||
const screenPos = this.root.camera.worldToScreen(new Vector(waypoint.center.x, waypoint.center.y));
|
||||
|
||||
// Distinguish between text and item waypoints -> Figure out parameters
|
||||
const originalLabel = this.getWaypointLabel(waypoint);
|
||||
let text, item, textWidth;
|
||||
|
||||
if (ShapeDefinition.isValidShortKey(originalLabel)) {
|
||||
// If the label is actually a key, render the shape icon
|
||||
item = this.root.shapeDefinitionMgr.getShapeItemFromShortKey(originalLabel);
|
||||
textWidth = 40;
|
||||
} else {
|
||||
// Otherwise render a regular waypoint
|
||||
text = originalLabel;
|
||||
textWidth = this.getTextWidth(text);
|
||||
}
|
||||
|
||||
return {
|
||||
screenBounds: new Rectangle(
|
||||
screenPos.x - 7 * scale,
|
||||
screenPos.y - 12 * scale,
|
||||
15 * scale + textWidth,
|
||||
15 * scale
|
||||
),
|
||||
item,
|
||||
text,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the currently intersected waypoint on the map overview under
|
||||
* the cursor.
|
||||
@@ -379,34 +458,10 @@ export class HUDWaypoints extends BaseHUDPart {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.root.camera.getIsMapOverlayActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const scale = this.root.app.getEffectiveUiScale();
|
||||
|
||||
this.dummyBuffer.font = "bold " + 12 * scale + "px GameFont";
|
||||
|
||||
for (let i = 0; i < this.waypoints.length; ++i) {
|
||||
const waypoint = this.waypoints[i];
|
||||
const screenPos = this.root.camera.worldToScreen(
|
||||
new Vector(waypoint.center.x, waypoint.center.y)
|
||||
);
|
||||
|
||||
let label = this.getWaypointLabel(waypoint);
|
||||
|
||||
// Special case for icons
|
||||
if (ShapeDefinition.isValidShortKey(label)) {
|
||||
label = SHAPE_LABEL_PLACEHOLDER;
|
||||
}
|
||||
|
||||
const intersectionRect = new Rectangle(
|
||||
screenPos.x - 7 * scale,
|
||||
screenPos.y - 12 * scale,
|
||||
15 * scale + this.dummyBuffer.measureText(label).width,
|
||||
15 * scale
|
||||
);
|
||||
if (intersectionRect.containsPoint(mousePos.x, mousePos.y)) {
|
||||
const params = this.getWaypointScreenParams(waypoint);
|
||||
if (params && params.screenBounds.containsPoint(mousePos.x, mousePos.y)) {
|
||||
return waypoint;
|
||||
}
|
||||
}
|
||||
@@ -449,18 +504,21 @@ export class HUDWaypoints extends BaseHUDPart {
|
||||
* Rerenders the compass
|
||||
*/
|
||||
rerenderWaypointsCompass() {
|
||||
const context = this.compassBuffer.context;
|
||||
const dims = 48;
|
||||
context.clearRect(0, 0, dims, dims);
|
||||
const indicatorSize = 30;
|
||||
|
||||
const cameraPos = this.root.camera.center;
|
||||
|
||||
const context = this.compassBuffer.context;
|
||||
context.clearRect(0, 0, dims, dims);
|
||||
|
||||
const distanceToHub = cameraPos.length();
|
||||
const compassVisible = distanceToHub > (10 * globalConfig.tileSize) / this.root.camera.zoomLevel;
|
||||
const targetCompassAlpha = compassVisible ? 1 : 0;
|
||||
|
||||
// Fade the compas in / out
|
||||
this.currentCompassOpacity = lerp(this.currentCompassOpacity, targetCompassAlpha, 0.08);
|
||||
|
||||
// Render the compass
|
||||
if (this.currentCompassOpacity > 0.01) {
|
||||
context.globalAlpha = this.currentCompassOpacity;
|
||||
const angle = cameraPos.angle() + Math.radians(45) + Math.PI / 2;
|
||||
@@ -472,9 +530,9 @@ export class HUDWaypoints extends BaseHUDPart {
|
||||
context.globalAlpha = 1;
|
||||
}
|
||||
|
||||
// Render the regualr icon
|
||||
const iconOpacity = 1 - this.currentCompassOpacity;
|
||||
if (iconOpacity > 0.01) {
|
||||
// Draw icon
|
||||
context.globalAlpha = iconOpacity;
|
||||
this.waypointSprite.drawCentered(context, dims / 2, dims / 2, dims * 0.7);
|
||||
context.globalAlpha = 1;
|
||||
@@ -485,7 +543,8 @@ export class HUDWaypoints extends BaseHUDPart {
|
||||
* Draws the waypoints on the map
|
||||
* @param {DrawParameters} parameters
|
||||
*/
|
||||
draw(parameters) {
|
||||
drawOverlays(parameters) {
|
||||
const mousePos = this.root.app.mousePosition;
|
||||
const desiredOpacity = this.root.camera.getIsMapOverlayActive() ? 1 : 0;
|
||||
this.currentMarkerOpacity = lerp(this.currentMarkerOpacity, desiredOpacity, 0.08);
|
||||
|
||||
@@ -496,61 +555,73 @@ export class HUDWaypoints extends BaseHUDPart {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find waypoint below cursor
|
||||
const selected = this.findCurrentIntersectedWaypoint();
|
||||
|
||||
// Determine rendering scale
|
||||
const scale = (1 / this.root.camera.zoomLevel) * this.root.app.getEffectiveUiScale();
|
||||
const scale = this.getWaypointUiScale();
|
||||
|
||||
// Render all of 'em
|
||||
// Set the font size
|
||||
const textSize = this.getTextScale();
|
||||
parameters.context.font = "bold " + textSize + "px GameFont";
|
||||
parameters.context.textBaseline = "middle";
|
||||
|
||||
// Loop over all waypoints
|
||||
for (let i = 0; i < this.waypoints.length; ++i) {
|
||||
const waypoint = this.waypoints[i];
|
||||
|
||||
const pos = waypoint.center;
|
||||
parameters.context.globalAlpha = this.currentMarkerOpacity * (selected === waypoint ? 1 : 0.7);
|
||||
|
||||
const yOffset = -5 * scale;
|
||||
const originalLabel = this.getWaypointLabel(waypoint);
|
||||
let renderLabel = originalLabel;
|
||||
let isShapeIcon = false;
|
||||
|
||||
if (ShapeDefinition.isValidShortKey(originalLabel)) {
|
||||
renderLabel = SHAPE_LABEL_PLACEHOLDER;
|
||||
isShapeIcon = true;
|
||||
const waypointData = this.getWaypointScreenParams(waypoint);
|
||||
if (!waypointData) {
|
||||
// Not relevant
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!parameters.visibleRect.containsRect(waypointData.screenBounds)) {
|
||||
// Out of screen
|
||||
continue;
|
||||
}
|
||||
|
||||
const bounds = waypointData.screenBounds;
|
||||
const contentPaddingX = 7 * scale;
|
||||
const isSelected = mousePos && bounds.containsPoint(mousePos.x, mousePos.y);
|
||||
|
||||
// Render the background rectangle
|
||||
parameters.context.font = "bold " + 12 * scale + "px GameFont";
|
||||
parameters.context.globalAlpha = this.currentMarkerOpacity * (isSelected ? 1 : 0.7);
|
||||
parameters.context.fillStyle = "rgba(255, 255, 255, 0.7)";
|
||||
parameters.context.fillRect(
|
||||
pos.x - 7 * scale,
|
||||
pos.y - 12 * scale,
|
||||
15 * scale + this.dummyBuffer.measureText(renderLabel).width / this.root.camera.zoomLevel,
|
||||
15 * scale
|
||||
);
|
||||
parameters.context.fillRect(bounds.x, bounds.y, bounds.w, bounds.h);
|
||||
|
||||
// Render the text
|
||||
if (isShapeIcon) {
|
||||
if (waypointData.item) {
|
||||
const canvas = this.getWaypointCanvas(waypoint);
|
||||
const itemSize = 14 * scale;
|
||||
parameters.context.drawImage(
|
||||
canvas,
|
||||
pos.x + 6 * scale,
|
||||
pos.y - 11.5 * scale,
|
||||
14 * scale,
|
||||
14 * scale
|
||||
bounds.x + contentPaddingX + 6 * scale,
|
||||
bounds.y + bounds.h / 2 - itemSize / 2,
|
||||
itemSize,
|
||||
itemSize
|
||||
);
|
||||
} else {
|
||||
} else if (waypointData.text) {
|
||||
// Render the text
|
||||
parameters.context.fillStyle = "#000";
|
||||
parameters.context.textBaseline = "middle";
|
||||
parameters.context.fillText(renderLabel, pos.x + 6 * scale, pos.y + 0.5 * scale + yOffset);
|
||||
parameters.context.fillText(
|
||||
waypointData.text,
|
||||
bounds.x + contentPaddingX + 6 * scale,
|
||||
bounds.y + bounds.h / 2
|
||||
);
|
||||
parameters.context.textBaseline = "alphabetic";
|
||||
} else {
|
||||
assertAlways(false, "Waypoint has no item and text");
|
||||
}
|
||||
|
||||
// Render the small icon on the left
|
||||
this.waypointSprite.drawCentered(parameters.context, pos.x, pos.y + yOffset, 10 * scale);
|
||||
this.waypointSprite.drawCentered(
|
||||
parameters.context,
|
||||
bounds.x + contentPaddingX,
|
||||
bounds.y + bounds.h / 2,
|
||||
bounds.h * 0.7
|
||||
);
|
||||
}
|
||||
|
||||
parameters.context.textBaseline = "alphabetic";
|
||||
parameters.context.globalAlpha = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
import { GameRoot, enumLayer } from "./root";
|
||||
import { globalConfig } from "../core/config";
|
||||
import { createLogger } from "../core/logging";
|
||||
import {
|
||||
clamp,
|
||||
fastArrayDeleteValueIfContained,
|
||||
make2DUndefinedArray,
|
||||
fastArrayDeleteValue,
|
||||
} from "../core/utils";
|
||||
import { RandomNumberGenerator } from "../core/rng";
|
||||
import { clamp, fastArrayDeleteValueIfContained, make2DUndefinedArray } from "../core/utils";
|
||||
import { Vector } from "../core/vector";
|
||||
import { BaseItem } from "./base_item";
|
||||
import { enumColors } from "./colors";
|
||||
import { Entity } from "./entity";
|
||||
import { ColorItem } from "./items/color_item";
|
||||
import { ShapeItem } from "./items/shape_item";
|
||||
import { enumLayer, GameRoot } from "./root";
|
||||
import { enumSubShape } from "./shape_definition";
|
||||
import { RandomNumberGenerator } from "../core/rng";
|
||||
|
||||
const logger = createLogger("map_chunk");
|
||||
|
||||
@@ -206,7 +200,11 @@ export class MapChunk {
|
||||
}
|
||||
|
||||
const definition = this.root.shapeDefinitionMgr.getDefinitionFromSimpleShapes(subShapes);
|
||||
this.internalGeneratePatch(rng, shapePatchSize, new ShapeItem(definition));
|
||||
this.internalGeneratePatch(
|
||||
rng,
|
||||
shapePatchSize,
|
||||
this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,13 +272,13 @@ export class MapChunk {
|
||||
return true;
|
||||
}
|
||||
if (this.x === -1 && this.y === 0) {
|
||||
const definition = this.root.shapeDefinitionMgr.getShapeFromShortKey("CuCuCuCu");
|
||||
this.internalGeneratePatch(rng, 2, new ShapeItem(definition), globalConfig.mapChunkSize - 9, 7);
|
||||
const item = this.root.shapeDefinitionMgr.getShapeItemFromShortKey("CuCuCuCu");
|
||||
this.internalGeneratePatch(rng, 2, item, globalConfig.mapChunkSize - 9, 7);
|
||||
return true;
|
||||
}
|
||||
if (this.x === 0 && this.y === -1) {
|
||||
const definition = this.root.shapeDefinitionMgr.getShapeFromShortKey("RuRuRuRu");
|
||||
this.internalGeneratePatch(rng, 2, new ShapeItem(definition), 5, globalConfig.mapChunkSize - 7);
|
||||
const item = this.root.shapeDefinitionMgr.getShapeItemFromShortKey("RuRuRuRu");
|
||||
this.internalGeneratePatch(rng, 2, item, 5, globalConfig.mapChunkSize - 7);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -290,8 +288,8 @@ export class MapChunk {
|
||||
}
|
||||
|
||||
if (this.x === 5 && this.y === -2) {
|
||||
const definition = this.root.shapeDefinitionMgr.getShapeFromShortKey("SuSuSuSu");
|
||||
this.internalGeneratePatch(rng, 2, new ShapeItem(definition), 5, globalConfig.mapChunkSize - 7);
|
||||
const item = this.root.shapeDefinitionMgr.getShapeItemFromShortKey("SuSuSuSu");
|
||||
this.internalGeneratePatch(rng, 2, item, 5, globalConfig.mapChunkSize - 7);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { BasicSerializableObject } from "../savegame/serialization";
|
||||
import { GameRoot } from "./root";
|
||||
import { ShapeDefinition, enumSubShape } from "./shape_definition";
|
||||
import { createLogger } from "../core/logging";
|
||||
import { BasicSerializableObject } from "../savegame/serialization";
|
||||
import { enumColors } from "./colors";
|
||||
import { ShapeItem } from "./items/shape_item";
|
||||
import { GameRoot } from "./root";
|
||||
import { enumSubShape, ShapeDefinition } from "./shape_definition";
|
||||
|
||||
const logger = createLogger("shape_definition_manager");
|
||||
|
||||
@@ -19,15 +20,24 @@ export class ShapeDefinitionManager extends BasicSerializableObject {
|
||||
super();
|
||||
this.root = root;
|
||||
|
||||
/**
|
||||
* Store a cache from key -> definition
|
||||
* @type {Object<string, ShapeDefinition>}
|
||||
*/
|
||||
this.shapeKeyToDefinition = {};
|
||||
|
||||
/**
|
||||
* Store a cache from key -> item
|
||||
*/
|
||||
this.shapeKeyToItem = {};
|
||||
|
||||
// Caches operations in the form of 'operation:def1[:def2]'
|
||||
/** @type {Object.<string, Array<ShapeDefinition>|ShapeDefinition>} */
|
||||
this.operationCache = {};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns a shape instance from a given short key
|
||||
* @param {string} hash
|
||||
* @returns {ShapeDefinition}
|
||||
*/
|
||||
@@ -39,6 +49,29 @@ export class ShapeDefinitionManager extends BasicSerializableObject {
|
||||
return (this.shapeKeyToDefinition[hash] = ShapeDefinition.fromShortKey(hash));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a item instance from a given short key
|
||||
* @param {string} hash
|
||||
* @returns {ShapeItem}
|
||||
*/
|
||||
getShapeItemFromShortKey(hash) {
|
||||
const cached = this.shapeKeyToItem[hash];
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
const definition = this.getShapeFromShortKey(hash);
|
||||
return (this.shapeKeyToItem[hash] = new ShapeItem(definition));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a shape item for a given definition
|
||||
* @param {ShapeDefinition} definition
|
||||
* @returns {ShapeItem}
|
||||
*/
|
||||
getShapeItemFromDefinition(definition) {
|
||||
return this.getShapeItemFromShortKey(definition.getHash());
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new shape definition
|
||||
* @param {ShapeDefinition} definition
|
||||
|
||||
@@ -15,7 +15,7 @@ import { MapChunkView } from "../map_chunk_view";
|
||||
import { defaultBuildingVariant } from "../meta_building";
|
||||
import { getCodeFromBuildingData } from "../building_codes";
|
||||
|
||||
export const BELT_ANIM_COUNT = 28;
|
||||
export const BELT_ANIM_COUNT = 14;
|
||||
|
||||
const logger = createLogger("belt");
|
||||
|
||||
@@ -29,9 +29,9 @@ export class BeltSystem extends GameSystemWithFilter {
|
||||
* @type {Object.<enumDirection, Array<AtlasSprite>>}
|
||||
*/
|
||||
this.beltSprites = {
|
||||
[enumDirection.top]: Loader.getSprite("sprites/belt/forward_0.png"),
|
||||
[enumDirection.left]: Loader.getSprite("sprites/belt/left_0.png"),
|
||||
[enumDirection.right]: Loader.getSprite("sprites/belt/right_0.png"),
|
||||
[enumDirection.top]: Loader.getSprite("sprites/belt/built/forward_0.png"),
|
||||
[enumDirection.left]: Loader.getSprite("sprites/belt/built/left_0.png"),
|
||||
[enumDirection.right]: Loader.getSprite("sprites/belt/built/right_0.png"),
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -45,11 +45,13 @@ export class BeltSystem extends GameSystemWithFilter {
|
||||
|
||||
for (let i = 0; i < BELT_ANIM_COUNT; ++i) {
|
||||
this.beltAnimations[enumDirection.top].push(
|
||||
Loader.getSprite("sprites/belt/forward_" + i + ".png")
|
||||
Loader.getSprite("sprites/belt/built/forward_" + i + ".png")
|
||||
);
|
||||
this.beltAnimations[enumDirection.left].push(
|
||||
Loader.getSprite("sprites/belt/built/left_" + i + ".png")
|
||||
);
|
||||
this.beltAnimations[enumDirection.left].push(Loader.getSprite("sprites/belt/left_" + i + ".png"));
|
||||
this.beltAnimations[enumDirection.right].push(
|
||||
Loader.getSprite("sprites/belt/right_" + i + ".png")
|
||||
Loader.getSprite("sprites/belt/built/right_" + i + ".png")
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ export class BeltUnderlaysSystem extends GameSystemWithFilter {
|
||||
this.underlayBeltSprites = [];
|
||||
|
||||
for (let i = 0; i < BELT_ANIM_COUNT; ++i) {
|
||||
this.underlayBeltSprites.push(Loader.getSprite("sprites/belt/forward_" + i + ".png"));
|
||||
this.underlayBeltSprites.push(Loader.getSprite("sprites/belt/built/forward_" + i + ".png"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,28 +77,28 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
|
||||
this.wireSprites = {
|
||||
regular: {
|
||||
[enumWireType.regular]: Loader.getSprite("sprites/buildings/wire.png"),
|
||||
[enumWireType.turn]: Loader.getSprite("sprites/buildings/wire-turn.png"),
|
||||
[enumWireType.split]: Loader.getSprite("sprites/buildings/wire-split.png"),
|
||||
[enumWireType.cross]: Loader.getSprite("sprites/buildings/wire-cross.png"),
|
||||
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/regular_forward.png"),
|
||||
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/regular_turn.png"),
|
||||
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/regular_split.png"),
|
||||
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/regular_cross.png"),
|
||||
},
|
||||
conflict: {
|
||||
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/conflict.png"),
|
||||
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/conflict-turn.png"),
|
||||
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/conflict-split.png"),
|
||||
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/conflict-cross.png"),
|
||||
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/conflict_forward.png"),
|
||||
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/conflict_turn.png"),
|
||||
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/conflict_split.png"),
|
||||
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/conflict_cross.png"),
|
||||
},
|
||||
shape: {
|
||||
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/shape.png"),
|
||||
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/shape-turn.png"),
|
||||
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/shape-split.png"),
|
||||
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/shape-cross.png"),
|
||||
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/shape_forward.png"),
|
||||
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/shape_turn.png"),
|
||||
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/shape_split.png"),
|
||||
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/shape_cross.png"),
|
||||
},
|
||||
color: {
|
||||
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/color.png"),
|
||||
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/color-turn.png"),
|
||||
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/color-split.png"),
|
||||
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/color-cross.png"),
|
||||
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/color_forward.png"),
|
||||
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/color_turn.png"),
|
||||
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/color_split.png"),
|
||||
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/color_cross.png"),
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ export class PlatformWrapperInterface {
|
||||
* @returns {number}
|
||||
*/
|
||||
getMaximumZoom() {
|
||||
return 4 * this.getScreenScale();
|
||||
return 3.5 * this.getScreenScale();
|
||||
}
|
||||
|
||||
getScreenScale() {
|
||||
|
||||
Reference in New Issue
Block a user