From 503f4f40a8bf47774f0086ff3abb2742f36dd71f Mon Sep 17 00:00:00 2001 From: kebhr <42484226+kebhr@users.noreply.github.com> Date: Tue, 16 Jun 2020 19:11:34 +0900 Subject: [PATCH 1/6] Update Japanese translation --- translations/base-ja.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/translations/base-ja.yaml b/translations/base-ja.yaml index d0782e28..d4e38dfc 100644 --- a/translations/base-ja.yaml +++ b/translations/base-ja.yaml @@ -249,7 +249,7 @@ dialogs: createMarker: title: マーカーを設置 - desc: Give it a meaningful name, you can also include a short key of a shape (Which you can generate here) + desc: わかりやすい名前をつけてください。形を表す短いキーを含めることもできます。(ここから生成できます) markerDemoLimit: desc: デモ版ではマーカー設置は2つまでに制限されています。スタンドアローン版は無制限です! @@ -537,7 +537,7 @@ storyRewards: reward_underground_belt_tier_2: title: トンネル レベルII - desc: You have unlocked a new variant of the tunnel - It has a bigger range, and you can also mix-n-match those tunnels now! + desc: トンネルのバリエーションが利用可能になりました。 - 距離拡張版が追加され、以前のものと組み合わせて目的に応じて利用することができます! reward_splitter_compact: title: 合流機 (コンパクト) @@ -546,7 +546,7 @@ storyRewards: reward_cutter_quad: title: 四分割 - desc: You have unlocked a variant of the cutter - It allows you to cut shapes in four parts instead of just two! + desc: 切断機のバリエーションが利用可能になりました。 - 上下の二分割ではなく、四分割に切断できます! reward_painter_double: title: 着色機 (ダブル) @@ -566,7 +566,7 @@ storyRewards: reward_blueprints: title: ブループリント - desc: You can now copy and paste parts of your factory! Select an area (Hold CTRL, then drag with your mouse), and press 'C' to copy it.

Pasting it is not free, you need to produce blueprint shapes to afford it! (Those you just delivered). + desc: 工場の建造物のコピー&ペーストが利用可能になりました! 範囲選択(CTRLキーを押したままマウスドラッグ)した状態で、'C'キーを押すことでコピーができます。

ペーストはタダではありません。ブループリントの形を生産することで可能になります!(たった今納品したものです) # Special reward, which is shown when there is no reward actually no_reward: @@ -732,7 +732,7 @@ keybindings: pasteLastBlueprint: 直前のブループリントをペーストする massSelectCut: 範囲カット exportScreenshot: 工場の全体像を画像出力 - mapMoveFaster: Move Faster + mapMoveFaster: より速く移動 about: title: このゲームについて From 010f2e4fde4539641a614370707c1d354d3c006a Mon Sep 17 00:00:00 2001 From: tobspr Date: Tue, 16 Jun 2020 12:31:16 +0200 Subject: [PATCH 2/6] Update translations --- translations/base-ar.yaml | 5 ++++- translations/base-cz.yaml | 5 ++++- translations/base-de.yaml | 5 ++++- translations/base-el.yaml | 5 ++++- translations/base-es.yaml | 5 ++++- translations/base-fr.yaml | 5 ++++- translations/base-hu.yaml | 5 ++++- translations/base-it.yaml | 5 ++++- translations/base-ja.yaml | 5 ++++- translations/base-kor.yaml | 5 ++++- translations/base-lt.yaml | 5 ++++- translations/base-nl.yaml | 5 ++++- translations/base-no.yaml | 5 ++++- translations/base-pl.yaml | 5 ++++- translations/base-pt-BR.yaml | 5 ++++- translations/base-pt-PT.yaml | 5 ++++- translations/base-ro.yaml | 5 ++++- translations/base-ru.yaml | 7 +++++-- translations/base-sv.yaml | 5 ++++- translations/base-tr.yaml | 5 ++++- translations/base-zh-CN.yaml | 5 ++++- translations/base-zh-TW.yaml | 5 ++++- 22 files changed, 89 insertions(+), 23 deletions(-) diff --git a/translations/base-ar.yaml b/translations/base-ar.yaml index 97f14ef8..25099768 100644 --- a/translations/base-ar.yaml +++ b/translations/base-ar.yaml @@ -480,13 +480,16 @@ buildings: painter: default: name: &painter Painter - description: Colors the whole shape on the left input with the color from the top input. + description: &painter_desc Colors the whole shape on the left input with the color from the top input. double: name: Painter (Double) description: Colors the shapes on the left inputs with the color from the top input. quad: name: Painter (Quad) description: Allows to color each quadrant of the shape with a different color. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-cz.yaml b/translations/base-cz.yaml index 7e28ffa0..6189ad06 100644 --- a/translations/base-cz.yaml +++ b/translations/base-cz.yaml @@ -461,13 +461,16 @@ buildings: painter: default: name: &painter Barvič - description: Obarví celý tvar v levém vstupu barvou z pravého vstupu. + description: &painter_desc Obarví celý tvar v levém vstupu barvou z pravého vstupu. double: name: Barvič (dvojnásobný) description: Obarví tvary z levých vstupů barvou z horního vstupu. quad: name: Barvič (čtyřnásobný) description: Umožňuje obarvit každý dílek tvaru samostatně. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-de.yaml b/translations/base-de.yaml index 713cabe8..2ab40c34 100644 --- a/translations/base-de.yaml +++ b/translations/base-de.yaml @@ -475,7 +475,7 @@ buildings: painter: default: name: &painter Färber - description: Färbt die ganze Form aus dem linken Eingang mit der Farbe aus dem oberen Eingang. + description: &painter_desc Färbt die ganze Form aus dem linken Eingang mit der Farbe aus dem oberen Eingang. double: name: Färber (2-Fach) @@ -484,6 +484,9 @@ buildings: quad: name: Färber (4-Fach) description: Erlaubt jedes einzelne Viertel einer Form beliebig einzufärben. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-el.yaml b/translations/base-el.yaml index 5d26b085..9e55e458 100644 --- a/translations/base-el.yaml +++ b/translations/base-el.yaml @@ -475,13 +475,16 @@ buildings: painter: default: name: &painter Painter - description: Colors the whole shape on the left input with the color from the right input. + description: &painter_desc Colors the whole shape on the left input with the color from the right input. double: name: Painter (Double) description: Colors the shapes on the left inputs with the color from the top input. quad: name: Painter (Quad) description: Allows to color each quadrant of the shape with a different color. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-es.yaml b/translations/base-es.yaml index 447eb2d5..2a41a917 100644 --- a/translations/base-es.yaml +++ b/translations/base-es.yaml @@ -469,13 +469,16 @@ buildings: painter: default: name: &painter Pintor - description: Colorea la figura entera con el color que entra por la izquierda. + description: &painter_desc Colorea la figura entera con el color que entra por la izquierda. double: name: Pintor (Doble) description: Colorea las figuras que entran por la izquierda con el color que entrapor arriba. quad: name: Pintor (Cuádruple) description: Permite colorear cada cuadrante de una figura con un color distinto. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-fr.yaml b/translations/base-fr.yaml index 79895108..17e52454 100644 --- a/translations/base-fr.yaml +++ b/translations/base-fr.yaml @@ -478,13 +478,16 @@ buildings: painter: default: name: &painter Peintre - description: Colorie entièrement la forme de gauche avec la couleur de droite. + description: &painter_desc Colorie entièrement la forme de gauche avec la couleur de droite. double: name: Peintre (Double) description: Colorie les deux formes de gauche avec la couleur de droite. quad: name: Peintre (Quadruple) description: Permet de colorier chaque quadrant d'une forme avec une couleur différente. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-hu.yaml b/translations/base-hu.yaml index 391d2962..8af3f34d 100644 --- a/translations/base-hu.yaml +++ b/translations/base-hu.yaml @@ -475,13 +475,16 @@ buildings: painter: default: name: &painter Painter - description: Colors the whole shape on the left input with the color from the right input. + description: &painter_desc Colors the whole shape on the left input with the color from the right input. double: name: Painter (Double) description: Colors the shapes on the left inputs with the color from the top input. quad: name: Painter (Quad) description: Allows to color each quadrant of the shape with a different color. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-it.yaml b/translations/base-it.yaml index 5d26b085..9e55e458 100644 --- a/translations/base-it.yaml +++ b/translations/base-it.yaml @@ -475,13 +475,16 @@ buildings: painter: default: name: &painter Painter - description: Colors the whole shape on the left input with the color from the right input. + description: &painter_desc Colors the whole shape on the left input with the color from the right input. double: name: Painter (Double) description: Colors the shapes on the left inputs with the color from the top input. quad: name: Painter (Quad) description: Allows to color each quadrant of the shape with a different color. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-ja.yaml b/translations/base-ja.yaml index d0782e28..e614b4f6 100644 --- a/translations/base-ja.yaml +++ b/translations/base-ja.yaml @@ -479,13 +479,16 @@ buildings: painter: default: name: &painter 着色機 - description: 左から入力された形の全体を、右から入力された色で着色します。 + description: &painter_desc 左から入力された形の全体を、右から入力された色で着色します。 double: name: 着色機 (ダブル) description: 左から入力された形を、上から入力された色で着色します。 quad: name: 着色機 (四分割) description: 入力された形を四分割づつ別の色で塗り分けられます。 + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-kor.yaml b/translations/base-kor.yaml index cbf3bc38..d24e7c47 100644 --- a/translations/base-kor.yaml +++ b/translations/base-kor.yaml @@ -480,13 +480,16 @@ buildings: painter: default: name: &painter 도형 색칠기 - description: 도형을 색소로 색칠한다. + description: &painter_desc 도형을 색소로 색칠한다. double: name: 2단 도형 색칠기 description: 왼쪽에 입력되는 도형을 위에서 입력되는 색소로 색칠한다. quad: name: 4단 도형 색칠기 description: 도형의 4가지 분단을 각각 다른 색으로 색칠할 수 있다. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-lt.yaml b/translations/base-lt.yaml index 0a50ecf0..4fce0ecb 100644 --- a/translations/base-lt.yaml +++ b/translations/base-lt.yaml @@ -480,13 +480,16 @@ buildings: painter: default: name: &painter Painter - description: Colors the whole shape on the left input with the color from the top input. + description: &painter_desc Colors the whole shape on the left input with the color from the top input. double: name: Painter (Double) description: Colors the shapes on the left inputs with the color from the top input. quad: name: Painter (Quad) description: Allows to color each quadrant of the shape with a different color. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-nl.yaml b/translations/base-nl.yaml index 8ad302cb..4cd4645b 100644 --- a/translations/base-nl.yaml +++ b/translations/base-nl.yaml @@ -474,13 +474,16 @@ buildings: painter: default: name: &painter Verver - description: Verft de volledige vorm in de linker input met de kleur van de rechter input. + description: &painter_desc Verft de volledige vorm in de linker input met de kleur van de rechter input. double: name: Verver (Dubbel) description: Verft de vormen in de linker inputs met de kleur van de rechter input. quad: name: Verver (Quad) description: Verft elke kwart van de vorm een andere kleur. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-no.yaml b/translations/base-no.yaml index 74ef4a06..73f99fcf 100644 --- a/translations/base-no.yaml +++ b/translations/base-no.yaml @@ -478,13 +478,16 @@ buildings: painter: default: name: &painter Maler - description: Maler hele objektet på venstre inngang med fargen fra øverste inngang. + description: &painter_desc Maler hele objektet på venstre inngang med fargen fra øverste inngang. double: name: Maler (Dobbel) description: Maler hele objektet på venstre inngang med fargen fra øverste inngang. quad: name: Maler (Fireganger) description: Farger enhver kvadrant av objektet med forskjellige farger. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-pl.yaml b/translations/base-pl.yaml index d15d4efc..1d40159e 100644 --- a/translations/base-pl.yaml +++ b/translations/base-pl.yaml @@ -489,13 +489,16 @@ buildings: # 2nd translator's note: All those buildings had different descriptions in english. Don't change them all to the same description. default: name: &painter Malarz - description: Koloruje kształt za pomocą koloru dostarczonego od boku. + description: &painter_desc Koloruje kształt za pomocą koloru dostarczonego od boku. double: name: Malarz (Podwójny) description: Koloruje kształt za pomocą koloru dostarczonych od boku. Koloruje 2 kształty używając 1 barwnika. quad: name: Malarz (Poczwórny) description: Koloruje każdą ćwiarkę kształtu na inny kolor, używając dostarczonych kolorów. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-pt-BR.yaml b/translations/base-pt-BR.yaml index d953aaee..185b7379 100644 --- a/translations/base-pt-BR.yaml +++ b/translations/base-pt-BR.yaml @@ -477,13 +477,16 @@ buildings: painter: default: name: &painter Pintor - description: Colore a forma inteira na entrada esquerda com a cor da entrada direita. + description: &painter_desc Colore a forma inteira na entrada esquerda com a cor da entrada direita. double: name: Pintor (Duplo) description: Colore as duas formas na entrada esquerda com a cor da entrada direita. quad: name: Pintor (Quádruplo) description: Permite colorir cada quadrante da forma com uma cor diferente. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-pt-PT.yaml b/translations/base-pt-PT.yaml index 37483770..6bb689af 100644 --- a/translations/base-pt-PT.yaml +++ b/translations/base-pt-PT.yaml @@ -474,13 +474,16 @@ buildings: painter: default: name: &painter Pintor - description: Pinta a forma geométrica da entrada esquerda com a cor da entrada superior. + description: &painter_desc Pinta a forma geométrica da entrada esquerda com a cor da entrada superior. double: name: Pintor (Duplo) description: Pinta as formas geométricas das entradas esquerdas com a cor da entrada superior. quad: name: Pintor (Quádruplo) description: Pinta cada quadrante da forma geométrica com uma cor diferente. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-ro.yaml b/translations/base-ro.yaml index 9243d108..71154262 100644 --- a/translations/base-ro.yaml +++ b/translations/base-ro.yaml @@ -475,13 +475,16 @@ buildings: painter: default: name: &painter Painter - description: Colors the whole shape on the left input with the color from the right input. + description: &painter_desc Colors the whole shape on the left input with the color from the right input. double: name: Painter (Double) description: Colors the shapes on the left inputs with the color from the top input. quad: name: Painter (Quad) description: Allows to color each quadrant of the shape with a different color. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-ru.yaml b/translations/base-ru.yaml index 59537eb9..d33b736d 100644 --- a/translations/base-ru.yaml +++ b/translations/base-ru.yaml @@ -476,13 +476,16 @@ buildings: painter: default: name: &painter Покрасчик - description: Красит всю фигуру из левого входа красителем из верхнего. + description: &painter_desc Красит всю фигуру из левого входа красителем из верхнего. double: name: Покрасчик (Двойной) description: Красит фигуру из левых входов красителем из верхнего. quad: name: Покрасчик (Четырехпоточный) description: Позволяет раскрасить каждую четверть фигуры разными цветами. + mirrored: + name: *painter + description: *painter_desc trash: default: @@ -652,7 +655,7 @@ settings: alwaysMultiplace: title: Многократное размещение description: >- - Если включено, все здания останутся выбранными после размещения, пока вы не отмените выбор. Это эквивалентно постоянному удержанию SHIFT. + Если включено, все здания останутся выбранными после размещения, пока вы не отмените выбор. Это эквивалентно постоянному удержанию SHIFT. offerHints: title: Подсказки & Обучение diff --git a/translations/base-sv.yaml b/translations/base-sv.yaml index 9243d108..71154262 100644 --- a/translations/base-sv.yaml +++ b/translations/base-sv.yaml @@ -475,13 +475,16 @@ buildings: painter: default: name: &painter Painter - description: Colors the whole shape on the left input with the color from the right input. + description: &painter_desc Colors the whole shape on the left input with the color from the right input. double: name: Painter (Double) description: Colors the shapes on the left inputs with the color from the top input. quad: name: Painter (Quad) description: Allows to color each quadrant of the shape with a different color. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-tr.yaml b/translations/base-tr.yaml index 12a73664..a5891111 100644 --- a/translations/base-tr.yaml +++ b/translations/base-tr.yaml @@ -480,13 +480,16 @@ buildings: painter: default: name: &painter Painter - description: Colors the whole shape on the left input with the color from the right input. + description: &painter_desc Colors the whole shape on the left input with the color from the right input. double: name: Painter (Double) description: Colors the shapes on the left inputs with the color from the top input. quad: name: Painter (Quad) description: Allows to color each quadrant of the shape with a different color. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-zh-CN.yaml b/translations/base-zh-CN.yaml index 9243d108..71154262 100644 --- a/translations/base-zh-CN.yaml +++ b/translations/base-zh-CN.yaml @@ -475,13 +475,16 @@ buildings: painter: default: name: &painter Painter - description: Colors the whole shape on the left input with the color from the right input. + description: &painter_desc Colors the whole shape on the left input with the color from the right input. double: name: Painter (Double) description: Colors the shapes on the left inputs with the color from the top input. quad: name: Painter (Quad) description: Allows to color each quadrant of the shape with a different color. + mirrored: + name: *painter + description: *painter_desc trash: default: diff --git a/translations/base-zh-TW.yaml b/translations/base-zh-TW.yaml index 9243d108..71154262 100644 --- a/translations/base-zh-TW.yaml +++ b/translations/base-zh-TW.yaml @@ -475,13 +475,16 @@ buildings: painter: default: name: &painter Painter - description: Colors the whole shape on the left input with the color from the right input. + description: &painter_desc Colors the whole shape on the left input with the color from the right input. double: name: Painter (Double) description: Colors the shapes on the left inputs with the color from the top input. quad: name: Painter (Quad) description: Allows to color each quadrant of the shape with a different color. + mirrored: + name: *painter + description: *painter_desc trash: default: From 3b365280c3fba07472cae2614bc6290d1f6a1984 Mon Sep 17 00:00:00 2001 From: Nikolay Date: Tue, 16 Jun 2020 14:01:58 +0300 Subject: [PATCH 3/6] Update base-ru.yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit раСделители -> раЗделители --- translations/base-ru.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/base-ru.yaml b/translations/base-ru.yaml index d33b736d..f3bac5ff 100644 --- a/translations/base-ru.yaml +++ b/translations/base-ru.yaml @@ -397,7 +397,7 @@ ingame: # All shop upgrades shopUpgrades: belt: - name: Конвейеры, Расделители & Туннели + name: Конвейеры, Разделители & Туннели description: Скорость x → x miner: name: Добыча From 7295a3882644a96aeb060a6ae7a81d4f2a0f6bd7 Mon Sep 17 00:00:00 2001 From: mini-bomba <55105495+mini-bomba@users.noreply.github.com> Date: Tue, 16 Jun 2020 13:06:22 +0200 Subject: [PATCH 4/6] Updated the polish translation --- translations/base-pl.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/base-pl.yaml b/translations/base-pl.yaml index 1d40159e..713884e8 100644 --- a/translations/base-pl.yaml +++ b/translations/base-pl.yaml @@ -254,7 +254,7 @@ dialogs: createMarker: title: Nowy Znacznik - desc: Give it a meaningful name, you can also include a short key of a shape (Which you can generate here) + desc: Podaj nazwę znacznika. Możesz w niej zawrzeć kod kształtu, który możesz wygenerować tutaj. markerDemoLimit: desc: Możesz stworzyć tylko dwa własne znaczniki w wersji demo. Zakup pełną wersję gry dla nielimitowanych znaczników! From b8c3668d88edf2a258e14f2d109f72b0469ede18 Mon Sep 17 00:00:00 2001 From: tobspr Date: Tue, 16 Jun 2020 13:19:53 +0200 Subject: [PATCH 5/6] Placing underground belts now removes belts and other (unneeded) tunnels inbetween --- src/js/changelog.js | 2 + src/js/game/hud/parts/building_placer.js | 4 + src/js/game/root.js | 1 + src/js/game/systems/underground_belt.js | 150 +++++++++++++++++++++-- 4 files changed, 150 insertions(+), 7 deletions(-) diff --git a/src/js/changelog.js b/src/js/changelog.js index 5574953b..a7122823 100644 --- a/src/js/changelog.js +++ b/src/js/changelog.js @@ -6,6 +6,8 @@ export const CHANGELOG = [ "There is now an indicator (compass) to the HUB for the HUB Marker!", "You can now include shape short keys in markers to render shape icons instead of text!", "Added mirrored variant of the painter", + "When placing tunnels, unnecessary belts inbetween are now removed!", + "You can now drag tunnels and they will automatically expand! (Just try it out, its intuitive)", ], }, { diff --git a/src/js/game/hud/parts/building_placer.js b/src/js/game/hud/parts/building_placer.js index 6da065b2..7e20eef7 100644 --- a/src/js/game/hud/parts/building_placer.js +++ b/src/js/game/hud/parts/building_placer.js @@ -483,6 +483,10 @@ export class HUDBuildingPlacer extends BaseHUDPart { ) { // Succesfully placed + const entity = this.root.map.getTileContent(tile); + assert(entity, "Entity was not actually placed"); + this.root.signals.entityManuallyPlaced.dispatch(entity); + if ( metaBuilding.getFlipOrientationAfterPlacement() && !this.root.keyMapper diff --git a/src/js/game/root.js b/src/js/game/root.js index 91efd137..cc6007de 100644 --- a/src/js/game/root.js +++ b/src/js/game/root.js @@ -130,6 +130,7 @@ export class GameRoot { this.signals = { // Entities + entityManuallyPlaced: /** @type {TypedSignal<[Entity]>} */ (new Signal()), entityAdded: /** @type {TypedSignal<[Entity]>} */ (new Signal()), entityGotNewComponent: /** @type {TypedSignal<[Entity]>} */ (new Signal()), entityComponentRemoved: /** @type {TypedSignal<[Entity]>} */ (new Signal()), diff --git a/src/js/game/systems/underground_belt.js b/src/js/game/systems/underground_belt.js index 34decc11..393df04a 100644 --- a/src/js/game/systems/underground_belt.js +++ b/src/js/game/systems/underground_belt.js @@ -1,12 +1,17 @@ -import { GameSystemWithFilter } from "../game_system_with_filter"; -import { UndergroundBeltComponent, enumUndergroundBeltMode } from "../components/underground_belt"; -import { Entity } from "../entity"; -import { Loader } from "../../core/loader"; import { Math_max } from "../../core/builtins"; import { globalConfig } from "../../core/config"; -import { enumDirection, enumDirectionToVector, enumDirectionToAngle } from "../../core/vector"; -import { MapChunkView } from "../map_chunk_view"; -import { DrawParameters } from "../../core/draw_parameters"; +import { Loader } from "../../core/loader"; +import { + enumDirection, + enumDirectionToAngle, + enumDirectionToVector, + Vector, + enumAngleToDirection, + enumInvertedDirections, +} from "../../core/vector"; +import { enumUndergroundBeltMode, UndergroundBeltComponent } from "../components/underground_belt"; +import { Entity } from "../entity"; +import { GameSystemWithFilter } from "../game_system_with_filter"; export class UndergroundBeltSystem extends GameSystemWithFilter { constructor(root) { @@ -20,6 +25,8 @@ export class UndergroundBeltSystem extends GameSystemWithFilter { "sprites/buildings/underground_belt_exit.png" ), }; + + this.root.signals.entityManuallyPlaced.add(this.onEntityPlaced, this); } update() { @@ -46,6 +53,135 @@ export class UndergroundBeltSystem extends GameSystemWithFilter { } } + /** + * Callback when an entity got placed, used to remove belts between underground belts + * @param {Entity} entity + */ + onEntityPlaced(entity) { + const undergroundComp = entity.components.UndergroundBelt; + if (undergroundComp && undergroundComp.mode === enumUndergroundBeltMode.receiver) { + const staticComp = entity.components.StaticMapEntity; + const tile = staticComp.origin; + + const direction = enumAngleToDirection[staticComp.rotation]; + const inverseDirection = enumInvertedDirections[direction]; + const offset = enumDirectionToVector[inverseDirection]; + + let currentPos = tile.copy(); + + const tier = undergroundComp.tier; + const range = globalConfig.undergroundBeltMaxTilesByTier[tier]; + + // Search for the entrance which is furthes apart (this is why we can't reuse logic here) + let matchingEntrance = null; + for (let i = 0; i < range; ++i) { + currentPos.addInplace(offset); + const contents = this.root.map.getTileContent(currentPos); + if (!contents) { + continue; + } + + const contentsUndergroundComp = contents.components.UndergroundBelt; + if ( + contentsUndergroundComp && + contentsUndergroundComp.tier === undergroundComp.tier && + contentsUndergroundComp.mode === enumUndergroundBeltMode.sender + ) { + matchingEntrance = { + entity: contents, + range: i, + }; + } + } + + if (!matchingEntrance) { + // Nothing found + return; + } + + // Remove any belts between entrance and exit which have the same direction + currentPos = tile.copy(); + for (let i = 0; i < matchingEntrance.range; ++i) { + currentPos.addInplace(offset); + + const contents = this.root.map.getTileContent(currentPos); + if (!contents) { + continue; + } + + const contentsStaticComp = contents.components.StaticMapEntity; + const contentsBeltComp = contents.components.Belt; + + if (contentsBeltComp) { + // It's a belt + if ( + contentsBeltComp.direction === enumDirection.top && + enumAngleToDirection[contentsStaticComp.rotation] === direction + ) { + // It's same rotation, drop it + this.root.logic.tryDeleteBuilding(contents); + } + } + } + + // Remove any double tunnels, by checking the tile plus the tile above + currentPos = tile.copy().add(offset); + for (let i = 0; i < matchingEntrance.range - 1; ++i) { + const posBefore = currentPos.copy(); + currentPos.addInplace(offset); + + const entityBefore = this.root.map.getTileContent(posBefore); + const entityAfter = this.root.map.getTileContent(currentPos); + + if (!entityBefore || !entityAfter) { + continue; + } + + const undergroundBefore = entityBefore.components.UndergroundBelt; + const undergroundAfter = entityAfter.components.UndergroundBelt; + + if (!undergroundBefore || !undergroundAfter) { + // Not an underground belt + continue; + } + + if ( + // Both same tier + undergroundBefore.tier !== undergroundAfter.tier || + // And same tier as our original entity + undergroundBefore.tier !== undergroundComp.tier + ) { + // Mismatching tier + continue; + } + + if ( + undergroundBefore.mode !== enumUndergroundBeltMode.sender || + undergroundAfter.mode !== enumUndergroundBeltMode.receiver + ) { + // Not the right mode + continue; + } + + // Check rotations + const staticBefore = entityBefore.components.StaticMapEntity; + const staticAfter = entityAfter.components.StaticMapEntity; + + if ( + enumAngleToDirection[staticBefore.rotation] !== direction || + enumAngleToDirection[staticAfter.rotation] !== direction + ) { + // Wrong rotation + continue; + } + + // All good, can remove + this.root.logic.tryDeleteBuilding(entityBefore); + this.root.logic.tryDeleteBuilding(entityAfter); + } + } + } + /** * * @param {Entity} entity From 512a1eb0d3f11e6a0ef0a94ac0e5a7f8d70a6a64 Mon Sep 17 00:00:00 2001 From: tobspr Date: Tue, 16 Jun 2020 14:09:05 +0200 Subject: [PATCH 6/6] Update changelog --- artwork/steam/announcement.png | Bin 13135 -> 16815 bytes artwork/steam/announcement.psd | 4 ++-- src/js/changelog.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/artwork/steam/announcement.png b/artwork/steam/announcement.png index 0f81fc7ff966b7dcaee6bd5f919048a5f1f642fe..c9a0446277deede87d6b7470490869403235ffc6 100644 GIT binary patch delta 13409 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 delta 9513 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