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
oid sha256:746c6cf3f0284798a78c08f77d7e9d0c28b02323081fda42b5fa876a7ade29a0
size 205925
oid sha256:40d458f800344d819ad4d3f38943f53f399258369ee5c20f6583d1b49847465f
size 188255

View File

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

View File

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

View File

@ -1,25 +1,78 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- 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">
<g transform="translate(-1)">
<path style="fill:#46B29D;" d="M328.61,98.163h0.088c1.971-0.012,3.923,0.379,5.738,1.148l71.683,29.484
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
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-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
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
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
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
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
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
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
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"/>
<path style="fill:#BDC3C7;" d="M283.478,97.103h35.31V220.69c0,9.751-7.904,17.655-17.655,17.655l0,0
c-9.751,0-17.655-7.904-17.655-17.655V97.103z"/>
<circle style="fill:#CC4B4C;" cx="301.133" cy="52.966" r="52.966"/>
<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
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
C292.305,57.841,288.353,61.793,283.478,61.793z"/>
<rect x="1.985" style="fill:#C8414B;" width="508.03" height="512"/>
<rect x="1.985" y="107.79" style="fill:#FFD250;" width="508.03" height="296.42"/>
<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-3.477,0-6.061,2.918-5.306,5.994L223.347,256.409z"/>
<rect x="213.681" y="238.89" style="fill:#F5F5F5;" width="19.322" height="74.42"/>
<rect x="208.861" y="230.14" style="fill:#FAB446;" width="28.984" height="8.756"/>
<g>
<rect x="189.531" y="256.41" style="fill:#C8414B;" width="48.3" height="8.756"/>
<polygon style="fill:#C8414B;" points="237.839,291.429 208.856,282.674 208.856,273.919 237.839,282.674 "/>
<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
c-3.477,0-6.061,2.918-5.306,5.994L78.435,256.409z"/>
</g>
<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
s48.305-20.006,48.305-30.643v-56.908c0-4.835-4.325-8.756-9.661-8.756H112.248L112.248,230.143z"/>
<g>
<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"/>
<path style="fill:#C8414B;" d="M150.891,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.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>

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 { PreloadState } from "./states/preload";
import { SettingsState } from "./states/settings";
import { ShapezGameAnalytics } from "./platform/browser/game_analytics";
const logger = createLogger("application");
@ -130,8 +131,7 @@ export class Application {
this.adProvider = new NoAdProvider(this);
this.sound = new SoundImplBrowser(this);
this.analytics = new GoogleAnalyticsImpl(this);
// this.gameAnalytics = new ShapezGameAnalytics(this);
this.gameAnalytics = new NoGameAnalytics(this);
this.gameAnalytics = new ShapezGameAnalytics(this);
}
/**

View File

@ -1,4 +1,14 @@
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",
date: "22.06.2020",

View File

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

View File

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

View File

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

View File

@ -46,7 +46,13 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
* The current rotation
* @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
@ -115,6 +121,39 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
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 {boolean}

View File

@ -7,6 +7,7 @@ import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { Math_min } from "../../core/builtins";
import { createLogger } from "../../core/logging";
import { Rectangle } from "../../core/rectangle";
const logger = createLogger("systems/ejector");
@ -14,23 +15,34 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
constructor(root) {
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.root.signals.entityAdded.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;
// 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() {
logger.log("Recomputing cache");
const cache = [];
// Try to find acceptors for every ejector
for (let i = 0; i < this.allEntities.length; ++i) {
const entity = this.allEntities[i];
const ejectorComp = entity.components.ItemEjector;
const staticComp = entity.components.StaticMapEntity;
// For every ejector slot, try to find an acceptor
for (let ejectorSlotIndex = 0; ejectorSlotIndex < ejectorComp.slots.length; ++ejectorSlotIndex) {
const ejectorSlot = ejectorComp.slots[ejectorSlotIndex];
// 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,
});
let entryCount = 0;
if (this.smallCacheAreas.length <= 4) {
// Only recompute caches of entities inside the rectangles.
for (let i = 0; i < this.smallCacheAreas.length; i++) {
entryCount += this.recomputeAreaCaches(this.smallCacheAreas[i]);
}
} else {
// Try to find acceptors for every ejector
for (let i = 0; i < this.allEntities.length; ++i) {
const entity = this.allEntities[i];
entryCount += this.recomputeSingleEntityCache(entity);
}
}
logger.log("Found", entryCount, "entries to update");
this.cache = cache;
logger.log("Found", cache.length, "entries to update");
this.smallCacheAreas = [];
}
/**
*
* @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() {
@ -109,35 +164,45 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
}
// Go over all cache entries
for (let i = 0; i < this.cache.length; ++i) {
const { sourceSlot, destSlot, targetEntity } = this.cache[i];
const item = sourceSlot.item;
if (!item) {
// No item available to be ejected
for (let i = 0; i < this.allEntities.length; ++i) {
const sourceEntity = this.allEntities[i];
const sourceEjectorComp = sourceEntity.components.ItemEjector;
if (!sourceEjectorComp.cachedConnectedSlots) {
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
sourceSlot.progress = Math_min(1, sourceSlot.progress + progressGrowth);
const item = sourceSlot.item;
// Check if we are still in the process of ejecting, can't proceed then
if (sourceSlot.progress < 1.0) {
continue;
}
if (!item) {
// No item available to be ejected
continue;
}
// Check if the target acceptor can actually accept this item
const targetAcceptorComp = targetEntity.components.ItemAcceptor;
if (!targetAcceptorComp.canAcceptItem(destSlot.index, item)) {
continue;
}
// Advance items on the slot
sourceSlot.progress = Math_min(1, sourceSlot.progress + progressGrowth);
// 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;
// Check if we are still in the process of ejecting, can't proceed then
if (sourceSlot.progress < 1.0) {
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
declare const G_IS_DEV: boolean;
declare const G_IS_PROD: boolean;
declare function assert(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: "",
},
"es-419": {
name: "Español (Latinoamérica)",
name: "Español",
data: require("./built-temp/base-es.json"),
code: "es",
region: "419",
region: "",
},
"pl": {
name: "Polski",
@ -80,12 +80,23 @@ export const LANGUAGES = {
code: "no",
region: "",
},
"zh-CN": {
name: "简体中文",
// simplified
name: "中文简体",
data: require("./built-temp/base-zh-CN.json"),
code: "zh",
region: "CN",
},
"zh-TW": {
// traditional
name: "中文繁體",
data: require("./built-temp/base-zh-TW.json"),
code: "zh",
region: "TW",
},
"sv": {
name: "Svenska",
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 { InGameState } from "../../states/ingame";
import { createLogger } from "../../core/logging";
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";
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
// users are tracked
const analyticsLocalFile = "analytics_token.3.bin";
const analyticsLocalFile = "shapez_token_123.bin";
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>}
*/
initialize() {
this.syncKey = null;
setInterval(() => this.sendTimePoints(), 120 * 1000);
setInterval(() => this.sendTimePoints(), 60 * 1000);
// Retrieve sync key from player
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
this.sendToApi("/v1/register", {
environment: G_APP_ENVIRONMENT,
environment: this.environment,
})
.then(res => {
// Try to read and parse the key from the api
@ -135,10 +152,12 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface {
playerKey: this.syncKey,
gameKey: savegameId,
ingameTime: root.time.now(),
environment: this.environment,
category,
value,
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
* @param {GameRoot} root
* @param {boolean=} metaOnly
* Returns true if the shape is interesting
* @param {string} key
*/
generateGameDump(root, metaOnly = false) {
let staticEntities = [];
isInterestingShape(key) {
if (key === blueprintShape) {
return true;
}
const entities = root.entityMgr.getAllWithComponent(StaticMapEntityComponent);
// Limit the entities
if (!metaOnly && entities.length < 500) {
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);
// Check if its a story goal
for (let i = 0; i < tutorialGoals.length; ++i) {
if (key === tutorialGoals[i].shape) {
return true;
}
}
return {
storedShapes: root.hubGoals.storedShapes,
gainedRewards: root.hubGoals.gainedRewards,
upgradeLevels: root.hubGoals.upgradeLevels,
staticEntities,
};
// Check if its required to unlock an upgrade
for (const upgradeKey in UPGRADES) {
const handle = UPGRADES[upgradeKey];
const tiers = handle.tiers;
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", "");
}
/**
*/
handleGameResumed() {
this.sendTimePoints();
}
/**
* Handles the given level completed
* @param {number} level

View File

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

View File

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

View File

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

View File

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

View File

@ -531,7 +531,7 @@ storyRewards:
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, 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:
title: Color Mixing
@ -728,6 +728,12 @@ settings:
enableColorBlindHelper:
title: Color Blind Mode
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:
title: Keybindings

View File

@ -512,7 +512,7 @@ storyRewards:
reward_painter:
title: Barvení
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:
title: Míchání barev
@ -708,6 +708,12 @@ settings:
enableColorBlindHelper:
title: Režim pro 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:
title: Klávesové zkratky

View File

@ -532,7 +532,7 @@ storyRewards:
reward_painter:
title: Färben
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:
title: Farben mischen
@ -728,6 +728,12 @@ settings:
enableColorBlindHelper:
title: Modus für Farbenblinde
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:
title: Tastenbelegung

View File

@ -531,7 +531,7 @@ storyRewards:
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, 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:
title: Color Mixing
@ -729,6 +729,12 @@ settings:
enableColorBlindHelper:
title: Color Blind Mode
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:
title: Keybindings

View File

@ -534,7 +534,7 @@ storyRewards:
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, 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:
title: Color Mixing
@ -721,6 +721,11 @@ settings:
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

View File

@ -528,7 +528,8 @@ storyRewards:
reward_painter:
title: Pintor
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:
title: Mezclador de Color
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:
title: Modo para Daltonicos
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:
title: Atajos de Teclado

View File

@ -533,7 +533,7 @@ storyRewards:
reward_painter:
title: Peintre
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:
title: Mélangeur de couleurs
@ -727,6 +727,12 @@ settings:
enableColorBlindHelper:
title: Mode 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:
title: Contrôles

View File

@ -531,7 +531,7 @@ storyRewards:
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, 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:
title: Color Mixing
@ -727,6 +727,12 @@ settings:
enableColorBlindHelper:
title: Color Blind Mode
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:
title: Keybindings

View File

@ -530,7 +530,7 @@ storyRewards:
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, 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:
title: Color Mixing
@ -726,6 +726,12 @@ settings:
enableColorBlindHelper:
title: Color Blind Mode
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:
title: Keybindings

View File

@ -531,7 +531,7 @@ storyRewards:
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, 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:
title: Color Mixing
@ -727,6 +727,12 @@ settings:
enableColorBlindHelper:
title: Color Blind Mode
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:
title: Keybindings

View File

@ -530,7 +530,7 @@ storyRewards:
reward_painter:
title: 着色
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:
title: 色の混合
@ -722,6 +722,12 @@ settings:
enableColorBlindHelper:
title: 色覚モード
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:
title: キー設定

View File

@ -531,7 +531,7 @@ storyRewards:
reward_painter:
title: 색칠기
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:
title: 혼합기
@ -728,6 +728,12 @@ settings:
enableColorBlindHelper:
title: Color Blind Mode
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:
title: 키바인딩

View File

@ -531,7 +531,7 @@ storyRewards:
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, 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:
title: Color Mixing
@ -726,6 +726,12 @@ settings:
enableColorBlindHelper:
title: Color Blind Mode
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:
title: Keybindings

View File

@ -529,7 +529,7 @@ storyRewards:
reward_painter:
title: Verven
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:
title: Kleuren mengen
@ -701,9 +701,9 @@ settings:
autosaveInterval:
title: Autosave Interval
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.
intervals:
one_minute: 1 Minuut
two_minutes: 2 Minuten
@ -715,7 +715,7 @@ settings:
title: Combacte gebouwinformatie
description: >-
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:
title: Schakel knip/delete waarschuwingen uit.
description: >-
@ -724,6 +724,12 @@ settings:
enableColorBlindHelper:
title: Kleurenblindmodus
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:
title: Sneltoetsen

View File

@ -529,7 +529,7 @@ storyRewards:
reward_painter:
title: Maling
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:
title: Fargemikser
@ -726,6 +726,12 @@ settings:
enableColorBlindHelper:
title: Fargeblind Modus
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:
title: Hurtigtaster

View File

@ -546,7 +546,7 @@ storyRewards:
reward_painter:
title: Malowanie
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:
title: Mieszanie
@ -752,6 +752,12 @@ settings:
enableColorBlindHelper:
title: Color Blind Mode
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:
title: Klawiszologia

View File

@ -532,7 +532,7 @@ storyRewards:
reward_painter:
title: Pintura
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:
title: Misturando cores
@ -727,6 +727,12 @@ settings:
enableColorBlindHelper:
title: Color Blind Mode
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:
title: Controles

View File

@ -287,10 +287,10 @@ ingame:
pasteLastBlueprint: Colar o último blueprint
lockBeltDirection: Ativa o planeamento de tapetes
plannerSwitchSide: Lado de rotação do planeamento
cutSelection: Cut
copySelection: Copy
clearSelection: Clear Selection
pipette: Pipette
cutSelection: Cortar
copySelection: Copiar
clearSelection: Cancelar
pipette: Pipeta
# Everything related to placing buildings (I.e. as soon as you selected a building
# 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.
colors:
red: Red
green: Green
blue: Blue
yellow: Yellow
purple: Purple
cyan: Cyan
white: White
uncolored: No color
red: Vermelho
green: Verde
blue: Azul
yellow: Amarelo
purple: Roxo
cyan: Azul-bebé
white: Branco
uncolored: Sem cor
shapeViewer:
title: Layers
empty: Empty
title: Camadas
empty: Vazio
# All shop upgrades
shopUpgrades:
@ -529,7 +529,7 @@ storyRewards:
reward_painter:
title: Pintura
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:
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.
movementSpeed:
title: Velociade de movimentação
title: Velocidade de movimentação
description: Define quão rápida é a movimentação usando o teclado.
speeds:
super_slow: Muito lenta
slow: Lenta
regular: Média
fast: Rápiada
super_fast: Muito rádida
fast: Rápida
super_fast: Muito rápida
extremely_fast: Extremamente rápida
enableTunnelSmartplace:
title: Túneis inteligentes
@ -700,31 +700,37 @@ settings:
mais fácil.
autosaveInterval:
title: Autosave Interval
title: Intervalo de gravação automática
description: >-
Controls how often the game saves automatically. You can also disable it
entirely here.
Define o quão frequentemente o jogo grava automaticamente. Também podes desativar
aqui.
intervals:
one_minute: 1 Minute
two_minutes: 2 Minutes
five_minutes: 5 Minutes
ten_minutes: 10 Minutes
twenty_minutes: 20 Minutes
disabled: Disabled
one_minute: 1 Minuto
two_minutes: 2 Minutos
five_minutes: 5 Minutos
ten_minutes: 10 Minutos
twenty_minutes: 20 Minutos
disabled: Desligado
compactBuildingInfo:
title: Compact Building Infos
title: Informações de construções compactas
description: >-
Shortens info boxes for buildings by only showing their ratios. Otherwise a
description and image is shown.
Encurta caixas de informação mostrando apenas os respetivos rácios. Caso contrário
é mostrada a descrição e a imagem.
disableCutDeleteWarnings:
title: Disable Cut/Delete Warnings
title: Desativar Avisos de Corte/Eliminação
description: >-
Disable the warning dialogs brought up when cutting/deleting more than 100
entities.
Desativa os avisos mostrados quando é feito o corte ou a eliminação de mais de 100
entidades.
enableColorBlindHelper:
title: Color Blind Mode
description: Enables various tools which allow to play the game if you are color blind.
title: Modo Daltónico
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:
title: Atalhos
@ -791,7 +797,7 @@ keybindings:
mapMoveFaster: Mover rapidamente
lockBeltDirection: Ativa o planeamento de tapetes
switchDirectionLockSide: "Planeador: Troca o lado"
pipette: Pipette
pipette: Pipeta
about:
title: Sobre o jogo
body: >-

View File

@ -530,7 +530,7 @@ storyRewards:
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, 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:
title: Color Mixing
@ -726,6 +726,12 @@ settings:
enableColorBlindHelper:
title: Color Blind Mode
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:
title: Keybindings

View File

@ -532,7 +532,7 @@ storyRewards:
reward_painter:
title: Покраска
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:
title: Смешивание Цветов
@ -727,6 +727,12 @@ settings:
enableColorBlindHelper:
title: Режим Дальтоника
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:
title: Настройки управления

View File

@ -530,7 +530,7 @@ storyRewards:
reward_painter:
title: Måleri
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:
title: Färgblandning
@ -726,6 +726,12 @@ settings:
enableColorBlindHelper:
title: Färgblint läge
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:
title: Tangentbindningar

View File

@ -531,7 +531,7 @@ storyRewards:
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, 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:
title: Color Mixing
@ -727,6 +727,12 @@ settings:
enableColorBlindHelper:
title: Color Blind Mode
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:
title: Keybindings

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
1.1.17
1.1.18