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.
316 lines
9.1 KiB
316 lines
9.1 KiB
import { Loader } from "../../core/loader";
|
|
import { generateMatrixRotations } from "../../core/utils";
|
|
import { enumDirection, Vector } from "../../core/vector";
|
|
import { SOUNDS } from "../../platform/sound";
|
|
import { enumWireType, enumWireVariant, WireComponent } from "../components/wire";
|
|
import { Entity } from "../entity";
|
|
import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
|
|
import { GameRoot } from "../root";
|
|
import { enumHubGoalRewards } from "../tutorial_goals";
|
|
|
|
export const arrayWireRotationVariantToType = [
|
|
enumWireType.forward,
|
|
enumWireType.turn,
|
|
enumWireType.split,
|
|
enumWireType.cross,
|
|
];
|
|
|
|
export const wireOverlayMatrices = {
|
|
[enumWireType.forward]: generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]),
|
|
[enumWireType.split]: generateMatrixRotations([0, 0, 0, 1, 1, 1, 0, 1, 0]),
|
|
[enumWireType.turn]: generateMatrixRotations([0, 0, 0, 0, 1, 1, 0, 1, 0]),
|
|
[enumWireType.cross]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 0]),
|
|
};
|
|
|
|
/** @enum {string} */
|
|
export const wireVariants = {
|
|
second: "second",
|
|
};
|
|
|
|
const enumWireVariantToVariant = {
|
|
[defaultBuildingVariant]: enumWireVariant.first,
|
|
[wireVariants.second]: enumWireVariant.second,
|
|
};
|
|
|
|
export class MetaWireBuilding extends MetaBuilding {
|
|
constructor() {
|
|
super("wire");
|
|
}
|
|
|
|
static getAllVariantCombinations() {
|
|
return [
|
|
{
|
|
internalId: 27,
|
|
variant: defaultBuildingVariant,
|
|
rotationVariant: 0,
|
|
},
|
|
{
|
|
internalId: 28,
|
|
variant: defaultBuildingVariant,
|
|
rotationVariant: 1,
|
|
},
|
|
{
|
|
internalId: 29,
|
|
variant: defaultBuildingVariant,
|
|
rotationVariant: 2,
|
|
},
|
|
{
|
|
internalId: 30,
|
|
variant: defaultBuildingVariant,
|
|
rotationVariant: 3,
|
|
},
|
|
{
|
|
internalId: 52,
|
|
variant: enumWireVariant.second,
|
|
rotationVariant: 0,
|
|
},
|
|
{
|
|
internalId: 53,
|
|
variant: enumWireVariant.second,
|
|
rotationVariant: 1,
|
|
},
|
|
{
|
|
internalId: 54,
|
|
variant: enumWireVariant.second,
|
|
rotationVariant: 2,
|
|
},
|
|
{
|
|
internalId: 55,
|
|
variant: enumWireVariant.second,
|
|
rotationVariant: 3,
|
|
},
|
|
];
|
|
}
|
|
|
|
getHasDirectionLockAvailable() {
|
|
return true;
|
|
}
|
|
|
|
getSilhouetteColor() {
|
|
return "#61ef6f";
|
|
}
|
|
|
|
getAvailableVariants() {
|
|
return [defaultBuildingVariant, wireVariants.second];
|
|
}
|
|
|
|
getDimensions() {
|
|
return new Vector(1, 1);
|
|
}
|
|
|
|
getStayInPlacementMode() {
|
|
return true;
|
|
}
|
|
|
|
getPlacementSound() {
|
|
return SOUNDS.placeBelt;
|
|
}
|
|
|
|
getRotateAutomaticallyWhilePlacing() {
|
|
return true;
|
|
}
|
|
|
|
/** @returns {"wires"} **/
|
|
getLayer() {
|
|
return "wires";
|
|
}
|
|
|
|
getSprite() {
|
|
return null;
|
|
}
|
|
|
|
getIsReplaceable() {
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @param {GameRoot} root
|
|
*/
|
|
getIsUnlocked(root) {
|
|
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_painter_and_levers);
|
|
}
|
|
|
|
/**
|
|
* Creates the entity at the given location
|
|
* @param {Entity} entity
|
|
*/
|
|
setupEntityComponents(entity) {
|
|
entity.addComponent(new WireComponent({}));
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {Entity} entity
|
|
* @param {number} rotationVariant
|
|
* @param {string} variant
|
|
*/
|
|
updateVariants(entity, rotationVariant, variant) {
|
|
entity.components.Wire.type = arrayWireRotationVariantToType[rotationVariant];
|
|
entity.components.Wire.variant = enumWireVariantToVariant[variant];
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {number} rotation
|
|
* @param {number} rotationVariant
|
|
* @param {string} variant
|
|
* @param {Entity} entity
|
|
*/
|
|
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
|
|
return wireOverlayMatrices[entity.components.Wire.type][rotation];
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {number} rotationVariant
|
|
* @param {string} variant
|
|
* @returns {import("../../core/draw_utils").AtlasSprite}
|
|
*/
|
|
getPreviewSprite(rotationVariant, variant) {
|
|
const wireVariant = enumWireVariantToVariant[variant];
|
|
switch (arrayWireRotationVariantToType[rotationVariant]) {
|
|
case enumWireType.forward: {
|
|
return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_forward.png");
|
|
}
|
|
case enumWireType.turn: {
|
|
return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_turn.png");
|
|
}
|
|
case enumWireType.split: {
|
|
return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_split.png");
|
|
}
|
|
case enumWireType.cross: {
|
|
return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_cross.png");
|
|
}
|
|
default: {
|
|
assertAlways(false, "Invalid wire rotation variant");
|
|
}
|
|
}
|
|
}
|
|
|
|
getBlueprintSprite(rotationVariant, variant) {
|
|
return this.getPreviewSprite(rotationVariant, variant);
|
|
}
|
|
|
|
/**
|
|
* Should compute the optimal rotation variant on the given tile
|
|
* @param {object} param0
|
|
* @param {GameRoot} param0.root
|
|
* @param {Vector} param0.tile
|
|
* @param {number} param0.rotation
|
|
* @param {string} param0.variant
|
|
* @param {string} param0.layer
|
|
* @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array<Entity> }}
|
|
*/
|
|
computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) {
|
|
const wireVariant = enumWireVariantToVariant[variant];
|
|
const connections = {
|
|
top: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.top }),
|
|
right: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.right }),
|
|
bottom: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.bottom }),
|
|
left: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.left }),
|
|
};
|
|
|
|
let flag = 0;
|
|
flag |= connections.top ? 0x1000 : 0;
|
|
flag |= connections.right ? 0x100 : 0;
|
|
flag |= connections.bottom ? 0x10 : 0;
|
|
flag |= connections.left ? 0x1 : 0;
|
|
|
|
let targetType = enumWireType.forward;
|
|
|
|
// First, reset rotation
|
|
rotation = 0;
|
|
|
|
switch (flag) {
|
|
case 0x0000:
|
|
// Nothing
|
|
break;
|
|
|
|
case 0x0001:
|
|
// Left
|
|
rotation += 90;
|
|
break;
|
|
|
|
case 0x0010:
|
|
// Bottom
|
|
// END
|
|
break;
|
|
|
|
case 0x0011:
|
|
// Bottom | Left
|
|
targetType = enumWireType.turn;
|
|
rotation += 90;
|
|
break;
|
|
|
|
case 0x0100:
|
|
// Right
|
|
rotation += 90;
|
|
break;
|
|
|
|
case 0x0101:
|
|
// Right | Left
|
|
rotation += 90;
|
|
break;
|
|
|
|
case 0x0110:
|
|
// Right | Bottom
|
|
targetType = enumWireType.turn;
|
|
break;
|
|
|
|
case 0x0111:
|
|
// Right | Bottom | Left
|
|
targetType = enumWireType.split;
|
|
break;
|
|
|
|
case 0x1000:
|
|
// Top
|
|
break;
|
|
|
|
case 0x1001:
|
|
// Top | Left
|
|
targetType = enumWireType.turn;
|
|
rotation += 180;
|
|
break;
|
|
|
|
case 0x1010:
|
|
// Top | Bottom
|
|
break;
|
|
|
|
case 0x1011:
|
|
// Top | Bottom | Left
|
|
targetType = enumWireType.split;
|
|
rotation += 90;
|
|
break;
|
|
|
|
case 0x1100:
|
|
// Top | Right
|
|
targetType = enumWireType.turn;
|
|
rotation -= 90;
|
|
break;
|
|
|
|
case 0x1101:
|
|
// Top | Right | Left
|
|
targetType = enumWireType.split;
|
|
rotation += 180;
|
|
break;
|
|
|
|
case 0x1110:
|
|
// Top | Right | Bottom
|
|
targetType = enumWireType.split;
|
|
rotation -= 90;
|
|
break;
|
|
|
|
case 0x1111:
|
|
// Top | Right | Bottom | Left
|
|
targetType = enumWireType.cross;
|
|
break;
|
|
}
|
|
|
|
return {
|
|
// Clamp rotation
|
|
rotation: (rotation + 360 * 10) % 360,
|
|
rotationVariant: arrayWireRotationVariantToType.indexOf(targetType),
|
|
};
|
|
}
|
|
}
|