From 0a1004aa7a3112463d9c8f2b26a9544041a2a57a Mon Sep 17 00:00:00 2001 From: Andrea Nardecchia <39597085+Doc-Ninja@users.noreply.github.com> Date: Wed, 23 Jun 2021 08:03:42 +0200 Subject: [PATCH 1/6] Italian translation addendum (#1218) * Italian translation addendum Added translation for the last added part * Italian translation addendum Fixed YAML warning * Italian translation addendum Fixed YAML error * Fixed missing suff, again (italian) Translated a missing section * Fix typos * Typo --- translations/base-it.yaml | 53 ++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/translations/base-it.yaml b/translations/base-it.yaml index 07b98f0f..ace9f13d 100644 --- a/translations/base-it.yaml +++ b/translations/base-it.yaml @@ -262,8 +262,8 @@ dialogs: title: Inserisci codice desc: Inserisci il codice del puzzle per caricarlo. puzzleDelete: - title: Delete Puzzle? - desc: Are you sure you want to delete ''? This can not be undone! + title: Cancellare il puzzle? + desc: Sei sicuro di voler cancellare '<title>'? Questa azione non può essere annullata! ingame: keybindingsOverlay: moveMap: Sposta @@ -455,7 +455,7 @@ ingame: obiettivi</strong> - 3. Una volta che un accettore di obiettivi riceve una forma per un certo lasso di tempo, lo <strong>salva come obiettivo</strong> che - il giocatore dovrà poi produrre (Indicato dal <strong>aimbolo + il giocatore dovrà poi produrre (Indicato dal <strong>simbolo verde</strong>). - 4. Clicca il <strong>bottone di blocco</strong> su un edificio per disabilitarlo. @@ -694,16 +694,16 @@ buildings: livello elettrico come oggetti sul livello normale. constant_producer: default: - name: Constant Producer - description: Constantly outputs a specified shape or color. + name: Produttore costante + description: Produce costantemente una forma o un colore specificati. goal_acceptor: default: - name: Goal Acceptor - description: Deliver shapes to the goal acceptor to set them as a goal. + name: Accettore di obiettivi. + description: Consegna forme all'accettore di obiettivi per impostarli come obiettivo. block: default: - name: Block - description: Allows you to block a tile. + name: Blocco + description: Blocca una casella. storyRewards: reward_cutter_and_trash: title: Taglio forme @@ -829,7 +829,7 @@ storyRewards: letto? Prova a mostrarlo su di un display!" reward_constant_signal: title: Sengale costante - desc: Hai sblocatto l'edificio <strong>segnale costante</strong> sul livello + desc: Hai sbloccato l'edificio <strong>segnale costante</strong> sul livello elettrico! È utile collegarlo ai <strong>filtri di oggetti</strong> per esempio.<br><br> Il segnale costante può emettere una <strong>forma</strong>, un <strong>colore</strong> o un @@ -1123,7 +1123,7 @@ keybindings: rotateToLeft: "Ruota: punta a sinistra" constant_producer: Produttore costante goal_acceptor: Accettore di obiettivi - block: Bloca + block: Blocco massSelectClear: Sgombra nastri about: title: Riguardo questo gioco @@ -1138,7 +1138,8 @@ about: La colonna sonora è stata composta da<a href="https://soundcloud.com/pettersumelius" target="_blank"> Peppsen</a> - È un grande.<br><br> - Per finire, grazie di cuore al mio migliore amico <a href="https://github.com/niklas-dahl" target="_blank">Niklas</a> - Senza le nostre sessioni su factorio questo gioco non sarebbe mai esistito. + Per finire, grazie di cuore al mio migliore amico <a href="https://github.com/niklas-dahl" target="_blank">Niklas</a> - + Senza le nostre sessioni su factorio questo gioco non sarebbe mai esistito. changelog: title: Registro modifiche demo: @@ -1241,14 +1242,14 @@ puzzleMenu: easy: Facili hard: Difficili completed: Completati - medium: Medium - official: Official - trending: Trending today - trending-weekly: Trending weekly - categories: Categories - difficulties: By Difficulty - account: My Puzzles - search: Search + medium: Medi + official: Ufficiali + trending: Più popolari di oggi + trending-weekly: Più popolari della settimana + categories: Categorie + difficulties: Per difficoltà + account: I miei puzzle + search: Cerca validation: title: Puzzle non valido noProducers: Per favore posiziona un Produttore costante! @@ -1264,9 +1265,9 @@ puzzleMenu: produttori costanti non consegnino direttamente agli accettori di obiettivi. difficulties: - easy: Easy - medium: Medium - hard: Hard + easy: Facile + medium: Medio + hard: Difficile backendErrors: ratelimit: Stai facendo troppe azioni velocemente. Per favore attendi un attimo. invalid-api-key: Comunicazione con il backend fallita, per favore prova ad @@ -1290,6 +1291,6 @@ backendErrors: bad-payload: La richiesta contiene dati non validi. bad-building-placement: Il tuo puzzle contiene edifici non validi. timeout: La richiesta è scaduta. - too-many-likes-already: The puzzle alreay got too many likes. If you still want - to remove it, please contact support@shapez.io! - no-permission: You do not have the permission to perform this action. + too-many-likes-already: Questo puzzle ha già ricevuto troppi "mi piace". Se vuoi ancora + rimuoverlo, per favore contatta support@shapez.io! + no-permission: Non hai i permessi per eseguire questa azione. From 53b321422a3a6721907b9ac1ea1818b936bfc7c4 Mon Sep 17 00:00:00 2001 From: lotgood <31810171+lotgood@users.noreply.github.com> Date: Wed, 23 Jun 2021 15:04:06 +0900 Subject: [PATCH 2/6] Update base-kor.yaml (#1219) make to 100% translite --- translations/base-kor.yaml | 47 +++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/translations/base-kor.yaml b/translations/base-kor.yaml index 5aa2cb3d..3e5139f6 100644 --- a/translations/base-kor.yaml +++ b/translations/base-kor.yaml @@ -175,7 +175,7 @@ dialogs: title: 아이템 설정 puzzleLoadFailed: title: 퍼즐 불러오기 실패 - desc: "Unfortunately the puzzles could not be loaded:" + desc: "불행히도 이 퍼즐은 불러오는데 실패하였습니다:" submitPuzzle: title: 퍼즐 보내기 descName: "퍼즐에 이름을 지어 주세요:" @@ -226,8 +226,8 @@ dialogs: title: 짧은 키 입력 desc: 불러올 퍼즐의 짧은 키를 입력해 주세요. puzzleDelete: - title: Delete Puzzle? - desc: Are you sure you want to delete '<title>'? This can not be undone! + title: 퍼즐을 지우시겠습니까? + desc: 정말로 퍼즐:'<title>'을 지우시겠습니까? 이것은 돌릴수 없습니다! ingame: keybindingsOverlay: moveMap: 이동 @@ -956,14 +956,14 @@ keybindings: comparator: 비교기 item_producer: 아이템 생성기 (샌드박스) copyWireValue: "전선: 커서 아래 값 복사" - rotateToUp: "Rotate: Point Up" - rotateToDown: "Rotate: Point Down" - rotateToRight: "Rotate: Point Right" - rotateToLeft: "Rotate: Point Left" + rotateToUp: "위로 향하게 회전" + rotateToDown: "아래로 향하게 회전" + rotateToRight: "오른쪽으로 향하게 회전" + rotateToLeft: "아래쪽으로 향하게 회전" constant_producer: 일정 생성기 - goal_acceptor: Goal Acceptor - block: Block - massSelectClear: Clear belts + goal_acceptor: 목표 수집기 + block: 블록 + massSelectClear: 밸트를 클리어합니다 about: title: 게임 정보 body: >- @@ -1062,14 +1062,14 @@ puzzleMenu: easy: 쉬움 hard: 어러움 completed: 완료함 - medium: Medium - official: Official - trending: Trending today - trending-weekly: Trending weekly - categories: Categories - difficulties: By Difficulty - account: My Puzzles - search: Search + medium: 중간 + official: 공식 + trending: 오늘의 인기 + trending-weekly: 이 주의 인기 + categories: 카테고리 + difficulties: 어려운 순서로 + account: 내 퍼즐들 + search: 검색 validation: title: 잘못된 퍼즐 noProducers: 일정 생성기를 배치해주세요! @@ -1079,9 +1079,9 @@ puzzleMenu: buildingOutOfBounds: 하나 이상의 건물이 지을 수 있는 영역 밖에 존재합니다. 영역을 늘리거나 건물을 제거하세요. autoComplete: 퍼즐이 스스로 완료됩니다! 일정 생성기가 만든 모양이 목표 수집기로 바로 들어가고 있는건 아닌지 확인해주세요. difficulties: - easy: Easy - medium: Medium - hard: Hard + easy: 쉬움 + medium: 중간 + hard: 어려움 backendErrors: ratelimit: 너무 빠른 시간 내 작업을 반복하고 있습니다. 조금만 기다려 주세요. invalid-api-key: 백엔드 서버와 통신할 수 없습니다. 게임을 업데이트하거나 재시작해 주세요 (잘못된 API 키). @@ -1102,6 +1102,5 @@ backendErrors: bad-payload: 요청이 잘못된 데이터를 포함하고 있습니다. bad-building-placement: 퍼즐에 잘못된 곳에 위치한 건물이 있습니다. timeout: 요청 시간이 초과되었습니다. - too-many-likes-already: The puzzle alreay got too many likes. If you still want - to remove it, please contact support@shapez.io! - no-permission: You do not have the permission to perform this action. + too-many-likes-already: 이 퍼즐은 이미 너무 많은 하트를 받았습니다. 그래도 부족하다면 support@shapez.io로 문의하세요! + no-permission: 이 작업을 할 권한이 없습니다 From 68f208181d3dca835547ec5ba0f55974e53646c0 Mon Sep 17 00:00:00 2001 From: "Thomas (DJ1TJOO)" <44841260+DJ1TJOO@users.noreply.github.com> Date: Wed, 23 Jun 2021 08:04:28 +0200 Subject: [PATCH 3/6] Added puzzle translations (#1220) Removed inconsistencies in formal and informal language --- translations/base-nl.yaml | 48 +++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/translations/base-nl.yaml b/translations/base-nl.yaml index 7b0ba3cc..a6e847a2 100644 --- a/translations/base-nl.yaml +++ b/translations/base-nl.yaml @@ -207,7 +207,7 @@ dialogs: title: Puzzel indienen descName: "Geef je puzzel een naam:" descIcon: "Voer een unieke vorm sleutel in, die wordt weergegeven als het icoon - van uw puzzel (je kunt ze <link>hier</link> genereren, of je kunt er + van je puzzel (je kunt ze <link>hier</link> genereren, of je kunt er een kiezen van de willekeurig voorgestelde vormen hieronder):" placeholderName: Puzzel Naam puzzleResizeBadBuildings: @@ -256,13 +256,13 @@ dialogs: desc: De puzzel is gemarkeerd. puzzleReportError: title: Melden mislukt - desc: "Uw melding kan niet worden verwerkt:" + desc: "Je melding kan niet worden verwerkt:" puzzleLoadShortKey: title: Voer een vorm sleutel in desc: Voer de vorm sleutel van de puzzel in om deze te laden. puzzleDelete: - title: Delete Puzzle? - desc: Are you sure you want to delete '<title>'? This can not be undone! + title: Puzzel verwijderen? + desc: Weet je zeker dat je '<title>' wilt verwijderen? Dit kan niet ongedaan gemaakt worden! ingame: keybindingsOverlay: moveMap: Beweeg rond de wereld @@ -1137,7 +1137,7 @@ demo: settingNotAvailable: Niet beschikbaar in de demo. tips: - De HUB accepteert elke vorm van invoer, niet alleen de huidige vorm! - - Zorg ervoor dat uw fabrieken modulair zijn - het loont! + - Zorg ervoor dat je fabrieken modulair zijn - het loont! - Bouw niet te dicht bij de HUB, anders wordt het een enorme chaos! - Als het stapelen niet werkt, probeer dan de invoeren om te wisselen. - Je kunt de richting van de lopende band planner wijzigen door op <b>R</b> @@ -1173,25 +1173,25 @@ tips: - Vormontginningen die verder van de HUB verwijderd zijn, zijn complexer. - Machines hebben een beperkte snelheid, verdeel ze voor maximale efficiëntie. - - Gebruik verdelers om uw efficiëntie te maximaliseren. + - Gebruik verdelers om je efficiëntie te maximaliseren. - Organisatie is belangrijk. Probeer de lopende banden niet te veel over te steken. - Plan van tevoren, anders wordt het een enorme chaos! - - Verwijder uw oude fabrieken niet! Je hebt ze nodig om upgrades te + - Verwijder je oude fabrieken niet! Je hebt ze nodig om upgrades te ontgrendelen. - Probeer in je eentje level 20 te verslaan voordat je hulp zoekt! - Maak de dingen niet ingewikkeld, probeer eenvoudig te blijven en je zult ver komen. - - Mogelijk zul je later in het spel fabrieken moeten hergebruiken. Plan uw + - Mogelijk zul je later in het spel fabrieken moeten hergebruiken. Plan je fabrieken zodat ze herbruikbaar zijn. - Soms kun je een gewenste vorm op de kaart vinden zonder deze met stapelaars te maken. - Volle windmolens kunnen nooit op natuurlijke wijze spawnen. - - Kleur uw vormen voordat je ze knipt voor maximale efficiëntie. + - Kleur je vormen voordat je ze knipt voor maximale efficiëntie. - Bij modules is ruimte slechts een beleving; een zorg voor sterfelijke mannen. - Maak een aparte blueprint fabriek. Ze zijn belangrijk voor modules. - - Bekijk de kleurenmixer eens wat beter, en uw vragen worden beantwoord. + - Bekijk de kleurenmixer eens wat beter, en je vragen worden beantwoord. - Gebruik <b>CTRL</b> + klik om een gebied te selecteren. - Te dicht bij de HUB bouwen kan latere projecten in de weg staan. - Met het speldpictogram naast elke vorm in de upgradelijst zet deze vast op @@ -1204,11 +1204,11 @@ tips: - Dit spel heeft veel handige sneltoetsen! Bekijk zeker de instellingenpagina. - Dit spel heeft veel instellingen, bekijk ze zeker! - - De markering naar uw HUB heeft een klein kompas om de richting aan te + - De markering naar je HUB heeft een klein kompas om de richting aan te geven! - Om de lopende banden leeg te maken, kun je een gebied kopiëren en plakken op dezelfde locatie. - - Druk op F4 om uw FPS en Tick Rate weer te geven. + - Druk op F4 om je FPS en Tick Rate weer te geven. - Druk twee keer op F4 om de tegel van je muis en camera weer te geven. - Je kan aan de linkerkant op een vastgezette vorm klikken om deze los te maken. @@ -1222,6 +1222,7 @@ puzzleMenu: validatingPuzzle: Puzzel Valideren submittingPuzzle: Puzzel Indienen noPuzzles: Er zijn momenteel geen puzzels in deze sectie. + dlcHint: Heb je de DLC al gekocht? Zorg ervoor dat het is geactiveerd door met de rechtermuisknop op shapez.io in uw bibliotheek te klikken, Eigenschappen > DLC's te selecteren. categories: levels: Levels new: Nieuw @@ -1231,13 +1232,13 @@ puzzleMenu: hard: Moeilijk completed: Voltooid medium: Medium - official: Official - trending: Trending today - trending-weekly: Trending weekly - categories: Categories - difficulties: By Difficulty - account: My Puzzles - search: Search + official: Officieell + trending: Trending vandaag + trending-weekly: Trending wekelijks + categories: Categorieën + difficulties: Op Moeilijkheidsgraad + account: Mijn Puzzels + search: Zoeken validation: title: Ongeldige Puzzel noProducers: Plaats alstublieft een Constante Producent! @@ -1251,9 +1252,9 @@ puzzleMenu: autoComplete: Je puzzel voltooit zichzelf automatisch! Zorg ervoor dat je Constante Producenten niet rechtstreeks aan je Ontvangers leveren. difficulties: - easy: Easy + easy: Makkelijk medium: Medium - hard: Hard + hard: Moeilijk backendErrors: ratelimit: Je voert je handelingen te vaak uit. Wacht alstublieft even. invalid-api-key: Kan niet communiceren met de servers, probeer alstublieft het @@ -1277,6 +1278,5 @@ backendErrors: bad-payload: Het verzoek bevat ongeldige gegevens. bad-building-placement: Je puzzel bevat ongeldig geplaatste gebouwen. timeout: Het verzoek is verlopen. - too-many-likes-already: The puzzle alreay got too many likes. If you still want - to remove it, please contact support@shapez.io! - no-permission: You do not have the permission to perform this action. + too-many-likes-already: De puzzel heeft al te veel likes. Als je het nog steeds wilt verwijderen, neem dan contact op support@shapez.io! + no-permission: Je bent niet gemachtigd om deze actie uit te voeren. From 6efbdc6ad13d9735253da161aa18238313ee4b90 Mon Sep 17 00:00:00 2001 From: Sense101 <67970865+Sense101@users.noreply.github.com> Date: Thu, 24 Jun 2021 17:39:50 +0100 Subject: [PATCH 4/6] Fix for cheating puzzles by quickly switching belts (#1226) * added the new splitter * Update base-en.yaml * adjusted how acceptor works to fix macro * fixed a minor bug * applied changes to the puzzle-editor-review script * minor cleanups --- src/js/core/config.js | 4 +-- src/js/game/components/goal_acceptor.js | 21 +++++++++----- src/js/game/hud/parts/puzzle_editor_review.js | 4 +-- src/js/game/systems/goal_acceptor.js | 22 +++++++------- src/js/game/systems/item_processor.js | 29 ++++++++++--------- 5 files changed, 45 insertions(+), 35 deletions(-) diff --git a/src/js/core/config.js b/src/js/core/config.js index b4f36af5..a4793384 100644 --- a/src/js/core/config.js +++ b/src/js/core/config.js @@ -72,8 +72,8 @@ export const globalConfig = { readerAnalyzeIntervalSeconds: 10, - goalAcceptorMinimumDurationSeconds: 5, - goalAcceptorsPerProducer: 4.5, + goalAcceptorItemsRequired: 10, + goalAcceptorsPerProducer: 5, puzzleModeSpeed: 3, puzzleMinBoundsSize: 2, puzzleMaxBoundsSize: 20, diff --git a/src/js/game/components/goal_acceptor.js b/src/js/game/components/goal_acceptor.js index 87c55501..485f385b 100644 --- a/src/js/game/components/goal_acceptor.js +++ b/src/js/game/components/goal_acceptor.js @@ -31,19 +31,26 @@ export class GoalAcceptorComponent extends Component { clear() { // the last items we delivered - /** @type {{ item: BaseItem; time: number; }[]} */ - this.deliveryHistory = []; + /** @type {{ item: BaseItem; time: number; }} */ + this.lastDelivery = null; + + this.currentDeliveredItems = 0; // Used for animations this.displayPercentage = 0; } - getRequiredDeliveryHistorySize() { + // clears items but doesn't instantly reset the progress bar + clearItems() { + this.lastDelivery = null; + + this.currentDeliveredItems = 0; + } + + getRequiredSecondsPerItem() { return ( - (globalConfig.puzzleModeSpeed * - globalConfig.goalAcceptorMinimumDurationSeconds * - globalConfig.beltSpeedItemsPerSecond) / - globalConfig.goalAcceptorsPerProducer + globalConfig.goalAcceptorsPerProducer / + (globalConfig.puzzleModeSpeed * globalConfig.beltSpeedItemsPerSecond) ); } } diff --git a/src/js/game/hud/parts/puzzle_editor_review.js b/src/js/game/hud/parts/puzzle_editor_review.js index 68f5360c..727006d6 100644 --- a/src/js/game/hud/parts/puzzle_editor_review.js +++ b/src/js/game/hud/parts/puzzle_editor_review.js @@ -216,8 +216,8 @@ export class HUDPuzzleEditorReview extends BaseHUDPart { if (!goalComp.item) { return T.puzzleMenu.validation.goalAcceptorNoItem; } - const required = goalComp.getRequiredDeliveryHistorySize(); - if (goalComp.deliveryHistory.length < required) { + const required = globalConfig.goalAcceptorItemsRequired; + if (goalComp.currentDeliveredItems < required) { return T.puzzleMenu.validation.goalAcceptorRateNotMet; } } diff --git a/src/js/game/systems/goal_acceptor.js b/src/js/game/systems/goal_acceptor.js index ff3f08f3..f7ac16a6 100644 --- a/src/js/game/systems/goal_acceptor.js +++ b/src/js/game/systems/goal_acceptor.js @@ -24,13 +24,15 @@ export class GoalAcceptorSystem extends GameSystemWithFilter { const entity = this.allEntities[i]; const goalComp = entity.components.GoalAcceptor; - // filter the ones which are no longer active, or which are not the same - goalComp.deliveryHistory = goalComp.deliveryHistory.filter( - d => - now - d.time < globalConfig.goalAcceptorMinimumDurationSeconds && d.item === goalComp.item - ); + if (!goalComp.lastDelivery) { + continue; + } + + if (now - goalComp.lastDelivery.time > goalComp.getRequiredSecondsPerItem()) { + goalComp.clearItems(); + } - if (goalComp.deliveryHistory.length < goalComp.getRequiredDeliveryHistorySize()) { + if (goalComp.currentDeliveredItems < globalConfig.goalAcceptorItemsRequired) { allAccepted = false; } } @@ -64,8 +66,8 @@ export class GoalAcceptorSystem extends GameSystemWithFilter { const staticComp = contents[i].components.StaticMapEntity; const item = goalComp.item; - const requiredItemsForSuccess = goalComp.getRequiredDeliveryHistorySize(); - const percentage = clamp(goalComp.deliveryHistory.length / requiredItemsForSuccess, 0, 1); + const requiredItemsForSuccess = globalConfig.goalAcceptorItemsRequired; + const percentage = clamp(goalComp.currentDeliveredItems / requiredItemsForSuccess, 0, 1); const center = staticComp.getTileSpaceBounds().getCenter().toWorldSpace(); if (item) { @@ -78,7 +80,7 @@ export class GoalAcceptorSystem extends GameSystemWithFilter { ); } - const isValid = item && goalComp.deliveryHistory.length >= requiredItemsForSuccess; + const isValid = item && goalComp.currentDeliveredItems >= requiredItemsForSuccess; parameters.context.translate(center.x, center.y); parameters.context.rotate((staticComp.rotation / 180) * Math.PI); @@ -90,7 +92,7 @@ export class GoalAcceptorSystem extends GameSystemWithFilter { // progress arc - goalComp.displayPercentage = lerp(goalComp.displayPercentage, percentage, 0.3); + goalComp.displayPercentage = lerp(goalComp.displayPercentage, percentage, 0.2); const startAngle = Math.PI * 0.595; const maxAngle = Math.PI * 1.82; diff --git a/src/js/game/systems/item_processor.js b/src/js/game/systems/item_processor.js index e06d4a21..3794473f 100644 --- a/src/js/game/systems/item_processor.js +++ b/src/js/game/systems/item_processor.js @@ -1,3 +1,4 @@ +import { globalConfig } from "../../core/config"; import { BaseItem } from "../base_item"; import { enumColorMixingResults, enumColors } from "../colors"; import { @@ -572,23 +573,23 @@ export class ItemProcessorSystem extends GameSystemWithFilter { const item = payload.items[0].item; const now = this.root.time.now(); + if (goalComp.item && !item.equals(goalComp.item)) { + goalComp.clearItems(); + } else { + goalComp.currentDeliveredItems = Math.min( + goalComp.currentDeliveredItems + 1, + globalConfig.goalAcceptorItemsRequired + ); + } + if (this.root.gameMode.getIsEditor()) { // while playing in editor, assign the item goalComp.item = payload.items[0].item; - goalComp.deliveryHistory.push({ - item, - time: now, - }); - } else { - // otherwise, make sure it is the same, otherwise reset - if (item.equals(goalComp.item)) { - goalComp.deliveryHistory.push({ - item, - time: now, - }); - } else { - goalComp.deliveryHistory = []; - } } + + goalComp.lastDelivery = { + item, + time: now, + }; } } From 1c23549b392acd8447f8ec31e03e6226b07a59c0 Mon Sep 17 00:00:00 2001 From: Sense101 <67970865+Sense101@users.noreply.github.com> Date: Thu, 24 Jun 2021 17:41:37 +0100 Subject: [PATCH 5/6] Added a button to clear all non fixed buildings in both modes (#1229) * added the new splitter * Update base-en.yaml * added clear buildings button to both game modes * Minor cleanups and added translation for new button --- .../ingame_hud/puzzle_editor_settings.scss | 9 +++++ src/css/ingame_hud/puzzle_play_settings.scss | 2 +- .../game/hud/parts/puzzle_editor_settings.js | 34 +++++++++++++++++-- src/js/game/hud/parts/puzzle_play_settings.js | 31 +++++++++++++++-- translations/base-en.yaml | 1 + 5 files changed, 70 insertions(+), 7 deletions(-) diff --git a/src/css/ingame_hud/puzzle_editor_settings.scss b/src/css/ingame_hud/puzzle_editor_settings.scss index 70d16123..9d093c42 100644 --- a/src/css/ingame_hud/puzzle_editor_settings.scss +++ b/src/css/ingame_hud/puzzle_editor_settings.scss @@ -57,6 +57,15 @@ } } } + + > .buildingsButton { + display: grid; + align-items: center; + @include S(margin-top, 4px); + > button { + @include SuperSmallText; + } + } } } } diff --git a/src/css/ingame_hud/puzzle_play_settings.scss b/src/css/ingame_hud/puzzle_play_settings.scss index 13e25c61..b53d0829 100644 --- a/src/css/ingame_hud/puzzle_play_settings.scss +++ b/src/css/ingame_hud/puzzle_play_settings.scss @@ -13,7 +13,7 @@ > .section { display: grid; - @include S(grid-gap, 10px); + @include S(grid-gap, 5px); grid-auto-flow: row; > button { diff --git a/src/js/game/hud/parts/puzzle_editor_settings.js b/src/js/game/hud/parts/puzzle_editor_settings.js index cf283a9b..bcd2c85c 100644 --- a/src/js/game/hud/parts/puzzle_editor_settings.js +++ b/src/js/game/hud/parts/puzzle_editor_settings.js @@ -9,6 +9,8 @@ import { makeDiv } from "../../../core/utils"; import { T } from "../../../translations"; import { StaticMapEntityComponent } from "../../components/static_map_entity"; import { BaseHUDPart } from "../base_hud_part"; +import { gMetaBuildingRegistry } from "../../../core/global_registries"; +import { MetaBlockBuilding } from "../../buildings/block"; const logger = createLogger("puzzle-editor"); @@ -43,8 +45,13 @@ export class HUDPuzzleEditorSettings extends BaseHUDPart { <div class="buttonBar"> <button class="styledButton trim">${T.ingame.puzzleEditorSettings.trimZone}</button> - <button class="styledButton clear">${T.ingame.puzzleEditorSettings.clearItems}</button> + <button class="styledButton clearItems">${T.ingame.puzzleEditorSettings.clearItems}</button> </div> + + <div class="buildingsButton"> + <button class="styledButton clearBuildings">${T.ingame.puzzleEditorSettings.clearBuildings}</button> + </div> + </div>` ); @@ -53,14 +60,35 @@ export class HUDPuzzleEditorSettings extends BaseHUDPart { bind(".zoneHeight .minus", () => this.modifyZone(0, -1)); bind(".zoneHeight .plus", () => this.modifyZone(0, 1)); bind("button.trim", this.trim); - bind("button.clear", this.clear); + bind("button.clearItems", this.clearItems); + bind("button.clearBuildings", this.clearBuildings); } } - clear() { + clearItems() { this.root.logic.clearAllBeltsAndItems(); } + clearBuildings() { + for (const entity of this.root.entityMgr.getAllWithComponent(StaticMapEntityComponent)) { + const staticComp = entity.components.StaticMapEntity; + const signalComp = entity.components.ConstantSignal; + const goalComp = entity.components.GoalAcceptor; + + if ( + signalComp || + goalComp || + staticComp.getMetaBuilding().id === gMetaBuildingRegistry.findByClass(MetaBlockBuilding).id + ) { + continue; + } + + this.root.map.removeStaticEntity(entity); + this.root.entityMgr.destroyEntity(entity); + } + this.root.entityMgr.processDestroyList(); + } + trim() { // Now, find the center const buildings = this.root.entityMgr.entities.slice(); diff --git a/src/js/game/hud/parts/puzzle_play_settings.js b/src/js/game/hud/parts/puzzle_play_settings.js index 168c3de2..88034f72 100644 --- a/src/js/game/hud/parts/puzzle_play_settings.js +++ b/src/js/game/hud/parts/puzzle_play_settings.js @@ -1,6 +1,9 @@ +import { gMetaBuildingRegistry } from "../../../core/global_registries"; import { createLogger } from "../../../core/logging"; import { makeDiv } from "../../../core/utils"; import { T } from "../../../translations"; +import { MetaBlockBuilding } from "../../buildings/block"; +import { StaticMapEntityComponent } from "../../components/static_map_entity"; import { BaseHUDPart } from "../base_hud_part"; const logger = createLogger("puzzle-play"); @@ -17,19 +20,41 @@ export class HUDPuzzlePlaySettings extends BaseHUDPart { null, ["section"], ` - <button class="styledButton clear">${T.ingame.puzzleEditorSettings.clearItems}</button> + <button class="styledButton clearItems">${T.ingame.puzzleEditorSettings.clearItems}</button> + <button class="styledButton clearBuildings">${T.ingame.puzzleEditorSettings.clearBuildings}</button> ` ); - bind("button.clear", this.clear); + bind("button.clearItems", this.clearItems); + bind("button.clearBuildings", this.clearBuildings); } } - clear() { + clearItems() { this.root.logic.clearAllBeltsAndItems(); } + clearBuildings() { + for (const entity of this.root.entityMgr.getAllWithComponent(StaticMapEntityComponent)) { + const staticComp = entity.components.StaticMapEntity; + const signalComp = entity.components.ConstantSignal; + const goalComp = entity.components.GoalAcceptor; + + if ( + signalComp || + goalComp || + staticComp.getMetaBuilding().id === gMetaBuildingRegistry.findByClass(MetaBlockBuilding).id + ) { + continue; + } + + this.root.map.removeStaticEntity(entity); + this.root.entityMgr.destroyEntity(entity); + } + this.root.entityMgr.processDestroyList(); + } + initialize() { this.visible = true; } diff --git a/translations/base-en.yaml b/translations/base-en.yaml index 80a6deb1..bf5a1890 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -632,6 +632,7 @@ ingame: zoneHeight: Height trimZone: Trim clearItems: Clear Items + clearBuildings: Clear Buildings share: Share report: Report From f7cc313ff4ccda53237cb05eb79440c312e754ff Mon Sep 17 00:00:00 2001 From: Sense101 <67970865+Sense101@users.noreply.github.com> Date: Thu, 24 Jun 2021 17:45:48 +0100 Subject: [PATCH 6/6] Add back copy/paste in puzzle mode. (#1230) * added the new splitter * Update base-en.yaml * added the new splitter Update changelog and update translation regarding 20 upgrade tiers, closes #907 * Update base-en.yaml * Added back copy/paste in puzzle mode * fixed rotating non-rotatable buildings as blueprints and made blocker non-rotatable --- src/js/game/blueprint.js | 7 +++++-- src/js/game/game_mode.js | 4 ++-- src/js/game/hud/parts/blueprint_placer.js | 14 +++++++++----- src/js/game/hud/parts/mass_selector.js | 15 +++++++++++++++ src/js/game/meta_building.js | 5 ++--- src/js/game/modes/puzzle.js | 8 ++++++-- 6 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/js/game/blueprint.js b/src/js/game/blueprint.js index 3e7cdaa6..a2aa7186 100644 --- a/src/js/game/blueprint.js +++ b/src/js/game/blueprint.js @@ -101,8 +101,11 @@ export class Blueprint { const entity = this.entities[i]; const staticComp = entity.components.StaticMapEntity; - staticComp.rotation = (staticComp.rotation + 90) % 360; - staticComp.originalRotation = (staticComp.originalRotation + 90) % 360; + if (staticComp.getMetaBuilding().getIsRotateable()) { + staticComp.rotation = (staticComp.rotation + 90) % 360; + staticComp.originalRotation = (staticComp.originalRotation + 90) % 360; + } + staticComp.origin = staticComp.origin.rotateFastMultipleOf90(90); } } diff --git a/src/js/game/game_mode.js b/src/js/game/game_mode.js index 5eca211a..bb60d8a6 100644 --- a/src/js/game/game_mode.js +++ b/src/js/game/game_mode.js @@ -166,8 +166,8 @@ export class GameMode extends BasicSerializableObject { } /** @returns {boolean} */ - getSupportsCopyPaste() { - return true; + getHasFreeCopyPaste() { + return false; } /** @returns {boolean} */ diff --git a/src/js/game/hud/parts/blueprint_placer.js b/src/js/game/hud/parts/blueprint_placer.js index 54e2e3b7..e006d24a 100644 --- a/src/js/game/hud/parts/blueprint_placer.js +++ b/src/js/game/hud/parts/blueprint_placer.js @@ -27,6 +27,8 @@ export class HUDBlueprintPlacer extends BaseHUDPart { } initialize() { + this.isCopyPasteFree = this.root.gameMode.getHasFreeCopyPaste(); + this.root.hud.signals.buildingsSelectedForCopy.add(this.createBlueprintFromBuildings, this); /** @type {TypedTrackedState<Blueprint?>} */ @@ -82,7 +84,7 @@ export class HUDBlueprintPlacer extends BaseHUDPart { update() { const currentBlueprint = this.currentBlueprint.get(); - this.domAttach.update(currentBlueprint && currentBlueprint.getCost() > 0); + this.domAttach.update(!this.isCopyPasteFree && currentBlueprint && currentBlueprint.getCost() > 0); this.trackedCanAfford.set(currentBlueprint && currentBlueprint.canAfford(this.root)); } @@ -114,7 +116,7 @@ export class HUDBlueprintPlacer extends BaseHUDPart { return; } - if (!blueprint.canAfford(this.root)) { + if (!this.isCopyPasteFree && !blueprint.canAfford(this.root)) { this.root.soundProxy.playUiError(); return; } @@ -122,8 +124,10 @@ export class HUDBlueprintPlacer extends BaseHUDPart { const worldPos = this.root.camera.screenToWorld(pos); const tile = worldPos.toTileSpace(); if (blueprint.tryPlace(this.root, tile)) { - const cost = blueprint.getCost(); - this.root.hubGoals.takeShapeByKey(this.root.gameMode.getBlueprintShapeKey(), cost); + if (!this.isCopyPasteFree) { + const cost = blueprint.getCost(); + this.root.hubGoals.takeShapeByKey(this.root.gameMode.getBlueprintShapeKey(), cost); + } this.root.soundProxy.playUi(SOUNDS.placeBuilding); } return STOP_PROPAGATION; @@ -131,7 +135,7 @@ export class HUDBlueprintPlacer extends BaseHUDPart { } /** - * Mose move handler + * Mouse move handler */ onMouseMove() { // Prevent movement while blueprint is selected diff --git a/src/js/game/hud/parts/mass_selector.js b/src/js/game/hud/parts/mass_selector.js index ab933da3..b8283d55 100644 --- a/src/js/game/hud/parts/mass_selector.js +++ b/src/js/game/hud/parts/mass_selector.js @@ -1,5 +1,6 @@ import { globalConfig } from "../../../core/config"; import { DrawParameters } from "../../../core/draw_parameters"; +import { gMetaBuildingRegistry } from "../../../core/global_registries"; import { createLogger } from "../../../core/logging"; import { STOP_PROPAGATION } from "../../../core/signal"; import { formatBigNumberFull } from "../../../core/utils"; @@ -7,6 +8,8 @@ import { Vector } from "../../../core/vector"; import { ACHIEVEMENTS } from "../../../platform/achievement_provider"; import { T } from "../../../translations"; import { Blueprint } from "../../blueprint"; +import { MetaBlockBuilding } from "../../buildings/block"; +import { MetaConstantProducerBuilding } from "../../buildings/constant_producer"; import { enumMouseButton } from "../../camera"; import { Component } from "../../component"; import { Entity } from "../../entity"; @@ -260,7 +263,14 @@ export class HUDMassSelector extends BaseHUDPart { for (let x = realTileStart.x; x <= realTileEnd.x; ++x) { for (let y = realTileStart.y; y <= realTileEnd.y; ++y) { const contents = this.root.map.getLayerContentXY(x, y, this.root.currentLayer); + if (contents && this.root.logic.canDeleteBuilding(contents)) { + const staticComp = contents.components.StaticMapEntity; + + if (!staticComp.getMetaBuilding().getIsRemovable(this.root)) { + continue; + } + this.selectedUids.add(contents.uid); } } @@ -320,6 +330,11 @@ export class HUDMassSelector extends BaseHUDPart { renderedUids.add(uid); const staticComp = contents.components.StaticMapEntity; + + if (!staticComp.getMetaBuilding().getIsRemovable(this.root)) { + continue; + } + const bounds = staticComp.getTileSpaceBounds(); parameters.context.beginRoundedRect( bounds.x * globalConfig.tileSize + boundsBorder, diff --git a/src/js/game/meta_building.js b/src/js/game/meta_building.js index f3df0b62..7bfbce25 100644 --- a/src/js/game/meta_building.js +++ b/src/js/game/meta_building.js @@ -158,10 +158,9 @@ export class MetaBuilding { /** * Returns whether this building is rotateable - * @param {string} variant * @returns {boolean} */ - getIsRotateable(variant) { + getIsRotateable() { return true; } @@ -243,7 +242,7 @@ export class MetaBuilding { * @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array<Entity> }} */ computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) { - if (!this.getIsRotateable(variant)) { + if (!this.getIsRotateable()) { return { rotation: 0, rotationVariant: 0, diff --git a/src/js/game/modes/puzzle.js b/src/js/game/modes/puzzle.js index 4bf3b1e6..75a47ee2 100644 --- a/src/js/game/modes/puzzle.js +++ b/src/js/game/modes/puzzle.js @@ -7,6 +7,8 @@ import { types } from "../../savegame/serialization"; import { enumGameModeTypes, GameMode } from "../game_mode"; import { HUDPuzzleBackToMenu } from "../hud/parts/puzzle_back_to_menu"; import { HUDPuzzleDLCLogo } from "../hud/parts/puzzle_dlc_logo"; +import { HUDBlueprintPlacer } from "../hud/parts/blueprint_placer"; +import { HUDMassSelector } from "../hud/parts/mass_selector"; export class PuzzleGameMode extends GameMode { static getType() { @@ -30,6 +32,8 @@ export class PuzzleGameMode extends GameMode { this.additionalHudParts = { puzzleBackToMenu: HUDPuzzleBackToMenu, puzzleDlcLogo: HUDPuzzleDLCLogo, + blueprintPlacer: HUDBlueprintPlacer, + massSelector: HUDMassSelector, }; this.zoneWidth = data.zoneWidth || 8; @@ -79,8 +83,8 @@ export class PuzzleGameMode extends GameMode { return false; } - getSupportsCopyPaste() { - return false; + getHasFreeCopyPaste() { + return true; } throughputDoesNotMatter() {