mirror of
https://github.com/tobspr/shapez.io.git
synced 2024-10-27 20:34:29 +00:00
Allow naming savegames
This commit is contained in:
parent
a095cd6324
commit
728f4ae253
@ -285,13 +285,13 @@
|
||||
@include S(border-radius, $globalBorderRadius);
|
||||
@include S(padding, 5px);
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto auto;
|
||||
grid-template-columns: 1fr 1fr auto auto;
|
||||
grid-template-rows: auto auto;
|
||||
@include S(grid-column-gap, 4px);
|
||||
@include S(grid-row-gap, 1px);
|
||||
|
||||
.playtime {
|
||||
grid-column: 1 / 2;
|
||||
grid-column: 2 / 3;
|
||||
grid-row: 2 / 3;
|
||||
@include SuperSmallText;
|
||||
opacity: 0.5;
|
||||
@ -299,13 +299,23 @@
|
||||
|
||||
.level {
|
||||
grid-column: 1 / 2;
|
||||
grid-row: 2 / 3;
|
||||
@include SuperSmallText;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.name {
|
||||
grid-column: 1 / 3;
|
||||
grid-row: 1 / 2;
|
||||
@include PlainText;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
button.resumeGame,
|
||||
button.downloadGame,
|
||||
button.deleteGame {
|
||||
button.deleteGame,
|
||||
button.renameGame {
|
||||
padding: 0;
|
||||
align-self: center;
|
||||
justify-self: center;
|
||||
@ -314,7 +324,7 @@
|
||||
}
|
||||
|
||||
button.downloadGame {
|
||||
grid-column: 2 / 3;
|
||||
grid-column: 3 / 4;
|
||||
grid-row: 1 / 2;
|
||||
background-color: $colorBlueBright;
|
||||
background-image: uiResource("icons/download.png");
|
||||
@ -326,7 +336,7 @@
|
||||
}
|
||||
|
||||
button.deleteGame {
|
||||
grid-column: 2 / 3;
|
||||
grid-column: 3 / 4;
|
||||
grid-row: 2 / 3;
|
||||
background-color: $colorRedBright;
|
||||
@include IncreasedClickArea(0px);
|
||||
@ -337,8 +347,26 @@
|
||||
background-size: 60%;
|
||||
}
|
||||
|
||||
button.renameGame {
|
||||
background-color: transparent;
|
||||
@include IncreasedClickArea(2px);
|
||||
background-image: uiResource("icons/edit_key.png");
|
||||
@include S(width, 10px);
|
||||
@include S(height, 10px);
|
||||
align-self: center;
|
||||
justify-self: center;
|
||||
|
||||
background-size: 90%;
|
||||
opacity: 0.25;
|
||||
@include S(margin-left, 4px);
|
||||
|
||||
&:hover {
|
||||
opacity: 0.35;
|
||||
}
|
||||
}
|
||||
|
||||
button.resumeGame {
|
||||
grid-column: 3 / 4;
|
||||
grid-column: 4 / 5;
|
||||
grid-row: 1 / 3;
|
||||
margin: 0;
|
||||
@include S(width, 32px);
|
||||
|
@ -37,7 +37,7 @@ export class SavegameManager extends ReadWriteProxy {
|
||||
}
|
||||
|
||||
getCurrentVersion() {
|
||||
return 1001;
|
||||
return 1002;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,6 +64,13 @@ export class SavegameManager extends ReadWriteProxy {
|
||||
data.version = 1001;
|
||||
}
|
||||
|
||||
if (data.version < 1002) {
|
||||
data.savegames.forEach(savegame => {
|
||||
savegame.name = null;
|
||||
});
|
||||
data.version = 1002;
|
||||
}
|
||||
|
||||
return ExplainedResult.good();
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
* version: number,
|
||||
* internalId: string,
|
||||
* level: number
|
||||
* name: string|null
|
||||
* }} SavegameMetadata
|
||||
*
|
||||
* @typedef {{
|
||||
|
@ -14,6 +14,8 @@ import { ReadWriteProxy } from "../core/read_write_proxy";
|
||||
import { HUDModalDialogs } from "../game/hud/parts/modal_dialogs";
|
||||
import { T } from "../translations";
|
||||
import { getApplicationSettingById } from "../profile/application_settings";
|
||||
import { FormElementInput } from "../core/modal_dialog_forms";
|
||||
import { DialogWithForm } from "../core/modal_dialog_elements";
|
||||
|
||||
/**
|
||||
* @typedef {import("../savegame/savegame_typedefs").SavegameMetadata} SavegameMetadata
|
||||
@ -392,6 +394,13 @@ export class MainMenuState extends GameState {
|
||||
: T.mainMenu.savegameLevelUnknown
|
||||
);
|
||||
|
||||
const name = makeDiv(
|
||||
elem,
|
||||
null,
|
||||
["name"],
|
||||
games[i].name ? games[i].name : T.mainMenu.savegameUnnamed
|
||||
);
|
||||
|
||||
const deleteButton = document.createElement("button");
|
||||
deleteButton.classList.add("styledButton", "deleteGame");
|
||||
elem.appendChild(deleteButton);
|
||||
@ -400,6 +409,10 @@ export class MainMenuState extends GameState {
|
||||
downloadButton.classList.add("styledButton", "downloadGame");
|
||||
elem.appendChild(downloadButton);
|
||||
|
||||
const renameButton = document.createElement("button");
|
||||
renameButton.classList.add("styledButton", "renameGame");
|
||||
name.appendChild(renameButton);
|
||||
|
||||
const resumeButton = document.createElement("button");
|
||||
resumeButton.classList.add("styledButton", "resumeGame");
|
||||
elem.appendChild(resumeButton);
|
||||
@ -407,10 +420,41 @@ export class MainMenuState extends GameState {
|
||||
this.trackClicks(deleteButton, () => this.deleteGame(games[i]));
|
||||
this.trackClicks(downloadButton, () => this.downloadGame(games[i]));
|
||||
this.trackClicks(resumeButton, () => this.resumeGame(games[i]));
|
||||
this.trackClicks(renameButton, () => this.requestRenameSavegame(games[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {SavegameMetadata} game
|
||||
*/
|
||||
requestRenameSavegame(game) {
|
||||
const regex = /^[a-zA-Z0-9_\- ]{1,20}$/;
|
||||
|
||||
const nameInput = new FormElementInput({
|
||||
id: "nameInput",
|
||||
label: null,
|
||||
placeholder: "",
|
||||
defaultValue: game.name || "",
|
||||
validator: val => val.match(regex),
|
||||
});
|
||||
const dialog = new DialogWithForm({
|
||||
app: this.app,
|
||||
title: T.dialogs.renameSavegame.title,
|
||||
desc: T.dialogs.renameSavegame.desc,
|
||||
formElements: [nameInput],
|
||||
buttons: ["cancel:bad:escape", "ok:good:enter"],
|
||||
});
|
||||
this.dialogs.internalShowDialog(dialog);
|
||||
|
||||
// When confirmed, save the name
|
||||
dialog.buttonSignals.ok.add(() => {
|
||||
game.name = nameInput.getValue();
|
||||
this.app.savegameMgr.writeAsync();
|
||||
this.renderSavegames();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {SavegameMetadata} game
|
||||
*/
|
||||
@ -473,7 +517,8 @@ export class MainMenuState extends GameState {
|
||||
const savegame = this.app.savegameMgr.getSavegameById(game.internalId);
|
||||
savegame.readAsync().then(() => {
|
||||
const data = ReadWriteProxy.serializeObject(savegame.currentData);
|
||||
generateFileDownload(savegame.filename, data);
|
||||
const filename = (game.name || "unnamed") + ".bin";
|
||||
generateFileDownload(filename, data);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -157,6 +157,7 @@ mainMenu:
|
||||
|
||||
savegameLevel: Level <x>
|
||||
savegameLevelUnknown: Unknown Level
|
||||
savegameUnnamed: Unnamed
|
||||
|
||||
dialogs:
|
||||
buttons:
|
||||
@ -274,6 +275,10 @@ dialogs:
|
||||
title: Export screenshot
|
||||
desc: You requested to export your base as a screenshot. Please note that this can be quite slow for a big base and even crash your game!
|
||||
|
||||
renameSavegame:
|
||||
title: Rename Savegame
|
||||
desc: You can rename your savegame here.
|
||||
|
||||
ingame:
|
||||
# This is shown in the top left corner and displays useful keybindings in
|
||||
# every situation
|
||||
|
Loading…
Reference in New Issue
Block a user