Refactor static map entity component to store building metaclass
This commit is contained in:
parent
567db72538
commit
bf2eee908f
Binary file not shown.
Before Width: | Height: | Size: 2.0 KiB |
|
@ -29,7 +29,6 @@
|
||||||
.buildings {
|
.buildings {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-auto-flow: column;
|
grid-auto-flow: column;
|
||||||
@include S(margin-bottom, 2px);
|
|
||||||
|
|
||||||
.building {
|
.building {
|
||||||
color: $accentColorDark;
|
color: $accentColorDark;
|
||||||
|
@ -43,7 +42,7 @@
|
||||||
@include S(width, 35px);
|
@include S(width, 35px);
|
||||||
@include S(height, 40px);
|
@include S(height, 40px);
|
||||||
|
|
||||||
background: center center / 70% no-repeat;
|
background: center center / 65% no-repeat;
|
||||||
|
|
||||||
&:not(.unlocked) {
|
&:not(.unlocked) {
|
||||||
@include S(width, 20px);
|
@include S(width, 20px);
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
display: none;
|
display: none;
|
||||||
transform: translate(50%, 50%);
|
transform: translate(50%, 50%);
|
||||||
// filter: blur(10px);
|
filter: blur(D(3px));
|
||||||
|
|
||||||
$opacity: 0.2;
|
$opacity: 0.2;
|
||||||
&.loaded {
|
&.loaded {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { createLogger } from "./logging";
|
||||||
import { Signal } from "./signal";
|
import { Signal } from "./signal";
|
||||||
import { SOUNDS, MUSIC } from "../platform/sound";
|
import { SOUNDS, MUSIC } from "../platform/sound";
|
||||||
import { AtlasDefinition, atlasFiles } from "./atlas_definitions";
|
import { AtlasDefinition, atlasFiles } from "./atlas_definitions";
|
||||||
|
import { initBuildingCodesAfterResourcesLoaded } from "../game/meta_building_registry";
|
||||||
|
|
||||||
const logger = createLogger("background_loader");
|
const logger = createLogger("background_loader");
|
||||||
|
|
||||||
|
@ -116,6 +117,7 @@ export class BackgroundResourcesLoader {
|
||||||
logger.log("⏰ Finish load: bare game");
|
logger.log("⏰ Finish load: bare game");
|
||||||
Loader.createAtlasLinks();
|
Loader.createAtlasLinks();
|
||||||
this.bareGameReady = true;
|
this.bareGameReady = true;
|
||||||
|
initBuildingCodesAfterResourcesLoaded();
|
||||||
this.signalBareGameLoaded.dispatch();
|
this.signalBareGameLoaded.dispatch();
|
||||||
this.internalStartLoadingAdditionalGameAssets();
|
this.internalStartLoadingAdditionalGameAssets();
|
||||||
});
|
});
|
||||||
|
|
|
@ -81,10 +81,6 @@ export class Blueprint {
|
||||||
for (let i = 0; i < this.entities.length; ++i) {
|
for (let i = 0; i < this.entities.length; ++i) {
|
||||||
const entity = this.entities[i];
|
const entity = this.entities[i];
|
||||||
const staticComp = entity.components.StaticMapEntity;
|
const staticComp = entity.components.StaticMapEntity;
|
||||||
if (!staticComp.blueprintSpriteKey) {
|
|
||||||
logger.warn("Blueprint entity without sprite!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const newPos = staticComp.origin.add(tile);
|
const newPos = staticComp.origin.add(tile);
|
||||||
|
|
||||||
const rect = staticComp.getTileSpaceBounds();
|
const rect = staticComp.getTileSpaceBounds();
|
||||||
|
@ -98,7 +94,7 @@ export class Blueprint {
|
||||||
|
|
||||||
staticComp.drawSpriteOnFullEntityBounds(
|
staticComp.drawSpriteOnFullEntityBounds(
|
||||||
parameters,
|
parameters,
|
||||||
Loader.getSprite(staticComp.blueprintSpriteKey),
|
staticComp.getBlueprintSprite(),
|
||||||
0,
|
0,
|
||||||
true,
|
true,
|
||||||
newPos
|
newPos
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
import { MetaBuilding, defaultBuildingVariant } from "./meta_building";
|
||||||
|
import { AtlasSprite } from "../core/sprites";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{
|
||||||
|
* metaClass: typeof MetaBuilding,
|
||||||
|
* metaInstance?: MetaBuilding,
|
||||||
|
* variant?: string,
|
||||||
|
* rotationVariant?: number,
|
||||||
|
* sprite?: AtlasSprite,
|
||||||
|
* blueprintSprite?: AtlasSprite,
|
||||||
|
* silhouetteColor?: string
|
||||||
|
* }} BuildingVariantIdentifier
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores a lookup table for all building variants (for better performance)
|
||||||
|
* @type {Object<number, BuildingVariantIdentifier>}
|
||||||
|
*/
|
||||||
|
export const gBuildingVariants = {
|
||||||
|
// Set later
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {*} id
|
||||||
|
* @param {*} meta
|
||||||
|
* @param {*} variant
|
||||||
|
* @param {*} rotationVariant
|
||||||
|
*/
|
||||||
|
export function registerBuildingVariant(id, meta, variant = defaultBuildingVariant, rotationVariant = 0) {
|
||||||
|
assert(!gBuildingVariants[id], "Duplicate id: " + id);
|
||||||
|
gBuildingVariants[id] = {
|
||||||
|
metaClass: meta,
|
||||||
|
variant,
|
||||||
|
rotationVariant,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {number} code
|
||||||
|
* @returns {BuildingVariantIdentifier}
|
||||||
|
*/
|
||||||
|
export function getBuildingDataFromCode(code) {
|
||||||
|
assert(gBuildingVariants[code], "Invalid building code: " + code);
|
||||||
|
return gBuildingVariants[code];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the code for a given variant
|
||||||
|
* @param {MetaBuilding} metaBuilding
|
||||||
|
* @param {string} variant
|
||||||
|
* @param {number} rotationVariant
|
||||||
|
*/
|
||||||
|
export function getCodeFromBuildingData(metaBuilding, variant, rotationVariant) {
|
||||||
|
for (const key in gBuildingVariants) {
|
||||||
|
const data = gBuildingVariants[key];
|
||||||
|
if (
|
||||||
|
data.metaInstance.getId() === metaBuilding.getId() &&
|
||||||
|
data.variant === variant &&
|
||||||
|
data.rotationVariant === rotationVariant
|
||||||
|
) {
|
||||||
|
return +key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertAlways(
|
||||||
|
false,
|
||||||
|
"Building not found by data: " + metaBuilding.getId() + " / " + variant + " / " + rotationVariant
|
||||||
|
);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
import { Loader } from "../../core/loader";
|
|
||||||
import { formatItemsPerSecond } from "../../core/utils";
|
import { formatItemsPerSecond } from "../../core/utils";
|
||||||
import { enumAngleToDirection, enumDirection, Vector } from "../../core/vector";
|
import { enumAngleToDirection, enumDirection, Vector } from "../../core/vector";
|
||||||
import { SOUNDS } from "../../platform/sound";
|
import { SOUNDS } from "../../platform/sound";
|
||||||
|
@ -40,6 +39,10 @@ export class MetaBeltBaseBuilding extends MetaBuilding {
|
||||||
return SOUNDS.placeBelt;
|
return SOUNDS.placeBelt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSprite() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the entity at the given location
|
* Creates the entity at the given location
|
||||||
* @param {Entity} entity
|
* @param {Entity} entity
|
||||||
|
@ -88,7 +91,6 @@ export class MetaBeltBaseBuilding extends MetaBuilding {
|
||||||
updateVariants(entity, rotationVariant) {
|
updateVariants(entity, rotationVariant) {
|
||||||
entity.components.Belt.direction = arrayBeltVariantToRotation[rotationVariant];
|
entity.components.Belt.direction = arrayBeltVariantToRotation[rotationVariant];
|
||||||
entity.components.ItemEjector.slots[0].direction = arrayBeltVariantToRotation[rotationVariant];
|
entity.components.ItemEjector.slots[0].direction = arrayBeltVariantToRotation[rotationVariant];
|
||||||
entity.components.StaticMapEntity.spriteKey = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,6 +28,11 @@ export class MetaHubBuilding extends MetaBuilding {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSprite() {
|
||||||
|
// We render it ourself
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the entity at the given location
|
* Creates the entity at the given location
|
||||||
* @param {Entity} entity
|
* @param {Entity} entity
|
||||||
|
@ -41,9 +46,6 @@ export class MetaHubBuilding extends MetaBuilding {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
// We render the sprite ourself
|
|
||||||
entity.components.StaticMapEntity.spriteKey = null;
|
|
||||||
|
|
||||||
entity.addComponent(new UnremovableComponent());
|
entity.addComponent(new UnremovableComponent());
|
||||||
entity.addComponent(
|
entity.addComponent(
|
||||||
new ItemAcceptorComponent({
|
new ItemAcceptorComponent({
|
||||||
|
|
|
@ -71,6 +71,10 @@ export class MetaUndergroundBeltBuilding extends MetaBuilding {
|
||||||
return super.getAvailableVariants(root);
|
return super.getAvailableVariants(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} rotationVariant
|
||||||
|
* @param {string} variant
|
||||||
|
*/
|
||||||
getPreviewSprite(rotationVariant, variant) {
|
getPreviewSprite(rotationVariant, variant) {
|
||||||
let suffix = "";
|
let suffix = "";
|
||||||
if (variant !== defaultBuildingVariant) {
|
if (variant !== defaultBuildingVariant) {
|
||||||
|
@ -87,6 +91,10 @@ export class MetaUndergroundBeltBuilding extends MetaBuilding {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} rotationVariant
|
||||||
|
* @param {string} variant
|
||||||
|
*/
|
||||||
getBlueprintSprite(rotationVariant, variant) {
|
getBlueprintSprite(rotationVariant, variant) {
|
||||||
let suffix = "";
|
let suffix = "";
|
||||||
if (variant !== defaultBuildingVariant) {
|
if (variant !== defaultBuildingVariant) {
|
||||||
|
@ -103,6 +111,14 @@ export class MetaUndergroundBeltBuilding extends MetaBuilding {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} rotationVariant
|
||||||
|
* @param {string} variant
|
||||||
|
*/
|
||||||
|
getSprite(rotationVariant, variant) {
|
||||||
|
return this.getPreviewSprite(rotationVariant, variant);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {GameRoot} root
|
* @param {GameRoot} root
|
||||||
*/
|
*/
|
||||||
|
@ -201,10 +217,6 @@ export class MetaUndergroundBeltBuilding extends MetaBuilding {
|
||||||
*/
|
*/
|
||||||
updateVariants(entity, rotationVariant, variant) {
|
updateVariants(entity, rotationVariant, variant) {
|
||||||
entity.components.UndergroundBelt.tier = enumUndergroundBeltVariantToTier[variant];
|
entity.components.UndergroundBelt.tier = enumUndergroundBeltVariantToTier[variant];
|
||||||
entity.components.StaticMapEntity.spriteKey = this.getPreviewSprite(
|
|
||||||
rotationVariant,
|
|
||||||
variant
|
|
||||||
).spriteName;
|
|
||||||
|
|
||||||
switch (arrayUndergroundRotationVariantToMode[rotationVariant]) {
|
switch (arrayUndergroundRotationVariantToMode[rotationVariant]) {
|
||||||
case enumUndergroundBeltMode.sender: {
|
case enumUndergroundBeltMode.sender: {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { AtlasSprite } from "../../core/sprites";
|
||||||
import { enumDirection, Vector } from "../../core/vector";
|
import { enumDirection, Vector } from "../../core/vector";
|
||||||
import { types } from "../../savegame/serialization";
|
import { types } from "../../savegame/serialization";
|
||||||
import { Component } from "../component";
|
import { Component } from "../component";
|
||||||
|
import { getBuildingDataFromCode } from "../building_codes";
|
||||||
|
|
||||||
export class StaticMapEntityComponent extends Component {
|
export class StaticMapEntityComponent extends Component {
|
||||||
static getId() {
|
static getId() {
|
||||||
|
@ -17,21 +18,43 @@ export class StaticMapEntityComponent extends Component {
|
||||||
tileSize: types.tileVector,
|
tileSize: types.tileVector,
|
||||||
rotation: types.float,
|
rotation: types.float,
|
||||||
originalRotation: types.float,
|
originalRotation: types.float,
|
||||||
spriteKey: types.nullable(types.string),
|
|
||||||
blueprintSpriteKey: types.string,
|
// See building_codes.js
|
||||||
silhouetteColor: types.nullable(types.string),
|
code: types.uint,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the sprite
|
||||||
|
* @returns {AtlasSprite}
|
||||||
|
*/
|
||||||
|
getSprite() {
|
||||||
|
return getBuildingDataFromCode(this.code).sprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the blueprint sprite
|
||||||
|
* @returns {AtlasSprite}
|
||||||
|
*/
|
||||||
|
getBlueprintSprite() {
|
||||||
|
return getBuildingDataFromCode(this.code).blueprintSprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the silhouette color
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
getSilhouetteColor() {
|
||||||
|
return getBuildingDataFromCode(this.code).silhouetteColor;
|
||||||
|
}
|
||||||
|
|
||||||
duplicateWithoutContents() {
|
duplicateWithoutContents() {
|
||||||
return new StaticMapEntityComponent({
|
return new StaticMapEntityComponent({
|
||||||
origin: this.origin.copy(),
|
origin: this.origin.copy(),
|
||||||
tileSize: this.tileSize.copy(),
|
tileSize: this.tileSize.copy(),
|
||||||
rotation: this.rotation,
|
rotation: this.rotation,
|
||||||
originalRotation: this.originalRotation,
|
originalRotation: this.originalRotation,
|
||||||
spriteKey: this.spriteKey,
|
code: this.code,
|
||||||
silhouetteColor: this.silhouetteColor,
|
|
||||||
blueprintSpriteKey: this.blueprintSpriteKey,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,18 +65,14 @@ export class StaticMapEntityComponent extends Component {
|
||||||
* @param {Vector=} param0.tileSize Size of the entity in tiles
|
* @param {Vector=} param0.tileSize Size of the entity in tiles
|
||||||
* @param {number=} param0.rotation Rotation in degrees. Must be multiple of 90
|
* @param {number=} param0.rotation Rotation in degrees. Must be multiple of 90
|
||||||
* @param {number=} param0.originalRotation Original Rotation in degrees. Must be multiple of 90
|
* @param {number=} param0.originalRotation Original Rotation in degrees. Must be multiple of 90
|
||||||
* @param {string=} param0.spriteKey Optional sprite
|
* @param {number=} param0.code Building code
|
||||||
* @param {string} param0.blueprintSpriteKey Blueprint sprite, required
|
|
||||||
* @param {string=} param0.silhouetteColor Optional silhouette color override
|
|
||||||
*/
|
*/
|
||||||
constructor({
|
constructor({
|
||||||
origin = new Vector(),
|
origin = new Vector(),
|
||||||
tileSize = new Vector(1, 1),
|
tileSize = new Vector(1, 1),
|
||||||
rotation = 0,
|
rotation = 0,
|
||||||
originalRotation = 0,
|
originalRotation = 0,
|
||||||
spriteKey = null,
|
code = 0,
|
||||||
silhouetteColor = null,
|
|
||||||
blueprintSpriteKey = null,
|
|
||||||
}) {
|
}) {
|
||||||
super();
|
super();
|
||||||
assert(
|
assert(
|
||||||
|
@ -63,11 +82,9 @@ export class StaticMapEntityComponent extends Component {
|
||||||
|
|
||||||
this.origin = origin;
|
this.origin = origin;
|
||||||
this.tileSize = tileSize;
|
this.tileSize = tileSize;
|
||||||
this.spriteKey = spriteKey;
|
|
||||||
this.rotation = rotation;
|
this.rotation = rotation;
|
||||||
|
this.code = code;
|
||||||
this.originalRotation = originalRotation;
|
this.originalRotation = originalRotation;
|
||||||
this.silhouetteColor = silhouetteColor;
|
|
||||||
this.blueprintSpriteKey = blueprintSpriteKey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||||
import { HUDBuildingPlacerLogic } from "./building_placer_logic";
|
import { HUDBuildingPlacerLogic } from "./building_placer_logic";
|
||||||
import { makeOffscreenBuffer } from "../../../core/buffer_utils";
|
import { makeOffscreenBuffer } from "../../../core/buffer_utils";
|
||||||
import { enumLayer } from "../../root";
|
import { enumLayer } from "../../root";
|
||||||
|
import { getCodeFromBuildingData } from "../../building_codes";
|
||||||
|
|
||||||
export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
||||||
/**
|
/**
|
||||||
|
@ -84,9 +85,8 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
||||||
label: "lock-direction-indicator",
|
label: "lock-direction-indicator",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Loader.getSprite("sprites/misc/lock_direction_indicator.png").draw(context, 0, 0, 48, 48);
|
context.fillStyle = THEME.map.directionLock[layer].color;
|
||||||
context.fillStyle = THEME.map.directionLock[enumLayer.wires].color;
|
context.strokeStyle = THEME.map.directionLock[layer].color;
|
||||||
context.strokeStyle = THEME.map.directionLock[enumLayer.wires].color;
|
|
||||||
context.lineWidth = 2;
|
context.lineWidth = 2;
|
||||||
|
|
||||||
const padding = 5;
|
const padding = 5;
|
||||||
|
@ -313,6 +313,11 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
||||||
staticComp.rotation = rotation;
|
staticComp.rotation = rotation;
|
||||||
staticComp.tileSize = metaBuilding.getDimensions(this.currentVariant.get());
|
staticComp.tileSize = metaBuilding.getDimensions(this.currentVariant.get());
|
||||||
metaBuilding.updateVariants(this.fakeEntity, rotationVariant, this.currentVariant.get());
|
metaBuilding.updateVariants(this.fakeEntity, rotationVariant, this.currentVariant.get());
|
||||||
|
staticComp.code = getCodeFromBuildingData(
|
||||||
|
this.currentMetaBuilding.get(),
|
||||||
|
this.currentVariant.get(),
|
||||||
|
rotationVariant
|
||||||
|
);
|
||||||
|
|
||||||
const canBuild = this.root.logic.checkCanPlaceEntity(this.fakeEntity);
|
const canBuild = this.root.logic.checkCanPlaceEntity(this.fakeEntity);
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { SOUNDS } from "../../../platform/sound";
|
||||||
import { MetaMinerBuilding, enumMinerVariants } from "../../buildings/miner";
|
import { MetaMinerBuilding, enumMinerVariants } from "../../buildings/miner";
|
||||||
import { enumHubGoalRewards } from "../../tutorial_goals";
|
import { enumHubGoalRewards } from "../../tutorial_goals";
|
||||||
import { enumLayer } from "../../root";
|
import { enumLayer } from "../../root";
|
||||||
|
import { getBuildingDataFromCode, getCodeFromBuildingData } from "../../building_codes";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains all logic for the building placer - this doesn't include the rendering
|
* Contains all logic for the building placer - this doesn't include the rendering
|
||||||
|
@ -338,109 +339,26 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to extract the building
|
// Try to extract the building
|
||||||
const extracted = this.hack_reconstructMetaBuildingAndVariantFromBuilding(contents);
|
const buildingCode = contents.components.StaticMapEntity.code;
|
||||||
|
const extracted = getBuildingDataFromCode(buildingCode);
|
||||||
|
|
||||||
// If the building we are picking is the same as the one we have, clear the cursor.
|
// If the building we are picking is the same as the one we have, clear the cursor.
|
||||||
if (
|
if (
|
||||||
!extracted ||
|
extracted.metaInstance.getId() === this.currentMetaBuilding.get().getId() &&
|
||||||
(extracted.metaBuilding === this.currentMetaBuilding.get() &&
|
extracted.variant === this.currentVariant.get()
|
||||||
extracted.variant === this.currentVariant.get())
|
|
||||||
) {
|
) {
|
||||||
this.currentMetaBuilding.set(null);
|
this.currentMetaBuilding.set(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentMetaBuilding.set(extracted.metaBuilding);
|
this.currentMetaBuilding.set(extracted.metaInstance);
|
||||||
this.currentVariant.set(extracted.variant);
|
this.currentVariant.set(extracted.variant);
|
||||||
this.currentBaseRotation = contents.components.StaticMapEntity.rotation;
|
this.currentBaseRotation = contents.components.StaticMapEntity.rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HACK!
|
* Switches the side for the direction lock manually
|
||||||
*
|
|
||||||
* This attempts to reconstruct the meta building and its variant from a given entity
|
|
||||||
* @param {Entity} entity
|
|
||||||
* @returns {{ metaBuilding: MetaBuilding, variant: string }}
|
|
||||||
*/
|
*/
|
||||||
hack_reconstructMetaBuildingAndVariantFromBuilding(entity) {
|
|
||||||
if (entity.components.Hub) {
|
|
||||||
// Hub is not copyable
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const matches = [];
|
|
||||||
const metaBuildings = gMetaBuildingRegistry.entries;
|
|
||||||
for (let i = 0; i < metaBuildings.length; ++i) {
|
|
||||||
const metaBuilding = metaBuildings[i];
|
|
||||||
const availableVariants = metaBuilding.getAvailableVariants(this.root);
|
|
||||||
checkVariant: for (let k = 0; k < availableVariants.length; ++k) {
|
|
||||||
const variant = availableVariants[k];
|
|
||||||
let unplaced = metaBuilding.createEntity({
|
|
||||||
root: this.root,
|
|
||||||
variant,
|
|
||||||
origin: new Vector(0, 0),
|
|
||||||
rotation: 0,
|
|
||||||
originalRotation: 0,
|
|
||||||
rotationVariant: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Compare if both entities share the same components
|
|
||||||
for (let component in entity.components) {
|
|
||||||
if ((entity.components[component] == null) !== (unplaced.components[component] == null)) {
|
|
||||||
continue checkVariant;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for same item processor
|
|
||||||
if (
|
|
||||||
entity.components.ItemProcessor &&
|
|
||||||
entity.components.ItemProcessor.type != unplaced.components.ItemProcessor.type
|
|
||||||
) {
|
|
||||||
continue checkVariant;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for underground belt
|
|
||||||
if (
|
|
||||||
entity.components.UndergroundBelt &&
|
|
||||||
entity.components.UndergroundBelt.tier != unplaced.components.UndergroundBelt.tier
|
|
||||||
) {
|
|
||||||
continue checkVariant;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for same sprite key - except for underground belts
|
|
||||||
// since the sprite may vary here
|
|
||||||
if (
|
|
||||||
!entity.components.UndergroundBelt &&
|
|
||||||
entity.components.StaticMapEntity.spriteKey !=
|
|
||||||
unplaced.components.StaticMapEntity.spriteKey
|
|
||||||
) {
|
|
||||||
continue checkVariant;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (metaBuilding.id === "wire" && entity.layer !== enumLayer.wires) {
|
|
||||||
continue checkVariant;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (metaBuilding.id === "belt" && entity.layer !== enumLayer.regular) {
|
|
||||||
continue checkVariant;
|
|
||||||
}
|
|
||||||
matches.push({ metaBuilding, variant });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (matches.length == 1) {
|
|
||||||
const staticEntity = entity.components.StaticMapEntity;
|
|
||||||
const key = staticEntity.spriteKey || staticEntity.blueprintSpriteKey;
|
|
||||||
assert(
|
|
||||||
key &&
|
|
||||||
key.includes(matches[0].metaBuilding.id) &&
|
|
||||||
(matches[0].variant === defaultBuildingVariant || key.includes(matches[0].variant))
|
|
||||||
);
|
|
||||||
return matches[0];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
switchDirectionLockSide() {
|
switchDirectionLockSide() {
|
||||||
this.currentDirectionLockSide = 1 - this.currentDirectionLockSide;
|
this.currentDirectionLockSide = 1 - this.currentDirectionLockSide;
|
||||||
}
|
}
|
||||||
|
@ -673,7 +591,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
|
||||||
origin: new Vector(0, 0),
|
origin: new Vector(0, 0),
|
||||||
rotation: 0,
|
rotation: 0,
|
||||||
tileSize: metaBuilding.getDimensions(this.currentVariant.get()).copy(),
|
tileSize: metaBuilding.getDimensions(this.currentVariant.get()).copy(),
|
||||||
blueprintSpriteKey: "",
|
code: getCodeFromBuildingData(metaBuilding, variant, 0),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
metaBuilding.updateVariants(this.fakeEntity, 0, this.currentVariant.get());
|
metaBuilding.updateVariants(this.fakeEntity, 0, this.currentVariant.get());
|
||||||
|
|
|
@ -88,8 +88,8 @@ export class HUDDebugInfo extends BaseHUDPart {
|
||||||
const mouseTile = this.root.camera.screenToWorld(mousePos).toTileSpace();
|
const mouseTile = this.root.camera.screenToWorld(mousePos).toTileSpace();
|
||||||
const cameraTile = this.root.camera.center.toTileSpace();
|
const cameraTile = this.root.camera.center.toTileSpace();
|
||||||
|
|
||||||
this.trackedMousePosition.set(`Pos: <code>${mouseTile.x}</code> / <code>${mouseTile.y}</code>`);
|
this.trackedMousePosition.set(`Mouse: <code>${mouseTile.x}</code> / <code>${mouseTile.y}</code>`);
|
||||||
this.trackedCameraPosition.set(`Center: <code>${cameraTile.x}</code> / <code>${cameraTile.y}</code>`);
|
this.trackedCameraPosition.set(`Camera: <code>${cameraTile.x}</code> / <code>${cameraTile.y}</code>`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { SOUNDS } from "../platform/sound";
|
||||||
import { StaticMapEntityComponent } from "./components/static_map_entity";
|
import { StaticMapEntityComponent } from "./components/static_map_entity";
|
||||||
import { Entity } from "./entity";
|
import { Entity } from "./entity";
|
||||||
import { enumLayer, GameRoot } from "./root";
|
import { enumLayer, GameRoot } from "./root";
|
||||||
|
import { getCodeFromBuildingData } from "./building_codes";
|
||||||
|
|
||||||
export const defaultBuildingVariant = "default";
|
export const defaultBuildingVariant = "default";
|
||||||
|
|
||||||
|
@ -157,20 +158,13 @@ export class MetaBuilding {
|
||||||
createEntity({ root, origin, rotation, originalRotation, rotationVariant, variant }) {
|
createEntity({ root, origin, rotation, originalRotation, rotationVariant, variant }) {
|
||||||
const entity = new Entity(root);
|
const entity = new Entity(root);
|
||||||
entity.layer = this.getLayer();
|
entity.layer = this.getLayer();
|
||||||
const blueprintSprite = this.getBlueprintSprite(rotationVariant, variant);
|
|
||||||
entity.addComponent(
|
entity.addComponent(
|
||||||
new StaticMapEntityComponent({
|
new StaticMapEntityComponent({
|
||||||
spriteKey:
|
|
||||||
"sprites/buildings/" +
|
|
||||||
this.id +
|
|
||||||
(variant === defaultBuildingVariant ? "" : "-" + variant) +
|
|
||||||
".png",
|
|
||||||
origin: new Vector(origin.x, origin.y),
|
origin: new Vector(origin.x, origin.y),
|
||||||
rotation,
|
rotation,
|
||||||
originalRotation,
|
originalRotation,
|
||||||
tileSize: this.getDimensions(variant).copy(),
|
tileSize: this.getDimensions(variant).copy(),
|
||||||
silhouetteColor: this.getSilhouetteColor(),
|
code: getCodeFromBuildingData(this, variant, rotationVariant),
|
||||||
blueprintSpriteKey: blueprintSprite ? blueprintSprite.spriteName : "",
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
this.setupEntityComponents(entity, root);
|
this.setupEntityComponents(entity, root);
|
||||||
|
@ -178,6 +172,21 @@ export class MetaBuilding {
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the sprite for a given variant
|
||||||
|
* @param {number} rotationVariant
|
||||||
|
* @param {string} variant
|
||||||
|
* @returns {AtlasSprite}
|
||||||
|
*/
|
||||||
|
getSprite(rotationVariant, variant) {
|
||||||
|
return Loader.getSprite(
|
||||||
|
"sprites/buildings/" +
|
||||||
|
this.id +
|
||||||
|
(variant === defaultBuildingVariant ? "" : "-" + variant) +
|
||||||
|
".png"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should compute the optimal rotation variant on the given tile
|
* Should compute the optimal rotation variant on the given tile
|
||||||
* @param {object} param0
|
* @param {object} param0
|
||||||
|
|
|
@ -1,20 +1,25 @@
|
||||||
import { gMetaBuildingRegistry } from "../core/global_registries";
|
import { gMetaBuildingRegistry } from "../core/global_registries";
|
||||||
import { MetaBeltBaseBuilding } from "./buildings/belt_base";
|
import { createLogger } from "../core/logging";
|
||||||
import { MetaCutterBuilding } from "./buildings/cutter";
|
|
||||||
import { MetaMinerBuilding } from "./buildings/miner";
|
|
||||||
import { MetaMixerBuilding } from "./buildings/mixer";
|
|
||||||
import { MetaPainterBuilding } from "./buildings/painter";
|
|
||||||
import { MetaRotaterBuilding } from "./buildings/rotater";
|
|
||||||
import { MetaSplitterBuilding } from "./buildings/splitter";
|
|
||||||
import { MetaStackerBuilding } from "./buildings/stacker";
|
|
||||||
import { MetaTrashBuilding } from "./buildings/trash";
|
|
||||||
import { MetaUndergroundBeltBuilding } from "./buildings/underground_belt";
|
|
||||||
import { MetaHubBuilding } from "./buildings/hub";
|
|
||||||
import { MetaEnergyGenerator } from "./buildings/energy_generator";
|
|
||||||
import { MetaWireBaseBuilding } from "./buildings/wire_base";
|
|
||||||
import { MetaAdvancedProcessorBuilding } from "./buildings/advanced_processor";
|
import { MetaAdvancedProcessorBuilding } from "./buildings/advanced_processor";
|
||||||
import { MetaBeltBuilding } from "./buildings/belt";
|
import { MetaBeltBuilding } from "./buildings/belt";
|
||||||
import { MetaWireCrossingsBuilding } from "./buildings/wire_crossings";
|
import { MetaBeltBaseBuilding } from "./buildings/belt_base";
|
||||||
|
import { enumCutterVariants, MetaCutterBuilding } from "./buildings/cutter";
|
||||||
|
import { MetaEnergyGenerator } from "./buildings/energy_generator";
|
||||||
|
import { MetaHubBuilding } from "./buildings/hub";
|
||||||
|
import { enumMinerVariants, MetaMinerBuilding } from "./buildings/miner";
|
||||||
|
import { MetaMixerBuilding } from "./buildings/mixer";
|
||||||
|
import { enumPainterVariants, MetaPainterBuilding } from "./buildings/painter";
|
||||||
|
import { enumRotaterVariants, MetaRotaterBuilding } from "./buildings/rotater";
|
||||||
|
import { enumSplitterVariants, MetaSplitterBuilding } from "./buildings/splitter";
|
||||||
|
import { MetaStackerBuilding } from "./buildings/stacker";
|
||||||
|
import { enumTrashVariants, MetaTrashBuilding } from "./buildings/trash";
|
||||||
|
import { enumUndergroundBeltVariants, MetaUndergroundBeltBuilding } from "./buildings/underground_belt";
|
||||||
|
import { MetaWireBaseBuilding } from "./buildings/wire_base";
|
||||||
|
import { enumWireCrossingVariants, MetaWireCrossingsBuilding } from "./buildings/wire_crossings";
|
||||||
|
import { gBuildingVariants, registerBuildingVariant } from "./building_codes";
|
||||||
|
import { defaultBuildingVariant } from "./meta_building";
|
||||||
|
|
||||||
|
const logger = createLogger("building_registry");
|
||||||
|
|
||||||
export function initMetaBuildingRegistry() {
|
export function initMetaBuildingRegistry() {
|
||||||
gMetaBuildingRegistry.register(MetaSplitterBuilding);
|
gMetaBuildingRegistry.register(MetaSplitterBuilding);
|
||||||
|
@ -32,4 +37,106 @@ export function initMetaBuildingRegistry() {
|
||||||
gMetaBuildingRegistry.register(MetaWireBaseBuilding);
|
gMetaBuildingRegistry.register(MetaWireBaseBuilding);
|
||||||
gMetaBuildingRegistry.register(MetaAdvancedProcessorBuilding);
|
gMetaBuildingRegistry.register(MetaAdvancedProcessorBuilding);
|
||||||
gMetaBuildingRegistry.register(MetaWireCrossingsBuilding);
|
gMetaBuildingRegistry.register(MetaWireCrossingsBuilding);
|
||||||
|
|
||||||
|
// Belt
|
||||||
|
registerBuildingVariant(1, MetaBeltBaseBuilding, defaultBuildingVariant, 0);
|
||||||
|
registerBuildingVariant(2, MetaBeltBaseBuilding, defaultBuildingVariant, 1);
|
||||||
|
registerBuildingVariant(3, MetaBeltBaseBuilding, defaultBuildingVariant, 2);
|
||||||
|
|
||||||
|
// Splitter
|
||||||
|
registerBuildingVariant(4, MetaSplitterBuilding);
|
||||||
|
registerBuildingVariant(5, MetaSplitterBuilding, enumSplitterVariants.compact);
|
||||||
|
registerBuildingVariant(6, MetaSplitterBuilding, enumSplitterVariants.compactInverse);
|
||||||
|
|
||||||
|
// Miner
|
||||||
|
registerBuildingVariant(7, MetaMinerBuilding);
|
||||||
|
registerBuildingVariant(8, MetaMinerBuilding, enumMinerVariants.chainable);
|
||||||
|
|
||||||
|
// Cutter
|
||||||
|
registerBuildingVariant(9, MetaCutterBuilding);
|
||||||
|
registerBuildingVariant(10, MetaCutterBuilding, enumCutterVariants.quad);
|
||||||
|
|
||||||
|
// Rotater
|
||||||
|
registerBuildingVariant(11, MetaRotaterBuilding);
|
||||||
|
registerBuildingVariant(12, MetaRotaterBuilding, enumRotaterVariants.ccw);
|
||||||
|
registerBuildingVariant(13, MetaRotaterBuilding, enumRotaterVariants.fl);
|
||||||
|
|
||||||
|
// Stacker
|
||||||
|
registerBuildingVariant(14, MetaStackerBuilding);
|
||||||
|
|
||||||
|
// Mixer
|
||||||
|
registerBuildingVariant(15, MetaMixerBuilding);
|
||||||
|
|
||||||
|
// Painter
|
||||||
|
registerBuildingVariant(16, MetaPainterBuilding);
|
||||||
|
registerBuildingVariant(17, MetaPainterBuilding, enumPainterVariants.mirrored);
|
||||||
|
registerBuildingVariant(18, MetaPainterBuilding, enumPainterVariants.double);
|
||||||
|
registerBuildingVariant(19, MetaPainterBuilding, enumPainterVariants.quad);
|
||||||
|
|
||||||
|
// Trash
|
||||||
|
registerBuildingVariant(20, MetaTrashBuilding);
|
||||||
|
registerBuildingVariant(21, MetaTrashBuilding, enumTrashVariants.storage);
|
||||||
|
|
||||||
|
// Underground belt
|
||||||
|
registerBuildingVariant(22, MetaUndergroundBeltBuilding, defaultBuildingVariant, 0);
|
||||||
|
registerBuildingVariant(23, MetaUndergroundBeltBuilding, defaultBuildingVariant, 1);
|
||||||
|
registerBuildingVariant(24, MetaUndergroundBeltBuilding, enumUndergroundBeltVariants.tier2, 0);
|
||||||
|
registerBuildingVariant(25, MetaUndergroundBeltBuilding, enumUndergroundBeltVariants.tier2, 1);
|
||||||
|
|
||||||
|
// Hub
|
||||||
|
registerBuildingVariant(26, MetaHubBuilding);
|
||||||
|
|
||||||
|
// Energy generator
|
||||||
|
registerBuildingVariant(27, MetaEnergyGenerator);
|
||||||
|
|
||||||
|
// Wire
|
||||||
|
registerBuildingVariant(28, MetaWireBaseBuilding, defaultBuildingVariant, 0);
|
||||||
|
registerBuildingVariant(29, MetaWireBaseBuilding, defaultBuildingVariant, 1);
|
||||||
|
registerBuildingVariant(30, MetaWireBaseBuilding, defaultBuildingVariant, 2);
|
||||||
|
|
||||||
|
// Advanced processor
|
||||||
|
registerBuildingVariant(31, MetaAdvancedProcessorBuilding);
|
||||||
|
|
||||||
|
// Wire crossing
|
||||||
|
registerBuildingVariant(32, MetaWireCrossingsBuilding);
|
||||||
|
registerBuildingVariant(33, MetaWireCrossingsBuilding, enumWireCrossingVariants.merger);
|
||||||
|
|
||||||
|
// Propagate instances
|
||||||
|
for (const key in gBuildingVariants) {
|
||||||
|
gBuildingVariants[key].metaInstance = gMetaBuildingRegistry.findByClass(
|
||||||
|
gBuildingVariants[key].metaClass
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const key in gBuildingVariants) {
|
||||||
|
const variant = gBuildingVariants[key];
|
||||||
|
assert(variant.metaClass, "Variant has no meta: " + key);
|
||||||
|
|
||||||
|
if (typeof variant.rotationVariant === "undefined") {
|
||||||
|
variant.rotationVariant = 0;
|
||||||
|
}
|
||||||
|
if (typeof variant.variant === "undefined") {
|
||||||
|
variant.variant = defaultBuildingVariant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.log("Registered", gMetaBuildingRegistry.getNumEntries(), "buildings");
|
||||||
|
logger.log("Registered", Object.keys(gBuildingVariants).length, "building codes");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Once all sprites are loaded, propagates the cache
|
||||||
|
*/
|
||||||
|
export function initBuildingCodesAfterResourcesLoaded() {
|
||||||
|
logger.log("Propagating sprite cache");
|
||||||
|
for (const key in gBuildingVariants) {
|
||||||
|
const variant = gBuildingVariants[key];
|
||||||
|
|
||||||
|
variant.sprite = variant.metaInstance.getSprite(variant.rotationVariant, variant.variant);
|
||||||
|
variant.blueprintSprite = variant.metaInstance.getBlueprintSprite(
|
||||||
|
variant.rotationVariant,
|
||||||
|
variant.variant
|
||||||
|
);
|
||||||
|
variant.silhouetteColor = variant.metaInstance.getSilhouetteColor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ export class StaticMapEntitySystem extends GameSystem {
|
||||||
const staticComp = entity.components.StaticMapEntity;
|
const staticComp = entity.components.StaticMapEntity;
|
||||||
if (drawOutlinesOnly) {
|
if (drawOutlinesOnly) {
|
||||||
const rect = staticComp.getTileSpaceBounds();
|
const rect = staticComp.getTileSpaceBounds();
|
||||||
parameters.context.fillStyle = staticComp.silhouetteColor || "#aaa";
|
parameters.context.fillStyle = staticComp.getSilhouetteColor() || "#aaa";
|
||||||
const beltComp = entity.components.Belt;
|
const beltComp = entity.components.Belt;
|
||||||
if (beltComp) {
|
if (beltComp) {
|
||||||
const sprite = this.beltOverviewSprites[beltComp.direction];
|
const sprite = this.beltOverviewSprites[beltComp.direction];
|
||||||
|
@ -58,9 +58,8 @@ export class StaticMapEntitySystem extends GameSystem {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const spriteKey = staticComp.spriteKey;
|
const sprite = staticComp.getSprite();
|
||||||
if (spriteKey) {
|
if (sprite) {
|
||||||
const sprite = Loader.getSprite(spriteKey);
|
|
||||||
staticComp.drawSpriteOnFullEntityBounds(parameters, sprite, 2, false);
|
staticComp.drawSpriteOnFullEntityBounds(parameters, sprite, 2, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,9 +90,8 @@ export class StaticMapEntitySystem extends GameSystem {
|
||||||
drawnUids.add(entity.uid);
|
drawnUids.add(entity.uid);
|
||||||
const staticComp = entity.components.StaticMapEntity;
|
const staticComp = entity.components.StaticMapEntity;
|
||||||
|
|
||||||
const spriteKey = staticComp.spriteKey;
|
const sprite = staticComp.getSprite();
|
||||||
if (spriteKey) {
|
if (sprite) {
|
||||||
const sprite = Loader.getSprite(spriteKey);
|
|
||||||
staticComp.drawSpriteOnFullEntityBounds(parameters, sprite, 2, false);
|
staticComp.drawSpriteOnFullEntityBounds(parameters, sprite, 2, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ function decompressInt(s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sanity
|
// Sanity
|
||||||
|
if (G_IS_DEV) {
|
||||||
for (let i = 0; i < 10000; ++i) {
|
for (let i = 0; i < 10000; ++i) {
|
||||||
if (decompressInt(compressInt(i)) !== i) {
|
if (decompressInt(compressInt(i)) !== i) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
@ -56,6 +57,7 @@ for (let i = 0; i < 10000; ++i) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function compressObjectInternal(obj, keys = [], values = []) {
|
function compressObjectInternal(obj, keys = [], values = []) {
|
||||||
if (Array.isArray(obj)) {
|
if (Array.isArray(obj)) {
|
||||||
|
|
Reference in New Issue