Merge branch 'master' into patch-1

pull/349/head
EnderDoom77 4 years ago committed by GitHub
commit b02c7560ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:191ff110356e8d8046e0ef05108b06809fad657d086d5e1821219966bbf1b8d7
size 861938
oid sha256:aaf7ee9ed1cf6c7f1a0c496f24663c98ab308d3531a450a2d41bdee266221eb0
size 963227

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a01502c651ee3de0a4350b3c7fc4c7e964a5a17ec6db031fe79524ed957fd516
size 77563
oid sha256:9adbc719ee8765117f5f1208f6121b6e5d417de1c62cbd6cbb9b127651830382
size 109524

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c334d77dabdc40fef4ece56ccef9eaa59b5b6b9381817c234f9bf07d00e676e5
size 12721033
oid sha256:5aa1330b9f7ec2babd99bf5f6de58ba80de0da10cfca9d3adca433b2fe34d3ff
size 12801882

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 MiB

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:468563187c9f4e2333c353d2822e21cd5859f363fa636a9f7acf88671d777e11
size 47276113

Binary file not shown.

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2adafebb258471fb88b16c16746f7468081e97f128910878740e6b1278003e94
size 92412

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:af7d1113b0cb0bbcf626889fc242cc6eabb5a9b50e0eef9bf013334f7e3eb7fa
size 70769
oid sha256:c35f217cbc3c687e3ee7c25a410ce953b38637e106b8ea348caeca55bfeac394
size 70555

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a1200717523a78bc2e98929a5d276458f9ce2041969fa54c40873ba08340b219
size 5196595
oid sha256:db1a0f44bc1b2fa66d18022d941e71063623d8036369739dc02e9b1c577a7d21
size 5197244

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 67 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 KiB

After

Width:  |  Height:  |  Size: 214 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 484 KiB

After

Width:  |  Height:  |  Size: 508 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 KiB

After

Width:  |  Height:  |  Size: 1016 KiB

@ -381,6 +381,27 @@
<key>scale9FromFile</key>
<false/>
</struct>
<key type="filename">sprites/blueprints/advanced_processor.png</key>
<key type="filename">sprites/blueprints/energy_generator.png</key>
<key type="filename">sprites/blueprints/painter-double.png</key>
<key type="filename">sprites/blueprints/trash-storage.png</key>
<key type="filename">sprites/buildings/advanced_processor.png</key>
<key type="filename">sprites/buildings/energy_generator.png</key>
<key type="filename">sprites/buildings/painter-double.png</key>
<struct type="IndividualSpriteSettings">
<key>pivotPoint</key>
<point_f>0.5,0.5</point_f>
<key>spriteScale</key>
<double>1</double>
<key>scale9Enabled</key>
<false/>
<key>scale9Borders</key>
<rect>96,96,192,192</rect>
<key>scale9Paddings</key>
<rect>96,96,192,192</rect>
<key>scale9FromFile</key>
<false/>
</struct>
<key type="filename">sprites/blueprints/cutter-quad.png</key>
<key type="filename">sprites/blueprints/painter-quad.png</key>
<key type="filename">sprites/buildings/cutter-quad.png</key>
@ -420,25 +441,6 @@
<key>scale9FromFile</key>
<false/>
</struct>
<key type="filename">sprites/blueprints/energy_generator.png</key>
<key type="filename">sprites/blueprints/painter-double.png</key>
<key type="filename">sprites/blueprints/trash-storage.png</key>
<key type="filename">sprites/buildings/energy_generator.png</key>
<key type="filename">sprites/buildings/painter-double.png</key>
<struct type="IndividualSpriteSettings">
<key>pivotPoint</key>
<point_f>0.5,0.5</point_f>
<key>spriteScale</key>
<double>1</double>
<key>scale9Enabled</key>
<false/>
<key>scale9Borders</key>
<rect>96,96,192,192</rect>
<key>scale9Paddings</key>
<rect>96,96,192,192</rect>
<key>scale9FromFile</key>
<false/>
</struct>
<key type="filename">sprites/blueprints/miner-chainable.png</key>
<key type="filename">sprites/blueprints/miner.png</key>
<key type="filename">sprites/blueprints/rotater-ccw.png</key>
@ -589,6 +591,10 @@
<key>scale9FromFile</key>
<false/>
</struct>
<key type="filename">sprites/wires/battery_empty.png</key>
<key type="filename">sprites/wires/battery_full.png</key>
<key type="filename">sprites/wires/battery_low.png</key>
<key type="filename">sprites/wires/battery_medium.png</key>
<key type="filename">sprites/wires/negative_energy.png</key>
<key type="filename">sprites/wires/positive_energy.png</key>
<struct type="IndividualSpriteSettings">

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8e94039ba13b6af3a9e59d8675ed2f7373aad20fc9bb0c12e35b1a901d906efd
size 1463494

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8e5dcd6de724297149a8c704bf07c850f002b6430fd6cf744519d0a20c8545bb
size 18285574

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8c334a9f100fce4647b4803d2a8270b30e26d53622b3717bdb81b3ea07f84aed
size 150286082
oid sha256:df7487fb5e8cb34cecee2519b9c3162a5107d2d7b1301c4a550904cfb108a015
size 223361394

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 936 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

@ -38,8 +38,11 @@
}
.additionalOptions {
display: flex;
flex-direction: column;
@include S(margin-top, 10px);
button {
@include S(margin-bottom, 2px);
@include IncreasedClickArea(0px);
@include SuperSmallText;
}

@ -5,6 +5,7 @@ export const CHANGELOG = [
entries: [
"Allow holding ALT in belt planner to reverse direction (by jakobhellermann)",
"Clear cursor when trying to pipette the same building twice (by hexy)",
"Updated the soundtrack again, it is now 20 minutes in total!",
],
},
{

@ -45,7 +45,7 @@ export const globalConfig = {
// Map
mapChunkSize: 16,
mapChunkPrerenderMinZoom: 1.15,
mapChunkPrerenderMinZoom: 0.7,
mapChunkOverviewMinZoom: 0.7,
// Belt speeds
@ -72,7 +72,7 @@ export const globalConfig = {
painterQuad: 1 / 8,
mixer: 1 / 5,
stacker: 1 / 6,
advancedProcessor: 1 / 15,
advancedProcessor: 1 / 6,
},
// Zooming

@ -1,5 +1,6 @@
import { DrawParameters } from "../core/draw_parameters";
import { BasicSerializableObject } from "../savegame/serialization";
import { enumLayer } from "./root";
/** @enum {string} */
export const enumItemType = {
@ -9,6 +10,14 @@ export const enumItemType = {
negativeEnergy: "negativeEnergy",
};
/** @enum {enumLayer} */
export const enumItemTypeToLayer = {
[enumItemType.shape]: enumLayer.regular,
[enumItemType.color]: enumLayer.regular,
[enumItemType.positiveEnergy]: enumLayer.wires,
[enumItemType.negativeEnergy]: enumLayer.wires,
};
/**
* Class for items on belts etc. Not an entity for performance reasons
*/

@ -9,6 +9,7 @@ import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { GameRoot, enumLayer } from "../root";
import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins";
import { EnergyConsumerComponent } from "../components/energy_consumer";
export class MetaAdvancedProcessorBuilding extends MetaBuilding {
constructor() {
@ -61,6 +62,16 @@ export class MetaAdvancedProcessorBuilding extends MetaBuilding {
],
})
);
entity.addComponent(
new EnergyConsumerComponent({
bufferSize: 3,
perCharge: 0.25,
batteryPosition: new Vector(4, 6.5),
acceptorSlotIndex: 1,
ejectorSlotIndex: 1,
})
);
entity.addComponent(
new WiredPinsComponent({
slots: [
@ -81,7 +92,7 @@ export class MetaAdvancedProcessorBuilding extends MetaBuilding {
new ItemAcceptorComponent({
slots: [
{
pos: new Vector(0, 0),
pos: new Vector(0, 1),
directions: [enumDirection.left],
filter: enumItemType.shape,
},

@ -1,13 +1,13 @@
import { enumDirection, Vector } from "../../core/vector";
import { enumItemType } from "../base_item";
import { EnergyGeneratorComponent } from "../components/energy_generator";
import { ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { GameRoot, enumLayer } from "../root";
import { enumLayer, GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals";
import { EnergyGeneratorComponent } from "../components/energy_generator";
import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins";
import { enumItemType } from "../base_item";
import { ItemEjectorComponent } from "../components/item_ejector";
export class MetaEnergyGenerator extends MetaBuilding {
constructor() {
@ -51,17 +51,6 @@ export class MetaEnergyGenerator extends MetaBuilding {
entity.addComponent(
new ItemAcceptorComponent({
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.top],
filter: enumItemType.shape,
},
{
pos: new Vector(1, 0),
directions: [enumDirection.top],
filter: enumItemType.shape,
},
{
pos: new Vector(0, 1),
directions: [enumDirection.bottom],
@ -72,7 +61,6 @@ export class MetaEnergyGenerator extends MetaBuilding {
directions: [enumDirection.bottom],
filter: enumItemType.shape,
},
{
pos: new Vector(1, 0),
directions: [enumDirection.top],
@ -99,6 +87,7 @@ export class MetaEnergyGenerator extends MetaBuilding {
new EnergyGeneratorComponent({
// Set by the energy generator system later
requiredKey: null,
acceptorSlotIndex: 2,
})
);

@ -10,6 +10,8 @@ export const enumColors = {
white: "white",
uncolored: "uncolored",
black: "black",
};
/** @enum {string} */
@ -24,6 +26,8 @@ export const enumColorToShortcode = {
[enumColors.white]: "w",
[enumColors.uncolored]: "u",
[enumColors.black]: "0",
};
/** @enum {enumColors} */
@ -50,9 +54,27 @@ export const enumColorsToHexCode = {
// blue + green + red
[enumColors.white]: "#ffffff",
[enumColors.black]: "#212428",
[enumColors.uncolored]: "#aaaaaa",
};
/** @enum {enumColors} */
export const enumInvertedColors = {
[enumColors.red]: enumColors.cyan,
[enumColors.green]: enumColors.purple,
[enumColors.blue]: enumColors.yellow,
[enumColors.yellow]: enumColors.blue,
[enumColors.purple]: enumColors.green,
[enumColors.cyan]: enumColors.red,
[enumColors.white]: enumColors.black,
[enumColors.black]: enumColors.white,
[enumColors.uncolored]: enumColors.uncolored,
};
const c = enumColors;
/** @enum {Object.<string, string>} */
export const enumColorMixingResults = {
@ -66,6 +88,7 @@ export const enumColorMixingResults = {
[c.cyan]: c.white,
[c.white]: c.white,
[c.black]: c.red,
},
// 0, 255, 0
@ -77,6 +100,7 @@ export const enumColorMixingResults = {
[c.cyan]: c.cyan,
[c.white]: c.white,
[c.black]: c.green,
},
// 0, 255, 0
@ -86,17 +110,20 @@ export const enumColorMixingResults = {
[c.cyan]: c.cyan,
[c.white]: c.white,
[c.black]: c.blue,
},
// 255, 255, 0
[c.yellow]: {
[c.purple]: c.white,
[c.cyan]: c.white,
[c.black]: c.yellow,
},
// 255, 0, 255
[c.purple]: {
[c.cyan]: c.white,
[c.black]: c.purple,
},
// 0, 255, 255
@ -113,6 +140,13 @@ export const enumColorMixingResults = {
[c.uncolored]: {
// auto
},
[c.black]: {
// auto
[c.white]: c.white,
[c.cyan]: c.cyan,
[c.uncolored]: c.uncolored,
},
};
// Create same color lookups

@ -12,6 +12,7 @@ import { HubComponent } from "./components/hub";
import { StorageComponent } from "./components/storage";
import { EnergyGeneratorComponent } from "./components/energy_generator";
import { WiredPinsComponent } from "./components/wired_pins";
import { EnergyConsumerComponent } from "./components/energy_consumer";
export function initComponentRegistry() {
gComponentRegistry.register(StaticMapEntityComponent);
@ -27,6 +28,7 @@ export function initComponentRegistry() {
gComponentRegistry.register(StorageComponent);
gComponentRegistry.register(EnergyGeneratorComponent);
gComponentRegistry.register(WiredPinsComponent);
gComponentRegistry.register(EnergyConsumerComponent);
// IMPORTANT ^^^^^ UPDATE ENTITY COMPONENT STORAGE AFTERWARDS

@ -0,0 +1,122 @@
import { Component } from "../component";
import { types } from "../../savegame/serialization";
import { Vector } from "../../core/vector";
import { BaseItem, enumItemTypeToLayer, enumItemType } from "../base_item";
export class EnergyConsumerComponent extends Component {
static getId() {
return "EnergyConsumer";
}
static getSchema() {
return {
bufferSize: types.float,
perCharge: types.float,
stored: types.float,
piledOutput: types.float,
batteryPosition: types.vector,
energyType: types.enum(enumItemType),
wasteType: types.enum(enumItemType),
acceptorSlotIndex: types.uint,
ejectorSlotIndex: types.uint,
};
}
/**
*
* @param {object} param0
* @param {number} param0.bufferSize How much energy this consumer can store
* @param {number} param0.perCharge How much energy this consumer needs per charge
* @param {Vector} param0.batteryPosition world space render offset of the battery icon
* @param {number} param0.acceptorSlotIndex Which slot to accept energy on
* @param {number} param0.ejectorSlotIndex Which slot to eject energy off
*
*/
constructor({
bufferSize = 3,
perCharge = 1,
batteryPosition = new Vector(),
acceptorSlotIndex = 0,
ejectorSlotIndex = 0,
}) {
super();
this.bufferSize = bufferSize;
this.perCharge = perCharge;
this.batteryPosition = batteryPosition;
this.energyType = enumItemType.positiveEnergy;
this.wasteType = enumItemType.negativeEnergy;
this.acceptorSlotIndex = acceptorSlotIndex;
this.ejectorSlotIndex = ejectorSlotIndex;
/**
* How much energy we have stored right now
*/
this.stored = 0;
/**
* How much waste we have piled up so far
*/
this.piledOutput = 0;
}
/**
* Tries to accept a given item
* @param {BaseItem} item
* @param {number} slotIndex
*/
tryAcceptItem(item, slotIndex) {
if (slotIndex !== this.acceptorSlotIndex) {
// Wrong slot
return false;
}
if (item.getItemType() !== this.energyType) {
// Not the right type
return false;
}
if (this.stored >= this.bufferSize) {
// We are full
return false;
}
// All good, consume
this.stored = Math.min(this.stored + 1, this.bufferSize);
return true;
}
/**
* Tries to start the next charge
*/
tryStartNextCharge() {
if (this.hasTooMuchWastePiled()) {
// Too much waste remaining
return false;
}
if (this.stored < this.perCharge) {
// Not enough energy stored
return false;
}
this.stored -= this.perCharge;
this.piledOutput += this.perCharge;
return true;
}
/**
* Returns if there is too much waste piled
*/
hasTooMuchWastePiled() {
return this.piledOutput >= 1.0;
}
/**
* Reduces the waste by the given amount
* @param {number} amount
*/
reduceWaste(amount) {
this.piledOutput = Math.max(0, this.piledOutput - amount);
}
}

@ -5,9 +5,6 @@ import { ShapeItem } from "../items/shape_item";
const maxQueueSize = 20;
export const ENERGY_GENERATOR_EJECT_SLOT = 0;
export const ENERGY_GENERATOR_ACCEPT_SLOT = 4;
export class EnergyGeneratorComponent extends Component {
static getId() {
return "EnergyGenerator";
@ -24,8 +21,9 @@ export class EnergyGeneratorComponent extends Component {
*
* @param {object} param0
* @param {string} param0.requiredKey Which shape this generator needs, can be null if not computed yet
* @param {number} param0.acceptorSlotIndex
*/
constructor({ requiredKey }) {
constructor({ requiredKey, acceptorSlotIndex = 0 }) {
super();
this.requiredKey = requiredKey;
@ -34,6 +32,12 @@ export class EnergyGeneratorComponent extends Component {
* @type {number}
*/
this.itemsInQueue = 0;
/**
* Stores which slot accepts the waste
* @type {number}
*/
this.acceptorSlotIndex = acceptorSlotIndex;
}
/**
@ -42,7 +46,7 @@ export class EnergyGeneratorComponent extends Component {
* @param {number} slot
*/
tryTakeItem(item, slot) {
if (slot === ENERGY_GENERATOR_ACCEPT_SLOT) {
if (slot === this.acceptorSlotIndex) {
// this is the acceptor slot on the wires layer
// just destroy it
return true;

@ -405,6 +405,7 @@ export class GameCore {
systems.hub.draw(params);
systems.energyGenerator.draw(params);
systems.storage.draw(params);
systems.energyConsumer.draw(params);
}
root.hud.parts.wiresOverlay.draw(params);

@ -12,6 +12,7 @@ import { HubComponent } from "./components/hub";
import { StorageComponent } from "./components/storage";
import { EnergyGeneratorComponent } from "./components/energy_generator";
import { WiredPinsComponent } from "./components/wired_pins";
import { EnergyConsumerComponent } from "./components/energy_consumer";
/* typehints:end */
/**
@ -61,6 +62,9 @@ export class EntityComponentStorage {
/** @type {WiredPinsComponent} */
this.WiredPins;
/** @type {EnergyConsumerComponent} */
this.EnergyConsumer;
/* typehints:end */
}
}

@ -15,6 +15,7 @@ import { ItemAcceptorSystem } from "./systems/item_acceptor";
import { StorageSystem } from "./systems/storage";
import { EnergyGeneratorSystem } from "./systems/energy_generator";
import { WiredPinsSystem } from "./systems/wired_pins";
import { EnergyConsumerSystem } from "./systems/energy_consumer";
const logger = createLogger("game_system_manager");
@ -64,6 +65,9 @@ export class GameSystemManager {
/** @type {WiredPinsSystem} */
wiredPins: null,
/** @type {EnergyConsumerSystem} */
energyConsumer: null,
/* typehints:end */
};
this.systemUpdateOrder = [];
@ -104,6 +108,8 @@ export class GameSystemManager {
add("wiredPins", WiredPinsSystem);
add("energyConsumer", EnergyConsumerSystem);
// IMPORTANT: Must be after belt system since belt system can change the
// orientation of an entity after it is placed -> the item acceptor cache
// then would be invalid

@ -48,6 +48,7 @@ export class HUDSandboxController extends BaseHUDPart {
<div class="additionalOptions">
<button class="styledButton giveBlueprints">Fill blueprint shapes</button>
<button class="styledButton maxOutAll">Max out all</button>
</div>
</div>
`
@ -56,6 +57,7 @@ export class HUDSandboxController extends BaseHUDPart {
const bind = (selector, handler) => this.trackClicks(this.element.querySelector(selector), handler);
bind(".giveBlueprints", this.giveBlueprints);
bind(".maxOutAll", this.maxOutAll);
bind(".levelToggle .minus", () => this.modifyLevel(-1));
bind(".levelToggle .plus", () => this.modifyLevel(1));
@ -76,6 +78,13 @@ export class HUDSandboxController extends BaseHUDPart {
this.root.hubGoals.storedShapes[blueprintShape] += 1e4;
}
maxOutAll() {
this.modifyUpgrade("belt", 100);
this.modifyUpgrade("miner", 100);
this.modifyUpgrade("processors", 100);
this.modifyUpgrade("painting", 100);
}
modifyUpgrade(id, amount) {
const handle = UPGRADES[id];
const maxLevel = handle.tiers.length;

@ -5,7 +5,13 @@ import { DrawParameters } from "../core/draw_parameters";
import { createLogger } from "../core/logging";
import { Vector } from "../core/vector";
import { BasicSerializableObject, types } from "../savegame/serialization";
import { enumColors, enumColorsToHexCode, enumColorToShortcode, enumShortcodeToColor } from "./colors";
import {
enumColors,
enumColorsToHexCode,
enumColorToShortcode,
enumShortcodeToColor,
enumInvertedColors,
} from "./colors";
import { THEME } from "./theme";
const rusha = require("rusha");
@ -566,6 +572,23 @@ export class ShapeDefinition extends BasicSerializableObject {
return new ShapeDefinition({ layers: newLayers });
}
/**
* Clones the shape and inverts all colors
*/
cloneAndInvertColors() {
const newLayers = this.internalCloneLayers();
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
const quadrants = newLayers[layerIndex];
for (let quadrantIndex = 0; quadrantIndex < 4; ++quadrantIndex) {
const item = quadrants[quadrantIndex];
if (item) {
item.color = enumInvertedColors[item.color];
}
}
}
return new ShapeDefinition({ layers: newLayers });
}
/**
* Clones the shape and colors everything in the given colors
* @param {[enumColors, enumColors, enumColors, enumColors]} colors

@ -161,6 +161,22 @@ export class ShapeDefinitionManager extends BasicSerializableObject {
));
}
/**
* Generates a definition for inverting all colors on that shape
* @param {ShapeDefinition} definition
* @returns {ShapeDefinition}
*/
shapeActionInvertColors(definition) {
const key = "invert:" + definition.getHash();
if (this.operationCache[key]) {
return /** @type {ShapeDefinition} */ (this.operationCache[key]);
}
const inverted = definition.cloneAndInvertColors();
return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle(
inverted
));
}
/**
* Generates a definition for painting it with the 4 colors
* @param {ShapeDefinition} definition

@ -546,7 +546,6 @@ export class BeltSystem extends GameSystemWithFilter {
return;
}
parameters.context.globalAlpha = 0.5;
const contents = chunk.wireContents;
for (let y = 0; y < globalConfig.mapChunkSize; ++y) {
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
@ -564,7 +563,6 @@ export class BeltSystem extends GameSystemWithFilter {
}
}
}
parameters.context.globalAlpha = 1;
}
/**

@ -0,0 +1,94 @@
import { DrawParameters } from "../../core/draw_parameters";
import { Loader } from "../../core/loader";
import { clamp } from "../../core/utils";
import { enumItemType } from "../base_item";
import { EnergyConsumerComponent } from "../components/energy_consumer";
import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { NEGATIVE_ENERGY_ITEM_SINGLETON } from "../items/negative_energy_item";
import { POSITIVE_ENERGY_ITEM_SINGLETON } from "../items/positive_energy_item";
export class EnergyConsumerSystem extends GameSystemWithFilter {
constructor(root) {
super(root, [EnergyConsumerComponent]);
this.batterySprites = [
Loader.getSprite("sprites/wires/battery_empty.png"),
Loader.getSprite("sprites/wires/battery_low.png"),
Loader.getSprite("sprites/wires/battery_medium.png"),
Loader.getSprite("sprites/wires/battery_full.png"),
];
this.piledWasteSprite = Loader.getSprite("sprites/wires/waste_piled.png");
}
update() {
for (let i = 0; i < this.allEntities.length; ++i) {
const entity = this.allEntities[i];
const energyConsumerComp = entity.components.EnergyConsumer;
if (energyConsumerComp.piledOutput >= 1.0) {
// Try to get rid of waste
const ejectorComp = entity.components.ItemEjector;
const item = this.getItemSingletonByType(energyConsumerComp.wasteType);
if (ejectorComp.tryEject(energyConsumerComp.ejectorSlotIndex, item)) {
// Got rid of waste
energyConsumerComp.reduceWaste(1.0);
}
}
}
}
/**
*
* @param {enumItemType} itemType
*/
getItemSingletonByType(itemType) {
switch (itemType) {
case enumItemType.positiveEnergy:
return POSITIVE_ENERGY_ITEM_SINGLETON;
case enumItemType.negativeEnergy:
return NEGATIVE_ENERGY_ITEM_SINGLETON;
default:
assertAlways(false, "Bad item type: " + itemType);
}
}
/**
* Draws everything
* @param {DrawParameters} parameters
*/
draw(parameters) {
this.forEachMatchingEntityOnScreen(parameters, this.drawSingleEntity.bind(this));
}
/**
* Draws a given entity
* @param {DrawParameters} parameters
* @param {Entity} entity
*/
drawSingleEntity(parameters, entity) {
const staticComp = entity.components.StaticMapEntity;
const consumerComp = entity.components.EnergyConsumer;
const position = staticComp
.getTileSpaceBounds()
.getCenter()
.toWorldSpace()
.add(consumerComp.batteryPosition);
if (consumerComp.hasTooMuchWastePiled()) {
this.piledWasteSprite.drawCachedCentered(parameters, position.x, position.y, 12);
} else {
const percentage = consumerComp.stored / consumerComp.bufferSize;
const index = clamp(
Math.round(percentage * this.batterySprites.length),
0,
this.batterySprites.length - 1
);
this.batterySprites[index].drawCachedCentered(parameters, position.x, position.y, 12);
}
}
}

@ -1,7 +1,7 @@
import { DrawParameters } from "../../core/draw_parameters";
import { formatBigNumber } from "../../core/utils";
import { T } from "../../translations";
import { EnergyGeneratorComponent, ENERGY_GENERATOR_EJECT_SLOT } from "../components/energy_generator";
import { EnergyGeneratorComponent } from "../components/energy_generator";
import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { POSITIVE_ENERGY_ITEM_SINGLETON } from "../items/positive_energy_item";
@ -36,7 +36,8 @@ export class EnergyGeneratorSystem extends GameSystemWithFilter {
}
if (energyGenComp.itemsInQueue > 0) {
if (ejectorComp.tryEject(ENERGY_GENERATOR_EJECT_SLOT, POSITIVE_ENERGY_ITEM_SINGLETON)) {
// FIXME: Find slot dynamically
if (ejectorComp.tryEject(0, POSITIVE_ENERGY_ITEM_SINGLETON)) {
energyGenComp.itemsInQueue -= 1;
}
}

@ -3,7 +3,7 @@ import { DrawParameters } from "../../core/draw_parameters";
import { createLogger } from "../../core/logging";
import { Rectangle } from "../../core/rectangle";
import { enumDirectionToVector, Vector } from "../../core/vector";
import { BaseItem } from "../base_item";
import { BaseItem, enumItemType, enumItemTypeToLayer } from "../base_item";
import { ItemEjectorComponent } from "../components/item_ejector";
import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
@ -257,6 +257,8 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
// TODO: Kinda hacky. How to solve this properly? Don't want to go through inheritance hell.
// Also its just a few cases (hope it stays like this .. :x).
const itemLayer = enumItemTypeToLayer[item.getItemType()];
const beltComp = receiver.components.Belt;
if (beltComp) {
const path = beltComp.assignedPath;
@ -268,14 +270,27 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
return false;
}
const energyConsumerComp = receiver.components.EnergyConsumer;
if (energyConsumerComp) {
if (energyConsumerComp.tryAcceptItem(item, slotIndex)) {
// All good
return true;
}
// Energy consumer can have more components
}
const itemProcessorComp = receiver.components.ItemProcessor;
if (itemProcessorComp) {
// Its an item processor ..
if (itemProcessorComp.tryTakeItem(item, slotIndex)) {
return true;
// Make sure its the same layer
if (itemLayer === receiver.layer) {
// Its an item processor ..
if (itemProcessorComp.tryTakeItem(item, slotIndex)) {
return true;
}
// Item processor can have nothing else
return false;
}
// Item processor can have nothing else
return false;
}
const undergroundBeltComp = receiver.components.UndergroundBelt;

@ -75,7 +75,16 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
// Check if we have an empty queue and can start a new charge
if (processorComp.itemsToEject.length === 0) {
if (processorComp.inputSlots.length >= processorComp.inputsPerCharge) {
this.startNewCharge(entity);
const energyConsumerComp = entity.components.EnergyConsumer;
if (energyConsumerComp) {
// Check if we have enough energy
if (energyConsumerComp.tryStartNextCharge()) {
this.startNewCharge(entity);
}
} else {
// No further checks required
this.startNewCharge(entity);
}
}
}
}
@ -339,10 +348,13 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
// ADVANCED PROCESSING
case enumItemProcessorTypes.advancedProcessor: {
// TODO
entity.components.ItemEjector.tryEject(1, NEGATIVE_ENERGY_ITEM_SINGLETON);
const shapeItem = /** @type {ShapeItem} */ (items[0].item);
const newItem = this.root.shapeDefinitionMgr.shapeActionInvertColors(shapeItem.definition);
outItems.push({
item: new ShapeItem(newItem),
requiredSlot: 0,
});
break;
}

@ -27,7 +27,7 @@ export class WiredPinsSystem extends GameSystemWithFilter {
}
/**
* Draws the given layer
* Draws the pins
* @param {DrawParameters} parameters
*/
draw(parameters) {
@ -35,7 +35,7 @@ export class WiredPinsSystem extends GameSystemWithFilter {
}
/**
* Draws a given chunk
* Draws a given entity
* @param {DrawParameters} parameters
* @param {Entity} entity
*/

@ -156,7 +156,7 @@ export const tutorialGoals = [
// 17
{
shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", // processors t4 (two varinats)
shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", // processors t4 (two variants)
required: 120000,
reward: enumHubGoalRewards.reward_painter_quad,
},

@ -29,6 +29,7 @@ The base translation is `base-en.yaml`. It will always contain the latest phrase
- [Kroatian](base-hr.yaml)
- [Danish](base-da.yaml)
- [Finnish](base-fi.yaml)
- [Catalan](base-cat.yaml)
(If you want to translate into a new language, see below!)

@ -0,0 +1,862 @@
#
# GAME TRANSLATIONS
#
# Contributing:
#
# If you want to contribute, please make a pull request on this respository
# and I will have a look.
#
# Placeholders:
#
# Do *not* replace placeholders! Placeholders have a special syntax like
# `Hotkey: <key>`. They are encapsulated within angle brackets. The correct
# translation for this one in German for example would be: `Taste: <key>` (notice
# how the placeholder stayed '<key>' and was not replaced!)
#
# Adding a new language:
#
# If you want to add a new language, ask me in the discord and I will setup
# the basic structure so the game also detects it.
#
steamPage:
# This is the short text appearing on the steam page
shortText: shapez.io is a game about building factories to automate the creation and combination of increasingly complex shapes within an infinite map.
# This is the long description for the steam page - It is contained here so you can help to translate it, and I will regulary update the store page.
# NOTICE:
# - Do not translate the first line (This is the gif image at the start of the store)
# - Please keep the markup (Stuff like [b], [list] etc) in the same format
longText: >-
[img]{STEAM_APP_IMAGE}/extras/store_page_gif.gif[/img]
shapez.io is a game about building factories to automate the creation and combination of shapes. Deliver the requested, increasingly complex shapes to progress within the game and unlock upgrades to speed up your factory.
Since the demand raises you will have to scale up your factory to fit the needs - Don't forget about resources though, you will have to expand in the [b]infinite map[/b]!
Since shapes can get boring soon you need to mix colors and paint your shapes with it - Combine red, green and blue color resources to produce different colors and paint shapes with it to satisfy the demand.
This game features 18 levels (Which should keep you busy for hours already!) but I'm constantly adding new content - There is a lot planned!
[b]Standalone Advantages[/b]
[list]
[*] Waypoints
[*] Unlimited Savegames
[*] Dark Mode
[*] More settings
[*] Allow me to further develop shapez.io ❤️
[*] More features in the future!
[/list]
[b]Planned features & Community suggestions[/b]
This game is open source - Anybody can contribute! Besides of that, I listen [b]a lot[/b] to the community! I try to read all suggestions and take as much feedback into account as possible.
[list]
[*] Wires!
[*] Story mode where buildings cost shapes
[*] More levels & buildings (standalone exclusive)
[*] Different maps, and maybe map obstacles
[*] Configurable map creation (Edit number and size of patches, seed, and more)
[*] More types of shapes
[*] More performance improvements (Although the game already runs pretty good!)
[*] And much more!
[/list]
Be sure to check out my trello board for the full roadmap! https://trello.com/b/ISQncpJP/shapezio
global:
loading: Loading
error: Error
# How big numbers are rendered, e.g. "10,000"
thousandsDivider: ","
# The suffix for large numbers, e.g. 1.3k, 400.2M, etc.
suffix:
thousands: k
millions: M
billions: B
trillions: T
# Shown for infinitely big numbers
infinite: inf
time:
# Used for formatting past time dates
oneSecondAgo: one second ago
xSecondsAgo: <x> seconds ago
oneMinuteAgo: one minute ago
xMinutesAgo: <x> minutes ago
oneHourAgo: one hour ago
xHoursAgo: <x> hours ago
oneDayAgo: one day ago
xDaysAgo: <x> days ago
# Short formats for times, e.g. '5h 23m'
secondsShort: <seconds>s
minutesAndSecondsShort: <minutes>m <seconds>s
hoursAndMinutesShort: <hours>h <minutes>m
xMinutes: <x> minutes
keys:
tab: TAB
control: CTRL
alt: ALT
escape: ESC
shift: SHIFT
space: SPACE
demoBanners:
# This is the "advertisement" shown in the main menu and other various places
title: Demo Version
intro: >-
Get the standalone to unlock all features!
mainMenu:
play: Play
continue: Continue
newGame: New Game
changelog: Changelog
subreddit: Reddit
importSavegame: Import
openSourceHint: This game is open source!
discordLink: Official Discord Server
helpTranslate: Help translate!
madeBy: Made by <author-link>
# This is shown when using firefox and other browsers which are not supported.
browserWarning: >-
Sorry, but the game is known to run slow on your browser! Get the standalone version or download chrome for the full experience.
savegameLevel: Level <x>
savegameLevelUnknown: Unknown Level
contests:
contest_01_03062020:
title: "Contest #01"
desc: Win <strong>$25</strong> for the coolest base!
longDesc: >-
To give something back to you, I thought it would be cool to make weekly contests!
<br><br>
<strong>This weeks topic:</strong> Build the coolest base!
<br><br>
Here's the deal:<br>
<ul class="bucketList">
<li>Submit a screenshot of your base to <strong>contest@shapez.io</strong></li>
<li>Bonus points if you share it on social media!</li>
<li>I will choose 5 screenshots and propose it to the <strong>discord</strong> community to vote.</li>
<li>The winner gets <strong>$25</strong> (Paypal, Amazon Gift Card, whatever you prefer)</li>
<li>Deadline: 07.06.2020 12:00 AM CEST</li>
</ul>
<br>
I'm looking forward to seeing your awesome creations!
showInfo: View
contestOver: This contest has ended - Join the discord to get noticed about new contests!
dialogs:
buttons:
ok: OK
delete: Delete
cancel: Cancel
later: Later
restart: Restart
reset: Reset
getStandalone: Get Standalone
deleteGame: I know what I do
viewUpdate: View Update
showUpgrades: Show Upgrades
showKeybindings: Show Keybindings
importSavegameError:
title: Import Error
text: >-
Failed to import your savegame:
importSavegameSuccess:
title: Savegame Imported
text: >-
Your savegame has been successfully imported.
gameLoadFailure:
title: Game is broken
text: >-
Failed to load your savegame:
confirmSavegameDelete:
title: Confirm deletion
text: >-
Are you sure you want to delete the game?
savegameDeletionError:
title: Failed to delete
text: >-
Failed to delete the savegame:
restartRequired:
title: Restart required
text: >-
You need to restart the game to apply the settings.
editKeybinding:
title: Change Keybinding
desc: Press the key or mouse button you want to assign, or escape to cancel.
resetKeybindingsConfirmation:
title: Reset keybindings
desc: This will reset all keybindings to their default values. Please confirm.
keybindingsResetOk:
title: Keybindings reset
desc: The keybindings have been reset to their respective defaults!
featureRestriction:
title: Demo Version
desc: You tried to access a feature (<feature>) which is not available in the demo. Consider to get the standalone for the full experience!
oneSavegameLimit:
title: Limited savegames
desc: You can only have one savegame at a time in the demo version. Please remove the existing one or get the standalone!
updateSummary:
title: New update!
desc: >-
Here are the changes since you last played:
upgradesIntroduction:
title: Unlock Upgrades
desc: >-
All shapes you produce can be used to unlock upgrades - <strong>Don't destroy your old factories!</strong>
The upgrades tab can be found on the top right corner of the screen.
massDeleteConfirm:
title: Confirm delete
desc: >-
You are deleting a lot of buildings (<count> to be exact)! Are you sure you want to do this?
massCutConfirm:
title: Confirm cut
desc: >-
You are cutting a lot of buildings (<count> to be exact)! Are you sure you want to do this?
blueprintsNotUnlocked:
title: Not unlocked yet
desc: >-
Complete level 12 to unlock Blueprints!
keybindingsIntroduction:
title: Useful keybindings
desc: >-
This game has a lot of keybindings which make it easier to build big factories.
Here are a few, but be sure to <strong>check out the keybindings</strong>!<br><br>
<code class='keybinding'>CTRL</code> + Drag: Select an area.<br>
<code class='keybinding'>SHIFT</code>: Hold to place multiple of one building.<br>
<code class='keybinding'>ALT</code>: Invert orientation of placed belts.<br>
createMarker:
title: New Marker
desc: Give it a meaningful name, you can also include a <strong>short key</strong> of a shape (Which you can generate <a href="https://viewer.shapez.io" target="_blank">here</a>)
markerDemoLimit:
desc: You can only create two custom markers in the demo. Get the standalone for unlimited markers!
exportScreenshotWarning:
title: Export screenshot
desc: You requested to export your base as a screenshot. Please note that this can be quite slow for a big base and even crash your game!
ingame:
# This is shown in the top left corner and displays useful keybindings in
# every situation
keybindingsOverlay:
moveMap: Move
selectBuildings: Select area
stopPlacement: Stop placement
rotateBuilding: Rotate building
placeMultiple: Place multiple
reverseOrientation: Reverse orientation
disableAutoOrientation: Disable auto orientation
toggleHud: Toggle HUD
placeBuilding: Place building
createMarker: Create Marker
delete: Delete
pasteLastBlueprint: Paste last blueprint
lockBeltDirection: Enable belt planner
plannerSwitchSide: Flip planner side
cutSelection: Cut
copySelection: Copy
clearSelection: Clear Selection
pipette: Pipette
switchLayers: Switch Layers
# Names of the colors, used for the color blind mode
colors:
red: Red
green: Green
blue: Blue
yellow: Yellow
purple: Purple
cyan: Cyan
white: White
uncolored: No color
# Everything related to placing buildings (I.e. as soon as you selected a building
# from the toolbar)
buildingPlacement:
# Buildings can have different variants which are unlocked at later levels,
# and this is the hint shown when there are multiple variants available.
cycleBuildingVariants: Press <key> to cycle variants.
# Shows the hotkey in the ui, e.g. "Hotkey: Q"
hotkeyLabel: >-
Hotkey: <key>
infoTexts:
speed: Speed
range: Range
storage: Storage
oneItemPerSecond: 1 item / second
itemsPerSecond: <x> items / s
itemsPerSecondDouble: (x2)
tiles: <x> tiles
# The notification when completing a level
levelCompleteNotification:
# <level> is replaced by the actual level, so this gets 'Level 03' for example.
levelTitle: Level <level>
completed: Completed
unlockText: Unlocked <reward>!
buttonNextLevel: Next Level
# Notifications on the lower right
notifications:
newUpgrade: A new upgrade is available!
gameSaved: Your game has been saved.
# The "Upgrades" window
shop:
title: Upgrades
buttonUnlock: Upgrade
# Gets replaced to e.g. "Tier IX"
tier: Tier <x>
# The roman number for each tier
tierLabels: [I, II, III, IV, V, VI, VII, VIII, IX, X]
maximumLevel: MAXIMUM LEVEL (Speed x<currentMult>)
# The "Statistics" window
statistics:
title: Statistics
dataSources:
stored:
title: Stored
description: Displaying amount of stored shapes in your central building.
produced:
title: Produced
description: Displaying all shapes your whole factory produces, including intermediate products.
delivered:
title: Delivered
description: Displaying shapes which are delivered to your central building.
noShapesProduced: No shapes have been produced so far.
# Displays the shapes per minute, e.g. '523 / m'
shapesPerMinute: <shapes> / m
# Settings menu, when you press "ESC"
settingsMenu:
playtime: Playtime
buildingsPlaced: Buildings
beltsPlaced: Belts
buttons:
continue: Continue
settings: Settings
menu: Return to menu
# Bottom left tutorial hints
tutorialHints:
title: Need help?
showHint: Show hint
hideHint: Close
# When placing a blueprint
blueprintPlacer:
cost: Cost
# Map markers
waypoints:
waypoints: Markers
hub: HUB
description: Left-click a marker to jump to it, right-click to delete it.<br><br>Press <keybinding> to create a marker from the current view, or <strong>right-click</strong> to create a marker at the selected location.
creationSuccessNotification: Marker has been created.
# Shape viewer
shapeViewer:
title: Layers
empty: Empty
copyKey: Copy Key
# Interactive tutorial
interactiveTutorial:
title: Tutorial
hints:
1_1_extractor: Place an <strong>extractor</strong> on top of a <strong>circle shape</strong> to extract it!
1_2_conveyor: >-
Connect the extractor with a <strong>conveyor belt</strong> to your hub!<br><br>Tip: <strong>Click and drag</strong> the belt with your mouse!
1_3_expand: >-
This is <strong>NOT</strong> an idle game! Build more extractors and belts to finish the goal quicker.<br><br>Tip: Hold <strong>SHIFT</strong> to place multiple extractors, and use <strong>R</strong> to rotate them.
# All shop upgrades
shopUpgrades:
belt:
name: Belts, Distributor & Tunnels
description: Speed x<currentMult> → x<newMult>
miner:
name: Extraction
description: Speed x<currentMult> → x<newMult>
processors:
name: Cutting, Rotating & Stacking
description: Speed x<currentMult> → x<newMult>
painting:
name: Mixing & Painting
description: Speed x<currentMult> → x<newMult>
# Buildings and their name / description
buildings:
hub:
deliver: Deliver
toUnlock: to unlock
levelShortcut: LVL
belt:
default:
name: &belt Conveyor Belt
description: Transports items, hold and drag to place multiple.
wire:
default:
name: &wire Wire
description: Allows to transport energy
miner: # Internal name for the Extractor
default:
name: &miner Extractor
description: Place over a shape or color to extract it.
chainable:
name: Extractor (Chain)
description: Place over a shape or color to extract it. Can be chained.
underground_belt: # Internal name for the Tunnel
default:
name: &underground_belt Tunnel
description: Allows to tunnel resources under buildings and belts.
tier2:
name: Tunnel Tier II
description: Allows to tunnel resources under buildings and belts.
splitter: # Internal name for the Balancer
default:
name: &splitter Balancer
description: Multifunctional - Evenly distributes all inputs onto all outputs.
compact:
name: Merger (compact)
description: Merges two conveyor belts into one.
compact-inverse:
name: Merger (compact)
description: Merges two conveyor belts into one.
cutter:
default:
name: &cutter Cutter
description: Cuts shapes from top to bottom and outputs both halfs. <strong>If you use only one part, be sure to destroy the other part or it will stall!</strong>
quad:
name: Cutter (Quad)
description: Cuts shapes into four parts. <strong>If you use only one part, be sure to destroy the other parts or it will stall!</strong>
advanced_processor:
default:
name: &advanced_processor Advanced Processor
description: Advanced shape processing
rotater:
default:
name: &rotater Rotate
description: Rotates shapes clockwise by 90 degrees.
ccw:
name: Rotate (CCW)
description: Rotates shapes counter clockwise by 90 degrees.
stacker:
default:
name: &stacker Stacker
description: Stacks both items. If they can not be merged, the right item is placed above the left item.
mixer:
default:
name: &mixer Color Mixer
description: Mixes two colors using additive blending.
painter:
default:
name: &painter Painter
description: &painter_desc Colors the whole shape on the left input with the color from the top input.
mirrored:
name: *painter
description: *painter_desc
double:
name: Painter (Double)
description: Colors the shapes on the left inputs with the color from the top input.
quad:
name: Painter (Quad)
description: Allows to color each quadrant of the shape with a different color.
trash:
default:
name: &trash Trash
description: Accepts inputs from all sides and destroys them. Forever.
storage:
name: Storage
description: Stores excess items, up to a given capacity. Can be used as an overflow gate.
energy_generator:
deliver: Deliver
# This will be shown before the amount, so for example 'For 123 Energy'
toGenerateEnergy: For
default:
name: &energy_generator Energy Generator
description: Generates energy by consuming shapes. Each energy generator requires a different shapes.
storyRewards:
# Those are the rewards gained from completing the store
reward_cutter_and_trash:
title: Cutting Shapes
desc: You just unlocked the <strong>cutter</strong> - it cuts shapes half from <strong>top to bottom</strong> regardless of its orientation!<br><br>Be sure to get rid of the waste, or otherwise <strong>it will stall</strong> - For this purpose I gave you a trash, which destroys everything you put into it!
reward_rotater:
title: Rotating
desc: The <strong>rotater</strong> has been unlocked! It rotates shapes clockwise by 90 degrees.
reward_painter:
title: Painting
desc: >-
The <strong>painter</strong> has been unlocked - Extract some color veins (just as you do with shapes) and combine it with a shape in the painter to color them!<br><br>PS: If you are colorblind, there is a <strong>color blind mode</strong> in the settings!
reward_mixer:
title: Color Mixing
desc: The <strong>mixer</strong> has been unlocked - Combine two colors using <strong>additive blending</strong> with this building!
reward_stacker:
title: Combiner
desc: You can now combine shapes with the <strong>combiner</strong>! Both inputs are combined, and if they can be put next to each other, they will be <strong>fused</strong>. If not, the right input is <strong>stacked on top</strong> of the left input!
reward_splitter:
title: Splitter/Merger
desc: The multifunctional <strong>balancer</strong> has been unlocked - It can be used to build bigger factories by <strong>splitting and merging items</strong> onto multiple belts!<br><br>
reward_tunnel:
title: Tunnel
desc: The <strong>tunnel</strong> has been unlocked - You can now tunnel items through belts and buildings with it!
reward_rotater_ccw:
title: CCW Rotating
desc: You have unlocked a variant of the <strong>rotater</strong> - It allows to rotate counter clockwise! To build it, select the rotater and <strong>press 'T' to cycle its variants</strong>!
reward_miner_chainable:
title: Chaining Extractor
desc: You have unlocked the <strong>chaining extractor</strong>! It can <strong>forward its resources</strong> to other extractors so you can more efficiently extract resources!
reward_underground_belt_tier_2:
title: Tunnel Tier II
desc: You have unlocked a new variant of the <strong>tunnel</strong> - It has a <strong>bigger range</strong>, and you can also mix-n-match those tunnels now!
reward_splitter_compact:
title: Compact Balancer
desc: >-
You have unlocked a compact variant of the <strong>balancer</strong> - It accepts two inputs and merges them into one!
reward_cutter_quad:
title: Quad Cutting
desc: You have unlocked a variant of the <strong>cutter</strong> - It allows you to cut shapes in <strong>four parts</strong> instead of just two!
reward_painter_double:
title: Double Painting
desc: You have unlocked a variant of the <strong>painter</strong> - It works as the regular painter but processes <strong>two shapes at once</strong> consuming just one color instead of two!
reward_painter_quad:
title: Quad Painting
desc: You have unlocked a variant of the <strong>painter</strong> - It allows to paint each part of the shape individually!
reward_storage:
title: Storage Buffer
desc: You have unlocked a variant of the <strong>trash</strong> - It allows to store items up to a given capacity!
reward_freeplay:
title: Freeplay
desc: You did it! You unlocked the <strong>free-play mode</strong>! This means that shapes are now randomly generated! (No worries, more content is planned for the standalone!)
reward_blueprints:
title: Blueprints
desc: You can now <strong>copy and paste</strong> parts of your factory! Select an area (Hold CTRL, then drag with your mouse), and press 'C' to copy it.<br><br>Pasting it is <strong>not free</strong>, you need to produce <strong>blueprint shapes</strong> to afford it! (Those you just delivered).
# Special reward, which is shown when there is no reward actually
no_reward:
title: Next level
desc: >-
This level gave you no reward, but the next one will! <br><br> PS: Better don't destroy your existing factory - You need <strong>all</strong> those shapes later again to <strong>unlock upgrades</strong>!
reward_wires:
title: Wires
desc: TODO
no_reward_freeplay:
title: Next level
desc: >-
Congratulations! By the way, more content is planned for the standalone!
settings:
title: Settings
categories:
game: Game
app: Application
versionBadges:
dev: Development
staging: Staging
prod: Production
buildDate: Built <at-date>
labels:
uiScale:
title: Interface scale
description: >-
Changes the size of the user interface. The interface will still scale based on your device resolution, but this setting controls the amount of scale.
scales:
super_small: Super small
small: Small
regular: Regular
large: Large
huge: Huge
autosaveInterval:
title: Autosave Interval
description: >-
Controls how often the game saves automatically. You can also disable it entirely here.
intervals:
one_minute: 1 Minute
two_minutes: 2 Minutes
five_minutes: 5 Minutes
ten_minutes: 10 Minutes
twenty_minutes: 20 Minutes
disabled: Disabled
scrollWheelSensitivity:
title: Zoom sensitivity
description: >-
Changes how sensitive the zoom is (Either mouse wheel or trackpad).
sensitivity:
super_slow: Super slow
slow: Slow
regular: Regular
fast: Fast
super_fast: Super fast
movementSpeed:
title: Movement speed
description: >-
Changes how fast the view moves when using the keyboard.
speeds:
super_slow: Super slow
slow: Slow
regular: Regular
fast: Fast
super_fast: Super Fast
extremely_fast: Extremely Fast
language:
title: Language
description: >-
Change the language. All translations are user contributed and might be incomplete!
enableColorBlindHelper:
title: Color Blind Mode
description: >-
Enables various tools which allow to play the game if you are color blind.
fullscreen:
title: Fullscreen
description: >-
It is recommended to play the game in fullscreen to get the best experience. Only available in the standalone.
soundsMuted:
title: Mute Sounds
description: >-
If enabled, mutes all sound effects.
musicMuted:
title: Mute Music
description: >-
If enabled, mutes all music.
theme:
title: Game theme
description: >-
Choose the game theme (light / dark).
themes:
dark: Dark
light: Light
refreshRate:
title: Simulation Target
description: >-
If you have a 144hz monitor, change the refresh rate here so the game will properly simulate at higher refresh rates. This might actually decrease the FPS if your computer is too slow.
alwaysMultiplace:
title: Multiplace
description: >-
If enabled, all buildings will stay selected after placement until you cancel it. This is equivalent to holding SHIFT permanently.
offerHints:
title: Hints & Tutorials
description: >-
Whether to offer hints and tutorials while playing. Also hides certain UI elements onto a given level to make it easier to get into the game.
enableTunnelSmartplace:
title: Smart Tunnels
description: >-
When enabled, placing tunnels will automatically remove unnecessary belts. This also enables to drag tunnels and excess tunnels will get removed.
vignette:
title: Vignette
description: >-
Enables the vignette which darkens the screen corners and makes text easier to read.
rotationByBuilding:
title: Rotation by building type
description: >-
Each building type remembers the rotation you last set it to individually. This may be more comfortable if you frequently switch between placing different building types.
compactBuildingInfo:
title: Compact Building Infos
description: >-
Shortens info boxes for buildings by only showing their ratios. Otherwise a description and image is shown.
disableCutDeleteWarnings:
title: Disable Cut/Delete Warnings
description: >-
Disable the warning dialogs brought up when cutting/deleting more than 100 entities.
keybindings:
title: Keybindings
hint: >-
Tip: Be sure to make use of CTRL, SHIFT and ALT! They enable different placement options.
resetKeybindings: Reset Keybindings
categoryLabels:
general: Application
ingame: Game
navigation: Navigating
placement: Placement
massSelect: Mass Select
buildings: Building Shortcuts
placementModifiers: Placement Modifiers
mappings:
confirm: Confirm
back: Back
mapMoveUp: Move Up
mapMoveRight: Move Right
mapMoveDown: Move Down
mapMoveLeft: Move Left
mapMoveFaster: Move Faster
centerMap: Center Map
mapZoomIn: Zoom in
mapZoomOut: Zoom out
createMarker: Create Marker
menuOpenShop: Upgrades
menuOpenStats: Statistics
toggleHud: Toggle HUD
toggleFPSInfo: Toggle FPS and Debug Info
switchLayers: Switch layers
exportScreenshot: Export whole Base as Image
belt: *belt
splitter: *splitter
underground_belt: *underground_belt
miner: *miner
cutter: *cutter
advanced_processor: *advanced_processor
rotater: *rotater
stacker: *stacker
mixer: *mixer
energy_generator: *energy_generator
painter: *painter
trash: *trash
wire: *wire
pipette: Pipette
rotateWhilePlacing: Rotate
rotateInverseModifier: >-
Modifier: Rotate CCW instead
cycleBuildingVariants: Cycle Variants
confirmMassDelete: Delete area
pasteLastBlueprint: Paste last blueprint
cycleBuildings: Cycle Buildings
lockBeltDirection: Enable belt planner
switchDirectionLockSide: >-
Planner: Switch side
massSelectStart: Hold and drag to start
massSelectSelectMultiple: Select multiple areas
massSelectCopy: Copy area
massSelectCut: Cut area
placementDisableAutoOrientation: Disable automatic orientation
placeMultiple: Stay in placement mode
placeInverse: Invert automatic belt orientation
about:
title: About this Game
body: >-
This game is open source and developed by <a href="https://github.com/tobspr" target="_blank">Tobias Springer</a> (this is me).<br><br>
If you want to contribute, check out <a href="<githublink>" target="_blank">shapez.io on github</a>.<br><br>
This game wouldn't have been possible without the great discord community around my games - You should really join the <a href="<discordlink>" target="_blank">discord server</a>!<br><br>
The soundtrack was made by <a href="https://soundcloud.com/pettersumelius" target="_blank">Peppsen</a> - He's awesome.<br><br>
Finally, huge thanks to my best friend <a href="https://github.com/niklas-dahl" target="_blank">Niklas</a> - Without our factorio sessions this game would never have existed.
changelog:
title: Changelog
demo:
features:
restoringGames: Restoring savegames
importingGames: Importing savegames
oneGameLimit: Limited to one savegame
customizeKeybindings: Customizing Keybindings
exportingBase: Exporting whole Base as Image
settingNotAvailable: Not available in the demo.

@ -301,6 +301,7 @@ ingame:
purple: Purple
cyan: Cyan
white: White
black: Black
uncolored: No color
# Everything related to placing buildings (I.e. as soon as you selected a building

@ -528,8 +528,9 @@ storyRewards:
reward_painter:
title: Pintor
desc: El <strong>pintor</strong> ha sido desbloqueado - ¡Extrae vetas de color (igual que lo haces con las figuras) y combínalas con una figura en el pintor para colorearlas! <br><br>PD: Si tienes alguna forma de daltonismo, ¡hay un <strong>modo para daltonicos</strong> en las configuraciones!
desc: >-
El <strong>pintor</strong> ha sido desbloqueado - ¡Extrae vetas de color (igual que lo haces con las figuras) y combínalas con una figura en el pintor para colorearlas! <br><br>PD: Si tienes alguna forma de daltonismo, ¡hay un <strong>modo para daltonicos</strong> en las configuraciones!
reward_mixer:
title: Mezclador de Color
desc: El <strong>mezclador</strong> ha sido desbloqueado - ¡Combina dos colores usando <strong>mezcla aditiva</strong> con este edificio!
@ -593,9 +594,9 @@ storyRewards:
Este nivel no da recompensa, ¡pero el siguiente si! <br><br> PS: Mejor no destruyas la fábrica que tienes - ¡Necesitarás <strong>todas</strong> esas figuras más adelante para <strong>desbloquear mejoras</strong>!
no_reward_freeplay:
title: Siguiente Nivel
desc: >-
¡Felicidades! ¡Por cierto, hay más contenido planeado para el juego completo!
title: Siguiente Nivel
desc: >-
¡Felicidades! ¡Por cierto, hay más contenido planeado para el juego completo!
settings:
title: Opciones
@ -721,10 +722,10 @@ settings:
description: Activa varias herramientas que facilitan jugar si tienes alguna forma de daltonismo.
rotationByBuilding:
title: Rotación por tipo de edificio
description: >-
Cada tipo de edificio recuerda la última rotación que le diste individualmente.
Esto puede ser más cómodo si cambias a menudo entre colocar diferentes tipos de edificios.
title: Rotación por tipo de edificio
description: >-
Cada tipo de edificio recuerda la última rotación que le diste individualmente.
Esto puede ser más cómodo si cambias a menudo entre colocar diferentes tipos de edificio.
keybindings:
title: Atajos de Teclado

@ -406,7 +406,7 @@ ingame:
purple: 보라
cyan: 청록
white: 하양
uncolored:
uncolored:
shapeViewer:
title: Layers
empty: Empty
@ -641,7 +641,7 @@ settings:
description: >-
키보드를 사용할 때, 화면 이동 속도를 설정합니다.
speeds:
super_slow:매우 느리게
super_slow: 매우 느리게
slow: 느리게
regular: 보통
fast: 빠르게
@ -696,7 +696,7 @@ settings:
description: >-
활성화 시키면, 터널을 설치하는 것이 자동적으로 불필요한 벨트를 없앱니다.
또한, 터널을 당겨서 남는 터널을 없앱니다.
vignette:
title: 삽화
description: >-
@ -722,15 +722,15 @@ settings:
title: 자르기/삭제 경고기능 끄기
description: >-
100개 이상의 건물을 자르기/삭제할 때 경고창이 나오지 않게 합니다.
enableColorBlindHelper:
title: 색맹 모드
description: 색맹이 게임을 플레이하는데 도움을 주는 다양한 도구를 활성화 시킵니다.
rotationByBuilding:
title: 건물 유형에 따른 방향
description: >-
각 건물 유형은 최근에 설정한 방향을 개별적으로 기억합니다.
다른 유형의 건물 배치 간에 자주 방향을 전환할 경우, 이 방법이 더 편할 수 있습니다.
title: 건물 유형에 따른 방향
description: >-
각 건물 유형은 최근에 설정한 방향을 개별적으로 기억합니다.
다른 유형의 건물 배치 간에 자주 방향을 전환할 경우, 이 방법이 더 편할 수 있습니다.
keybindings:
title: 키바인딩

Loading…
Cancel
Save