Add building speed infos to all buildings

pull/33/head
tobspr 4 years ago
parent 97f52f509b
commit d58d15ef8c

@ -40,6 +40,17 @@
}
}
.additionalInfo {
display: grid;
grid-template-columns: auto 1fr;
label {
color: lighten($colorGreenBright, 10);
font-weight: bold;
@include S(margin-right, 5px);
}
}
.hotkey {
color: lighten($colorGreenBright, 10);
font-weight: bold;

@ -49,11 +49,11 @@ export const globalConfig = {
cutterQuad: 1 / 4,
rotater: 1 / 1,
rotaterCCW: 1 / 1,
painter: 1 / 3,
painterDouble: 1 / 3,
painterQuad: 1 / 3,
mixer: 1 / 2,
stacker: 1 / 5,
painter: 1 / 6,
painterDouble: 1 / 7,
painterQuad: 1 / 7,
mixer: 1 / 5,
stacker: 1 / 6,
},
// Zooming
@ -76,7 +76,7 @@ export const globalConfig = {
debug: {
/* dev:start */
fastGameEnter: true,
// fastGameEnter: true,
noArtificialDelays: true,
// disableSavegameWrite: true,
showEntityBounds: false,
@ -87,7 +87,7 @@ export const globalConfig = {
disableZoomLimits: false,
showChunkBorders: false,
rewardsInstant: false,
// allBuildingsUnlocked: true,
allBuildingsUnlocked: true,
upgradesNoCost: true,
disableUnlockDialog: true,
// testTranslations: true,
@ -114,5 +114,4 @@ export const IS_MOBILE = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
globalConfig.physicsDeltaMs = 1000.0 / globalConfig.physicsUpdateRate;
globalConfig.physicsDeltaSeconds = 1.0 / globalConfig.physicsUpdateRate;
globalConfig.minerSpeedItemsPerSecond =
globalConfig.beltSpeedItemsPerSecond / globalConfig.itemSpacingOnBelts / 6;
globalConfig.minerSpeedItemsPerSecond = globalConfig.beltSpeedItemsPerSecond / 5;

@ -900,3 +900,15 @@ export function generateFileDownload(filename, text) {
export function capitalizeFirstLetter(str) {
return str.substr(0, 1).toUpperCase() + str.substr(1).toLowerCase();
}
/**
* Formats a number like 2.5 to "2.5 items / s"
* @param {number} speed
* @param {boolean=} double
*/
export function formatItemsPerSecond(speed, double = false) {
return speed === 1.0
? T.ingame.buildingPlacement.infoTexts.oneItemPerSecond
: T.ingame.buildingPlacement.infoTexts.itemsPerSecond.replace("<x>", "" + round2Digits(speed)) +
(double ? " " + T.ingame.buildingPlacement.infoTexts.itemsPerSecondDouble : "");
}

@ -8,6 +8,9 @@ import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { GameRoot } from "../root";
import { SOUNDS } from "../../platform/sound";
import { T } from "../../translations";
import { round1Digit, formatItemsPerSecond } from "../../core/utils";
import { globalConfig } from "../../core/config";
export const arrayBeltVariantToRotation = [enumDirection.top, enumDirection.left, enumDirection.right];
@ -20,6 +23,17 @@ export class MetaBeltBaseBuilding extends MetaBuilding {
return "#777";
}
/**
* @param {GameRoot} root
* @param {string} variant
* @returns {Array<[string, string]>}
*/
getAdditionalStatistics(root, variant) {
const beltSpeed = root.hubGoals.getBeltBaseSpeed();
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(beltSpeed)]];
}
getPreviewSprite(rotationVariant) {
switch (arrayBeltVariantToRotation[rotationVariant]) {
case enumDirection.top: {

@ -7,6 +7,8 @@ import { Entity } from "../entity";
import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
import { GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals";
import { T } from "../../translations";
import { formatItemsPerSecond } from "../../core/utils";
/** @enum {string} */
export const enumCutterVariants = { quad: "quad" };
@ -31,6 +33,20 @@ export class MetaCutterBuilding extends MetaBuilding {
}
}
/**
* @param {GameRoot} root
* @param {string} variant
* @returns {Array<[string, string]>}
*/
getAdditionalStatistics(root, variant) {
const speed = root.hubGoals.getProcessorBaseSpeed(
variant === enumCutterVariants.quad
? enumItemProcessorTypes.cutterQuad
: enumItemProcessorTypes.cutter
);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
}
/**
* @param {GameRoot} root
*/

@ -5,6 +5,8 @@ import { Entity } from "../entity";
import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
import { GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals";
import { T } from "../../translations";
import { round1Digit, round2Digits, formatItemsPerSecond } from "../../core/utils";
/** @enum {string} */
export const enumMinerVariants = { chainable: "chainable" };
@ -18,6 +20,16 @@ export class MetaMinerBuilding extends MetaBuilding {
return "#b37dcd";
}
/**
* @param {GameRoot} root
* @param {string} variant
* @returns {Array<[string, string]>}
*/
getAdditionalStatistics(root, variant) {
const speed = root.hubGoals.getMinerBaseSpeed();
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
}
/**
*
* @param {GameRoot} root

@ -7,6 +7,8 @@ import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals";
import { T } from "../../translations";
import { formatItemsPerSecond } from "../../core/utils";
export class MetaMixerBuilding extends MetaBuilding {
constructor() {
@ -28,6 +30,16 @@ export class MetaMixerBuilding extends MetaBuilding {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_mixer);
}
/**
* @param {GameRoot} root
* @param {string} variant
* @returns {Array<[string, string]>}
*/
getAdditionalStatistics(root, variant) {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.mixer);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
}
/**
* Creates the entity at the given location
* @param {Entity} entity

@ -7,6 +7,8 @@ import { Entity } from "../entity";
import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
import { enumHubGoalRewards } from "../tutorial_goals";
import { GameRoot } from "../root";
import { T } from "../../translations";
import { formatItemsPerSecond } from "../../core/utils";
/** @enum {string} */
export const enumPainterVariants = { double: "double", quad: "quad" };
@ -33,6 +35,28 @@ export class MetaPainterBuilding extends MetaBuilding {
return "#cd9b7d";
}
/**
* @param {GameRoot} root
* @param {string} variant
* @returns {Array<[string, string]>}
*/
getAdditionalStatistics(root, variant) {
switch (variant) {
case defaultBuildingVariant: {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.painter);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
}
case enumPainterVariants.double: {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.painterDouble);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed, true)]];
}
case enumPainterVariants.quad: {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.painterQuad);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
}
}
}
/**
* @param {GameRoot} root
*/

@ -7,6 +7,8 @@ import { Entity } from "../entity";
import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
import { enumHubGoalRewards } from "../tutorial_goals";
import { GameRoot } from "../root";
import { T } from "../../translations";
import { formatItemsPerSecond } from "../../core/utils";
/** @enum {string} */
export const enumRotaterVariants = { ccw: "ccw" };
@ -20,6 +22,20 @@ export class MetaRotaterBuilding extends MetaBuilding {
return "#7dc6cd";
}
/**
* @param {GameRoot} root
* @param {string} variant
* @returns {Array<[string, string]>}
*/
getAdditionalStatistics(root, variant) {
const speed = root.hubGoals.getProcessorBaseSpeed(
variant === enumRotaterVariants.ccw
? enumItemProcessorTypes.rotaterCCW
: enumItemProcessorTypes.rotater
);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
}
/**
*
* @param {GameRoot} root

@ -7,6 +7,8 @@ import { Entity } from "../entity";
import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
import { GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals";
import { T } from "../../translations";
import { formatItemsPerSecond } from "../../core/utils";
/** @enum {string} */
export const enumSplitterVariants = { compact: "compact", compactInverse: "compact-inverse" };
@ -28,6 +30,16 @@ export class MetaSplitterBuilding extends MetaBuilding {
}
}
/**
* @param {GameRoot} root
* @param {string} variant
* @returns {Array<[string, string]>}
*/
getAdditionalStatistics(root, variant) {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.splitter);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
}
getSilhouetteColor() {
return "#444";
}

@ -7,6 +7,8 @@ import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals";
import { formatItemsPerSecond } from "../../core/utils";
import { T } from "../../translations";
export class MetaStackerBuilding extends MetaBuilding {
constructor() {
@ -21,6 +23,16 @@ export class MetaStackerBuilding extends MetaBuilding {
return new Vector(2, 1);
}
/**
* @param {GameRoot} root
* @param {string} variant
* @returns {Array<[string, string]>}
*/
getAdditionalStatistics(root, variant) {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.stacker);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
}
/**
* @param {GameRoot} root
*/

@ -8,6 +8,8 @@ import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
import { GameRoot } from "../root";
import { globalConfig } from "../../core/config";
import { enumHubGoalRewards } from "../tutorial_goals";
import { formatItemsPerSecond } from "../../core/utils";
import { T } from "../../translations";
/** @enum {string} */
export const arrayUndergroundRotationVariantToMode = [
@ -40,6 +42,16 @@ export class MetaUndergroundBeltBuilding extends MetaBuilding {
return true;
}
/**
* @param {GameRoot} root
* @param {string} variant
* @returns {Array<[string, string]>}
*/
getAdditionalStatistics(root, variant) {
const beltSpeed = root.hubGoals.getUndergroundBeltBaseSpeed();
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(beltSpeed)]];
}
/**
* @param {GameRoot} root
*/

@ -4,7 +4,7 @@ import { Component } from "../component";
import { BaseItem } from "../base_item";
import { gItemRegistry } from "../../core/global_registries";
const chainBufferSize = 10;
const chainBufferSize = 3;
export class MinerComponent extends Component {
static getId() {

@ -62,7 +62,7 @@ export class UndergroundBeltComponent extends Component {
return false;
}
this.pendingItems.push([item, 0.5 / beltSpeed]);
this.pendingItems.push([item, 1 / beltSpeed / globalConfig.itemSpacingOnBelts]);
return true;
}
@ -88,7 +88,7 @@ export class UndergroundBeltComponent extends Component {
// NOTICE:
// This corresponds to the item ejector - it needs 0.5 additional tiles to eject the item.
// So instead of adding 1 we add 0.5 only.
const travelDuration = (travelDistance + 0.5) / beltSpeed;
const travelDuration = (travelDistance + 0.5) / beltSpeed / globalConfig.itemSpacingOnBelts;
this.pendingItems.push([item, travelDuration]);

@ -71,6 +71,7 @@ export class HUDBuildingPlacer extends BaseHUDPart {
this.initialDragTile = null;
this.root.signals.storyGoalCompleted.add(this.rerenderVariants, this);
this.root.signals.upgradePurchased.add(this.rerenderVariants, this);
}
createElements(parent) {
@ -80,6 +81,12 @@ export class HUDBuildingPlacer extends BaseHUDPart {
this.buildingInfoElements.label = makeDiv(this.element, null, ["buildingLabel"], "Extract");
this.buildingInfoElements.desc = makeDiv(this.element, null, ["description"], "");
this.buildingInfoElements.descText = makeDiv(this.buildingInfoElements.desc, null, ["text"], "");
this.buildingInfoElements.additionalInfo = makeDiv(
this.buildingInfoElements.desc,
null,
["additionalInfo"],
""
);
this.buildingInfoElements.hotkey = makeDiv(this.buildingInfoElements.desc, null, ["hotkey"], "");
this.buildingInfoElements.tutorialImage = makeDiv(this.element, null, ["buildingImage"]);
@ -234,17 +241,6 @@ export class HUDBuildingPlacer extends BaseHUDPart {
this.abortDragging();
this.root.hud.signals.selectedPlacementBuildingChanged.dispatch(metaBuilding);
if (metaBuilding) {
this.buildingInfoElements.label.innerHTML = T.buildings[metaBuilding.id].name;
this.buildingInfoElements.descText.innerHTML = T.buildings[metaBuilding.id].description;
const binding = this.root.gameState.keyActionMapper.getBinding(
"building_" + metaBuilding.getId()
);
this.buildingInfoElements.hotkey.innerHTML = T.ingame.buildingPlacement.hotkeyLabel.replace(
"<key>",
"<code class='keybinding'>" + binding.getKeyCodeString() + "</code>"
);
const variant = this.preferredVariants[metaBuilding.getId()] || defaultBuildingVariant;
this.currentVariant.set(variant);
@ -272,8 +268,42 @@ export class HUDBuildingPlacer extends BaseHUDPart {
this.rerenderVariants();
}
/**
* Rerenders the building info dialog
*/
rerenderInfoDialog() {
const metaBuilding = this.currentMetaBuilding.get();
if (!metaBuilding) {
return;
}
this.buildingInfoElements.label.innerHTML = T.buildings[metaBuilding.id].name;
this.buildingInfoElements.descText.innerHTML = T.buildings[metaBuilding.id].description;
const binding = this.root.gameState.keyActionMapper.getBinding("building_" + metaBuilding.getId());
this.buildingInfoElements.hotkey.innerHTML = T.ingame.buildingPlacement.hotkeyLabel.replace(
"<key>",
"<code class='keybinding'>" + binding.getKeyCodeString() + "</code>"
);
removeAllChildren(this.buildingInfoElements.additionalInfo);
const additionalInfo = metaBuilding.getAdditionalStatistics(this.root, this.currentVariant.get());
for (let i = 0; i < additionalInfo.length; ++i) {
const [label, contents] = additionalInfo[i];
this.buildingInfoElements.additionalInfo.innerHTML += `
<label>${label}:</label>
<span>${contents}</contents>
`;
}
}
/**
* Rerenders the variants displayed
*/
rerenderVariants() {
removeAllChildren(this.variantsElement);
this.rerenderInfoDialog();
const metaBuilding = this.currentMetaBuilding.get();

@ -38,6 +38,16 @@ export class MetaBuilding {
return false;
}
/**
* Should return additional statistics about this building
* @param {GameRoot} root
* @param {string} variant
* @returns {Array<[string, string]>}
*/
getAdditionalStatistics(root, variant) {
return [];
}
/**
* Whether to flip the orientation after a building has been placed - useful
* for tunnels.

@ -11,6 +11,7 @@ import { MapChunkView } from "../map_chunk_view";
import { gMetaBuildingRegistry } from "../../core/global_registries";
import { MetaBeltBaseBuilding } from "../buildings/belt_base";
import { defaultBuildingVariant } from "../meta_building";
import { GameRoot } from "../root";
const BELT_ANIM_COUNT = 6;
@ -109,7 +110,11 @@ export class BeltSystem extends GameSystemWithFilter {
}
update() {
const beltSpeed = this.root.hubGoals.getBeltBaseSpeed() * globalConfig.physicsDeltaSeconds;
// Divide by item spacing on belts since we use throughput and not speed
const beltSpeed =
this.root.hubGoals.getBeltBaseSpeed() *
globalConfig.physicsDeltaSeconds *
globalConfig.itemSpacingOnBelts;
for (let i = 0; i < this.allEntities.length; ++i) {
const entity = this.allEntities[i];

@ -31,7 +31,10 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
for (let animIndex = 0; animIndex < aceptorComp.itemConsumptionAnimations.length; ++animIndex) {
const anim = aceptorComp.itemConsumptionAnimations[animIndex];
anim.animProgress +=
globalConfig.physicsDeltaSeconds * this.root.hubGoals.getBeltBaseSpeed() * 2;
globalConfig.physicsDeltaSeconds *
this.root.hubGoals.getBeltBaseSpeed() *
2 *
globalConfig.itemSpacingOnBelts;
if (anim.animProgress > 1) {
aceptorComp.itemConsumptionAnimations.splice(animIndex, 1);
animIndex -= 1;

@ -13,7 +13,7 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
}
update() {
const effectiveBeltSpeed = this.root.hubGoals.getBeltBaseSpeed();
const effectiveBeltSpeed = this.root.hubGoals.getBeltBaseSpeed() * globalConfig.itemSpacingOnBelts;
const progressGrowth = (effectiveBeltSpeed / 0.5) * globalConfig.physicsDeltaSeconds;
// Try to find acceptors for every ejector

@ -1,11 +1,11 @@
import { globalConfig } from "../../core/config";
import { DrawParameters } from "../../core/draw_parameters";
import { enumDirectionToVector } from "../../core/vector";
import { BaseItem } from "../base_item";
import { MinerComponent } from "../components/miner";
import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { MapChunkView } from "../map_chunk_view";
import { enumDirectionToVector } from "../../core/vector";
import { Entity } from "../entity";
import { BaseItem } from "../base_item";
export class MinerSystem extends GameSystemWithFilter {
constructor(root) {

@ -1,4 +1,5 @@
import { ShapeDefinition } from "./shape_definition";
import { finalGameShape } from "./upgrades";
/**
* @enum {string}
@ -125,7 +126,7 @@ export const tutorialGoals = [
},
{
shape: "RuCw--Cw:----Ru--",
shape: finalGameShape,
required: 50000,
reward: enumHubGoalRewards.reward_freeplay,
},

@ -1,7 +1,7 @@
import { findNiceIntegerValue } from "../core/utils";
import { ShapeDefinition } from "./shape_definition";
const finalShape = "RuCw--Cw:----Ru--";
export const finalGameShape = "RuCw--Cw:----Ru--";
export const UPGRADES = {
belt: {
@ -27,7 +27,7 @@ export const UPGRADES = {
improvement: 4,
},
{
required: [{ shape: finalShape, amount: 150000 }],
required: [{ shape: finalGameShape, amount: 150000 }],
improvement: 4,
excludePrevious: true,
},
@ -57,7 +57,7 @@ export const UPGRADES = {
improvement: 4,
},
{
required: [{ shape: finalShape, amount: 150000 }],
required: [{ shape: finalGameShape, amount: 150000 }],
improvement: 4,
excludePrevious: true,
},
@ -87,7 +87,7 @@ export const UPGRADES = {
improvement: 4,
},
{
required: [{ shape: finalShape, amount: 150000 }],
required: [{ shape: finalGameShape, amount: 150000 }],
improvement: 4,
excludePrevious: true,
},
@ -117,7 +117,7 @@ export const UPGRADES = {
improvement: 4,
},
{
required: [{ shape: finalShape, amount: 150000 }],
required: [{ shape: finalGameShape, amount: 150000 }],
improvement: 4,
excludePrevious: true,
},

@ -138,6 +138,12 @@ ingame:
hotkeyLabel: >-
Hotkey: <key>
infoTexts:
speed: Speed
oneItemPerSecond: 1 item / second
itemsPerSecond: <x> items / s
itemsPerSecondDouble: (x2)
# The notification when completing a level
levelCompleteNotification:
# <level> is replaced by the actual level, so this gets 'Level 03' for example.
@ -222,7 +228,7 @@ buildings:
miner: # Internal name for the Extractor
name: Extractor
description: Place over a shape or color to extract it. Six extractors fill exactly one belt.
description: Place over a shape or color to extract it.
underground_belt: # Internal name for the Tunnel
name: Tunnel

Loading…
Cancel
Save