From 8a50fdb3927c54e526ecedb72ff96804be305455 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 16 Jun 2020 19:43:29 -0400 Subject: [PATCH 01/57] Remove belt cache array; use BeltComponent instead Removed the belt cache array. Follow-up belts are cached in the belt's BeltComponent instead. This change also removes the recursive follow-up search, which could cause a stack overflow for an extremely long belt chain. Saves one object allocation per belt per change, two very large array allocations per change, many function calls, and belts are only visited exactly once per change. --- src/js/game/components/belt.js | 5 ++++ src/js/game/systems/belt.js | 49 ++++++---------------------------- 2 files changed, 13 insertions(+), 41 deletions(-) diff --git a/src/js/game/components/belt.js b/src/js/game/components/belt.js index d98db49a..a9be5c99 100644 --- a/src/js/game/components/belt.js +++ b/src/js/game/components/belt.js @@ -5,6 +5,7 @@ import { BaseItem } from "../base_item"; import { Vector, enumDirection } from "../../core/vector"; import { Math_PI, Math_sin, Math_cos } from "../../core/builtins"; import { globalConfig } from "../../core/config"; +import { Entity } from "../entity"; export class BeltComponent extends Component { static getId() { @@ -12,6 +13,7 @@ export class BeltComponent extends Component { } static getSchema() { + // The followUpCache field is not serialized. return { direction: types.string, sortedItems: types.array(types.pair(types.float, types.obj(gItemRegistry))), @@ -34,6 +36,9 @@ export class BeltComponent extends Component { /** @type {Array<[number, BaseItem]>} */ this.sortedItems = []; + + /** @type {Entity} */ + this.followUpCache = null; } /** diff --git a/src/js/game/systems/belt.js b/src/js/game/systems/belt.js index 5fa5a265..494c9fa0 100644 --- a/src/js/game/systems/belt.js +++ b/src/js/game/systems/belt.js @@ -19,8 +19,6 @@ const SQRT_2 = Math_sqrt(2); const logger = createLogger("belt"); -/** @typedef {Array<{ entity: Entity, followUp: Entity }>} BeltCache */ - export class BeltSystem extends GameSystemWithFilter { constructor(root) { super(root, [BeltComponent]); @@ -66,9 +64,6 @@ export class BeltSystem extends GameSystemWithFilter { this.root.signals.entityDestroyed.add(this.updateSurroundingBeltPlacement, this); this.cacheNeedsUpdate = true; - - /** @type {BeltCache} */ - this.beltCache = []; } /** @@ -163,42 +158,14 @@ export class BeltSystem extends GameSystemWithFilter { return null; } - /** - * Adds a single entity to the cache - * @param {Entity} entity - * @param {BeltCache} cache - * @param {Set} visited - */ - computeSingleBeltCache(entity, cache, visited) { - // Check for double visit - if (visited.has(entity.uid)) { - return; - } - visited.add(entity.uid); - - const followUp = this.findFollowUpEntity(entity); - if (followUp) { - // Process followup first - this.computeSingleBeltCache(followUp, cache, visited); - } - - cache.push({ entity, followUp }); - } - computeBeltCache() { logger.log("Updating belt cache"); - let cache = []; let visited = new Set(); for (let i = 0; i < this.allEntities.length; ++i) { - this.computeSingleBeltCache(this.allEntities[i], cache, visited); + const entity = this.allEntities[i]; + entity.components.Belt.followUpCache = this.findFollowUpEntity(entity); } - assert( - cache.length === this.allEntities.length, - "Belt cache mismatch: Has " + cache.length + " entries but should have " + this.allEntities.length - ); - - this.beltCache = cache; } update() { @@ -217,8 +184,8 @@ export class BeltSystem extends GameSystemWithFilter { beltSpeed *= 100; } - for (let i = 0; i < this.beltCache.length; ++i) { - const { entity, followUp } = this.beltCache[i]; + for (let i = 0; i < this.allEntities.length; ++i) { + const entity = this.allEntities[i]; const beltComp = entity.components.Belt; const items = beltComp.sortedItems; @@ -244,8 +211,8 @@ export class BeltSystem extends GameSystemWithFilter { maxProgress = 1 - globalConfig.itemSpacingOnBelts; } else { // Otherwise our progress depends on the follow up - if (followUp) { - const spacingOnBelt = followUp.components.Belt.getDistanceToFirstItemCenter(); + if (beltComp.followUpCache) { + const spacingOnBelt = beltComp.followUpCache.components.Belt.getDistanceToFirstItemCenter(); maxProgress = Math.min(2, 1 - globalConfig.itemSpacingOnBelts + spacingOnBelt); // Useful check, but hurts performance @@ -270,8 +237,8 @@ export class BeltSystem extends GameSystemWithFilter { progressAndItem[0] = Math.min(maxProgress, progressAndItem[0] + speedMultiplier * beltSpeed); if (progressAndItem[0] >= 1.0) { - if (followUp) { - const followUpBelt = followUp.components.Belt; + if (beltComp.followUpCache) { + const followUpBelt = beltComp.followUpCache.components.Belt; if (followUpBelt.canAcceptItem()) { followUpBelt.takeItem(progressAndItem[1], progressAndItem[0] - 1.0); items.splice(itemIndex, 1); From 23417724257a7ee5d5e5d4e046da9722897a504a Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 16 Jun 2020 20:23:11 -0400 Subject: [PATCH 02/57] Optimize belt cache for common case Most of the time, we're adding/removing one building at a time. We don't need to recheck every belt, only the ones near the changed belt. --- src/js/game/systems/belt.js | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/js/game/systems/belt.js b/src/js/game/systems/belt.js index 494c9fa0..056692a8 100644 --- a/src/js/game/systems/belt.js +++ b/src/js/game/systems/belt.js @@ -13,6 +13,7 @@ import { MetaBeltBaseBuilding } from "../buildings/belt_base"; import { defaultBuildingVariant } from "../meta_building"; import { GameRoot } from "../root"; import { createLogger } from "../../core/logging"; +import { Rectangle } from "../../core/rectangle"; const BELT_ANIM_COUNT = 6; const SQRT_2 = Math_sqrt(2); @@ -64,6 +65,9 @@ export class BeltSystem extends GameSystemWithFilter { this.root.signals.entityDestroyed.add(this.updateSurroundingBeltPlacement, this); this.cacheNeedsUpdate = true; + /** @type {Rectangle} */ + this.singleUpdateArea = null; + this.isMultiUpdate = false; } /** @@ -114,6 +118,17 @@ export class BeltSystem extends GameSystemWithFilter { } } } + + // Optimize for the common case of adding or removing one belt. + if (this.cacheNeedsUpdate) { + if (this.isMultiUpdate || this.singleUpdateArea) { + // This isn't the common case. + // The singleUpdateArea will be cleared by the cache update. + this.isMultiUpdate = true; + } else { + this.singleUpdateArea = affectedArea.expandedInAllDirections(1); + } + } } draw(parameters) { @@ -161,11 +176,23 @@ export class BeltSystem extends GameSystemWithFilter { computeBeltCache() { logger.log("Updating belt cache"); - let visited = new Set(); - for (let i = 0; i < this.allEntities.length; ++i) { - const entity = this.allEntities[i]; - entity.components.Belt.followUpCache = this.findFollowUpEntity(entity); + if (this.singleUpdateArea && !this.isMultiUpdate) { + for (let x = this.singleUpdateArea.x; x < this.singleUpdateArea.right(); ++x) { + for (let y = this.singleUpdateArea.y; y < this.singleUpdateArea.bottom(); ++y) { + const tile = this.root.map.getTileContentXY(x, y); + if (tile && tile.components.Belt) { + tile.components.Belt.followUpCache = this.findFollowUpEntity(tile); + } + } + } + } else { + for (let i = 0; i < this.allEntities.length; ++i) { + const entity = this.allEntities[i]; + entity.components.Belt.followUpCache = this.findFollowUpEntity(entity); + } } + this.isMultiUpdate = false; + this.singleUpdateArea = null; } update() { From 36cf28029ecdd68a085a848184eb989f03b40e83 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 16 Jun 2020 21:11:26 -0400 Subject: [PATCH 03/57] Remove ejector cache; use slot caches instead This is a small refactoring that removes the main ejector cache. The cache is now tracked by slots and ejector components. It avoids a large array allocation and many small object allocations, but adds many small array allocations. It's net neutral for performance. --- src/js/game/components/item_ejector.js | 12 +++- src/js/game/systems/item_ejector.js | 91 ++++++++++++++------------ 2 files changed, 61 insertions(+), 42 deletions(-) diff --git a/src/js/game/components/item_ejector.js b/src/js/game/components/item_ejector.js index 5a40870b..e78faa36 100644 --- a/src/js/game/components/item_ejector.js +++ b/src/js/game/components/item_ejector.js @@ -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, }); } } diff --git a/src/js/game/systems/item_ejector.js b/src/js/game/systems/item_ejector.js index 2f327725..06e5d449 100644 --- a/src/js/game/systems/item_ejector.js +++ b/src/js/game/systems/item_ejector.js @@ -14,15 +14,6 @@ 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); @@ -39,18 +30,24 @@ export class ItemEjectorSystem extends GameSystemWithFilter { recomputeCache() { logger.log("Recomputing cache"); - const cache = []; - // Try to find acceptors for every ejector + let entryCount = 0; for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; 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 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); @@ -82,16 +79,18 @@ export class ItemEjectorSystem extends GameSystemWithFilter { } // Ok we found a connection - cache.push({ - targetEntity, - sourceSlot: ejectorSlot, - destSlot: matchingSlot, - }); + if (ejectorComp.cachedConnectedSlots) { + ejectorComp.cachedConnectedSlots.push(ejectorSlot); + } else { + ejectorComp.cachedConnectedSlots = [ejectorSlot]; + } + ejectorSlot.cachedTargetEntity = targetEntity; + ejectorSlot.cachedDestSlot = matchingSlot; + entryCount += 1; } } - this.cache = cache; - logger.log("Found", cache.length, "entries to update"); + logger.log("Found", entryCount, "entries to update"); } update() { @@ -109,35 +108,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; + } } } } From aef96cff6ebd21a19c1019c0ae8800fec2893dbb Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 16 Jun 2020 21:50:16 -0400 Subject: [PATCH 04/57] Optimize ejector cache for common case This commit optimizes the ejector cache for clicking and dragging belts, or adding/removing a building. It's a big performance improvement for large maps; on average, it only has to visit 60 slots per update, compared to 20,000+ slots. --- src/js/game/systems/item_ejector.js | 165 +++++++++++++++++++--------- 1 file changed, 111 insertions(+), 54 deletions(-) diff --git a/src/js/game/systems/item_ejector.js b/src/js/game/systems/item_ejector.js index 06e5d449..310767f7 100644 --- a/src/js/game/systems/item_ejector.js +++ b/src/js/game/systems/item_ejector.js @@ -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"); @@ -18,10 +19,30 @@ export class ItemEjectorSystem extends GameSystemWithFilter { 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); } /** @@ -30,67 +51,103 @@ export class ItemEjectorSystem extends GameSystemWithFilter { recomputeCache() { logger.log("Recomputing cache"); - // Try to find acceptors for every ejector let entryCount = 0; - for (let i = 0; i < this.allEntities.length; ++i) { - const entity = this.allEntities[i]; - const ejectorComp = entity.components.ItemEjector; - const staticComp = entity.components.StaticMapEntity; + 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); + } - // Clear the old cache. - ejectorComp.cachedConnectedSlots = null; + } + logger.log("Found", entryCount, "entries to update"); - // For every ejector slot, try to find an acceptor - for (let ejectorSlotIndex = 0; ejectorSlotIndex < ejectorComp.slots.length; ++ejectorSlotIndex) { - const ejectorSlot = ejectorComp.slots[ejectorSlotIndex]; + this.smallCacheAreas = []; + } - // 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; + /** + * + * @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); } - - 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; + } - logger.log("Found", entryCount, "entries to update"); + /** + * + * @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() { From da24c472d7aeb3942cf145d80e6871b570cf0f2f Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 16 Jun 2020 22:08:46 -0400 Subject: [PATCH 05/57] Fix click and drag Clicking and dragging can trigger up to 4 add/destroy signals, and it's a common case. --- src/js/game/systems/belt.js | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/js/game/systems/belt.js b/src/js/game/systems/belt.js index 056692a8..a4b6d85f 100644 --- a/src/js/game/systems/belt.js +++ b/src/js/game/systems/belt.js @@ -65,9 +65,8 @@ export class BeltSystem extends GameSystemWithFilter { this.root.signals.entityDestroyed.add(this.updateSurroundingBeltPlacement, this); this.cacheNeedsUpdate = true; - /** @type {Rectangle} */ - this.singleUpdateArea = null; - this.isMultiUpdate = false; + /** @type {Rectangle[]} */ + this.smallUpdateAreas = []; } /** @@ -119,15 +118,10 @@ export class BeltSystem extends GameSystemWithFilter { } } - // Optimize for the common case of adding or removing one belt. + // Optimize for the common case of adding or removing buildings one at a time. + // Clicking and dragging can fire up to 4 create/destroy signals. if (this.cacheNeedsUpdate) { - if (this.isMultiUpdate || this.singleUpdateArea) { - // This isn't the common case. - // The singleUpdateArea will be cleared by the cache update. - this.isMultiUpdate = true; - } else { - this.singleUpdateArea = affectedArea.expandedInAllDirections(1); - } + this.smallUpdateAreas.push(affectedArea.expandedInAllDirections(1)); } } @@ -176,12 +170,15 @@ export class BeltSystem extends GameSystemWithFilter { computeBeltCache() { logger.log("Updating belt cache"); - if (this.singleUpdateArea && !this.isMultiUpdate) { - for (let x = this.singleUpdateArea.x; x < this.singleUpdateArea.right(); ++x) { - for (let y = this.singleUpdateArea.y; y < this.singleUpdateArea.bottom(); ++y) { - const tile = this.root.map.getTileContentXY(x, y); - if (tile && tile.components.Belt) { - tile.components.Belt.followUpCache = this.findFollowUpEntity(tile); + if (this.smallUpdateAreas.length <= 4) { + for (let i = 0; i < this.smallUpdateAreas.length; ++i) { + const area = this.smallUpdateAreas[i]; + for (let x = area.x; x < area.right(); ++x) { + for (let y = area.y; y < area.bottom(); ++y) { + const tile = this.root.map.getTileContentXY(x, y); + if (tile && tile.components.Belt) { + tile.components.Belt.followUpCache = this.findFollowUpEntity(tile); + } } } } @@ -191,8 +188,7 @@ export class BeltSystem extends GameSystemWithFilter { entity.components.Belt.followUpCache = this.findFollowUpEntity(entity); } } - this.isMultiUpdate = false; - this.singleUpdateArea = null; + this.smallUpdateAreas = []; } update() { From eb182d6e94468e742a78671ea49789de4b531d8d Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 16 Jun 2020 22:48:29 -0400 Subject: [PATCH 06/57] Fix lint issues --- src/js/game/systems/item_ejector.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/js/game/systems/item_ejector.js b/src/js/game/systems/item_ejector.js index 310767f7..f5837ac1 100644 --- a/src/js/game/systems/item_ejector.js +++ b/src/js/game/systems/item_ejector.js @@ -27,8 +27,8 @@ export class ItemEjectorSystem extends GameSystemWithFilter { } /** - * - * @param {Entity} entity + * + * @param {Entity} entity */ invalidateCache(entity) { if (!entity.components.StaticMapEntity) { @@ -63,7 +63,6 @@ export class ItemEjectorSystem extends GameSystemWithFilter { const entity = this.allEntities[i]; entryCount += this.recomputeSingleEntityCache(entity); } - } logger.log("Found", entryCount, "entries to update"); @@ -71,8 +70,8 @@ export class ItemEjectorSystem extends GameSystemWithFilter { } /** - * - * @param {Rectangle} area + * + * @param {Rectangle} area */ recomputeAreaCaches(area) { let entryCount = 0; @@ -88,8 +87,8 @@ export class ItemEjectorSystem extends GameSystemWithFilter { } /** - * - * @param {Entity} entity + * + * @param {Entity} entity */ recomputeSingleEntityCache(entity) { const ejectorComp = entity.components.ItemEjector; From 23b17467eac35c45607a6b767698ea1bc2bde0ba Mon Sep 17 00:00:00 2001 From: Wessel <66781896+Ryoncai@users.noreply.github.com> Date: Mon, 22 Jun 2020 17:18:37 +0200 Subject: [PATCH 07/57] Update base-nl.yaml Translated the newest additions --- translations/base-nl.yaml | 65 +++++++++++++++------------------------ 1 file changed, 24 insertions(+), 41 deletions(-) diff --git a/translations/base-nl.yaml b/translations/base-nl.yaml index b3694576..66e3168a 100644 --- a/translations/base-nl.yaml +++ b/translations/base-nl.yaml @@ -156,7 +156,6 @@ mainMenu: continue: Verder newGame: Nieuw Spel madeBy: Gemaakt door - subreddit: Reddit dialogs: buttons: @@ -284,12 +283,12 @@ ingame: createMarker: Plaats markering delete: Vernietig pasteLastBlueprint: Plak de laatst gekopiëerde blauwdruk - lockBeltDirection: Enable belt planner - plannerSwitchSide: Flip planner side - cutSelection: Cut - copySelection: Copy - clearSelection: Clear Selection - pipette: Pipette + lockBeltDirection: Maak gebruik van de lopende band planner + plannerSwitchSide: Draai de richting van de planner + cutSelection: Knip + copySelection: Kopieer + clearSelection: Cancel selectie + pipette: Pipet # Everything related to placing buildings (I.e. as soon as you selected a building # from the toolbar) @@ -396,19 +395,6 @@ ingame: 1_3_expand: >- Dit is GEEN nietsdoen-spel! bouw meer ontginners en lopende banden om het doel sneller te behalen.

Tip: Houd SHIFT ingedrukt om meerdere ontginners te plaatsen en gebruik R om ze te draaien. - colors: - red: Red - green: Green - blue: Blue - yellow: Yellow - purple: Purple - cyan: Cyan - white: White - uncolored: No color - shapeViewer: - title: Layers - empty: Empty - # All shop upgrades shopUpgrades: belt: @@ -533,7 +519,7 @@ storyRewards: reward_mixer: title: Kleuren mengen - desc: The mixer has been unlocked - Combine two colors using additive blending with this building! + desc: De menger is ontgrendeld - gebruik dit gebouw om twee kleuren te mengen via 'additive blending'! reward_stacker: title: Stapelaar @@ -701,29 +687,26 @@ settings: autosaveInterval: title: Autosave Interval description: >- - Controls how often the game saves automatically. You can also disable it - entirely here. + Bepaalt hoe vaak het spel automatisch opslaat. Je kan het hier ook volledig + mee uitschakelen. + 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 Minuut + two_minutes: 2 Minuten + five_minutes: 5 Minuten + ten_minutes: 10 Minuten + twenty_minutes: 20 Minuten + disabled: Uitgeschakeld compactBuildingInfo: - title: Compact Building Infos + title: Combacte gebouwinformatie description: >- - Shortens info boxes for buildings by only showing their ratios. Otherwise a - description and image is shown. + Informatie weergeven bij gebouwen wordt beperkt tot alleen hun ratios. Anders + zie je een beschrijving en een afbeelding. disableCutDeleteWarnings: - title: Disable Cut/Delete Warnings + title: Schakel knip/delete waarschuwingen uit. description: >- - Disable the warning dialogs brought up when cutting/deleting more than 100 - entities. - - enableColorBlindHelper: - title: Color Blind Mode - description: Enables various tools which allow to play the game if you are color blind. + Schakelt de waarschuwing uit die wordt weergegeven wanneer je meer dan 100 dingen probeert te + knippen/deleten. keybindings: title: Sneltoetsen @@ -789,8 +772,8 @@ keybindings: exportScreenshot: Exporteer volledige basis als afbeelding mapMoveFaster: Beweeg sneller lockBeltDirection: Schakel lopende band-planner in - switchDirectionLockSide: "Planner: Wissel van kant" - pipette: Pipette + switchDirectionLockSide: "Planner: Wissel van richting" + pipette: Pipet about: title: Over dit spel From 6b87cd11421c6c0bc0ca47925ed8ffa5a6e18228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20Gross=C3=A9?= Date: Mon, 22 Jun 2020 17:25:12 +0200 Subject: [PATCH 08/57] Updated french translation --- translations/base-fr.yaml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/translations/base-fr.yaml b/translations/base-fr.yaml index fb2b25e1..716f3c78 100644 --- a/translations/base-fr.yaml +++ b/translations/base-fr.yaml @@ -399,17 +399,17 @@ ingame: Ceci n'est PAS un jeu incrémental et inactif ! Construisez plus d'extracteurs et de convoyeurs pour atteindre plus vite votre votre but.

Astuce: Gardez SHIFT enfoncé pour placer plusieurs extracteurs, et utilisez R pour les faire pivoter. colors: - red: Red - green: Green - blue: Blue - yellow: Yellow - purple: Purple + red: Rouge + green: Vert + blue: Bleu + yellow: Jaune + purple: Violet cyan: Cyan - white: White - uncolored: No color + white: Blanc + uncolored: Non coloré shapeViewer: - title: Layers - empty: Empty + title: Calques + empty: Vide # All shop upgrades shopUpgrades: @@ -725,8 +725,8 @@ settings: Désactive la boîte de dialogue qui s'affiche lorsque vous vous apprêtez à couper/effacer plus de 100 entités. enableColorBlindHelper: - title: Color Blind Mode - description: Enables various tools which allow to play the game if you are color blind. + title: Mode Daltonien + description: Active divers outils qui permettent de jouer à ce jeu si vous êtes daltonien. keybindings: title: Contrôles From ecaa2a83d7ef6423ff8ca7293cc3471b2ebe64e8 Mon Sep 17 00:00:00 2001 From: Wessel <66781896+Ryoncai@users.noreply.github.com> Date: Mon, 22 Jun 2020 17:31:15 +0200 Subject: [PATCH 09/57] Update base-nl.yaml Added some translations to text it said I had removed without having translated them. --- translations/base-nl.yaml | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/translations/base-nl.yaml b/translations/base-nl.yaml index 66e3168a..bca1d76f 100644 --- a/translations/base-nl.yaml +++ b/translations/base-nl.yaml @@ -156,6 +156,7 @@ mainMenu: continue: Verder newGame: Nieuw Spel madeBy: Gemaakt door + Subreddit: Reddit dialogs: buttons: @@ -395,6 +396,22 @@ ingame: 1_3_expand: >- Dit is GEEN nietsdoen-spel! bouw meer ontginners en lopende banden om het doel sneller te behalen.

Tip: Houd SHIFT ingedrukt om meerdere ontginners te plaatsen en gebruik R om ze te draaien. + Colors: + red: Rood + green: Groen + blue: Blauw + yellow: Geel + purple: Paars + cyan: Cyaan + white: Wit + uncolored: Geen kleur + ShapeViewer: + title: Layers + empty: Empty + + + + # All shop upgrades shopUpgrades: belt: @@ -700,13 +717,16 @@ settings: compactBuildingInfo: title: Combacte gebouwinformatie 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. disableCutDeleteWarnings: title: Schakel knip/delete waarschuwingen uit. description: >- Schakelt de waarschuwing uit die wordt weergegeven wanneer je meer dan 100 dingen probeert te knippen/deleten. + enableColorBlindHelper: + title: Kleurenblindmodus + description: Schakelt verschillende hulpmiddelen in zodat je het spel alsnog kunt spelen wanneer je kleurenblind bent. keybindings: title: Sneltoetsen From 6c877fbe3fad09edf762f2f44200d494b7ab34bf Mon Sep 17 00:00:00 2001 From: Wessel <66781896+Ryoncai@users.noreply.github.com> Date: Mon, 22 Jun 2020 17:31:43 +0200 Subject: [PATCH 10/57] Update base-nl.yaml Added some translations to text it said I had removed without having translated them. From 1be4a75776774692b940192c4869852de2de4eef Mon Sep 17 00:00:00 2001 From: Wessel <66781896+Ryoncai@users.noreply.github.com> Date: Mon, 22 Jun 2020 17:33:10 +0200 Subject: [PATCH 11/57] Update base-nl.yaml --- translations/base-nl.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/translations/base-nl.yaml b/translations/base-nl.yaml index bca1d76f..ce22282f 100644 --- a/translations/base-nl.yaml +++ b/translations/base-nl.yaml @@ -406,8 +406,8 @@ ingame: white: Wit uncolored: Geen kleur ShapeViewer: - title: Layers - empty: Empty + title: Lagen + empty: Leeg From 878ba9e61647d60462515378afb443fe3104721e Mon Sep 17 00:00:00 2001 From: Wessel <66781896+Ryoncai@users.noreply.github.com> Date: Mon, 22 Jun 2020 17:33:43 +0200 Subject: [PATCH 12/57] Update base-nl.yaml --- translations/base-nl.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/translations/base-nl.yaml b/translations/base-nl.yaml index ce22282f..d92558a8 100644 --- a/translations/base-nl.yaml +++ b/translations/base-nl.yaml @@ -409,9 +409,6 @@ ingame: title: Lagen empty: Leeg - - - # All shop upgrades shopUpgrades: belt: From c23e05904de58f4326f8ff84a34ef730b0b114f1 Mon Sep 17 00:00:00 2001 From: DerFeldspatz <57270769+DerFeldspatz@users.noreply.github.com> Date: Mon, 22 Jun 2020 18:33:50 +0200 Subject: [PATCH 13/57] Update base-de.yaml Minor typos, new features translated. Translated About Me (not word-for-word). --- translations/base-de.yaml | 52 +++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/translations/base-de.yaml b/translations/base-de.yaml index cdce7f8d..f360b856 100644 --- a/translations/base-de.yaml +++ b/translations/base-de.yaml @@ -396,17 +396,17 @@ ingame: Dies ist KEIN Idle-Game! Baue mehr Extrahierer und Förderbänder, um das Ziel schneller zu erreichen.

Tipp: Halte UMSCH, um mehrere Gebäude zu platzieren und nutze R um sie zu rotieren. colors: - red: Red - green: Green - blue: Blue - yellow: Yellow - purple: Purple - cyan: Cyan - white: White - uncolored: No color + red: Rot + green: Grün + blue: Blau + yellow: Gelb + purple: Violett + cyan: Blaugrün + white: Weiß + uncolored: farblos shapeViewer: - title: Layers - empty: Empty + title: Ebenen + empty: Leer # All shop upgrades shopUpgrades: @@ -726,8 +726,8 @@ settings: Deaktiviert die Warnung, die beim Löschen und Ausschneiden von mehr als 100 Feldern angezeigt wird. enableColorBlindHelper: - title: Color Blind Mode - description: Enables various tools which allow to play the game if you are color blind. + title: Modus für Farbenblinde + description: Aktiviert verschiedene Werkzeuge, die dir das Spielen trotz Farbenblindheit ermöglichen. keybindings: title: Tastenbelegung @@ -756,7 +756,7 @@ keybindings: mapZoomIn: Hineinzoomen mapZoomOut: Herauszoomen - createMarker: Markeirung erstellen + createMarker: Markierung erstellen menuOpenShop: Upgrades menuOpenStats: Statistiken @@ -776,7 +776,7 @@ keybindings: rotateWhilePlacing: Rotieren rotateInverseModifier: >- - Modifier: stattdessen gegen UZS rotieren + Modifikator: stattdessen gegen UZS rotieren cycleBuildingVariants: Variante wählen confirmMassDelete: Massenlöschung bestätigen cycleBuildings: Gebäude rotieren @@ -799,22 +799,22 @@ keybindings: about: title: Über dieses Spiel body: >- - This game is open source and developed by Tobias Springer (this is me).

+ Dieses Spiel hat einen offenen Quellcode (Open Source) und wurde von Tobias Springer (Das bin ich) entwickelt.

- If you want to contribute, check out shapez.io on github.

+ Wenn du zum Spiel beitragen möchtest, dann schaue dir shapez.io auf GitHub an.

- This game wouldn't have been possible without the great discord community - around my games - You should really join the discord server!

+ Das Spiel wurde erst durch die großartige Discord-Community + um meine Spiele möglich gemacht. Komm doch einfach mal auf dem Discord-Server vorbei!

- The soundtrack was made by Peppsen - He's awesome.

+ Der Soundtrack wurde von Peppsen komponiert! Klasse Typ.

- Finally, huge thanks to my best friend Niklas - Without our - factorio sessions this game would never have existed. + Abschließend möchte ich meinem Kumpel Niklas danken! Ohne unsere + etlichen gemeinsamen Stunden in Factorio wäre dieses Projekt nie zustande gekommen. changelog: title: Änderungen From c25775f82a789e2459220b495a1f9ca2112124cf Mon Sep 17 00:00:00 2001 From: DerFeldspatz <57270769+DerFeldspatz@users.noreply.github.com> Date: Mon, 22 Jun 2020 19:12:58 +0200 Subject: [PATCH 14/57] Update base-de.yaml --- translations/base-de.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/translations/base-de.yaml b/translations/base-de.yaml index f360b856..762469eb 100644 --- a/translations/base-de.yaml +++ b/translations/base-de.yaml @@ -401,9 +401,9 @@ ingame: blue: Blau yellow: Gelb purple: Violett - cyan: Blaugrün + cyan: Cyan white: Weiß - uncolored: farblos + uncolored: Farblos shapeViewer: title: Ebenen empty: Leer From 85f38c8a6d7d82fc04a31bdfcdd70c69808cb35f Mon Sep 17 00:00:00 2001 From: tobspr Date: Mon, 22 Jun 2020 19:58:51 +0200 Subject: [PATCH 15/57] Minor translation update --- translations/base-de.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/translations/base-de.yaml b/translations/base-de.yaml index 762469eb..08bc12e4 100644 --- a/translations/base-de.yaml +++ b/translations/base-de.yaml @@ -800,9 +800,9 @@ about: title: Über dieses Spiel body: >- Dieses Spiel hat einen offenen Quellcode (Open Source) und wurde von Tobias Springer (Das bin ich) entwickelt.

+ target="_blank">Tobias Springer (das bin ich!) entwickelt.

- Wenn du zum Spiel beitragen möchtest, dann schaue dir shapez.io auf GitHub an.

Das Spiel wurde erst durch die großartige Discord-Community From d541f451bfbe18d2da4d9dd69b970e46e2b603bf Mon Sep 17 00:00:00 2001 From: rostaklein Date: Mon, 22 Jun 2020 22:43:12 +0200 Subject: [PATCH 16/57] Filled in missing Czech translations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep up doing this great job man! 😊 I filled in some of the missing 🇨🇿 translations. Hope everything is okay. --- translations/base-cz.yaml | 90 +++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 46 deletions(-) diff --git a/translations/base-cz.yaml b/translations/base-cz.yaml index a4e8c3a0..a79d5a66 100644 --- a/translations/base-cz.yaml +++ b/translations/base-cz.yaml @@ -134,9 +134,9 @@ mainMenu: showInfo: Zobrazit contestOver: Tato soutěž skončila - Připojte se na Discord a získejte informace o nových soutěžích! - continue: Continue - newGame: New Game - madeBy: Made by + continue: Pokračovat + newGame: Nová hra + madeBy: Vytvořil subreddit: Reddit dialogs: @@ -267,12 +267,12 @@ ingame: createMarker: Vytvořit značku delete: Zničit pasteLastBlueprint: Vložit poslední plán - lockBeltDirection: Enable belt planner - plannerSwitchSide: Flip planner side - cutSelection: Cut - copySelection: Copy - clearSelection: Clear Selection - pipette: Pipette + lockBeltDirection: Zamknout směr pásu + plannerSwitchSide: Otočit strany plánovače + cutSelection: Vyjmout + copySelection: Kopířovat + clearSelection: Zrušit výběr + pipette: Kapátko # Everything related to placing buildings (I.e. as soon as you selected a building # from the toolbar) @@ -380,17 +380,17 @@ ingame: Toto NENÍ hra o čekání! Sestavte další extraktory a pásy, abyste dosáhli cíle rychleji.

Tip: Chcete-li umístit více extraktorů, podržte SHIFT. Pomocí R je můžete otočit. colors: - red: Red - green: Green - blue: Blue - yellow: Yellow - purple: Purple - cyan: Cyan - white: White - uncolored: No color + red: Červená + green: Zelená + blue: Modrá + yellow: Žlutá + purple: Fialová + cyan: Tyrkysová + white: Bílá + uncolored: Bez barvy shapeViewer: - title: Layers - empty: Empty + title: Vrstvy + empty: Prázdné # All shop upgrades shopUpgrades: @@ -596,7 +596,7 @@ settings: labels: uiScale: - title: Škála UI + title: Škálování UI description: >- Změní velikost uživatelského rozhraní. Rozhraní se bude stále přizpůsobovoat rozlišení vaší obrazovky, toto nastavení pouze mění jeho škálu. scales: @@ -672,44 +672,42 @@ settings: super_fast: Hodně Rychlá extremely_fast: Extrémně Rychlá enableTunnelSmartplace: - title: Smart Tunnels + title: Chytré tunely description: >- - When enabled, placing tunnels will automatically remove unnecessary belts. - This also enables to drag tunnels and excess tunnels will get removed. + Pokládání tunelů po zapnutí bude samo odstraňovat nepotřebné pásy. + Umožňuje také potahování tunelů a nadbytečné tunely budou odstraněny. vignette: - title: Vignette + title: Viněta description: >- - Enables the vignette which darkens the screen corners and makes text easier - to read. + Zapne vinětu, která ztmaví rohy obrazovky, což umožňuje lepší čtení textu. autosaveInterval: - title: Autosave Interval + title: Interval automatického ukládání description: >- - Controls how often the game saves automatically. You can also disable it - entirely here. + Určuje jak často se hra automaticky ukládá. Lze ji zde také úplně zakázat. 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 minuta + two_minutes: 2 minuty + five_minutes: 5 minut + ten_minutes: 10 minut + twenty_minutes: 20 minut + disabled: Zrušeno compactBuildingInfo: - title: Compact Building Infos + title: Kompaktní informace o stavbách description: >- - Shortens info boxes for buildings by only showing their ratios. Otherwise a - description and image is shown. + Zkrátí informační políčka pro budovy tím, že pouze ukáže jejich koeficient. + V opačném případě zobrazí popis a obrázek. disableCutDeleteWarnings: - title: Disable Cut/Delete Warnings + title: Zakázat upozornění o vyjmutí nebo odstranění description: >- - Disable the warning dialogs brought up when cutting/deleting more than 100 - entities. + Deaktivujte varovná dialogová okna vyvolaná při vymutí/mazání více než 100 + entit. enableColorBlindHelper: - title: Color Blind Mode - description: Enables various tools which allow to play the game if you are color blind. + title: Režim pro barvoslepé + description: Zapné různé nástroje, které vám umožní hrát hru i pokud jste barvoslepí. keybindings: title: Klávesové zkratky @@ -774,9 +772,9 @@ keybindings: pasteLastBlueprint: Vložit poslední plán massSelectCut: Vyjmout oblast exportScreenshot: Exportovat celou základnu jako obrázek - lockBeltDirection: Enable belt planner - switchDirectionLockSide: "Planner: Switch side" - pipette: Pipette + lockBeltDirection: Zamknout směr pásu + switchDirectionLockSide: Otočit strany zámku plánovače + pipette: Kapátko about: title: O hře From bfc123a75dc84cc5e3ca95715a89723e51e1669f Mon Sep 17 00:00:00 2001 From: Wessel <66781896+Ryoncai@users.noreply.github.com> Date: Mon, 22 Jun 2020 22:47:35 +0200 Subject: [PATCH 17/57] Update base-nl.yaml Apologies for the mistake, should be good now. --- translations/base-nl.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/translations/base-nl.yaml b/translations/base-nl.yaml index d92558a8..d8917721 100644 --- a/translations/base-nl.yaml +++ b/translations/base-nl.yaml @@ -156,7 +156,7 @@ mainMenu: continue: Verder newGame: Nieuw Spel madeBy: Gemaakt door - Subreddit: Reddit + subreddit: Reddit dialogs: buttons: @@ -396,7 +396,7 @@ ingame: 1_3_expand: >- Dit is GEEN nietsdoen-spel! bouw meer ontginners en lopende banden om het doel sneller te behalen.

Tip: Houd SHIFT ingedrukt om meerdere ontginners te plaatsen en gebruik R om ze te draaien. - Colors: + colors: red: Rood green: Groen blue: Blauw @@ -405,7 +405,7 @@ ingame: cyan: Cyaan white: Wit uncolored: Geen kleur - ShapeViewer: + shapeViewer: title: Lagen empty: Leeg From 97b33ddcd092b37ef5620c5fa4f6da0c7d336b2f Mon Sep 17 00:00:00 2001 From: otougas <49008219+otougas@users.noreply.github.com> Date: Mon, 22 Jun 2020 20:31:42 -0400 Subject: [PATCH 18/57] ixed typo in norwegian translation --- translations/base-no.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/base-no.yaml b/translations/base-no.yaml index 687efc9c..f730a2bd 100644 --- a/translations/base-no.yaml +++ b/translations/base-no.yaml @@ -586,7 +586,7 @@ storyRewards: reward_blueprints: title: Blåkopier - desc: Du kan nå kopiere og lime inn deler av fabrikken din! Velg et område (Hold inne CTRL, så dra med musa), trykk så 'C' for å kopiere det.

Lime det inn er ikke graits, du må produsere blåkopi objekter for å få råd til det! (Det du nettop leverte). + desc: Du kan nå kopiere og lime inn deler av fabrikken din! Velg et område (Hold inne CTRL, så dra med musa), trykk så 'C' for å kopiere det.

Lime det inn er ikke gratis, du må produsere blåkopi objekter for å få råd til det! (Det du nettop leverte). # Special reward, which is shown when there is no reward actually no_reward: From a53a69096e089b60ad36295371c94fdc00163af6 Mon Sep 17 00:00:00 2001 From: K3rcus <38012836+K3rcus@users.noreply.github.com> Date: Tue, 23 Jun 2020 03:33:48 +0200 Subject: [PATCH 19/57] Update Spanish translation Translation of untranslated strings, and correction of some errors --- translations/base-es.yaml | 74 ++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/translations/base-es.yaml b/translations/base-es.yaml index 40de327b..f7381e13 100644 --- a/translations/base-es.yaml +++ b/translations/base-es.yaml @@ -57,7 +57,7 @@ steamPage: [*] Modo historia en el que los edificios cuesten figuras [*] Más niveles y edificios (exclusivos del juego completo) [*] Mapas diferentes y tal vez obstáculos en el mapa - [*] Configuración en la cración del mapa (Editar el número y tamaño de los recursos, la semilla, y más) + [*] Configuración en la creación del mapa (Editar el número y tamaño de los recursos, la semilla, y más) [*] Más tipos de formas [*] Mejoras de rendimiento (Aunque el juego ya funciona muy bien!) [*] Modo para daltónicos @@ -283,12 +283,12 @@ ingame: placeBuilding: Colocar edificio createMarker: Crear marca delete: Destruir - pasteLastBlueprint: Paste last blueprint - lockBeltDirection: Enable belt planner - plannerSwitchSide: Flip planner side - cutSelection: Cut - copySelection: Copy - clearSelection: Clear Selection + pasteLastBlueprint: Pegar último plano + lockBeltDirection: Activar planificador de cintas transportadoras + plannerSwitchSide: Invertir giro del planificador + cutSelection: Cortar + copySelection: Copiar + clearSelection: Limpiar Selección pipette: Pipette # Everything related to placing buildings (I.e. as soon as you selected a building @@ -396,17 +396,17 @@ ingame: ¡Esto NO es un "juego de esperar"! Construye más extractores y cintas transportadoras para completar el objetivo más rápido.

Pista: Mantén pulsado SHIFT para colocar varios extractores y usa R para rotarlos. colors: - red: Red - green: Green - blue: Blue - yellow: Yellow - purple: Purple - cyan: Cyan - white: White - uncolored: No color + red: Rojo + green: Verde + blue: Azul + yellow: Amarillo + purple: Morado + cyan: Cian + white: Blanco + uncolored: Sin color shapeViewer: - title: Layers - empty: Empty + title: Capas + empty: Vacio # All shop upgrades shopUpgrades: @@ -454,7 +454,7 @@ buildings: description: Multifuncional - Distribuye equitativamente todas las entradas a todas las salidas. compact: - name: fusionador (compacto) + name: Fusionador (compacto) description: Junta dos cintas transportadoras en una. compact-inverse: @@ -620,7 +620,7 @@ settings: huge: Enorme scrollWheelSensitivity: - title: Sensitividad del zoom + title: Sensibilidad del zoom description: >- Cambia como de sensible es el zoom (Tanto la ruedo del ratón como el trackpad) sensitivity: @@ -689,37 +689,33 @@ settings: Si está activado, colocar túneles automáticamente removerá las cintas transportadoras innecesarias. Esto también permite arrastrar con el ratón y los túneles excedentes serán removidos. vignette: - title: Vignette + title: Viñeta description: >- - Enables the vignette which darkens the screen corners and makes text easier - to read. + Activa el efecto viñeta que oscurece loas esquinas de la pantalla y hace el texto mas fácil de leer. autosaveInterval: - title: Autosave Interval + title: Intervalo de Autoguardado description: >- - Controls how often the game saves automatically. You can also disable it - entirely here. + Controla cada cuanto tiempo se guarda el juego automaticamente. Aquí tambien puedes deshabilitarlo por completo. 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: Deshabilitado compactBuildingInfo: - title: Compact Building Infos + title: Información Compacta de Edificios description: >- - Shortens info boxes for buildings by only showing their ratios. Otherwise a - description and image is shown. + Acorta la caja de información mostrando solo sus ratios. Si no, se mostrara una descripción y una imagen. disableCutDeleteWarnings: - title: Disable Cut/Delete Warnings + title: Deshabilitar las advertencias de Cortar/Eliminar description: >- - Disable the warning dialogs brought up when cutting/deleting more than 100 - entities. + Deshabilita los dialogos de advertencia que se muestran cuando se cortan/eliminan mas de 100 elementos. enableColorBlindHelper: - title: Color Blind Mode - description: Enables various tools which allow to play the game if you are color blind. + title: Modo para Daltonicos + description: Activa varias herramientas que permiten jugar si eres daltonico. keybindings: title: Atajos de Teclado From b62a1e2d400d5234ecbc65d18033e77d68787e2a Mon Sep 17 00:00:00 2001 From: kebhr <42484226+kebhr@users.noreply.github.com> Date: Tue, 23 Jun 2020 15:59:03 +0900 Subject: [PATCH 20/57] Update Japanese translation --- translations/base-ja.yaml | 61 +++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/translations/base-ja.yaml b/translations/base-ja.yaml index f60eabec..c4cb3536 100644 --- a/translations/base-ja.yaml +++ b/translations/base-ja.yaml @@ -287,10 +287,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) @@ -398,17 +398,17 @@ ingame: このゲームは放置系のゲームではありません! もっと早く要件を満たせるように、追加の抽出機とベルトを設置しましょう。

Tip: SHIFT キーを押し続けると抽出機を連続配置できます。Rキーで設置方向を回転できます。 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: レイヤー + empty: 空 # All shop upgrades shopUpgrades: @@ -700,31 +700,28 @@ 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: 色覚異常を持っていてもゲームがプレイできるようにするための各種ツールを有効化します。 keybindings: title: キー設定 @@ -791,7 +788,7 @@ keybindings: mapMoveFaster: より速く移動 lockBeltDirection: ベルトプランナーを有効化 switchDirectionLockSide: "プランナー: 通る側を切り替え" - pipette: Pipette + pipette: ピペット about: title: このゲームについて From c7f8b50d1358127b777840721177bb64f9ade9cb Mon Sep 17 00:00:00 2001 From: Magnus Grimstvedt Saltnes Date: Thu, 18 Jun 2020 22:18:32 +0200 Subject: [PATCH 21/57] Adds tracking for rotation per building type. Adds a setting to go back to one global base rotation. --- src/js/game/hud/parts/building_placer.js | 16 +++---- .../game/hud/parts/building_placer_logic.js | 48 +++++++++++++++---- src/js/profile/application_settings.js | 11 ++++- 3 files changed, 56 insertions(+), 19 deletions(-) diff --git a/src/js/game/hud/parts/building_placer.js b/src/js/game/hud/parts/building_placer.js index 5faec6ab..e3a75400 100644 --- a/src/js/game/hud/parts/building_placer.js +++ b/src/js/game/hud/parts/building_placer.js @@ -82,9 +82,9 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic { this.buildingInfoElements.tutorialImage.setAttribute( "data-icon", "building_tutorials/" + - metaBuilding.getId() + - (variant === defaultBuildingVariant ? "" : "-" + variant) + - ".png" + metaBuilding.getId() + + (variant === defaultBuildingVariant ? "" : "-" + variant) + + ".png" ); removeAllChildren(this.buildingInfoElements.additionalInfo); @@ -122,10 +122,10 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic { T.ingame.buildingPlacement.cycleBuildingVariants.replace( "", "" + - this.root.keyMapper - .getBinding(KEYMAPPINGS.placement.cycleBuildingVariants) - .getKeyCodeString() + - "" + this.root.keyMapper + .getBinding(KEYMAPPINGS.placement.cycleBuildingVariants) + .getKeyCodeString() + + "" ) ); @@ -201,7 +201,7 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic { } = metaBuilding.computeOptimalDirectionAndRotationVariantAtTile( this.root, mouseTile, - this.currentBaseRotation, + this.getBaseRotation(), this.currentVariant.get() ); diff --git a/src/js/game/hud/parts/building_placer_logic.js b/src/js/game/hud/parts/building_placer_logic.js index 6aee65b6..a58d2b64 100644 --- a/src/js/game/hud/parts/building_placer_logic.js +++ b/src/js/game/hud/parts/building_placer_logic.js @@ -1,3 +1,4 @@ + import { Math_abs, Math_degrees, Math_round } from "../../../core/builtins"; import { globalConfig } from "../../../core/config"; import { gMetaBuildingRegistry } from "../../../core/global_registries"; @@ -45,7 +46,34 @@ 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.} + */ + this.preferredRotations = {}; + + this.getBaseRotation = function () { + const rotationByBuilding = this.root.app.settings.getAllSettings().rotationByBuilding; + if (!rotationByBuilding) { + return this.currentBaseRotationGeneral; + } + const id = this.currentMetaBuilding.get().getId(); + return this.preferredRotations[id] || this.currentBaseRotationGeneral; + + } + + this.setBaseRotation = function (rotation) { + const rotationByBuilding = this.root.app.settings.getAllSettings().rotationByBuilding; + if (!rotationByBuilding) { + this.currentBaseRotationGeneral = rotation; + } else { + const id = this.currentMetaBuilding.get().getId(); + this.preferredRotations[id] = rotation; + } + } + /** * Whether we are currently dragging @@ -200,12 +228,12 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { const selectedBuilding = this.currentMetaBuilding.get(); if (selectedBuilding) { if (this.root.keyMapper.getBinding(KEYMAPPINGS.placement.rotateInverseModifier).pressed) { - this.currentBaseRotation = (this.currentBaseRotation + 270) % 360; + this.setBaseRotation((this.getBaseRotation() + 270) % 360); } else { - this.currentBaseRotation = (this.currentBaseRotation + 90) % 360; + this.setBaseRotation((this.getBaseRotation() + 90) % 360); } const staticComp = this.fakeEntity.components.StaticMapEntity; - staticComp.rotation = this.currentBaseRotation; + staticComp.rotation = this.getBaseRotation(); } } /** @@ -377,7 +405,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { const { rotation, rotationVariant } = metaBuilding.computeOptimalDirectionAndRotationVariantAtTile( this.root, tile, - this.currentBaseRotation, + this.getBaseRotation(), this.currentVariant.get() ); @@ -385,7 +413,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { origin: tile, rotation, rotationVariant, - originalRotation: this.currentBaseRotation, + originalRotation: this.getBaseRotation(), building: this.currentMetaBuilding.get(), variant: this.currentVariant.get(), }); @@ -401,7 +429,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { KEYMAPPINGS.placementModifiers.placementDisableAutoOrientation ).pressed ) { - this.currentBaseRotation = (180 + this.currentBaseRotation) % 360; + this.setBaseRotation((180 + this.getBaseRotation()) % 360); } // Check if we should stop placement @@ -451,7 +479,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { for (let i = 0; i < path.length; ++i) { const { rotation, tile } = path[i]; - this.currentBaseRotation = rotation; + this.setBaseRotation(rotation); this.tryPlaceCurrentBuildingAt(tile); } }); @@ -634,11 +662,11 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { ) { const delta = newPos.sub(oldPos); const angleDeg = Math_degrees(delta.angle()); - this.currentBaseRotation = (Math.round(angleDeg / 90) * 90 + 360) % 360; + this.setBaseRotation((Math.round(angleDeg / 90) * 90 + 360) % 360); // Holding alt inverts the placement if (this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeInverse).pressed) { - this.currentBaseRotation = (180 + this.currentBaseRotation) % 360; + this.setBaseRotation((180 + this.getBaseRotation()) % 360); } } diff --git a/src/js/profile/application_settings.js b/src/js/profile/application_settings.js index 16ec4cbd..0e03e902 100644 --- a/src/js/profile/application_settings.js +++ b/src/js/profile/application_settings.js @@ -248,9 +248,10 @@ export const allApplicationSettings = [ new BoolSetting("alwaysMultiplace", categoryGame, (app, value) => {}), new BoolSetting("enableTunnelSmartplace", categoryGame, (app, value) => {}), - new BoolSetting("vignette", categoryGame, (app, value) => {}), + new BoolSetting("vignette", categoryGame, (app, value) => {}),<<<<<<< HEAD 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,8 @@ class SettingsStorage { this.vignette = true; this.compactBuildingInfo = false; this.disableCutDeleteWarnings = false; + this.rotationByBuilding = true; + this.enableColorBlindHelper = false; @@ -527,6 +530,7 @@ export class ApplicationSettings extends ReadWriteProxy { } if (data.version < 13) { +<<<<<<< HEAD data.settings.compactBuildingInfo = false; data.version = 13; } @@ -550,6 +554,11 @@ export class ApplicationSettings extends ReadWriteProxy { if (data.version < 17) { data.settings.enableColorBlindHelper = false; data.version = 17; +======= + data.settings.rotationByBuilding = true; + data.version = 13; + +>>>>>>> 655c356... Adds tracking for rotation per building type. } return ExplainedResult.good(); From efdaf74659e4c74bae5d778165abb23b28b0a0fa Mon Sep 17 00:00:00 2001 From: Magnus Grimstvedt Saltnes Date: Thu, 18 Jun 2020 22:30:17 +0200 Subject: [PATCH 22/57] Adds English strings for rotationByBuilding. --- translations/base-en.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/translations/base-en.yaml b/translations/base-en.yaml index 2ad5ef07..458086ac 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -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 From 9a00931c3fb3d602e4c01e7ade63039b5628591e Mon Sep 17 00:00:00 2001 From: Magnus Grimstvedt Saltnes Date: Thu, 18 Jun 2020 22:48:36 +0200 Subject: [PATCH 23/57] Implements some linter recommendations for CI check. --- src/js/game/hud/parts/building_placer_logic.js | 7 ++----- src/js/profile/application_settings.js | 8 +++----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/js/game/hud/parts/building_placer_logic.js b/src/js/game/hud/parts/building_placer_logic.js index a58d2b64..5a462f47 100644 --- a/src/js/game/hud/parts/building_placer_logic.js +++ b/src/js/game/hud/parts/building_placer_logic.js @@ -1,4 +1,3 @@ - import { Math_abs, Math_degrees, Math_round } from "../../../core/builtins"; import { globalConfig } from "../../../core/config"; import { gMetaBuildingRegistry } from "../../../core/global_registries"; @@ -61,8 +60,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { } const id = this.currentMetaBuilding.get().getId(); return this.preferredRotations[id] || this.currentBaseRotationGeneral; - - } + }; this.setBaseRotation = function (rotation) { const rotationByBuilding = this.root.app.settings.getAllSettings().rotationByBuilding; @@ -72,8 +70,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { const id = this.currentMetaBuilding.get().getId(); this.preferredRotations[id] = rotation; } - } - + }; /** * Whether we are currently dragging diff --git a/src/js/profile/application_settings.js b/src/js/profile/application_settings.js index 0e03e902..92edf124 100644 --- a/src/js/profile/application_settings.js +++ b/src/js/profile/application_settings.js @@ -530,7 +530,6 @@ export class ApplicationSettings extends ReadWriteProxy { } if (data.version < 13) { -<<<<<<< HEAD data.settings.compactBuildingInfo = false; data.version = 13; } @@ -554,11 +553,10 @@ export class ApplicationSettings extends ReadWriteProxy { if (data.version < 17) { data.settings.enableColorBlindHelper = false; data.version = 17; -======= + } + if(data.version < 18) { data.settings.rotationByBuilding = true; - data.version = 13; - ->>>>>>> 655c356... Adds tracking for rotation per building type. + data.version = 18; } return ExplainedResult.good(); From e18a888210ecc72132d7dfee91ddde142b98b1d7 Mon Sep 17 00:00:00 2001 From: Magnus Grimstvedt Saltnes Date: Thu, 18 Jun 2020 22:55:03 +0200 Subject: [PATCH 24/57] Attempts to fix some whitespace differences. --- src/js/game/hud/parts/building_placer.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/js/game/hud/parts/building_placer.js b/src/js/game/hud/parts/building_placer.js index e3a75400..6ccf00ad 100644 --- a/src/js/game/hud/parts/building_placer.js +++ b/src/js/game/hud/parts/building_placer.js @@ -82,9 +82,9 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic { this.buildingInfoElements.tutorialImage.setAttribute( "data-icon", "building_tutorials/" + - metaBuilding.getId() + - (variant === defaultBuildingVariant ? "" : "-" + variant) + - ".png" + metaBuilding.getId() + + (variant === defaultBuildingVariant ? "" : "-" + variant) + + ".png" ); removeAllChildren(this.buildingInfoElements.additionalInfo); @@ -122,10 +122,10 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic { T.ingame.buildingPlacement.cycleBuildingVariants.replace( "", "" + - this.root.keyMapper - .getBinding(KEYMAPPINGS.placement.cycleBuildingVariants) - .getKeyCodeString() + - "" + this.root.keyMapper + .getBinding(KEYMAPPINGS.placement.cycleBuildingVariants) + .getKeyCodeString() + + "" ) ); From 553ebb5ef6ae7ab721dac2af6c3170d981b1f80e Mon Sep 17 00:00:00 2001 From: Magnus Grimstvedt Saltnes Date: Tue, 23 Jun 2020 12:03:32 +0200 Subject: [PATCH 25/57] Switches to using ES6 get/set for currentBaseRotation. --- src/js/game/hud/parts/building_placer.js | 2 +- .../game/hud/parts/building_placer_logic.js | 69 +++++++++++-------- src/js/profile/application_settings.js | 5 +- 3 files changed, 42 insertions(+), 34 deletions(-) diff --git a/src/js/game/hud/parts/building_placer.js b/src/js/game/hud/parts/building_placer.js index 6ccf00ad..5faec6ab 100644 --- a/src/js/game/hud/parts/building_placer.js +++ b/src/js/game/hud/parts/building_placer.js @@ -201,7 +201,7 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic { } = metaBuilding.computeOptimalDirectionAndRotationVariantAtTile( this.root, mouseTile, - this.getBaseRotation(), + this.currentBaseRotation, this.currentVariant.get() ); diff --git a/src/js/game/hud/parts/building_placer_logic.js b/src/js/game/hud/parts/building_placer_logic.js index 5a462f47..43abaf6a 100644 --- a/src/js/game/hud/parts/building_placer_logic.js +++ b/src/js/game/hud/parts/building_placer_logic.js @@ -49,28 +49,9 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { /** * The current rotation preference for each building. - * @type {Object.} + * @type{Object.} */ - this.preferredRotations = {}; - - this.getBaseRotation = function () { - const rotationByBuilding = this.root.app.settings.getAllSettings().rotationByBuilding; - if (!rotationByBuilding) { - return this.currentBaseRotationGeneral; - } - const id = this.currentMetaBuilding.get().getId(); - return this.preferredRotations[id] || this.currentBaseRotationGeneral; - }; - - this.setBaseRotation = function (rotation) { - const rotationByBuilding = this.root.app.settings.getAllSettings().rotationByBuilding; - if (!rotationByBuilding) { - this.currentBaseRotationGeneral = rotation; - } else { - const id = this.currentMetaBuilding.get().getId(); - this.preferredRotations[id] = rotation; - } - }; + this.preferredBaseRotations = {}; /** * Whether we are currently dragging @@ -139,6 +120,34 @@ 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() { + const rotationByBuilding = this.root.app.settings.getAllSettings().rotationByBuilding; + if (!rotationByBuilding) { + return this.currentBaseRotationGeneral; + } + const id = this.currentMetaBuilding.get().getId(); + return this.preferredBaseRotations[id] == null + ? this.currentBaseRotationGeneral + : this.preferredBaseRotations[id]; + } + + /** + * Sets the base rotation for the current meta-building. + */ + set currentBaseRotation(rotation) { + const rotationByBuilding = this.root.app.settings.getAllSettings().rotationByBuilding; + if (!rotationByBuilding) { + this.currentBaseRotationGeneral = rotation; + } else { + const id = this.currentMetaBuilding.get().getId(); + this.preferredBaseRotations[id] = rotation; + } + } + /** * Returns if the direction lock is currently active * @returns {boolean} @@ -225,12 +234,12 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { const selectedBuilding = this.currentMetaBuilding.get(); if (selectedBuilding) { if (this.root.keyMapper.getBinding(KEYMAPPINGS.placement.rotateInverseModifier).pressed) { - this.setBaseRotation((this.getBaseRotation() + 270) % 360); + this.currentBaseRotation = (this.currentBaseRotation + 270) % 360; } else { - this.setBaseRotation((this.getBaseRotation() + 90) % 360); + this.currentBaseRotation = (this.currentBaseRotation + 90) % 360; } const staticComp = this.fakeEntity.components.StaticMapEntity; - staticComp.rotation = this.getBaseRotation(); + staticComp.rotation = this.currentBaseRotation; } } /** @@ -402,7 +411,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { const { rotation, rotationVariant } = metaBuilding.computeOptimalDirectionAndRotationVariantAtTile( this.root, tile, - this.getBaseRotation(), + this.currentBaseRotation, this.currentVariant.get() ); @@ -410,7 +419,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { origin: tile, rotation, rotationVariant, - originalRotation: this.getBaseRotation(), + originalRotation: this.currentBaseRotation, building: this.currentMetaBuilding.get(), variant: this.currentVariant.get(), }); @@ -426,7 +435,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { KEYMAPPINGS.placementModifiers.placementDisableAutoOrientation ).pressed ) { - this.setBaseRotation((180 + this.getBaseRotation()) % 360); + this.currentBaseRotation = (180 + this.currentBaseRotation) % 360; } // Check if we should stop placement @@ -476,7 +485,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { for (let i = 0; i < path.length; ++i) { const { rotation, tile } = path[i]; - this.setBaseRotation(rotation); + this.currentBaseRotation = rotation; this.tryPlaceCurrentBuildingAt(tile); } }); @@ -659,11 +668,11 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { ) { const delta = newPos.sub(oldPos); const angleDeg = Math_degrees(delta.angle()); - this.setBaseRotation((Math.round(angleDeg / 90) * 90 + 360) % 360); + this.currentBaseRotation = (Math.round(angleDeg / 90) * 90 + 360) % 360; // Holding alt inverts the placement if (this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeInverse).pressed) { - this.setBaseRotation((180 + this.getBaseRotation()) % 360); + this.currentBaseRotation = (180 + this.currentBaseRotation) % 360; } } diff --git a/src/js/profile/application_settings.js b/src/js/profile/application_settings.js index 92edf124..8fd80df0 100644 --- a/src/js/profile/application_settings.js +++ b/src/js/profile/application_settings.js @@ -248,7 +248,7 @@ export const allApplicationSettings = [ new BoolSetting("alwaysMultiplace", categoryGame, (app, value) => {}), new BoolSetting("enableTunnelSmartplace", categoryGame, (app, value) => {}), - new BoolSetting("vignette", categoryGame, (app, value) => {}),<<<<<<< HEAD + new BoolSetting("vignette", categoryGame, (app, value) => {}), new BoolSetting("compactBuildingInfo", categoryGame, (app, value) => {}), new BoolSetting("disableCutDeleteWarnings", categoryGame, (app, value) => {}), new BoolSetting("rotationByBuilding", categoryGame, (app, value) => {}), @@ -280,7 +280,6 @@ class SettingsStorage { this.disableCutDeleteWarnings = false; this.rotationByBuilding = true; - this.enableColorBlindHelper = false; /** @@ -554,7 +553,7 @@ export class ApplicationSettings extends ReadWriteProxy { data.settings.enableColorBlindHelper = false; data.version = 17; } - if(data.version < 18) { + if (data.version < 18) { data.settings.rotationByBuilding = true; data.version = 18; } From 40b159078179aa21ac3a89ddf8250a3c3f0d3315 Mon Sep 17 00:00:00 2001 From: Victor <67063010+senjorsalsa@users.noreply.github.com> Date: Tue, 23 Jun 2020 15:50:12 +0200 Subject: [PATCH 26/57] Swedish translation Typos and small fixes --- translations/base-sv.yaml | 114 +++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/translations/base-sv.yaml b/translations/base-sv.yaml index 752a1fa8..e7c88eea 100644 --- a/translations/base-sv.yaml +++ b/translations/base-sv.yaml @@ -107,7 +107,7 @@ global: control: CTRL alt: ALT escape: ESC - shift: SHIFT + shift: SKIFT space: MELLANSLAG demoBanners: @@ -162,7 +162,7 @@ dialogs: buttons: ok: OK delete: Radera - cancel: Cancel + cancel: Avbryt later: Senare restart: Starta om reset: Återställ @@ -236,7 +236,7 @@ dialogs: massDeleteConfirm: title: Bekräfta borttagning desc: >- - Du tar nu bort ganska många byggnader ( för att vara exakt)! Är du säker på att du vill göra detta? + Du tar nu bort ganska många byggnader ( för att vara exakt)! Är du säker på att du vill göra detta? blueprintsNotUnlocked: title: Inte än upplåst @@ -246,7 +246,7 @@ dialogs: keybindingsIntroduction: title: Användbara tangentbindningar desc: >- - Detta spel använder en stor mängd tangentbindningar so gör det lättare att bygga stora fabriker. + Detta spel använder en stor mängd tangentbindningar som gör det lättare att bygga stora fabriker. Här är några men se till att kolla in tangentbindningarna!

CTRL + Dra: Välj en yta att kopiera / radera.
SHIFT: Håll ned för att placera flera av samma byggnad.
@@ -257,7 +257,7 @@ dialogs: desc: Ge den ett meningsfullt namn, du kan också inkludera en kort kod av en form (Vilket du kan generera här ) markerDemoLimit: - desc: Du kan bara skapa två markörer i demoversionen. Skaffa den fristående versionen för ett oändligt antal! + desc: Du kan endast skapa två markörer i demoversionen. Skaffa den fristående versionen för ett oändligt antal! massCutConfirm: title: Bekräfta Klipp desc: >- @@ -287,7 +287,7 @@ ingame: delete: Förstör pasteLastBlueprint: Klistra in ritning lockBeltDirection: Sätt på rullbandsplannerare - plannerSwitchSide: Vänd plannerarsidan + plannerSwitchSide: Vänd planerarsidan cutSelection: Klipp copySelection: Kopiera clearSelection: Rensa vald @@ -308,8 +308,8 @@ ingame: speed: Hastighet range: Räckvidd storage: Förvaring - oneItemPerSecond: 1 obejekt / sekund - itemsPerSecond: obejekt / s + oneItemPerSecond: 1 objekt / sekund + itemsPerSecond: objekt / s itemsPerSecondDouble: (x2) tiles: plattor @@ -353,7 +353,7 @@ ingame: delivered: title: Levererade description: Visar former som levereras till din centrala byggnad. - noShapesProduced: Inga former har hitils producerats. + noShapesProduced: Inga former har producerats än. # Displays the shapes per minute, e.g. '523 / m' shapesPerMinute: / m @@ -399,17 +399,17 @@ ingame: Detta är INTE ett idle-spel! Bygg fler extraktörer för att klara målet snabbare.

Tips: Håll SHIFT för att placera flera extraktörer, och använd R för att rotera dem. colors: - red: Red - green: Green - blue: Blue - yellow: Yellow - purple: Purple - cyan: Cyan - white: White - uncolored: No color + red: Röd + green: Grön + blue: Blå + yellow: Gul + purple: Lila + cyan: Turkos + white: Vit + uncolored: Ofärgad shapeViewer: - title: Layers - empty: Empty + title: Lager + empty: Tom # All shop upgrades shopUpgrades: @@ -474,10 +474,10 @@ buildings: rotater: default: - name: &rotater Rotatör + name: &rotater Roterare description: Roterar former 90 grader. ccw: - name: Rotatör (CCW) + name: Roterare (CCW) description: Roterar former 90 motsols. stacker: @@ -493,10 +493,10 @@ buildings: painter: default: name: &painter Färgläggare - description: &painter_desc Färgar hela formen på den vänstra inputten med färgen från den högra. + description: &painter_desc Färgar hela formen på den vänstra ingången med färgen från den högra. double: name: Färgläggare (Dubbel) - description: Färgar formerna på de vänstra inputterna med färgen från den högra. + description: Färgar formerna på de vänstra ingångarna med färgen från den högra. quad: name: Färgläggare (Quad) description: Låter dig färglägga varje hörn av formen med olika färger. @@ -507,14 +507,14 @@ buildings: trash: default: name: &trash Skräphantering - description: Tar in inputs från alla sidor och förstår dem. För alltid. + description: Tar in former från alla sidor och förstör dem. För alltid. storage: name: Förvaring - description: Förvarar överskottliga obejekt, till kapacitet. Kan användas somöverflödsport. + description: Förvarar överskottliga objekt, till kapacitet. Kan användas som överflödsport. hub: deliver: Leverera - toUnlock: att låsa upp + toUnlock: Att låsa upp levelShortcut: LVL storyRewards: @@ -525,7 +525,7 @@ storyRewards: reward_rotater: title: Rotation - desc: Rotatorn har blivit upplåst! Den roterar former 90 grader medsols. + desc: Roteraren har blivit upplåst! Den roterar former 90 grader medsols. reward_painter: title: Måleri @@ -538,11 +538,11 @@ storyRewards: reward_stacker: title: Kombinera - desc: Du kan nu kombinera former medstaplaren! Båda inputs blir combinerade och om de kan sättas brevid varandra kommer de att sättas ihop. Om inte kommer den högra staplas över den vänstra! + desc: Du kan nu kombinera former medstaplaren! Båda inputs blir kombinerade och om de kan sättas brevid varandra kommer de att sättas ihop. Om inte kommer den högra staplas över den vänstra! reward_splitter: title: Delning/Sammanslagning - desc: Den multifunktiionella balancer har blivit upplåst - Den kan användas för att bygga större fabriker genom att dela eller slå ihop obejekt till flera rullband!

+ desc: Den multifunktiionella balanseraren har blivit upplåst - Den kan användas för att bygga större fabriker genom att dela eller slå ihop objekt till flera rullband!

reward_tunnel: title: Tunnel @@ -550,20 +550,20 @@ storyRewards: reward_rotater_ccw: title: Motsols rotation - desc: Du har låst upp en variant av rotatorn - Den låter dig rotera saker motsols! För att bygga den, välj rotatorn och tryck ned 'T' för att cykla genom dess varianter! + desc: Du har låst upp en variant av roteraren - Den låter dig rotera saker motsols! För att bygga den, välj roteraren och tryck ned 'T' för att cykla genom dess varianter! reward_miner_chainable: title: Kedjeextraktor - desc: Du har låst upp Kedjeextraktorn! Den kan föra sina resurser framåt till andra extraktorerså att du kan mer effektivt extrahera resurser! + desc: Du har låst upp Kedjeextraktorn! Den kan föra sina resurser framåt till andra extraktorer så att du kan mer effektivt extrahera resurser! reward_underground_belt_tier_2: title: Tunnel Tier II desc: Du har låst upp en ny variant av tunneln - Den har en större räckvidd, och du kan också mix-matcha tunnlarna nu! reward_splitter_compact: - title: Kompakt Balancer + title: Kompakt Balanserare desc: >- - Du har låst upp en ny veriant av balancer - Den accepterar två input och gör dem till en! + Du har låst upp en ny variant av balanseraren - Den accepterar två input och gör dem till en! reward_cutter_quad: title: Quad Klippning @@ -575,11 +575,11 @@ storyRewards: reward_painter_quad: title: Quad Färgläggning - desc: Du har låst upp en ny variant av Färgläggaren - Den tillåter dig att färglägga varje del av formen individuellt! + desc: Du har låst upp en ny variant av Färgläggaren - Den tillåter dig att färglägga varje del av en form individuellt! reward_storage: title: Förvaringsbuffert - desc: Du har låst upp en ny variant av skräphantering - Den tillåter dig att förvara obejekt upp till en viss kapacitet! + desc: Du har låst upp en ny variant av skräphantering - Den tillåter dig att förvara objekt upp till en viss kapacitet! reward_freeplay: title: Friläge @@ -587,13 +587,13 @@ storyRewards: reward_blueprints: title: Ritningar - desc: Du kan nu kopiera och klistra in delar av din fabrik! Välj ett område (håll in CTRL, dra sedan med musen), och tryck 'C' för att kopiera det.

Att klistra in ärinte gratis, du behöver produvera ritningsformer för att ha råd med det! (De du just levererade). + desc: Du kan nu kopiera och klistra in delar av din fabrik! Välj ett område (håll in CTRL, dra sedan med musen), och tryck 'C' för att kopiera det.

Att klistra in ärinte gratis, du behöver producera ritningsformer för att ha råd med det! (De du just levererade). # Special reward, which is shown when there is no reward actually no_reward: title: Nästa nivå desc: >- - Denna nivå har ingen belöning, men nästa kommer!

PS: Se till att inte förstöra din redan existerande fabrik - Du behöver alla dom där formerna igen för att låsa upp uppgraderignar! + Denna nivå har ingen belöning, men nästa kommer!

PS: Se till att inte förstöra din redan existerande fabrik - Du behöver alla de där formerna igen för att låsa upp uppgraderingar! no_reward_freeplay: title: Nästa nivå @@ -616,7 +616,7 @@ settings: uiScale: title: Gränssnittsskala description: >- - Ändrar storleken på gränssnittet. gränssnittet kommer fortförande baseras på skrärmupplåsning, men denna inställning kontrollerar mängdskala. + Ändrar storleken på gränssnittet. gränssnittet kommer fortfarande baseras på skärmupplösning, men denna inställning kontrollerar mängdskala. scales: super_small: Superliten small: Liten @@ -630,7 +630,7 @@ settings: Ändrar hur känslig zoomen är (Mushjul eller styrplatta). sensitivity: super_slow: Superlångsam - slow: långsam + slow: Långsam regular: Normal fast: Snabb super_fast: Supersnabb @@ -643,7 +643,7 @@ settings: fullscreen: title: Fullskärm description: >- - Det är rekomenderat att spela i fullskärm för bästa upplevelse. Endast tillgänglig i den fristående versionen. + Det är rekommenderat att spela i fullskärm för bästa upplevelse. Endast tillgänglig i den fristående versionen. soundsMuted: title: Dämpa Ljud @@ -667,12 +667,12 @@ settings: refreshRate: title: Simulationsmål description: >- - Om du har en 144hz skärm, ändra uppdateringshastigheten här så kommer spelet simulera vid en högre uppdateringshastighet. Detta kan dock sänka FPS om din dator är lågsam. + Om du har en 144hz skärm, ändra uppdateringshastigheten här så kommer spelet simulera vid en högre uppdateringshastighet. Detta kan dock sänka FPS om din dator är långsam. alwaysMultiplace: title: Flerplacering description: >- - Om på, alla byggnader kommer fortsätta vara valda efter placering. Att ha detta på är som att konstant hålla ned SHIFT. + Om på, alla byggnader kommer fortsätta vara valda efter placering. Att ha detta på är som att konstant hålla ned SKIFT. offerHints: title: Tips & Tutorials @@ -684,9 +684,9 @@ settings: description: Ändrar hur snabbt kameran förflyttar sig när du använder tangentbordet för att flytta kameran. speeds: super_slow: Superlångsamt - slow: långsamt + slow: Långsamt regular: Normal - fast: snabbt + fast: Snabbt super_fast: Supersnabbt extremely_fast: Extremt snabbt enableTunnelSmartplace: @@ -713,7 +713,7 @@ settings: twenty_minutes: 20 Minuter disabled: Avstängd compactBuildingInfo: - title: Kompaktera byggnadsinfo + title: Kompakt byggnadsinfo description: >- Kortar ned infotexter för byggnader genom att endast visa dess storlek. Annars visas en beskrivning och bild. @@ -724,13 +724,13 @@ settings: ska tas bort enableColorBlindHelper: - title: Color Blind Mode - description: Enables various tools which allow to play the game if you are color blind. + title: Färgblint läge + description: Aktiverar olika verktyg som låter dig spela spelet om du är färbling. keybindings: title: Tangentbindningar hint: >- - Tips: Se till att använda CTRL, SHIFT, och ALT! De låter dig använda olika placeringslägen. + Tips: Se till att använda CTRL, SKIFT, och ALT! De låter dig använda olika placeringslägen. resetKeybindings: Återställ Tangentbindningar @@ -746,10 +746,10 @@ keybindings: mappings: confirm: Godkänn back: Tillbaka - mapMoveUp: Gå upp - mapMoveRight: Gå höger - mapMoveDown: Gå nedåt - mapMoveLeft: Gå vänster + mapMoveUp: Gå Upp + mapMoveRight: Gå Höger + mapMoveDown: Gå Nedåt + mapMoveLeft: Gå Vänster centerMap: Till mitten av världen mapZoomIn: Zooma in @@ -783,15 +783,15 @@ keybindings: massSelectSelectMultiple: Välj flera ytor massSelectCopy: Kopiera yta - placementDisableAutoOrientation: Stäng av automatisk orientation + placementDisableAutoOrientation: Stäng av automatisk orientering placeMultiple: Stanna kvar i placeringsläge - placeInverse: Invertera automatisk rullbandsorientation + placeInverse: Invertera automatisk rullbandsorientering pasteLastBlueprint: Klistra in ritning massSelectCut: Klipp yta exportScreenshot: Exportera hela fabriken som bild mapMoveFaster: Flytta dig snabbare - lockBeltDirection: Sätt på rullbandsplannerare - switchDirectionLockSide: "Plannerare: Byt sida" + lockBeltDirection: Sätt på rullbandsplanerare + switchDirectionLockSide: "Planerare: Byt sida" pipette: Pipett about: @@ -808,7 +808,7 @@ about: target="_blank">discord server!

Musiken skapades av Peppsen - Han är grymm!

+ target="_blank">Peppsen - Han är grym!

Och sist men inte minst, tack till min bästa vän Niklas - Utan våra From bbe6edce9fdbb622bdd8ff080445eafc7620bab4 Mon Sep 17 00:00:00 2001 From: YellowSugarHK <67306569+YellowSugarHK@users.noreply.github.com> Date: Tue, 23 Jun 2020 22:57:42 +0800 Subject: [PATCH 27/57] Update base-zh-TW.yaml --- translations/base-zh-TW.yaml | 892 ++++++++++++++++++----------------- 1 file changed, 461 insertions(+), 431 deletions(-) diff --git a/translations/base-zh-TW.yaml b/translations/base-zh-TW.yaml index aac39324..f2fa0fe0 100644 --- a/translations/base-zh-TW.yaml +++ b/translations/base-zh-TW.yaml @@ -19,9 +19,36 @@ # the basic structure so the game also detects it. # +# Chinese (traditional) translation dictionary. TODO: better names for the buildings. +# Standalone:獨立版 +# Demo:演示版 +# Level:關 +# Shape:圖形 +# tile:格子 +# Keybind:按鍵設置 +# Menu:主界面 +# Center/Hub:基地 +# Upgrade:升級 +# Efficiency:效率 +# Building:建築 +# Variant:建築變體 +# Belt: 傳送帶 +# Balancer:平衡機 +# Compact Balancer:小型合流機 +# Merger:合併機 +# Tunnel:隧道 +# Extractor:開採機 +# Cutter:切割機 +# Rotate:旋轉機 +# Stacker:混合機 +# Color Mixer:混色機 +# Painter:上色機 +# Trash:垃圾桶 + steamPage: # This is the short text appearing on the steam page - shortText: shapez.io is a game about building factories to automate the creation and combination of increasingly complex shapes within an infinite map. + shortText: shapez.io 是一款在一個無邊際的地圖上建造工廠、自動化生產與組合愈加複雜圖形的遊戲。 + # shortText: shapez.io is a game about building factories to automate the creation and combination of increasingly complex shapes within an infinite map. # This is the long description for the steam page - It is contained here so you can help to translate it, and I will regulary update the store page. # NOTICE: @@ -30,77 +57,78 @@ steamPage: longText: >- [img]{STEAM_APP_IMAGE}/extras/store_page_gif.gif[/img] - shapez.io is a game about building factories to automate the creation and combination of shapes. Deliver the requested, increasingly complex shapes to progress within the game and unlock upgrades to speed up your factory. + shapez.io 是一款在無邊際的地圖上建造工廠、自動化生產與組合愈加複雜的圖形的遊戲。提交任務,製造更複雜的流水線,解鎖升級來提升您工廠的運作速度。 - Since the demand raises you will have to scale up your factory to fit the needs - Don't forget about resources though, you will have to expand in the [b]infinite map[/b]! + 你將會需要隨著不斷上升得需求擴大你的工廠。當然,不要忘記你可以在[b]無盡[/b]的地圖上開採資源! - Since shapes can get boring soon you need to mix colors and paint your shapes with it - Combine red, green and blue color resources to produce different colors and paint shapes with it to satisfy the demand. + 只對圖形進行加工可能會使你感到無聊。我們為你準備了顏色資源——將紅、綠、藍三種顏色混合,生產更多不同的顏色並粉刷在圖形上以滿足需求。 - This game features 18 levels (Which should keep you busy for hours already!) but I'm constantly adding new content - There is a lot planned! + 這個遊戲目前有18個關卡(這應該已經能讓你忙碌幾個小時了!),並且遊戲正在不斷地更新中。很多新關卡已經在開發計劃當中! - [b]Standalone Advantages[/b] + [b]獨立版優勢[/b] [list] - [*] Waypoints - [*] Unlimited Savegames - [*] Dark Mode - [*] More settings - [*] Allow me to further develop shapez.io ❤️ - [*] More features in the future! + [*] 地圖標記 + [*] 無限存檔 + [*] 深色模式 + [*] 更多設置 + [*] 支持作者繼續開發shapez.io❤️ + [*] 在以後還有更多特性! [/list] - [b]Planned features & Community suggestions[/b] - This game is open source - Anybody can contribute! Besides of that, I listen [b]a lot[/b] to the community! I try to read all suggestions and take as much feedback into account as possible. + [b]開發計劃與社區意見[/b] + + 本遊戲已開源,所有人都能參與遊戲內容的開發!除此以外,我[b]非常重視[/b]玩家社區的反饋!我會閱讀每一條建議並儘量顧及所有建議。 [list] - [*] Story mode where buildings cost shapes - [*] More levels & buildings (standalone exclusive) - [*] Different maps, and maybe map obstacles - [*] Configurable map creation (Edit number and size of patches, seed, and more) - [*] More types of shapes - [*] More performance improvements (Although the game already runs pretty good!) - [*] Color blind mode - [*] And much more! + [*] 要消耗圖形來造建築的的故事模式 + [*] 更多關卡&建築(單機版獨有) + [*] 更多地圖,也許會有障礙物 + [*] 可配置的地圖生成(礦脈密度與大小、 隨機種子以及其他地圖設置) + [*] 更多圖形 + [*] 更多的性能改進(當然,現在遊戲已經非常流暢了!) + [*] 色盲模式 + [*] 以及更多其他的功能! [/list] - Be sure to check out my trello board for the full roadmap! https://trello.com/b/ISQncpJP/shapezio + 記得查看我的Trello計劃板!那裡有所有的開發計劃! https://trello.com/b/ISQncpJP/shapezio global: - loading: Loading - error: Error + loading: 加載中 + error: 錯誤 # How big numbers are rendered, e.g. "10,000" - thousandsDivider: "," + thousandsDivider: " " # The suffix for large numbers, e.g. 1.3k, 400.2M, etc. suffix: - thousands: k - millions: M - billions: B - trillions: T + thousands: 千 + millions: 百萬 + billions: 十億 + trillions: 兆 # Shown for infinitely big numbers - infinite: inf + infinite: 無限 time: # Used for formatting past time dates - oneSecondAgo: one second ago - xSecondsAgo: seconds ago - oneMinuteAgo: one minute ago - xMinutesAgo: minutes ago - oneHourAgo: one hour ago - xHoursAgo: hours ago - oneDayAgo: one day ago - xDaysAgo: days ago + oneSecondAgo: 1秒前 + xSecondsAgo: 秒前 + oneMinuteAgo: 1分鐘前 + xMinutesAgo: 分鐘前 + oneHourAgo: 1小時前 + xHoursAgo: 小時前 + oneDayAgo: 1天前 + xDaysAgo: 天前 # Short formats for times, e.g. '5h 23m' - secondsShort: s - minutesAndSecondsShort: m s - hoursAndMinutesShort: h s + secondsShort: 秒 + minutesAndSecondsShort: 秒 + hoursAndMinutesShort: 小時 秒 - xMinutes: minutes + xMinutes: 分鐘 keys: tab: TAB @@ -108,224 +136,222 @@ global: alt: ALT escape: ESC shift: SHIFT - space: SPACE + space: 空格 demoBanners: # This is the "advertisement" shown in the main menu and other various places - title: Demo Version + title: 演示版 intro: >- - Get the standalone to unlock all features! + 獲取獨立版以解鎖所有功能! mainMenu: - play: Play - changelog: Changelog - importSavegame: Import - openSourceHint: This game is open source! - discordLink: Official Discord Server - helpTranslate: Help translate! + play: 開始遊戲 + changelog: 更新日誌 + importSavegame: 導入 + openSourceHint: 本游戏已开源頭! + discordLink: 官方Discord服務器 + helpTranslate: 幫助我們翻譯! # This is shown when using firefox and other browsers which are not supported. browserWarning: >- - Sorry, but the game is known to run slow on your browser! Get the standalone version or download chrome for the full experience. + 很抱歉, 本遊戲在當前瀏覽器上可能運行緩慢! 使用chrome或者獲取獨立版以得到更好的體驗。 - savegameLevel: Level - savegameLevelUnknown: Unknown Level + savegameLevel: 第關/關 + savegameLevelUnknown: 未知關卡 contests: contest_01_03062020: - title: "Contest #01" - desc: Win $25 for the coolest base! + title: "比賽 #01" + desc: 最屌的工廠將能贏得25美元的獎金! longDesc: >- - To give something back to you, I thought it would be cool to make weekly contests! -

- This weeks topic: Build the coolest base! -

- Here's the deal:
-
    -
  • Submit a screenshot of your base to contest@shapez.io
  • -
  • Bonus points if you share it on social media!
  • -
  • I will choose 5 screenshots and propose it to the discord community to vote.
  • -
  • The winner gets $25 (Paypal, Amazon Gift Card, whatever you prefer)
  • -
  • Deadline: 07.06.2020 12:00 AM CEST
  • -
-
- I'm looking forward to seeing your awesome creations! - - showInfo: View - contestOver: This contest has ended - Join the discord to get noticed about new contests! - continue: Continue - newGame: New Game - madeBy: Made by + 為了回饋您,我認為每週進行比賽也很酷! +

+ 本週主題:建立最酷的基地! +

+ 這是交易:
+