Merge branch 'master' of git://github.com/tobspr/shapez.io into feature/ore-q-ing

This commit is contained in:
Gerdon Abbink 2020-06-24 19:44:39 +02:00
commit f43a266fad
44 changed files with 1101 additions and 707 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:746c6cf3f0284798a78c08f77d7e9d0c28b02323081fda42b5fa876a7ade29a0 oid sha256:40d458f800344d819ad4d3f38943f53f399258369ee5c20f6583d1b49847465f
size 205925 size 188255

View File

@ -36,7 +36,6 @@ module.exports = ({ watch = false, standalone = false }) => {
lzString.compressToEncodedURIComponent("http://localhost:10005/v1") lzString.compressToEncodedURIComponent("http://localhost:10005/v1")
), ),
G_IS_DEV: "true", G_IS_DEV: "true",
G_IS_PROD: "false",
G_IS_RELEASE: "false", G_IS_RELEASE: "false",
G_IS_MOBILE_APP: "false", G_IS_MOBILE_APP: "false",
G_IS_BROWSER: "true", G_IS_BROWSER: "true",

View File

@ -24,7 +24,6 @@ module.exports = ({
assertAlways: "window.assert", assertAlways: "window.assert",
abstract: "window.assert(false, 'abstract method called');", abstract: "window.assert(false, 'abstract method called');",
G_IS_DEV: "false", G_IS_DEV: "false",
G_IS_PROD: "true",
G_IS_RELEASE: environment === "prod" ? "true" : "false", G_IS_RELEASE: environment === "prod" ? "true" : "false",
G_IS_STANDALONE: standalone ? "true" : "false", G_IS_STANDALONE: standalone ? "true" : "false",
G_IS_BROWSER: isBrowser ? "true" : "false", G_IS_BROWSER: isBrowser ? "true" : "false",

View File

@ -1,25 +1,78 @@
<?xml version="1.0" encoding="iso-8859-1"?> <?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve"> viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g transform="translate(-1)"> <rect x="1.985" style="fill:#C8414B;" width="508.03" height="512"/>
<path style="fill:#46B29D;" d="M328.61,98.163h0.088c1.971-0.012,3.923,0.379,5.738,1.148l71.683,29.484 <rect x="1.985" y="107.79" style="fill:#FFD250;" width="508.03" height="296.42"/>
c4.07,1.723,7.249,5.049,8.787,9.193c1.537,4.144,1.297,8.739-0.665,12.699l-11.652,24.099 <path style="fill:#C8414B;" d="M223.347,256.409l8.191-33.404c0.754-3.076-1.829-5.994-5.306-5.994h-5.77
c-5.942,12.252-10.388,25.174-13.242,38.488l-12.624,58.086c-1.107,5.424-5.003,9.857-10.24,11.652l-11.653,3.972 c-3.477,0-6.061,2.918-5.306,5.994L223.347,256.409z"/>
c-5.094,1.809-8.94,6.053-10.241,11.299l-6.885,28.513c-0.25,1.103-0.635,2.17-1.148,3.178l-5.473,11.211 <rect x="213.681" y="238.89" style="fill:#F5F5F5;" width="19.322" height="74.42"/>
c-2.003,4.139-5.709,7.201-10.152,8.386l-18.715,4.855c-7.018,1.83-11.893,8.196-11.829,15.448v11.211 <rect x="208.861" y="230.14" style="fill:#FAB446;" width="28.984" height="8.756"/>
c-0.023,3.42-1.102,6.75-3.09,9.534l-19.51,26.748c-3.683,5.056-5.967,10.993-6.621,17.214l-6.091,56.585 <g>
c-0.638,5.71-3.3,11.002-7.503,14.919c-4.172,3.812-9.621,5.922-15.272,5.914c-10.207-0.042-19.147-6.854-21.896-16.684 <rect x="189.531" y="256.41" style="fill:#C8414B;" width="48.3" height="8.756"/>
L187.45,416.75c-0.269-0.922-0.447-1.868-0.53-2.825l-17.656-163.84c-0.585-5.323-3.801-9.997-8.563-12.447l-21.629-11.211 <polygon style="fill:#C8414B;" points="237.839,291.429 208.856,282.674 208.856,273.919 237.839,282.674 "/>
c-5.391-2.781-9.662-7.331-12.094-12.888l-26.661-61.793c-4.326-9.941-2.235-21.509,5.297-29.308l10.064-10.417 <path style="fill:#C8414B;" d="M78.435,256.409l8.191-33.404c0.754-3.076-1.829-5.994-5.306-5.994h-5.77
c3.583-3.658,5.192-8.813,4.326-13.859l-4.414-27.63c-2.316-13.91,2.107-28.094,11.918-38.223l18.715-19.244 c-3.477,0-6.061,2.918-5.306,5.994L78.435,256.409z"/>
C154.266,4.72,165.356,0.003,176.945,0h29.662c11.59,0.003,22.679,4.72,30.721,13.065l16.244,16.684L328.61,98.163z"/> </g>
<path style="fill:#BDC3C7;" d="M283.478,97.103h35.31V220.69c0,9.751-7.904,17.655-17.655,17.655l0,0 <path style="fill:#F5F5F5;" d="M112.248,230.143c-5.335,0-9.661,3.919-9.661,8.756v56.908c0,10.638,10.955,30.643,48.305,30.643
c-9.751,0-17.655-7.904-17.655-17.655V97.103z"/> s48.305-20.006,48.305-30.643v-56.908c0-4.835-4.325-8.756-9.661-8.756H112.248L112.248,230.143z"/>
<circle style="fill:#CC4B4C;" cx="301.133" cy="52.966" r="52.966"/> <g>
<path style="fill:#FB7B76;" d="M283.478,61.793c-4.875,0-8.828-3.952-8.828-8.828c0.016-14.619,11.863-26.467,26.483-26.483 <path style="fill:#C8414B;" d="M150.891,273.919h-48.305V239.34c0-5.079,4.118-9.197,9.197-9.197h39.107v43.776H150.891z"/>
c4.875,0,8.828,3.952,8.828,8.828s-3.952,8.828-8.828,8.828c-4.873,0.006-8.821,3.955-8.828,8.828 <path style="fill:#C8414B;" d="M150.891,273.919h48.305v20.784c0,12.698-10.294,22.992-22.992,22.992h-2.32
C292.305,57.841,288.353,61.793,283.478,61.793z"/> c-12.698,0-22.992-10.294-22.992-22.992L150.891,273.919L150.891,273.919z"/>
</g>
<path style="fill:#FAB446;" d="M102.587,273.919h48.305v20.784c0,12.698-10.294,22.992-22.992,22.992h-2.32
c-12.698,0-22.992-10.294-22.992-22.992C102.587,294.703,102.587,273.919,102.587,273.919z"/>
<g>
<path style="fill:#C8414B;" d="M141.231,313.218v-39.299h-9.661v43.334C135.162,316.592,138.41,315.15,141.231,313.218z"/>
<path style="fill:#C8414B;" d="M121.909,317.253v-43.334h-9.661v39.299C115.069,315.15,118.316,316.592,121.909,317.253z"/>
</g>
<rect x="112.241" y="256.41" style="fill:#FFB441;" width="28.984" height="8.756"/>
<g>
<rect x="112.241" y="238.89" style="fill:#FAB446;" width="28.984" height="8.756"/>
<rect x="117.081" y="244.1" style="fill:#FAB446;" width="19.322" height="15.861"/>
</g>
<rect x="68.774" y="238.89" style="fill:#F5F5F5;" width="19.322" height="74.42"/>
<g>
<rect x="63.941" y="308.94" style="fill:#FAB446;" width="28.984" height="8.756"/>
<rect x="63.941" y="230.14" style="fill:#FAB446;" width="28.984" height="8.756"/>
</g>
<rect x="59.111" y="317.7" style="fill:#5064AA;" width="38.643" height="8.756"/>
<rect x="213.681" y="308.94" style="fill:#FAB446;" width="28.984" height="8.756"/>
<rect x="204.031" y="317.7" style="fill:#5064AA;" width="38.643" height="8.756"/>
<rect x="121.911" y="221.39" style="fill:#FAB446;" width="57.967" height="8.756"/>
<rect x="146.061" y="195.13" style="fill:#FFB441;" width="9.661" height="26.27"/>
<g>
<path style="fill:#F5F5F5;" d="M141.231,208.255c-7.991,0-14.491-5.891-14.491-13.132s6.5-13.132,14.491-13.132
s14.491,5.891,14.491,13.132C155.721,202.364,149.221,208.255,141.231,208.255z M141.231,190.745c-2.665,0-4.83,1.963-4.83,4.378
c0,2.415,2.165,4.378,4.83,4.378c2.665,0,4.83-1.963,4.83-4.378C146.061,192.707,143.896,190.745,141.231,190.745z"/>
<path style="fill:#F5F5F5;" d="M160.552,208.255c-7.991,0-14.491-5.891-14.491-13.132s6.5-13.132,14.491-13.132
s14.491,5.891,14.491,13.132C175.042,202.364,168.543,208.255,160.552,208.255z M160.552,190.745c-2.665,0-4.83,1.963-4.83,4.378
c0,2.415,2.165,4.378,4.83,4.378c2.665,0,4.83-1.963,4.83-4.378C165.382,192.707,163.217,190.745,160.552,190.745z"/>
<path style="fill:#F5F5F5;" d="M179.874,217.011c-7.991,0-14.491-5.891-14.491-13.132s6.5-13.132,14.491-13.132
s14.491,5.891,14.491,13.132S187.864,217.011,179.874,217.011z M179.874,199.5c-2.665,0-4.83,1.963-4.83,4.378
c0,2.415,2.165,4.378,4.83,4.378c2.665,0,4.83-1.963,4.83-4.378C184.704,201.462,182.539,199.5,179.874,199.5z"/>
<path style="fill:#F5F5F5;" d="M121.909,217.011c-7.991,0-14.491-5.891-14.491-13.132s6.5-13.132,14.491-13.132
s14.491,5.891,14.491,13.132C136.399,211.12,129.899,217.011,121.909,217.011z M121.909,199.5c-2.665,0-4.83,1.963-4.83,4.378
c0,2.415,2.165,4.378,4.83,4.378s4.83-1.963,4.83-4.378C126.739,201.462,124.574,199.5,121.909,199.5z"/>
</g>
<path style="fill:#FAB446;" d="M179.874,291.429v4.378c0,2.414-2.167,4.378-4.83,4.378s-4.83-1.964-4.83-4.378v-4.378H179.874
M189.534,282.674h-28.983v13.132c0,7.241,6.501,13.132,14.491,13.132c7.991,0,14.491-5.891,14.491-13.132L189.534,282.674
L189.534,282.674z"/>
<path style="fill:#FFA0D2;" d="M175.507,265.163h-0.928c-5.079,0-9.197-4.118-9.197-9.197v-7.872c0-5.079,4.118-9.197,9.197-9.197
h0.928c5.079,0,9.197,4.118,9.197,9.197v7.872C184.704,261.047,180.586,265.163,175.507,265.163z"/>
<ellipse style="fill:#5064AA;" cx="150.891" cy="273.92" rx="14.491" ry="13.13"/>
<rect x="146.061" y="177.61" style="fill:#FAB446;" width="9.661" height="26.27"/>
<path style="fill:#C8414B;" d="M121.909,221.388l-9.661-8.756l5.659-5.129c8.748-7.928,20.613-12.381,32.984-12.381l0,0
c12.371,0,24.237,4.454,32.984,12.381l5.659,5.129l-9.661,8.756H121.909z"/>
<g>
<ellipse style="fill:#FFD250;" cx="150.891" cy="212.63" rx="4.83" ry="4.378"/>
<ellipse style="fill:#FFD250;" cx="131.571" cy="212.63" rx="4.83" ry="4.378"/>
<ellipse style="fill:#FFD250;" cx="170.211" cy="212.63" rx="4.83" ry="4.378"/>
</g>
<g>
<rect x="63.941" y="256.41" style="fill:#C8414B;" width="48.3" height="8.756"/>
<polygon style="fill:#C8414B;" points="63.943,291.429 92.926,282.674 92.926,273.919 63.943,282.674 "/>
</g> </g>
<g> <g>
</g> </g>

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -33,6 +33,7 @@ import { MainMenuState } from "./states/main_menu";
import { MobileWarningState } from "./states/mobile_warning"; import { MobileWarningState } from "./states/mobile_warning";
import { PreloadState } from "./states/preload"; import { PreloadState } from "./states/preload";
import { SettingsState } from "./states/settings"; import { SettingsState } from "./states/settings";
import { ShapezGameAnalytics } from "./platform/browser/game_analytics";
const logger = createLogger("application"); const logger = createLogger("application");
@ -130,8 +131,7 @@ export class Application {
this.adProvider = new NoAdProvider(this); this.adProvider = new NoAdProvider(this);
this.sound = new SoundImplBrowser(this); this.sound = new SoundImplBrowser(this);
this.analytics = new GoogleAnalyticsImpl(this); this.analytics = new GoogleAnalyticsImpl(this);
// this.gameAnalytics = new ShapezGameAnalytics(this); this.gameAnalytics = new ShapezGameAnalytics(this);
this.gameAnalytics = new NoGameAnalytics(this);
} }
/** /**

View File

@ -1,4 +1,14 @@
export const CHANGELOG = [ export const CHANGELOG = [
{
version: "1.1.18",
date: "24.06.2020",
entries: [
"Preparations for the wires update",
"Add setting (on by default) to store the last used rotation per building instead of globally storing it (by Magos)",
"Added chinese (traditional) translation",
"Updated translations",
],
},
{ {
version: "1.1.17", version: "1.1.17",
date: "22.06.2020", date: "22.06.2020",

View File

@ -9,7 +9,7 @@ export const IS_DEBUG =
export const IS_DEMO = queryParamOptions.fullVersion export const IS_DEMO = queryParamOptions.fullVersion
? false ? false
: (G_IS_PROD && !G_IS_STANDALONE) || : (!G_IS_DEV && !G_IS_STANDALONE) ||
(typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0); (typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0);
export const SUPPORT_TOUCH = false; export const SUPPORT_TOUCH = false;

View File

@ -769,7 +769,7 @@ export function quantizeFloat(value) {
* @param {number} tickRate Interval of the timer * @param {number} tickRate Interval of the timer
*/ */
export function checkTimerExpired(now, lastTick, tickRate) { export function checkTimerExpired(now, lastTick, tickRate) {
if (!G_IS_PROD) { if (G_IS_DEV) {
if (quantizeFloat(now) !== now) { if (quantizeFloat(now) !== now) {
console.error("Got non-quantizied time:" + now + " vs " + quantizeFloat(now)); console.error("Got non-quantizied time:" + now + " vs " + quantizeFloat(now));
now = quantizeFloat(now); now = quantizeFloat(now);

View File

@ -3,13 +3,16 @@ import { BaseItem } from "../base_item";
import { Component } from "../component"; import { Component } from "../component";
import { types } from "../../savegame/serialization"; import { types } from "../../savegame/serialization";
import { gItemRegistry } from "../../core/global_registries"; import { gItemRegistry } from "../../core/global_registries";
import { Entity } from "../entity";
/** /**
* @typedef {{ * @typedef {{
* pos: Vector, * pos: Vector,
* direction: enumDirection, * direction: enumDirection,
* item: BaseItem, * item: BaseItem,
* progress: number? * progress: number?,
* cachedDestSlot?: import("./item_acceptor").ItemAcceptorLocatedSlot,
* cachedTargetEntity?: Entity
* }} ItemEjectorSlot * }} ItemEjectorSlot
*/ */
@ -19,6 +22,8 @@ export class ItemEjectorComponent extends Component {
} }
static getSchema() { static getSchema() {
// The cachedDestSlot, cachedTargetEntity, and cachedConnectedSlots fields
// are not serialized.
return { return {
instantEject: types.bool, instantEject: types.bool,
slots: types.array( slots: types.array(
@ -61,6 +66,9 @@ export class ItemEjectorComponent extends Component {
this.instantEject = instantEject; this.instantEject = instantEject;
this.setSlots(slots); this.setSlots(slots);
/** @type {ItemEjectorSlot[]} */
this.cachedConnectedSlots = null;
} }
/** /**
@ -76,6 +84,8 @@ export class ItemEjectorComponent extends Component {
direction: slot.direction, direction: slot.direction,
item: null, item: null,
progress: 0, progress: 0,
cachedDestSlot: null,
cachedTargetEntity: null,
}); });
} }
} }

View File

@ -46,7 +46,13 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
* The current rotation * The current rotation
* @type {number} * @type {number}
*/ */
this.currentBaseRotation = 0; this.currentBaseRotationGeneral = 0;
/**
* The current rotation preference for each building.
* @type{Object.<string,number>}
*/
this.preferredBaseRotations = {};
/** /**
* Whether we are currently dragging * Whether we are currently dragging
@ -115,6 +121,39 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
this.root.camera.upPostHandler.add(this.onMouseUp, this); this.root.camera.upPostHandler.add(this.onMouseUp, this);
} }
/**
* Returns the current base rotation for the current meta-building.
* @returns {number}
*/
get currentBaseRotation() {
if (!this.root.app.settings.getAllSettings().rotationByBuilding) {
return this.currentBaseRotationGeneral;
}
const metaBuilding = this.currentMetaBuilding.get();
if (metaBuilding && this.preferredBaseRotations.hasOwnProperty(metaBuilding.getId())) {
return this.preferredBaseRotations[metaBuilding.getId()];
} else {
return this.currentBaseRotationGeneral;
}
}
/**
* Sets the base rotation for the current meta-building.
* @param {number} rotation The new rotation/angle.
*/
set currentBaseRotation(rotation) {
if (!this.root.app.settings.getAllSettings().rotationByBuilding) {
this.currentBaseRotationGeneral = rotation;
} else {
const metaBuilding = this.currentMetaBuilding.get();
if (metaBuilding) {
this.preferredBaseRotations[metaBuilding.getId()] = rotation;
} else {
this.currentBaseRotationGeneral = rotation;
}
}
}
/** /**
* Returns if the direction lock is currently active * Returns if the direction lock is currently active
* @returns {boolean} * @returns {boolean}

View File

@ -7,6 +7,7 @@ import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter"; import { GameSystemWithFilter } from "../game_system_with_filter";
import { Math_min } from "../../core/builtins"; import { Math_min } from "../../core/builtins";
import { createLogger } from "../../core/logging"; import { createLogger } from "../../core/logging";
import { Rectangle } from "../../core/rectangle";
const logger = createLogger("systems/ejector"); const logger = createLogger("systems/ejector");
@ -14,23 +15,34 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
constructor(root) { constructor(root) {
super(root, [ItemEjectorComponent]); super(root, [ItemEjectorComponent]);
/**
* @type {Array<{
* targetEntity: Entity,
* sourceSlot: import("../components/item_ejector").ItemEjectorSlot,
* destSlot: import("../components/item_acceptor").ItemAcceptorLocatedSlot
* }>}
*/
this.cache = [];
this.cacheNeedsUpdate = true; this.cacheNeedsUpdate = true;
this.root.signals.entityAdded.add(this.invalidateCache, this); this.root.signals.entityAdded.add(this.invalidateCache, this);
this.root.signals.entityDestroyed.add(this.invalidateCache, this); this.root.signals.entityDestroyed.add(this.invalidateCache, this);
/**
* @type {Rectangle[]}
*/
this.smallCacheAreas = [];
} }
invalidateCache() { /**
*
* @param {Entity} entity
*/
invalidateCache(entity) {
if (!entity.components.StaticMapEntity) {
return;
}
this.cacheNeedsUpdate = true; this.cacheNeedsUpdate = true;
// Optimize for the common case: adding or removing one building at a time. Clicking
// and dragging can cause up to 4 add/remove signals.
const staticComp = entity.components.StaticMapEntity;
const bounds = staticComp.getTileSpaceBounds();
const expandedBounds = bounds.expandedInAllDirections(2);
this.smallCacheAreas.push(expandedBounds);
} }
/** /**
@ -39,59 +51,102 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
recomputeCache() { recomputeCache() {
logger.log("Recomputing cache"); logger.log("Recomputing cache");
const cache = []; let entryCount = 0;
if (this.smallCacheAreas.length <= 4) {
// Try to find acceptors for every ejector // Only recompute caches of entities inside the rectangles.
for (let i = 0; i < this.allEntities.length; ++i) { for (let i = 0; i < this.smallCacheAreas.length; i++) {
const entity = this.allEntities[i]; entryCount += this.recomputeAreaCaches(this.smallCacheAreas[i]);
const ejectorComp = entity.components.ItemEjector; }
const staticComp = entity.components.StaticMapEntity; } else {
// Try to find acceptors for every ejector
// For every ejector slot, try to find an acceptor for (let i = 0; i < this.allEntities.length; ++i) {
for (let ejectorSlotIndex = 0; ejectorSlotIndex < ejectorComp.slots.length; ++ejectorSlotIndex) { const entity = this.allEntities[i];
const ejectorSlot = ejectorComp.slots[ejectorSlotIndex]; entryCount += this.recomputeSingleEntityCache(entity);
// Figure out where and into which direction we eject items
const ejectSlotWsTile = staticComp.localTileToWorld(ejectorSlot.pos);
const ejectSlotWsDirection = staticComp.localDirectionToWorld(ejectorSlot.direction);
const ejectSlotWsDirectionVector = enumDirectionToVector[ejectSlotWsDirection];
const ejectSlotTargetWsTile = ejectSlotWsTile.add(ejectSlotWsDirectionVector);
// Try to find the given acceptor component to take the item
const targetEntity = this.root.map.getTileContent(ejectSlotTargetWsTile);
if (!targetEntity) {
// No consumer for item
continue;
}
const targetAcceptorComp = targetEntity.components.ItemAcceptor;
const targetStaticComp = targetEntity.components.StaticMapEntity;
if (!targetAcceptorComp) {
// Entity doesn't accept items
continue;
}
const matchingSlot = targetAcceptorComp.findMatchingSlot(
targetStaticComp.worldToLocalTile(ejectSlotTargetWsTile),
targetStaticComp.worldDirectionToLocal(ejectSlotWsDirection)
);
if (!matchingSlot) {
// No matching slot found
continue;
}
// Ok we found a connection
cache.push({
targetEntity,
sourceSlot: ejectorSlot,
destSlot: matchingSlot,
});
} }
} }
logger.log("Found", entryCount, "entries to update");
this.cache = cache; this.smallCacheAreas = [];
logger.log("Found", cache.length, "entries to update"); }
/**
*
* @param {Rectangle} area
*/
recomputeAreaCaches(area) {
let entryCount = 0;
for (let x = area.x; x < area.right(); ++x) {
for (let y = area.y; y < area.bottom(); ++y) {
const entity = this.root.map.getTileContentXY(x, y);
if (entity && entity.components.ItemEjector) {
entryCount += this.recomputeSingleEntityCache(entity);
}
}
}
return entryCount;
}
/**
*
* @param {Entity} entity
*/
recomputeSingleEntityCache(entity) {
const ejectorComp = entity.components.ItemEjector;
const staticComp = entity.components.StaticMapEntity;
// Clear the old cache.
ejectorComp.cachedConnectedSlots = null;
// For every ejector slot, try to find an acceptor
let entryCount = 0;
for (let ejectorSlotIndex = 0; ejectorSlotIndex < ejectorComp.slots.length; ++ejectorSlotIndex) {
const ejectorSlot = ejectorComp.slots[ejectorSlotIndex];
// Clear the old cache.
ejectorSlot.cachedDestSlot = null;
ejectorSlot.cachedTargetEntity = null;
// Figure out where and into which direction we eject items
const ejectSlotWsTile = staticComp.localTileToWorld(ejectorSlot.pos);
const ejectSlotWsDirection = staticComp.localDirectionToWorld(ejectorSlot.direction);
const ejectSlotWsDirectionVector = enumDirectionToVector[ejectSlotWsDirection];
const ejectSlotTargetWsTile = ejectSlotWsTile.add(ejectSlotWsDirectionVector);
// Try to find the given acceptor component to take the item
const targetEntity = this.root.map.getTileContent(ejectSlotTargetWsTile);
if (!targetEntity) {
// No consumer for item
continue;
}
const targetAcceptorComp = targetEntity.components.ItemAcceptor;
const targetStaticComp = targetEntity.components.StaticMapEntity;
if (!targetAcceptorComp) {
// Entity doesn't accept items
continue;
}
const matchingSlot = targetAcceptorComp.findMatchingSlot(
targetStaticComp.worldToLocalTile(ejectSlotTargetWsTile),
targetStaticComp.worldDirectionToLocal(ejectSlotWsDirection)
);
if (!matchingSlot) {
// No matching slot found
continue;
}
// Ok we found a connection
if (ejectorComp.cachedConnectedSlots) {
ejectorComp.cachedConnectedSlots.push(ejectorSlot);
} else {
ejectorComp.cachedConnectedSlots = [ejectorSlot];
}
ejectorSlot.cachedTargetEntity = targetEntity;
ejectorSlot.cachedDestSlot = matchingSlot;
entryCount += 1;
}
return entryCount;
} }
update() { update() {
@ -109,35 +164,45 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
} }
// Go over all cache entries // Go over all cache entries
for (let i = 0; i < this.cache.length; ++i) { for (let i = 0; i < this.allEntities.length; ++i) {
const { sourceSlot, destSlot, targetEntity } = this.cache[i]; const sourceEntity = this.allEntities[i];
const item = sourceSlot.item; const sourceEjectorComp = sourceEntity.components.ItemEjector;
if (!sourceEjectorComp.cachedConnectedSlots) {
if (!item) {
// No item available to be ejected
continue; continue;
} }
for (let j = 0; j < sourceEjectorComp.cachedConnectedSlots.length; j++) {
const sourceSlot = sourceEjectorComp.cachedConnectedSlots[j];
const destSlot = sourceSlot.cachedDestSlot;
const targetEntity = sourceSlot.cachedTargetEntity;
// Advance items on the slot const item = sourceSlot.item;
sourceSlot.progress = Math_min(1, sourceSlot.progress + progressGrowth);
// Check if we are still in the process of ejecting, can't proceed then if (!item) {
if (sourceSlot.progress < 1.0) { // No item available to be ejected
continue; continue;
} }
// Check if the target acceptor can actually accept this item // Advance items on the slot
const targetAcceptorComp = targetEntity.components.ItemAcceptor; sourceSlot.progress = Math_min(1, sourceSlot.progress + progressGrowth);
if (!targetAcceptorComp.canAcceptItem(destSlot.index, item)) {
continue;
}
// Try to hand over the item // Check if we are still in the process of ejecting, can't proceed then
if (this.tryPassOverItem(item, targetEntity, destSlot.index)) { if (sourceSlot.progress < 1.0) {
// Handover successful, clear slot continue;
targetAcceptorComp.onItemAccepted(destSlot.index, destSlot.acceptedDirection, item); }
sourceSlot.item = null;
continue; // Check if the target acceptor can actually accept this item
const targetAcceptorComp = targetEntity.components.ItemAcceptor;
if (!targetAcceptorComp.canAcceptItem(destSlot.index, item)) {
continue;
}
// Try to hand over the item
if (this.tryPassOverItem(item, targetEntity, destSlot.index)) {
// Handover successful, clear slot
targetAcceptorComp.onItemAccepted(destSlot.index, destSlot.acceptedDirection, item);
sourceSlot.item = null;
continue;
}
} }
} }
} }

1
src/js/globals.d.ts vendored
View File

@ -1,7 +1,6 @@
// Globals defined by webpack // Globals defined by webpack
declare const G_IS_DEV: boolean; declare const G_IS_DEV: boolean;
declare const G_IS_PROD: boolean;
declare function assert(condition: boolean | object | string, ...errorMessage: string[]): void; declare function assert(condition: boolean | object | string, ...errorMessage: string[]): void;
declare function assertAlways(condition: boolean | object | string, ...errorMessage: string[]): void; declare function assertAlways(condition: boolean | object | string, ...errorMessage: string[]): void;

View File

@ -51,10 +51,10 @@ export const LANGUAGES = {
region: "", region: "",
}, },
"es-419": { "es-419": {
name: "Español (Latinoamérica)", name: "Español",
data: require("./built-temp/base-es.json"), data: require("./built-temp/base-es.json"),
code: "es", code: "es",
region: "419", region: "",
}, },
"pl": { "pl": {
name: "Polski", name: "Polski",
@ -80,12 +80,23 @@ export const LANGUAGES = {
code: "no", code: "no",
region: "", region: "",
}, },
"zh-CN": { "zh-CN": {
name: "简体中文", // simplified
name: "中文简体",
data: require("./built-temp/base-zh-CN.json"), data: require("./built-temp/base-zh-CN.json"),
code: "zh", code: "zh",
region: "CN", region: "CN",
}, },
"zh-TW": {
// traditional
name: "中文繁體",
data: require("./built-temp/base-zh-TW.json"),
code: "zh",
region: "TW",
},
"sv": { "sv": {
name: "Svenska", name: "Svenska",
data: require("./built-temp/base-sv.json"), data: require("./built-temp/base-sv.json"),

View File

@ -1,11 +1,12 @@
import { GameAnalyticsInterface } from "../game_analytics";
import { createLogger } from "../../core/logging";
import { ShapeDefinition } from "../../game/shape_definition";
import { Savegame } from "../../savegame/savegame";
import { FILE_NOT_FOUND } from "../storage";
import { globalConfig } from "../../core/config"; import { globalConfig } from "../../core/config";
import { InGameState } from "../../states/ingame"; import { createLogger } from "../../core/logging";
import { GameRoot } from "../../game/root"; import { GameRoot } from "../../game/root";
import { InGameState } from "../../states/ingame";
import { GameAnalyticsInterface } from "../game_analytics";
import { FILE_NOT_FOUND } from "../storage";
import { blueprintShape, UPGRADES } from "../../game/upgrades";
import { tutorialGoals } from "../../game/tutorial_goals";
import { BeltComponent } from "../../game/components/belt";
import { StaticMapEntityComponent } from "../../game/components/static_map_entity"; import { StaticMapEntityComponent } from "../../game/components/static_map_entity";
const logger = createLogger("game_analytics"); const logger = createLogger("game_analytics");
@ -14,16 +15,32 @@ const analyticsUrl = G_IS_DEV ? "http://localhost:8001" : "https://analytics.sha
// Be sure to increment the ID whenever it changes to make sure all // Be sure to increment the ID whenever it changes to make sure all
// users are tracked // users are tracked
const analyticsLocalFile = "analytics_token.3.bin"; const analyticsLocalFile = "shapez_token_123.bin";
export class ShapezGameAnalytics extends GameAnalyticsInterface { export class ShapezGameAnalytics extends GameAnalyticsInterface {
get environment() {
if (G_IS_DEV) {
return "dev";
}
if (G_IS_STANDALONE) {
return "steam";
}
if (G_IS_RELEASE) {
return "prod";
}
return "beta";
}
/** /**
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
initialize() { initialize() {
this.syncKey = null; this.syncKey = null;
setInterval(() => this.sendTimePoints(), 120 * 1000); setInterval(() => this.sendTimePoints(), 60 * 1000);
// Retrieve sync key from player // Retrieve sync key from player
return this.app.storage.readFileAsync(analyticsLocalFile).then( return this.app.storage.readFileAsync(analyticsLocalFile).then(
@ -38,7 +55,7 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface {
// Perform call to get a new key from the API // Perform call to get a new key from the API
this.sendToApi("/v1/register", { this.sendToApi("/v1/register", {
environment: G_APP_ENVIRONMENT, environment: this.environment,
}) })
.then(res => { .then(res => {
// Try to read and parse the key from the api // Try to read and parse the key from the api
@ -135,10 +152,12 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface {
playerKey: this.syncKey, playerKey: this.syncKey,
gameKey: savegameId, gameKey: savegameId,
ingameTime: root.time.now(), ingameTime: root.time.now(),
environment: this.environment,
category, category,
value, value,
version: G_BUILD_VERSION, version: G_BUILD_VERSION,
gameDump: this.generateGameDump(root, category === "sync"), level: root.hubGoals.level,
gameDump: this.generateGameDump(root),
}); });
} }
@ -151,52 +170,58 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface {
} }
/** /**
* Generates a game dump * Returns true if the shape is interesting
* @param {GameRoot} root * @param {string} key
* @param {boolean=} metaOnly
*/ */
generateGameDump(root, metaOnly = false) { isInterestingShape(key) {
let staticEntities = []; if (key === blueprintShape) {
return true;
}
const entities = root.entityMgr.getAllWithComponent(StaticMapEntityComponent); // Check if its a story goal
for (let i = 0; i < tutorialGoals.length; ++i) {
// Limit the entities if (key === tutorialGoals[i].shape) {
if (!metaOnly && entities.length < 500) { return true;
for (let i = 0; i < entities.length; ++i) {
const entity = entities[i];
const staticComp = entity.components.StaticMapEntity;
const payload = {};
payload.origin = staticComp.origin;
payload.tileSize = staticComp.tileSize;
payload.rotation = staticComp.rotation;
if (entity.components.Belt) {
payload.type = "belt";
} else if (entity.components.UndergroundBelt) {
payload.type = "tunnel";
} else if (entity.components.ItemProcessor) {
payload.type = entity.components.ItemProcessor.type;
} else if (entity.components.Miner) {
payload.type = "extractor";
} else {
logger.warn("Unkown entity type", entity);
}
staticEntities.push(payload);
} }
} }
return { // Check if its required to unlock an upgrade
storedShapes: root.hubGoals.storedShapes, for (const upgradeKey in UPGRADES) {
gainedRewards: root.hubGoals.gainedRewards, const handle = UPGRADES[upgradeKey];
upgradeLevels: root.hubGoals.upgradeLevels, const tiers = handle.tiers;
staticEntities, for (let i = 0; i < tiers.length; ++i) {
}; const tier = tiers[i];
const required = tier.required;
for (let k = 0; k < required.length; ++k) {
if (required[k].shape === key) {
return true;
}
}
}
}
return false;
} }
/** /**
* @param {ShapeDefinition} definition * Generates a game dump
* @param {GameRoot} root
*/ */
handleShapeDelivered(definition) {} generateGameDump(root) {
const shapeIds = Object.keys(root.hubGoals.storedShapes).filter(this.isInterestingShape.bind(this));
let shapes = {};
for (let i = 0; i < shapeIds.length; ++i) {
shapes[shapeIds[i]] = root.hubGoals.storedShapes[shapeIds[i]];
}
return {
shapes,
upgrades: root.hubGoals.upgradeLevels,
belts: root.entityMgr.getAllWithComponent(BeltComponent).length,
buildings:
root.entityMgr.getAllWithComponent(StaticMapEntityComponent).length -
root.entityMgr.getAllWithComponent(BeltComponent).length,
};
}
/** /**
*/ */
@ -204,6 +229,12 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface {
this.sendGameEvent("game_start", ""); this.sendGameEvent("game_start", "");
} }
/**
*/
handleGameResumed() {
this.sendTimePoints();
}
/** /**
* Handles the given level completed * Handles the given level completed
* @param {number} level * @param {number} level

View File

@ -25,9 +25,9 @@ export class GameAnalyticsInterface {
handleGameStarted() {} handleGameStarted() {}
/** /**
* @param {ShapeDefinition} definition * Handles a resumed game
*/ */
handleShapeDelivered(definition) {} handleGameResumed() {}
/** /**
* Handles the given level completed * Handles the given level completed

View File

@ -251,6 +251,7 @@ export const allApplicationSettings = [
new BoolSetting("vignette", categoryGame, (app, value) => {}), new BoolSetting("vignette", categoryGame, (app, value) => {}),
new BoolSetting("compactBuildingInfo", categoryGame, (app, value) => {}), new BoolSetting("compactBuildingInfo", categoryGame, (app, value) => {}),
new BoolSetting("disableCutDeleteWarnings", categoryGame, (app, value) => {}), new BoolSetting("disableCutDeleteWarnings", categoryGame, (app, value) => {}),
new BoolSetting("rotationByBuilding", categoryGame, (app, value) => {}),
]; ];
export function getApplicationSettingById(id) { export function getApplicationSettingById(id) {
@ -277,6 +278,7 @@ class SettingsStorage {
this.vignette = true; this.vignette = true;
this.compactBuildingInfo = false; this.compactBuildingInfo = false;
this.disableCutDeleteWarnings = false; this.disableCutDeleteWarnings = false;
this.rotationByBuilding = true;
this.enableColorBlindHelper = false; this.enableColorBlindHelper = false;
@ -479,7 +481,7 @@ export class ApplicationSettings extends ReadWriteProxy {
} }
getCurrentVersion() { getCurrentVersion() {
return 17; return 18;
} }
/** @param {{settings: SettingsStorage, version: number}} data */ /** @param {{settings: SettingsStorage, version: number}} data */
@ -552,6 +554,11 @@ export class ApplicationSettings extends ReadWriteProxy {
data.version = 17; data.version = 17;
} }
if (data.version < 18) {
data.settings.rotationByBuilding = true;
data.version = 18;
}
return ExplainedResult.good(); return ExplainedResult.good();
} }
} }

View File

@ -217,7 +217,6 @@ export class InGameState extends GameState {
this.core.initializeRoot(this, this.savegame); this.core.initializeRoot(this, this.savegame);
if (this.savegame.hasGameDump()) { if (this.savegame.hasGameDump()) {
this.app.gameAnalytics.handleGameStarted();
this.stage4bResumeGame(); this.stage4bResumeGame();
} else { } else {
this.app.gameAnalytics.handleGameStarted(); this.app.gameAnalytics.handleGameStarted();
@ -245,6 +244,7 @@ export class InGameState extends GameState {
this.onInitializationFailure("Savegame is corrupt and can not be restored."); this.onInitializationFailure("Savegame is corrupt and can not be restored.");
return; return;
} }
this.app.gameAnalytics.handleGameResumed();
this.stage5FirstUpdate(); this.stage5FirstUpdate();
} }
} }

View File

@ -21,7 +21,7 @@ const placeholderRegexp = /<([a-zA-Z_0-9]+)>/gi;
function match(originalObj, translatedObj, path = "/") { function match(originalObj, translatedObj, path = "/") {
for (const key in originalObj) { for (const key in originalObj) {
if (!translatedObj[key]) { if (!translatedObj.hasOwnProperty(key)) {
console.warn(" | Missing key", path + key); console.warn(" | Missing key", path + key);
translatedObj[key] = originalObj[key]; translatedObj[key] = originalObj[key];
continue; continue;
@ -60,7 +60,7 @@ function match(originalObj, translatedObj, path = "/") {
} }
for (const key in translatedObj) { for (const key in translatedObj) {
if (!originalObj[key]) { if (!originalObj.hasOwnProperty(key)) {
console.warn(" | Obsolete key", path + key); console.warn(" | Obsolete key", path + key);
delete translatedObj[key]; delete translatedObj[key];
} }

View File

@ -531,7 +531,7 @@ storyRewards:
reward_painter: reward_painter:
title: Painting title: Painting
desc: >- 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, I'm working on a solution already! 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: reward_mixer:
title: Color Mixing title: Color Mixing
@ -728,6 +728,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Color Blind Mode title: Color Blind Mode
description: Enables various tools which allow to play the game if you are color blind. description: Enables various tools which allow to play the game if you are color blind.
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.
keybindings: keybindings:
title: Keybindings title: Keybindings

View File

@ -512,7 +512,7 @@ storyRewards:
reward_painter: reward_painter:
title: Barvení title: Barvení
desc: >- desc: >-
<strong>Barvič</strong> byl právě odemčen - vytěžte nějakou barvu (stejně jako těžíte tvary) a skombinujte ji v barviči s tvarem pro obarvení!<br><br>PS: Pokud jste barvoslepí, nebojte, již pracuju na řešení.! 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: reward_mixer:
title: Míchání barev title: Míchání barev
@ -708,6 +708,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Režim pro barvoslepé title: Režim pro barvoslepé
description: Zapné různé nástroje, které vám umožní hrát hru i pokud jste barvoslepí. description: Zapné různé nástroje, které vám umožní hrát hru i pokud jste barvoslepí.
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.
keybindings: keybindings:
title: Klávesové zkratky title: Klávesové zkratky

View File

@ -532,7 +532,7 @@ storyRewards:
reward_painter: reward_painter:
title: Färben title: Färben
desc: >- desc: >-
Der <strong>Färber</strong> wurde freigeschaltet! Extrahiere ein paar Farben (genauso wie die Formen) und lasse sie vom Färber bemalen!<br><br>PS: Falls du farbenblind bist: Ich arbeite bereits an einer Lösung! 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: reward_mixer:
title: Farben mischen title: Farben mischen
@ -728,6 +728,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Modus für Farbenblinde title: Modus für Farbenblinde
description: Aktiviert verschiedene Werkzeuge, die dir das Spielen trotz Farbenblindheit ermöglichen. description: Aktiviert verschiedene Werkzeuge, die dir das Spielen trotz Farbenblindheit ermöglichen.
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.
keybindings: keybindings:
title: Tastenbelegung title: Tastenbelegung

View File

@ -531,7 +531,7 @@ storyRewards:
reward_painter: reward_painter:
title: Painting title: Painting
desc: >- 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, I'm working on a solution already! 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: reward_mixer:
title: Color Mixing title: Color Mixing
@ -729,6 +729,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Color Blind Mode title: Color Blind Mode
description: Enables various tools which allow to play the game if you are color blind. description: Enables various tools which allow to play the game if you are color blind.
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.
keybindings: keybindings:
title: Keybindings title: Keybindings

View File

@ -534,7 +534,7 @@ storyRewards:
reward_painter: reward_painter:
title: Painting title: Painting
desc: >- 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, I'm working on a solution already! 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: reward_mixer:
title: Color Mixing title: Color Mixing
@ -721,6 +721,11 @@ settings:
title: Vignette title: Vignette
description: >- description: >-
Enables the vignette which darkens the screen corners and makes text easier to read. 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: compactBuildingInfo:
title: Compact Building Infos title: Compact Building Infos

View File

@ -528,7 +528,8 @@ storyRewards:
reward_painter: reward_painter:
title: Pintor title: Pintor
desc: >- desc: >-
El <strong> pintor</strong> ha sido desbloqueado - ¡Extrae color de las betas (al igual que haces con las figuras) y combínalo con una figura para pintarla de ese color!<br><br> PS: Si eres daltónico, estoy trabajando en una solución! 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: reward_mixer:
title: Mezclador de Color title: Mezclador de Color
desc: El <strong>mezclador</strong> ha sido desbloqueado - ¡Combina dos colores usando <strong>mezcla aditiva</strong> con este edificio! desc: El <strong>mezclador</strong> ha sido desbloqueado - ¡Combina dos colores usando <strong>mezcla aditiva</strong> con este edificio!
@ -716,6 +717,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Modo para Daltonicos title: Modo para Daltonicos
description: Activa varias herramientas que permiten jugar si eres daltonico. description: Activa varias herramientas que permiten jugar si eres daltonico.
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.
keybindings: keybindings:
title: Atajos de Teclado title: Atajos de Teclado

View File

@ -533,7 +533,7 @@ storyRewards:
reward_painter: reward_painter:
title: Peintre title: Peintre
desc: >- desc: >-
Le <strong>peintre</strong> a été débloqué - Extrayez des pigments de couleur (comme vous le faites avec les formes) et combinez les avec une forme dans un peintre pour les colorier !<br><br>PS: Si vous êtes daltonien, je travaille déjà à une solution ! 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: reward_mixer:
title: Mélangeur de couleurs title: Mélangeur de couleurs
@ -727,6 +727,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Mode Daltonien title: Mode Daltonien
description: Active divers outils qui permettent de jouer à ce jeu si vous êtes daltonien. description: Active divers outils qui permettent de jouer à ce jeu si vous êtes daltonien.
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.
keybindings: keybindings:
title: Contrôles title: Contrôles

View File

@ -531,7 +531,7 @@ storyRewards:
reward_painter: reward_painter:
title: Painting title: Painting
desc: >- 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, I'm working on a solution already! 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: reward_mixer:
title: Color Mixing title: Color Mixing
@ -727,6 +727,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Color Blind Mode title: Color Blind Mode
description: Enables various tools which allow to play the game if you are color blind. description: Enables various tools which allow to play the game if you are color blind.
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.
keybindings: keybindings:
title: Keybindings title: Keybindings

View File

@ -530,7 +530,7 @@ storyRewards:
reward_painter: reward_painter:
title: Painting title: Painting
desc: >- 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, I'm working on a solution already! 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: reward_mixer:
title: Color Mixing title: Color Mixing
@ -726,6 +726,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Color Blind Mode title: Color Blind Mode
description: Enables various tools which allow to play the game if you are color blind. description: Enables various tools which allow to play the game if you are color blind.
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.
keybindings: keybindings:
title: Keybindings title: Keybindings

View File

@ -531,7 +531,7 @@ storyRewards:
reward_painter: reward_painter:
title: Painting title: Painting
desc: >- 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, I'm working on a solution already! 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: reward_mixer:
title: Color Mixing title: Color Mixing
@ -727,6 +727,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Color Blind Mode title: Color Blind Mode
description: Enables various tools which allow to play the game if you are color blind. description: Enables various tools which allow to play the game if you are color blind.
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.
keybindings: keybindings:
title: Keybindings title: Keybindings

View File

@ -530,7 +530,7 @@ storyRewards:
reward_painter: reward_painter:
title: 着色 title: 着色
desc: >- desc: >-
<strong>着色機</strong>が利用可能になりました。 - 色の鉱脈から形の手順と同様に色を抽出し、着色機で形と組み合わせることで着色できます。<br><br>PS:もしあなたが色の認識に問題があっても安心してください。我々はすでにその解決に着手しています! 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: reward_mixer:
title: 色の混合 title: 色の混合
@ -722,6 +722,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: 色覚モード title: 色覚モード
description: 色覚異常を持っていてもゲームがプレイできるようにするための各種ツールを有効化します。 description: 色覚異常を持っていてもゲームがプレイできるようにするための各種ツールを有効化します。
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.
keybindings: keybindings:
title: キー設定 title: キー設定

View File

@ -531,7 +531,7 @@ storyRewards:
reward_painter: reward_painter:
title: 색칠기 title: 색칠기
desc: >- desc: >-
<strong>색칠기</strong>가 잠금 해제 되었습니다! 색소 광물을 추출해서 이 기계로 도형을 색칠하세요. <br><br>PS: 당신이 색맹이라면, 해결책을 찾고 있으니 잠시만 기다려주세요! 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: reward_mixer:
title: 혼합기 title: 혼합기
@ -728,6 +728,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Color Blind Mode title: Color Blind Mode
description: Enables various tools which allow to play the game if you are color blind. description: Enables various tools which allow to play the game if you are color blind.
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.
keybindings: keybindings:
title: 키바인딩 title: 키바인딩

View File

@ -531,7 +531,7 @@ storyRewards:
reward_painter: reward_painter:
title: Painting title: Painting
desc: >- 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, I'm working on a solution already! 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: reward_mixer:
title: Color Mixing title: Color Mixing
@ -726,6 +726,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Color Blind Mode title: Color Blind Mode
description: Enables various tools which allow to play the game if you are color blind. description: Enables various tools which allow to play the game if you are color blind.
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.
keybindings: keybindings:
title: Keybindings title: Keybindings

View File

@ -529,7 +529,7 @@ storyRewards:
reward_painter: reward_painter:
title: Verven title: Verven
desc: >- desc: >-
De <strong>verver</strong> is ontgrendeld - Onttrek wat kleurstoffen (net als met vormen) en combineer deze met een vorm in de verver om de vorm een kleur te geven!<br><br>PS: Ik werk aan een oplossing voor kleurenblinden! 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: reward_mixer:
title: Kleuren mengen title: Kleuren mengen
@ -701,9 +701,9 @@ settings:
autosaveInterval: autosaveInterval:
title: Autosave Interval title: Autosave Interval
description: >- description: >-
Bepaalt hoe vaak het spel automatisch opslaat. Je kan het hier ook volledig Bepaalt hoe vaak het spel automatisch opslaat. Je kan het hier ook volledig
mee uitschakelen. mee uitschakelen.
intervals: intervals:
one_minute: 1 Minuut one_minute: 1 Minuut
two_minutes: 2 Minuten two_minutes: 2 Minuten
@ -715,7 +715,7 @@ settings:
title: Combacte gebouwinformatie title: Combacte gebouwinformatie
description: >- description: >-
Informatie weergeven bij gebouwen wordt beperkt tot alleen hun 'ratios'. Anders Informatie weergeven bij gebouwen wordt beperkt tot alleen hun 'ratios'. Anders
zie je een beschrijving en een afbeelding. zie je een beschrijving en een afbeelding.
disableCutDeleteWarnings: disableCutDeleteWarnings:
title: Schakel knip/delete waarschuwingen uit. title: Schakel knip/delete waarschuwingen uit.
description: >- description: >-
@ -724,6 +724,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Kleurenblindmodus title: Kleurenblindmodus
description: Schakelt verschillende hulpmiddelen in zodat je het spel alsnog kunt spelen wanneer je kleurenblind bent. description: Schakelt verschillende hulpmiddelen in zodat je het spel alsnog kunt spelen wanneer je kleurenblind bent.
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.
keybindings: keybindings:
title: Sneltoetsen title: Sneltoetsen

View File

@ -529,7 +529,7 @@ storyRewards:
reward_painter: reward_painter:
title: Maling title: Maling
desc: >- desc: >-
<strong>Maleren</strong> har blitt tilgjengelig - Hent ut fargeressurser (på samme måte som du gjør med objekter) og kombiner det med et objekt i maleren for å male de!<br><br>PS: Hvis du er fargeblind, så jobber jeg med en løsning alt! 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: reward_mixer:
title: Fargemikser title: Fargemikser
@ -726,6 +726,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Fargeblind Modus title: Fargeblind Modus
description: Aktiverer forskjellige verktøy som lar deg spille spillet om du er fargeblind. description: Aktiverer forskjellige verktøy som lar deg spille spillet om du er fargeblind.
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.
keybindings: keybindings:
title: Hurtigtaster title: Hurtigtaster

View File

@ -546,7 +546,7 @@ storyRewards:
reward_painter: reward_painter:
title: Malowanie title: Malowanie
desc: >- desc: >-
Odblokowano nową maszynę: <strong>Malarz</strong> - Wydobądź barwniki (tak jak w przypadku kształtów) i połącz z kształtem, by go pomalować!<br><br>PS: Jeśli cierpisz na ślepotę barw, pracuję nad tym! 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: reward_mixer:
title: Mieszanie title: Mieszanie
@ -752,6 +752,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Color Blind Mode title: Color Blind Mode
description: Enables various tools which allow to play the game if you are color blind. description: Enables various tools which allow to play the game if you are color blind.
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.
keybindings: keybindings:
title: Klawiszologia title: Klawiszologia

View File

@ -532,7 +532,7 @@ storyRewards:
reward_painter: reward_painter:
title: Pintura title: Pintura
desc: >- desc: >-
O <strong> pintor </strong> foi desbloqueado - Extraia algumas fontes coloridas (como você faz com formas) e combine-as com uma forma no pintor para colorí-las! <br> <br> PS: Se você é daltônico, já estou trabalhando em uma solução! 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: reward_mixer:
title: Misturando cores title: Misturando cores
@ -727,6 +727,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Color Blind Mode title: Color Blind Mode
description: Enables various tools which allow to play the game if you are color blind. description: Enables various tools which allow to play the game if you are color blind.
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.
keybindings: keybindings:
title: Controles title: Controles

View File

@ -287,10 +287,10 @@ ingame:
pasteLastBlueprint: Colar o último blueprint pasteLastBlueprint: Colar o último blueprint
lockBeltDirection: Ativa o planeamento de tapetes lockBeltDirection: Ativa o planeamento de tapetes
plannerSwitchSide: Lado de rotação do planeamento plannerSwitchSide: Lado de rotação do planeamento
cutSelection: Cut cutSelection: Cortar
copySelection: Copy copySelection: Copiar
clearSelection: Clear Selection clearSelection: Cancelar
pipette: Pipette pipette: Pipeta
# Everything related to placing buildings (I.e. as soon as you selected a building # Everything related to placing buildings (I.e. as soon as you selected a building
# from the toolbar) # from the toolbar)
@ -398,17 +398,17 @@ ingame:
Isto <strong>NÃO</strong> é um jogo idle! Constrói mais extratores e tapetes para atingir o objetivo mais rapidamente.<br><br>Dica: Pressiona <strong>SHIFT</strong> para colocar vários extratores, e usa <strong>R</strong> para os rodar. Isto <strong>NÃO</strong> é um jogo idle! Constrói mais extratores e tapetes para atingir o objetivo mais rapidamente.<br><br>Dica: Pressiona <strong>SHIFT</strong> para colocar vários extratores, e usa <strong>R</strong> para os rodar.
colors: colors:
red: Red red: Vermelho
green: Green green: Verde
blue: Blue blue: Azul
yellow: Yellow yellow: Amarelo
purple: Purple purple: Roxo
cyan: Cyan cyan: Azul-bebé
white: White white: Branco
uncolored: No color uncolored: Sem cor
shapeViewer: shapeViewer:
title: Layers title: Camadas
empty: Empty empty: Vazio
# All shop upgrades # All shop upgrades
shopUpgrades: shopUpgrades:
@ -529,7 +529,7 @@ storyRewards:
reward_painter: reward_painter:
title: Pintura title: Pintura
desc: >- desc: >-
O <strong>Pintor</strong> foi desbloqueado - Extrai alguns pigmentos coloridos (tal como fazes com as formas) e combina-os com uma forma no pintor para a colorir!<br><br>PS: Se fores daltónico, já estou a trabalhar para encontrar uma solução! 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: reward_mixer:
title: Mistura de Cores title: Mistura de Cores
@ -679,14 +679,14 @@ settings:
Se ativado, dá dicas e tutoriais de apoio ao jogo. Adicionalmente, esconde certos elementos da interface do utilizador até ao nível em que são desbloqueados de forma a simplificar o início do jogo. Se ativado, dá dicas e tutoriais de apoio ao jogo. Adicionalmente, esconde certos elementos da interface do utilizador até ao nível em que são desbloqueados de forma a simplificar o início do jogo.
movementSpeed: movementSpeed:
title: Velociade de movimentação title: Velocidade de movimentação
description: Define quão rápida é a movimentação usando o teclado. description: Define quão rápida é a movimentação usando o teclado.
speeds: speeds:
super_slow: Muito lenta super_slow: Muito lenta
slow: Lenta slow: Lenta
regular: Média regular: Média
fast: Rápiada fast: Rápida
super_fast: Muito rádida super_fast: Muito rápida
extremely_fast: Extremamente rápida extremely_fast: Extremamente rápida
enableTunnelSmartplace: enableTunnelSmartplace:
title: Túneis inteligentes title: Túneis inteligentes
@ -700,31 +700,37 @@ settings:
mais fácil. mais fácil.
autosaveInterval: autosaveInterval:
title: Autosave Interval title: Intervalo de gravação automática
description: >- description: >-
Controls how often the game saves automatically. You can also disable it Define o quão frequentemente o jogo grava automaticamente. Também podes desativar
entirely here. aqui.
intervals: intervals:
one_minute: 1 Minute one_minute: 1 Minuto
two_minutes: 2 Minutes two_minutes: 2 Minutos
five_minutes: 5 Minutes five_minutes: 5 Minutos
ten_minutes: 10 Minutes ten_minutes: 10 Minutos
twenty_minutes: 20 Minutes twenty_minutes: 20 Minutos
disabled: Disabled disabled: Desligado
compactBuildingInfo: compactBuildingInfo:
title: Compact Building Infos title: Informações de construções compactas
description: >- description: >-
Shortens info boxes for buildings by only showing their ratios. Otherwise a Encurta caixas de informação mostrando apenas os respetivos rácios. Caso contrário
description and image is shown. é mostrada a descrição e a imagem.
disableCutDeleteWarnings: disableCutDeleteWarnings:
title: Disable Cut/Delete Warnings title: Desativar Avisos de Corte/Eliminação
description: >- description: >-
Disable the warning dialogs brought up when cutting/deleting more than 100 Desativa os avisos mostrados quando é feito o corte ou a eliminação de mais de 100
entities. entidades.
enableColorBlindHelper: enableColorBlindHelper:
title: Color Blind Mode title: Modo Daltónico
description: Enables various tools which allow to play the game if you are color blind. description: Ativa várias ferramentas para daltónicos.
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.
keybindings: keybindings:
title: Atalhos title: Atalhos
@ -791,7 +797,7 @@ keybindings:
mapMoveFaster: Mover rapidamente mapMoveFaster: Mover rapidamente
lockBeltDirection: Ativa o planeamento de tapetes lockBeltDirection: Ativa o planeamento de tapetes
switchDirectionLockSide: "Planeador: Troca o lado" switchDirectionLockSide: "Planeador: Troca o lado"
pipette: Pipette pipette: Pipeta
about: about:
title: Sobre o jogo title: Sobre o jogo
body: >- body: >-

View File

@ -530,7 +530,7 @@ storyRewards:
reward_painter: reward_painter:
title: Painting title: Painting
desc: >- 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, I'm working on a solution already! 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: reward_mixer:
title: Color Mixing title: Color Mixing
@ -726,6 +726,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Color Blind Mode title: Color Blind Mode
description: Enables various tools which allow to play the game if you are color blind. description: Enables various tools which allow to play the game if you are color blind.
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.
keybindings: keybindings:
title: Keybindings title: Keybindings

View File

@ -532,7 +532,7 @@ storyRewards:
reward_painter: reward_painter:
title: Покраска title: Покраска
desc: >- desc: >-
Разблокирован <strong>покрасчик</strong>! Добудьте краситель из жилы (так же как и фигуры) и объедините его с фигурой в покрасчике, чтобы раскрасить ее!<br><br>PS: Если вы дальтоник, я уже работаю над решением! 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: reward_mixer:
title: Смешивание Цветов title: Смешивание Цветов
@ -727,6 +727,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Режим Дальтоника title: Режим Дальтоника
description: Включает различные инструменты, которые позволяют играть в игру дальтоникам. description: Включает различные инструменты, которые позволяют играть в игру дальтоникам.
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.
keybindings: keybindings:
title: Настройки управления title: Настройки управления

View File

@ -530,7 +530,7 @@ storyRewards:
reward_painter: reward_painter:
title: Måleri title: Måleri
desc: >- desc: >-
<strong>Färgläggaren</strong> har blivit upplåst - Extrahera färg (precis som du gör med former) och kombinera dem med former för att färglägga dem!<br><br>PS: Om du är färgblind, jag jobbar redan på en lösning! 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: reward_mixer:
title: Färgblandning title: Färgblandning
@ -726,6 +726,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Färgblint läge title: Färgblint läge
description: Aktiverar olika verktyg som låter dig spela spelet om du är färbling. description: Aktiverar olika verktyg som låter dig spela spelet om du är färbling.
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.
keybindings: keybindings:
title: Tangentbindningar title: Tangentbindningar

View File

@ -531,7 +531,7 @@ storyRewards:
reward_painter: reward_painter:
title: Painting title: Painting
desc: >- 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, I'm working on a solution already! 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: reward_mixer:
title: Color Mixing title: Color Mixing
@ -727,6 +727,12 @@ settings:
enableColorBlindHelper: enableColorBlindHelper:
title: Color Blind Mode title: Color Blind Mode
description: Enables various tools which allow to play the game if you are color blind. description: Enables various tools which allow to play the game if you are color blind.
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.
keybindings: keybindings:
title: Keybindings title: Keybindings

View File

@ -319,10 +319,10 @@ ingame:
pasteLastBlueprint: 粘贴上一个蓝图 pasteLastBlueprint: 粘贴上一个蓝图
lockBeltDirection: 启用传送带规划 lockBeltDirection: 启用传送带规划
plannerSwitchSide: 规划器换边 plannerSwitchSide: 规划器换边
cutSelection: Cut cutSelection: 剪切
copySelection: Copy copySelection: 复制
clearSelection: Clear Selection clearSelection: 取消选择
pipette: Pipette pipette: 选取器
# Everything related to placing buildings (I.e. as soon as you selected a building # Everything related to placing buildings (I.e. as soon as you selected a building
# from the toolbar) # from the toolbar)
@ -377,14 +377,14 @@ ingame:
title: 统计信息 title: 统计信息
dataSources: dataSources:
stored: stored:
title: 储存 title: 已交付
description: 显示基地中每种图形储存的数量。 description: 显示基地中每种图形已交付且未使用的数量。
produced: produced:
title: 生产 title: 生产
description: 显示所有正在被生产的图形数量,包括中间产物。 description: 显示所有正在被生产的图形数量,包括中间产物。
delivered: delivered:
title: 送达 title: 送达
description: 显示图形送达基地的速度。 description: 显示图形送达基地并交付的速度。
noShapesProduced: 你还没有生产任何图形。 noShapesProduced: 你还没有生产任何图形。
# Displays the shapes per minute, e.g. '523 / m' # Displays the shapes per minute, e.g. '523 / m'
@ -416,7 +416,7 @@ ingame:
waypoints: waypoints:
waypoints: 地图标记 waypoints: 地图标记
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. description: 左键跳转到地图标记,右键删除地图标记。<br><br>按<keybinding>在当前地点创建地图标记,或者在选定位置上<strong>右键</strong>创建地图标记.
creationSuccessNotification: 成功创建地图标记。 creationSuccessNotification: 成功创建地图标记。
# Interactive tutorial # Interactive tutorial
@ -432,17 +432,17 @@ ingame:
提示:按住<strong>SHIFT</strong>键来放置多个开采机,用<strong>R</strong>键旋转它们。 提示:按住<strong>SHIFT</strong>键来放置多个开采机,用<strong>R</strong>键旋转它们。
colors: colors:
red: Red red: 红色
green: Green green: 绿色
blue: Blue blue: 蓝色
yellow: Yellow yellow: 黄色
purple: Purple purple: 紫色
cyan: Cyan cyan: 青色
white: White white: 白色
uncolored: No color uncolored: 无色
shapeViewer: shapeViewer:
title: Layers title: 层 # TODO: find better translation
empty: Empty empty:
# All shop upgrades # All shop upgrades
shopUpgrades: shopUpgrades:
@ -502,7 +502,7 @@ buildings:
name: &cutter 切割机 name: &cutter 切割机
description: 将图形从上到下切开并输出。 <strong>如果你只需要其中一半,记得把另一半销毁掉,否则切割机会停止工作!</strong> description: 将图形从上到下切开并输出。 <strong>如果你只需要其中一半,记得把另一半销毁掉,否则切割机会停止工作!</strong>
quad: quad:
name: 切割机(四 name: 切割机(四
description: 将输入的图形切成四块。 <strong>如果你只需要其中一块,记得把其他的销毁掉,否则切割机会停止工作!</strong> description: 将输入的图形切成四块。 <strong>如果你只需要其中一块,记得把其他的销毁掉,否则切割机会停止工作!</strong>
rotater: rotater:
@ -554,16 +554,16 @@ storyRewards:
# Those are the rewards gained from completing the store # Those are the rewards gained from completing the store
reward_cutter_and_trash: reward_cutter_and_trash:
title: 切割图形 title: 切割图形
desc: <strong>切割机</strong>已解锁不论切割机的方向,它都会把图形<strong>从上到下</strong>切成两半。<br><br>记得把不需要的部分处理掉,否则这个这个建筑会停止工作。为此我给你准备了<strong>垃圾桶</strong>,它会把所有放进去的物品销毁掉。 desc: 恭喜!你解锁了<strong>切割机</strong>。切割机会把图形<strong>从上到下</strong>切成两半。注意切割的方向和切割机的朝向无关。<br><br>记得把不需要的部分处理掉,否则这个这个建筑会停止工作。为此我给你准备了<strong>垃圾桶</strong>,它会把所有放进去的物品销毁掉。
reward_rotater: reward_rotater:
title: 顺时针旋转 title: 顺时针旋转
desc: <strong>旋转机</strong>已解锁。它会顺时针旋转输入的图形90度。 desc: 恭喜!你解锁了<strong>旋转机</strong>。它会顺时针旋转输入的图形90度。
reward_painter: reward_painter:
title: 上色 title: 上色
desc: >- desc: >-
<strong>上色机</strong>已解锁。和图形一样,从颜色矿脉中开采颜色,然后将在上色机中将颜色涂在图形上。<br><br>PS我们正在开发色盲模式 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: reward_mixer:
title: 混合颜色 title: 混合颜色
@ -571,56 +571,55 @@ storyRewards:
reward_stacker: reward_stacker:
title: 堆叠 title: 堆叠
desc: <strong>堆叠机</strong>已解锁。堆叠机会尝试把两个输入的图形<strong>拼贴</strong>在一起。如果有重叠的部分,右边的输入会被<strong>堆叠</strong>在左边的输入上方! desc: 恭喜!你解锁了<strong>堆叠机</strong>。堆叠机会尝试把两个输入的图形<strong>拼贴</strong>在一起。如果有重叠的部分,右边的输入会被<strong>堆叠</strong>在左边的输入上方!
reward_splitter: reward_splitter:
title: 分离与合并 title: 分离与合并
desc: <strong>平衡机</strong>已解锁。在大型工厂中,平衡机负责<strong>合并或分离</strong>多个传送带上的物品。<br><br> desc: 恭喜!你解锁了<strong>平衡机</strong>。在大型工厂中,平衡机负责<strong>合并或分离</strong>多个传送带上的物品。<br><br>
reward_tunnel: reward_tunnel:
title: 隧道 title: 隧道
desc: <strong>隧道</strong>已解锁。你现在可以从其他传送带或建筑底下运送物品了! desc: 恭喜!你解锁了<strong>隧道</strong>。你现在可以从其他传送带或建筑底下运送物品了!
reward_rotater_ccw: reward_rotater_ccw:
title: 逆时针旋转 title: 逆时针旋转
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>! desc: 恭喜!你解锁了<strong>旋转机</strong>的<strong>逆时针</strong>变体。这个变体可以逆时针旋转图形。选择旋转机然后按“T”键来选取这个变体。
reward_miner_chainable: reward_miner_chainable:
title: 链式开采机 title: 链式开采机
desc: <strong>链式开采机</strong>变体已解锁。它是开采机的一个变体。它可以将开采出来的资源<strong>传递</strong>给其他的开采机,使得资源提取更加高效! 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: reward_underground_belt_tier_2:
title: 二级隧道 title: 二级隧道
desc: <strong>二级隧道</strong>变体已解锁。这个隧道有<strong>更长的传输距离</strong>。你还可以混用不同的隧道变体! desc: 恭喜!你解锁了<strong>二级隧道</strong>。这是隧道的一个变体。二级隧道有<strong>更长的传输距离</strong>。你还可以混用不同的隧道变体!
reward_splitter_compact: reward_splitter_compact:
title: 小型合流机 title: 小型合流机
desc: >- desc: You have unlocked a compact variant of the <strong>balancer</strong> - It accepts two inputs and merges them into one!
<strong>小型合流机</strong>变体已解锁。它可以把两个输入合并到一个输出上。
reward_cutter_quad: reward_cutter_quad:
title: 切割机 title: 切割机
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! desc: 恭喜!你解锁了<strong>切割机</strong>的<strong>四向</strong>变体。它可以将输入的图形切成四块而不只是左右两块!
reward_painter_double: reward_painter_double:
title: 双倍上色机 title: 双倍上色机
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! desc: 恭喜!你解锁了<strong>上色机</strong>的<strong>双倍</strong>变体。它可以同时为两个图形上色,每次只消耗一份颜色!
reward_painter_quad: reward_painter_quad:
title: 四向上色机 title: 四向上色机
desc: <strong>上色机</strong>四向变体已解锁。它可以在一个图形的四个角上涂不同的颜色! desc: 恭喜!你解锁了<strong>上色机</strong>四向变体。它可以在一个图形的四个角上涂不同的颜色!
reward_storage: reward_storage:
title: 仓库 title: 仓库
desc: <strong>仓库</strong>变体已解锁。它可以暂时储存一些材料,有容量上限。 desc: You have unlocked a variant of the <strong>trash</strong> - It allows to store items up to a given capacity!
reward_freeplay: reward_freeplay:
title: 自由模式 title: 自由模式
desc: 恭喜你!你解锁了<strong>自由模式</strong>现在图形将会是随机生成的!(不用担心,我计划在独立版本中加入更多内容!) desc: 恭喜你!你解锁了<strong>自由模式</strong>现在图形将会是随机生成的!(不用担心,我计划在独立版本中加入更多内容!)
reward_blueprints: reward_blueprints:
title: 蓝图 title: 蓝图
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). desc: 你现在可以<strong>复制粘贴</strong>你的工厂的一部分了按住CTRL键并拖动鼠标来选择一块区域然后按C键复制。<br><br>粘贴并<strong>不是免费的</strong>,你需要使用<strong>蓝图图形</strong>来粘贴你的蓝图。蓝图图形是你刚刚交付的图形。
# Special reward, which is shown when there is no reward actually # Special reward, which is shown when there is no reward actually
no_reward: no_reward:
@ -740,31 +739,34 @@ settings:
启用晕映,将屏幕角落里的颜色变深,更容易阅读文本。 启用晕映,将屏幕角落里的颜色变深,更容易阅读文本。
autosaveInterval: autosaveInterval:
title: Autosave Interval title: 自动保存间隔
description: >- description: >-
Controls how often the game saves automatically. You can also disable it 在这里控制你的游戏多长时间保存一次,或者完全关闭这个功能。
entirely here.
intervals: intervals:
one_minute: 1 Minute one_minute: 1分钟
two_minutes: 2 Minutes two_minutes: 2分钟
five_minutes: 5 Minutes five_minutes: 5分钟
ten_minutes: 10 Minutes ten_minutes: 10分钟
twenty_minutes: 20 Minutes twenty_minutes: 20分钟
disabled: Disabled disabled: 关闭
compactBuildingInfo: compactBuildingInfo:
title: Compact Building Infos title: 精简建筑信息
description: >- description: >-
Shortens info boxes for buildings by only showing their ratios. Otherwise a 缩小建筑信息展示框。如果打开,放置建筑时建筑将不再显示建筑说明和图片,只显示建筑速度或其他数据。
description and image is shown.
disableCutDeleteWarnings: disableCutDeleteWarnings:
title: Disable Cut/Delete Warnings title: 关闭剪切/删除警告
description: >- description: >-
Disable the warning dialogs brought up when cutting/deleting more than 100 如果打开将不再在剪切或者删除100+建筑时显示警告信息。
entities.
enableColorBlindHelper: enableColorBlindHelper:
title: Color Blind Mode title: 色盲模式
description: Enables various tools which allow to play the game if you are color blind. description: 提供一些分辨颜色的工具。目前当鼠标移至颜色资源上方时,屏幕上方会显示颜色名称。
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.
keybindings: keybindings:
title: 按键设置 title: 按键设置
@ -840,7 +842,7 @@ keybindings:
lockBeltDirection: 启用传送带规划 lockBeltDirection: 启用传送带规划
switchDirectionLockSide: "规划器:换边" switchDirectionLockSide: "规划器:换边"
pipette: Pipette pipette: 选取器
about: about:
title: 关于游戏 title: 关于游戏

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
1.1.17 1.1.18