mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-12-17 12:11:51 +00:00
Minor fixes and adjustments for easier use
This commit is contained in:
parent
900fcc8479
commit
a0421ff14b
BIN
res/ui/icons/upload.png
Normal file
BIN
res/ui/icons/upload.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.6 KiB |
@ -1,4 +1,4 @@
|
|||||||
#ingame_HUD_PuzzleEditorDownload {
|
#ingame_HUD_PuzzleImportExport {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@include S(top, 35px);
|
@include S(top, 35px);
|
||||||
left: 50%;
|
left: 50%;
|
||||||
@ -17,12 +17,14 @@
|
|||||||
transition-property: opacity, transform;
|
transition-property: opacity, transform;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
@include PlainText;
|
@include PlainText;
|
||||||
@include S(width, 30px);
|
@include S(width, 20px);
|
||||||
@include S(height, 30px);
|
@include S(height, 20px);
|
||||||
|
margin: 8px 5px;
|
||||||
|
|
||||||
@include DarkThemeInvert;
|
@include DarkThemeInvert;
|
||||||
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: 0.9 !important;
|
opacity: 0.9 !important;
|
||||||
}
|
}
|
||||||
@ -31,7 +33,13 @@
|
|||||||
transform: scale(0.95) !important;
|
transform: scale(0.95) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
& {
|
&.import {
|
||||||
|
/* @load-async */
|
||||||
|
background: uiResource("icons/upload.png") center center / D(15px) no-repeat;
|
||||||
|
//transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.export {
|
||||||
/* @load-async */
|
/* @load-async */
|
||||||
background: uiResource("icons/download.png") center center / D(15px) no-repeat;
|
background: uiResource("icons/download.png") center center / D(15px) no-repeat;
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@
|
|||||||
@import "ingame_hud/puzzle_play_settings";
|
@import "ingame_hud/puzzle_play_settings";
|
||||||
@import "ingame_hud/puzzle_play_metadata";
|
@import "ingame_hud/puzzle_play_metadata";
|
||||||
@import "ingame_hud/puzzle_complete_notification";
|
@import "ingame_hud/puzzle_complete_notification";
|
||||||
@import "ingame_hud/puzzle_editor_download";
|
@import "ingame_hud/puzzle_import_export";
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
$elements:
|
$elements:
|
||||||
@ -85,7 +85,7 @@ ingame_HUD_GameMenu,
|
|||||||
ingame_HUD_KeybindingOverlay,
|
ingame_HUD_KeybindingOverlay,
|
||||||
ingame_HUD_PuzzleBackToMenu,
|
ingame_HUD_PuzzleBackToMenu,
|
||||||
ingame_HUD_PuzzleEditorReview,
|
ingame_HUD_PuzzleEditorReview,
|
||||||
ingame_HUD_PuzzleEditorDownload,
|
ingame_HUD_PuzzleImportExport,
|
||||||
ingame_HUD_PuzzleEditorControls,
|
ingame_HUD_PuzzleEditorControls,
|
||||||
ingame_HUD_PuzzleEditorTitle,
|
ingame_HUD_PuzzleEditorTitle,
|
||||||
ingame_HUD_PuzzleEditorSettings,
|
ingame_HUD_PuzzleEditorSettings,
|
||||||
@ -138,7 +138,7 @@ body.uiHidden {
|
|||||||
#ingame_HUD_PuzzleEditorSettings,
|
#ingame_HUD_PuzzleEditorSettings,
|
||||||
#ingame_HUD_PuzzlePlaySettings,
|
#ingame_HUD_PuzzlePlaySettings,
|
||||||
#ingame_HUD_PuzzleEditorControls,
|
#ingame_HUD_PuzzleEditorControls,
|
||||||
#ingame_HUD_PuzzleEditorDownload,
|
#ingame_HUD_PuzzleImportExport,
|
||||||
#ingame_HUD_PuzzlePlayMetadata,
|
#ingame_HUD_PuzzlePlayMetadata,
|
||||||
#ingame_HUD_Notifications,
|
#ingame_HUD_Notifications,
|
||||||
#ingame_HUD_TutorialHints,
|
#ingame_HUD_TutorialHints,
|
||||||
|
|||||||
@ -302,8 +302,9 @@ export class HUDBaseToolbar extends BaseHUDPart {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {MetaBuilding} metaBuilding
|
* @param {MetaBuilding} metaBuilding
|
||||||
|
* @param {boolean | null} force
|
||||||
*/
|
*/
|
||||||
toggleBuildingLock(metaBuilding) {
|
toggleBuildingLock(metaBuilding, force = null) {
|
||||||
if (!this.visibilityCondition()) {
|
if (!this.visibilityCondition()) {
|
||||||
// Not active
|
// Not active
|
||||||
return;
|
return;
|
||||||
@ -315,7 +316,11 @@ export class HUDBaseToolbar extends BaseHUDPart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handle = this.buildingHandles[metaBuilding.getId()];
|
const handle = this.buildingHandles[metaBuilding.getId()];
|
||||||
|
if (force != null) {
|
||||||
|
handle.puzzleLocked = force;
|
||||||
|
} else {
|
||||||
handle.puzzleLocked = !handle.puzzleLocked;
|
handle.puzzleLocked = !handle.puzzleLocked;
|
||||||
|
}
|
||||||
handle.element.classList.toggle("unlocked", !handle.puzzleLocked);
|
handle.element.classList.toggle("unlocked", !handle.puzzleLocked);
|
||||||
|
|
||||||
const entityManager = this.root.entityMgr;
|
const entityManager = this.root.entityMgr;
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
import { ReadWriteProxy } from "../../../core/read_write_proxy";
|
|
||||||
import { generateFileDownload, makeDiv } from "../../../core/utils";
|
|
||||||
import { PuzzleSerializer } from "../../../savegame/puzzle_serializer";
|
|
||||||
import { T } from "../../../translations";
|
|
||||||
import { BaseHUDPart } from "../base_hud_part";
|
|
||||||
|
|
||||||
export class HUDPuzzleEditorDownload extends BaseHUDPart {
|
|
||||||
constructor(root) {
|
|
||||||
super(root);
|
|
||||||
}
|
|
||||||
|
|
||||||
createElements(parent) {
|
|
||||||
this.element = makeDiv(parent, "ingame_HUD_PuzzleEditorDownload");
|
|
||||||
this.button = document.createElement("button");
|
|
||||||
this.button.classList.add("button");
|
|
||||||
this.element.appendChild(this.button);
|
|
||||||
|
|
||||||
this.trackClicks(this.button, () => {
|
|
||||||
const { ok } = this.root.hud.parts.dialogs.showWarning(
|
|
||||||
T.dialogs.puzzleDownload.title,
|
|
||||||
T.dialogs.puzzleDownload.desc,
|
|
||||||
["cancel", "ok:good:enter"]
|
|
||||||
);
|
|
||||||
ok.add(() => this.downloadPuzzle());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
initialize() {}
|
|
||||||
|
|
||||||
downloadPuzzle() {
|
|
||||||
const serialized = new PuzzleSerializer().generateDumpFromGameRoot(this.root);
|
|
||||||
|
|
||||||
const data = ReadWriteProxy.serializeObject(serialized);
|
|
||||||
const filename = "puzzle.bin";
|
|
||||||
generateFileDownload(filename, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -92,9 +92,8 @@ export class HUDPuzzleEditorSettings extends BaseHUDPart {
|
|||||||
testButton.classList.toggle("disabled", false);
|
testButton.classList.toggle("disabled", false);
|
||||||
}, 140);
|
}, 140);
|
||||||
|
|
||||||
this.root.logic.performBulkOperation(() => {
|
|
||||||
for (const entity of this.root.entityMgr.getAllWithComponent(StaticMapEntityComponent)) {
|
|
||||||
if (this.testMode) {
|
if (this.testMode) {
|
||||||
|
for (const entity of this.root.entityMgr.getAllWithComponent(StaticMapEntityComponent)) {
|
||||||
this.storedSolution.push(entity.clone());
|
this.storedSolution.push(entity.clone());
|
||||||
|
|
||||||
const metaBuilding = entity.components.StaticMapEntity.getMetaBuilding();
|
const metaBuilding = entity.components.StaticMapEntity.getMetaBuilding();
|
||||||
@ -111,26 +110,32 @@ export class HUDPuzzleEditorSettings extends BaseHUDPart {
|
|||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this.root.map.removeStaticEntity(entity);
|
this.root.map.removeStaticEntity(entity);
|
||||||
this.root.entityMgr.destroyEntity(entity);
|
this.root.entityMgr.destroyEntity(entity);
|
||||||
}
|
}
|
||||||
this.root.entityMgr.processDestroyList();
|
this.root.entityMgr.processDestroyList();
|
||||||
|
} else if (this.storedSolution.length) {
|
||||||
|
this.root.logic.performBulkOperation(() => {
|
||||||
|
this.root.logic.performImmutableOperation(() => {
|
||||||
|
for (const entity of this.root.entityMgr.getAllWithComponent(StaticMapEntityComponent)) {
|
||||||
|
this.root.map.removeStaticEntity(entity);
|
||||||
|
this.root.entityMgr.destroyEntity(entity);
|
||||||
|
}
|
||||||
|
this.root.entityMgr.processDestroyList();
|
||||||
|
|
||||||
if (!this.testMode) {
|
|
||||||
for (const entity of this.storedSolution) {
|
for (const entity of this.storedSolution) {
|
||||||
const placedEntity = this.root.logic.tryPlaceEntity(entity);
|
const placedEntity = this.root.logic.tryPlaceEntity(entity);
|
||||||
|
|
||||||
for (const key in entity.components) {
|
for (const key in entity.components) {
|
||||||
/** @type {import("../../../core/global_registries").Component} */ (entity.components[
|
/** @type {import("../../../core/global_registries").Component} */ (entity
|
||||||
key
|
.components[key]).copyAdditionalStateTo(placedEntity.components[key]);
|
||||||
]).copyAdditionalStateTo(placedEntity.components[key]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.storedSolution = [];
|
this.storedSolution = [];
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trim() {
|
trim() {
|
||||||
|
|||||||
118
src/js/game/hud/parts/puzzle_import_export.js
Normal file
118
src/js/game/hud/parts/puzzle_import_export.js
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
import { gMetaBuildingRegistry } from "../../../core/global_registries";
|
||||||
|
import { ReadWriteProxy } from "../../../core/read_write_proxy";
|
||||||
|
import { generateFileDownload, makeDiv, startFileChoose, waitNextFrame } from "../../../core/utils";
|
||||||
|
import { PuzzleSerializer } from "../../../savegame/puzzle_serializer";
|
||||||
|
import { T } from "../../../translations";
|
||||||
|
import { StaticMapEntityComponent } from "../../components/static_map_entity";
|
||||||
|
import { PuzzleGameMode } from "../../modes/puzzle";
|
||||||
|
import { BaseHUDPart } from "../base_hud_part";
|
||||||
|
|
||||||
|
export class HUDPuzzleImportExport extends BaseHUDPart {
|
||||||
|
constructor(root) {
|
||||||
|
super(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
createElements(parent) {
|
||||||
|
this.element = makeDiv(parent, "ingame_HUD_PuzzleImportExport");
|
||||||
|
this.importButton = document.createElement("button");
|
||||||
|
this.importButton.classList.add("button", "import");
|
||||||
|
this.element.appendChild(this.importButton);
|
||||||
|
|
||||||
|
this.exportButton = document.createElement("button");
|
||||||
|
this.exportButton.classList.add("button", "export");
|
||||||
|
this.element.appendChild(this.exportButton);
|
||||||
|
|
||||||
|
this.trackClicks(this.importButton, this.importPuzzle);
|
||||||
|
|
||||||
|
this.trackClicks(this.exportButton, () => {
|
||||||
|
const { yes } = this.root.hud.parts.dialogs.showWarning(
|
||||||
|
T.dialogs.puzzleExport.title,
|
||||||
|
T.dialogs.puzzleExport.desc,
|
||||||
|
["no", "yes:good:enter"]
|
||||||
|
);
|
||||||
|
yes.add(() => this.exportPuzzle());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
initialize() {}
|
||||||
|
|
||||||
|
importPuzzle() {
|
||||||
|
startFileChoose(".bin").then(file => {
|
||||||
|
if (file) {
|
||||||
|
const closeLoader = this.root.hud.parts.dialogs.showLoadingDialog("Importing Puzzle");
|
||||||
|
waitNextFrame().then(() => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.addEventListener("load", event => {
|
||||||
|
const fileContents = String(event.target.result);
|
||||||
|
|
||||||
|
/** @type {import("../../../savegame/savegame_typedefs").PuzzleGameData} */
|
||||||
|
let gameData;
|
||||||
|
|
||||||
|
try {
|
||||||
|
gameData = ReadWriteProxy.deserializeObject(fileContents);
|
||||||
|
} catch (err) {
|
||||||
|
closeLoader();
|
||||||
|
this.root.hud.parts.dialogs.showWarning(T.global.error, String(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mode = /** @type {PuzzleGameMode} */ (this.root.gameMode);
|
||||||
|
let errorText;
|
||||||
|
try {
|
||||||
|
// set excluded buildings first so if we get an error we haven't removed buildings yet
|
||||||
|
const toolbar = this.root.hud.parts.buildingsToolbar;
|
||||||
|
const handles = toolbar.buildingHandles;
|
||||||
|
const ids = gMetaBuildingRegistry.getAllIds();
|
||||||
|
|
||||||
|
for (let i = 0; i < ids.length; ++i) {
|
||||||
|
const handle = handles[ids[i]];
|
||||||
|
if (handle && !toolbar.inRequiredBuildings(handle.metaBuilding)) {
|
||||||
|
const locked = gameData.excludedBuildings.includes(ids[i]);
|
||||||
|
|
||||||
|
toolbar.toggleBuildingLock(handle.metaBuilding, locked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const entity of this.root.entityMgr.getAllWithComponent(
|
||||||
|
StaticMapEntityComponent
|
||||||
|
)) {
|
||||||
|
this.root.map.removeStaticEntity(entity);
|
||||||
|
this.root.entityMgr.destroyEntity(entity);
|
||||||
|
}
|
||||||
|
this.root.entityMgr.processDestroyList();
|
||||||
|
|
||||||
|
mode.zoneWidth = gameData.bounds.w;
|
||||||
|
mode.zoneHeight = gameData.bounds.h;
|
||||||
|
|
||||||
|
errorText = new PuzzleSerializer().deserializePuzzle(this.root, gameData);
|
||||||
|
} catch (ex) {
|
||||||
|
errorText = ex.message || ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorText) {
|
||||||
|
this.root.hud.parts.dialogs.showWarning(
|
||||||
|
T.dialogs.puzzleLoadError.title,
|
||||||
|
T.dialogs.puzzleLoadError.desc + " " + errorText
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.root.hud.parts.dialogs.showInfo(
|
||||||
|
T.dialogs.puzzleImport.title,
|
||||||
|
T.dialogs.puzzleImport.desc
|
||||||
|
);
|
||||||
|
}
|
||||||
|
closeLoader();
|
||||||
|
});
|
||||||
|
reader.readAsText(file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
exportPuzzle() {
|
||||||
|
const serialized = new PuzzleSerializer().generateDumpFromGameRoot(this.root);
|
||||||
|
|
||||||
|
const data = ReadWriteProxy.serializeObject(serialized);
|
||||||
|
const filename = "puzzle.bin";
|
||||||
|
generateFileDownload(filename, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -23,10 +23,7 @@ import { HUDPuzzleEditorControls } from "../hud/parts/puzzle_editor_controls";
|
|||||||
import { HUDPuzzleEditorReview } from "../hud/parts/puzzle_editor_review";
|
import { HUDPuzzleEditorReview } from "../hud/parts/puzzle_editor_review";
|
||||||
import { HUDPuzzleEditorSettings } from "../hud/parts/puzzle_editor_settings";
|
import { HUDPuzzleEditorSettings } from "../hud/parts/puzzle_editor_settings";
|
||||||
import { createLogger } from "../../core/logging";
|
import { createLogger } from "../../core/logging";
|
||||||
import { PuzzleSerializer } from "../../savegame/puzzle_serializer";
|
import { HUDPuzzleImportExport } from "../hud/parts/puzzle_import_export";
|
||||||
import { T } from "../../translations";
|
|
||||||
import { gMetaBuildingRegistry } from "../../core/global_registries";
|
|
||||||
import { HUDPuzzleEditorDownload } from "../hud/parts/puzzle_editor_download";
|
|
||||||
|
|
||||||
const logger = createLogger("puzzle-edit");
|
const logger = createLogger("puzzle-edit");
|
||||||
|
|
||||||
@ -41,11 +38,8 @@ export class PuzzleEditGameMode extends PuzzleGameMode {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {GameRoot} root
|
* @param {GameRoot} root
|
||||||
* @param {object} payload
|
|
||||||
* @param {import("../../savegame/savegame_typedefs").PuzzleGameData} payload.gameData
|
|
||||||
* @param {boolean} payload.startInTestMode
|
|
||||||
*/
|
*/
|
||||||
constructor(root, { gameData = null, startInTestMode = false }) {
|
constructor(root) {
|
||||||
super(root);
|
super(root);
|
||||||
|
|
||||||
this.hiddenBuildings = [
|
this.hiddenBuildings = [
|
||||||
@ -70,57 +64,7 @@ export class PuzzleEditGameMode extends PuzzleGameMode {
|
|||||||
this.additionalHudParts.puzzleEditorControls = HUDPuzzleEditorControls;
|
this.additionalHudParts.puzzleEditorControls = HUDPuzzleEditorControls;
|
||||||
this.additionalHudParts.puzzleEditorReview = HUDPuzzleEditorReview;
|
this.additionalHudParts.puzzleEditorReview = HUDPuzzleEditorReview;
|
||||||
this.additionalHudParts.puzzleEditorSettings = HUDPuzzleEditorSettings;
|
this.additionalHudParts.puzzleEditorSettings = HUDPuzzleEditorSettings;
|
||||||
this.additionalHudParts.puzzleEditorDownload = HUDPuzzleEditorDownload;
|
this.additionalHudParts.puzzleEditorDownload = HUDPuzzleImportExport;
|
||||||
|
|
||||||
this.gameData = gameData;
|
|
||||||
|
|
||||||
if (gameData) {
|
|
||||||
root.signals.postLoadHook.add(() => this.loadPuzzle(gameData), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.startInTestMode = startInTestMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {import("../../savegame/savegame_typedefs").PuzzleGameData} puzzle
|
|
||||||
*/
|
|
||||||
loadPuzzle(puzzle) {
|
|
||||||
let errorText;
|
|
||||||
logger.log("Loading puzzle", puzzle);
|
|
||||||
|
|
||||||
// set zone and add buildings
|
|
||||||
try {
|
|
||||||
this.zoneWidth = puzzle.bounds.w;
|
|
||||||
this.zoneHeight = puzzle.bounds.h;
|
|
||||||
errorText = new PuzzleSerializer().deserializePuzzle(this.root, puzzle);
|
|
||||||
} catch (ex) {
|
|
||||||
errorText = ex.message || ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorText) {
|
|
||||||
this.root.gameState.moveToState("PuzzleMenuState", {
|
|
||||||
error: {
|
|
||||||
title: T.dialogs.puzzleLoadError.title,
|
|
||||||
desc: T.dialogs.puzzleLoadError.desc + " " + errorText,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const toolbar = this.root.hud.parts.buildingsToolbar;
|
|
||||||
|
|
||||||
// lock excluded buildings
|
|
||||||
for (let i = 0; i < this.gameData.excludedBuildings.length; ++i) {
|
|
||||||
const id = this.gameData.excludedBuildings[i];
|
|
||||||
|
|
||||||
if (!gMetaBuildingRegistry.hasId(id)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
toolbar.toggleBuildingLock(gMetaBuildingRegistry.findById(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.startInTestMode) {
|
|
||||||
this.root.hud.parts.puzzleEditorSettings.toggleTestMode();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getIsEditor() {
|
getIsEditor() {
|
||||||
|
|||||||
@ -43,7 +43,6 @@ export class PuzzleMenuState extends TextualGameState {
|
|||||||
<h1><button class="backButton"></button> ${this.getStateHeaderTitle()}</h1>
|
<h1><button class="backButton"></button> ${this.getStateHeaderTitle()}</h1>
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="styledButton importPuzzle">Import</button>
|
|
||||||
<button class="styledButton loadPuzzle">${T.puzzleMenu.loadPuzzle}</button>
|
<button class="styledButton loadPuzzle">${T.puzzleMenu.loadPuzzle}</button>
|
||||||
<button class="styledButton createPuzzle">+ ${T.puzzleMenu.createPuzzle}</button>
|
<button class="styledButton createPuzzle">+ ${T.puzzleMenu.createPuzzle}</button>
|
||||||
</div>
|
</div>
|
||||||
@ -390,7 +389,6 @@ export class PuzzleMenuState extends TextualGameState {
|
|||||||
|
|
||||||
this.trackClicks(this.htmlElement.querySelector("button.createPuzzle"), () => this.createNewPuzzle());
|
this.trackClicks(this.htmlElement.querySelector("button.createPuzzle"), () => this.createNewPuzzle());
|
||||||
this.trackClicks(this.htmlElement.querySelector("button.loadPuzzle"), () => this.loadPuzzle());
|
this.trackClicks(this.htmlElement.querySelector("button.loadPuzzle"), () => this.loadPuzzle());
|
||||||
this.trackClicks(this.htmlElement.querySelector("button.importPuzzle"), () => this.importPuzzle());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createEmptySavegame() {
|
createEmptySavegame() {
|
||||||
|
|||||||
@ -189,6 +189,8 @@ dialogs:
|
|||||||
retry: Retry
|
retry: Retry
|
||||||
continue: Continue
|
continue: Continue
|
||||||
playOffline: Play Offline
|
playOffline: Play Offline
|
||||||
|
yes: Yes
|
||||||
|
no: No
|
||||||
|
|
||||||
importSavegameError:
|
importSavegameError:
|
||||||
title: Import Error
|
title: Import Error
|
||||||
@ -400,8 +402,13 @@ dialogs:
|
|||||||
desc: >-
|
desc: >-
|
||||||
Are you sure you want to delete '<title>'? This can not be undone!
|
Are you sure you want to delete '<title>'? This can not be undone!
|
||||||
|
|
||||||
puzzleDownload:
|
puzzleImport:
|
||||||
title: Download Puzzle
|
title: Puzzle Imported
|
||||||
|
desc: >-
|
||||||
|
Your puzzle has been successfully imported.
|
||||||
|
|
||||||
|
puzzleExport:
|
||||||
|
title: Export Puzzle
|
||||||
desc: >-
|
desc: >-
|
||||||
Do you want to download this puzzle?
|
Do you want to download this puzzle?
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user