Fix keys being stuck, show savegame levels in main menu
This commit is contained in:
parent
2a4ee8e784
commit
e0facaf788
|
@ -292,7 +292,7 @@ function gulptasksHTML($, gulp, buildFolder, browserSync) {
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("html.prod", () => {
|
gulp.task("html.prod", () => {
|
||||||
return buildHtml("https://api.shapez.io", {
|
return buildHtml("https://analytics.shapez.io", {
|
||||||
analytics: true,
|
analytics: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -315,7 +315,7 @@ function gulptasksHTML($, gulp, buildFolder, browserSync) {
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("html.standalone-prod", () => {
|
gulp.task("html.standalone-prod", () => {
|
||||||
return buildHtml("https://api.shapez.io", {
|
return buildHtml("https://analytics.shapez.io", {
|
||||||
analytics: false,
|
analytics: false,
|
||||||
standalone: true,
|
standalone: true,
|
||||||
enableCachebust: false,
|
enableCachebust: false,
|
||||||
|
|
|
@ -46,7 +46,6 @@ function gulptasksJS($, gulp, buildFolder, browserSync) {
|
||||||
requireUncached("./webpack.production.config.js")({
|
requireUncached("./webpack.production.config.js")({
|
||||||
enableAssert: true,
|
enableAssert: true,
|
||||||
environment: "staging",
|
environment: "staging",
|
||||||
apiEndpoint: "https://api-staging.shapez.io/v1",
|
|
||||||
es6: false,
|
es6: false,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -63,7 +62,6 @@ function gulptasksJS($, gulp, buildFolder, browserSync) {
|
||||||
requireUncached("./webpack.production.config.js")({
|
requireUncached("./webpack.production.config.js")({
|
||||||
enableAssert: true,
|
enableAssert: true,
|
||||||
environment: "staging",
|
environment: "staging",
|
||||||
apiEndpoint: "https://api-staging.shapez.io/v1",
|
|
||||||
es6: true,
|
es6: true,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -81,7 +79,6 @@ function gulptasksJS($, gulp, buildFolder, browserSync) {
|
||||||
requireUncached("./webpack.production.config.js")({
|
requireUncached("./webpack.production.config.js")({
|
||||||
enableAssert: false,
|
enableAssert: false,
|
||||||
environment: "prod",
|
environment: "prod",
|
||||||
apiEndpoint: "https://api.shapez.io/v1",
|
|
||||||
es6: false,
|
es6: false,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -100,7 +97,6 @@ function gulptasksJS($, gulp, buildFolder, browserSync) {
|
||||||
enableAssert: false,
|
enableAssert: false,
|
||||||
environment: "prod",
|
environment: "prod",
|
||||||
es6: true,
|
es6: true,
|
||||||
apiEndpoint: "https://api.shapez.io/v1",
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -148,7 +144,6 @@ function gulptasksJS($, gulp, buildFolder, browserSync) {
|
||||||
requireUncached("./webpack.production.config.js")({
|
requireUncached("./webpack.production.config.js")({
|
||||||
enableAssert: true,
|
enableAssert: true,
|
||||||
environment: "staging",
|
environment: "staging",
|
||||||
apiEndpoint: "https://api-staging.shapez.io/v1",
|
|
||||||
es6: true,
|
es6: true,
|
||||||
standalone: true,
|
standalone: true,
|
||||||
})
|
})
|
||||||
|
@ -165,7 +160,6 @@ function gulptasksJS($, gulp, buildFolder, browserSync) {
|
||||||
requireUncached("./webpack.production.config.js")({
|
requireUncached("./webpack.production.config.js")({
|
||||||
enableAssert: false,
|
enableAssert: false,
|
||||||
environment: "prod",
|
environment: "prod",
|
||||||
apiEndpoint: "https://api.shapez.io/v1",
|
|
||||||
es6: true,
|
es6: true,
|
||||||
standalone: true,
|
standalone: true,
|
||||||
})
|
})
|
||||||
|
|
|
@ -32,9 +32,6 @@ module.exports = ({ watch = false, standalone = false }) => {
|
||||||
"window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));",
|
"window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));",
|
||||||
G_HAVE_ASSERT: "true",
|
G_HAVE_ASSERT: "true",
|
||||||
G_APP_ENVIRONMENT: JSON.stringify("dev"),
|
G_APP_ENVIRONMENT: JSON.stringify("dev"),
|
||||||
G_API_ENDPOINT: JSON.stringify(
|
|
||||||
lzString.compressToEncodedURIComponent("http://localhost:5005/v1")
|
|
||||||
),
|
|
||||||
G_TRACKING_ENDPOINT: JSON.stringify(
|
G_TRACKING_ENDPOINT: JSON.stringify(
|
||||||
lzString.compressToEncodedURIComponent("http://localhost:10005/v1")
|
lzString.compressToEncodedURIComponent("http://localhost:10005/v1")
|
||||||
),
|
),
|
||||||
|
|
|
@ -13,7 +13,6 @@ const UnusedFilesPlugin = require("unused-files-webpack-plugin").UnusedFilesWebp
|
||||||
|
|
||||||
module.exports = ({
|
module.exports = ({
|
||||||
enableAssert = false,
|
enableAssert = false,
|
||||||
apiEndpoint,
|
|
||||||
environment,
|
environment,
|
||||||
es6 = false,
|
es6 = false,
|
||||||
standalone = false,
|
standalone = false,
|
||||||
|
@ -30,7 +29,6 @@ module.exports = ({
|
||||||
G_IS_STANDALONE: standalone ? "true" : "false",
|
G_IS_STANDALONE: standalone ? "true" : "false",
|
||||||
G_IS_BROWSER: isBrowser ? "true" : "false",
|
G_IS_BROWSER: isBrowser ? "true" : "false",
|
||||||
G_IS_MOBILE_APP: mobileApp ? "true" : "false",
|
G_IS_MOBILE_APP: mobileApp ? "true" : "false",
|
||||||
G_API_ENDPOINT: JSON.stringify(lzString.compressToEncodedURIComponent(apiEndpoint)),
|
|
||||||
G_TRACKING_ENDPOINT: JSON.stringify(
|
G_TRACKING_ENDPOINT: JSON.stringify(
|
||||||
lzString.compressToEncodedURIComponent("https://tracking.shapez.io/v1")
|
lzString.compressToEncodedURIComponent("https://tracking.shapez.io/v1")
|
||||||
),
|
),
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
border-bottom-width: 0;
|
border-bottom-width: 0;
|
||||||
transition: transform 0.12s ease-in-out;
|
transition: transform 0.12s ease-in-out;
|
||||||
|
|
||||||
background: rgba(mix(#ddd, $colorBlueBright, 80%), 0.89);
|
background: rgba(mix(#ddd, $colorBlueBright, 80%), 0.69);
|
||||||
|
|
||||||
&:not(.visible) {
|
&:not(.visible) {
|
||||||
transform: translateX(-50%) translateY(#{D(100px)});
|
transform: translateX(-50%) translateY(#{D(100px)});
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
.keybinding {
|
.keybinding {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
@include S(margin, 0, 4px);
|
@include S(margin, 0, 1px);
|
||||||
position: relative;
|
position: relative;
|
||||||
top: unset;
|
top: unset;
|
||||||
left: unset;
|
left: unset;
|
||||||
|
|
|
@ -235,7 +235,7 @@
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.updateTime {
|
.level {
|
||||||
grid-column: 1 / 2;
|
grid-column: 1 / 2;
|
||||||
grid-row: 1 / 2;
|
grid-row: 1 / 2;
|
||||||
@include PlainText;
|
@include PlainText;
|
||||||
|
|
|
@ -3,12 +3,15 @@ export const CHANGELOG = [
|
||||||
version: "1.1.0",
|
version: "1.1.0",
|
||||||
date: "unreleased",
|
date: "unreleased",
|
||||||
entries: [
|
entries: [
|
||||||
"BLUEPRINTS!",
|
"BLUEPRINTS! They are unlocked at level 11.",
|
||||||
|
"Savegame levels are now shown in the main menu. For existing games, save them again to make the level show up.",
|
||||||
"Allow holding SHIFT to rotate counter clockwise",
|
"Allow holding SHIFT to rotate counter clockwise",
|
||||||
"Allow changing all keybindings, including CTRL, ALT and SHIFT (by Dimava)",
|
"Allow changing all keybindings, including CTRL, ALT and SHIFT (by Dimava)",
|
||||||
"Added confirmation when deleting more than 500 buildings at a time",
|
"Added confirmation when deleting more than 500 buildings at a time",
|
||||||
"Added background to toolbar to increase contrast",
|
"Added background to toolbar to increase contrast",
|
||||||
"Further decrease requirements of first levels",
|
"Further decrease requirements of first levels",
|
||||||
|
"Pinned shapes now are saved",
|
||||||
|
"Fix keys being stuck when opening a dialog",
|
||||||
"Allow placing extractors anywhere again, but they don't work at all if not placed on a resource",
|
"Allow placing extractors anywhere again, but they don't work at all if not placed on a resource",
|
||||||
"Fix cycling through keybindings selecting locked buildings as well (by Dimava)",
|
"Fix cycling through keybindings selecting locked buildings as well (by Dimava)",
|
||||||
"There is now a github action, checking all pull requests with eslint. (by mrHedgehog)",
|
"There is now a github action, checking all pull requests with eslint. (by mrHedgehog)",
|
||||||
|
|
|
@ -83,7 +83,7 @@ export const globalConfig = {
|
||||||
|
|
||||||
debug: {
|
debug: {
|
||||||
/* dev:start */
|
/* dev:start */
|
||||||
fastGameEnter: true,
|
// fastGameEnter: true,
|
||||||
// noArtificialDelays: true,
|
// noArtificialDelays: true,
|
||||||
// disableSavegameWrite: true,
|
// disableSavegameWrite: true,
|
||||||
// showEntityBounds: true,
|
// showEntityBounds: true,
|
||||||
|
@ -100,7 +100,7 @@ export const globalConfig = {
|
||||||
// testClipping: true,
|
// testClipping: true,
|
||||||
// framePausesBetweenTicks: 40,
|
// framePausesBetweenTicks: 40,
|
||||||
// testTranslations: true,
|
// testTranslations: true,
|
||||||
enableEntityInspector: true,
|
// enableEntityInspector: true,
|
||||||
// testAds: true,
|
// testAds: true,
|
||||||
// disableMapOverview: true,
|
// disableMapOverview: true,
|
||||||
disableTutorialHints: true,
|
disableTutorialHints: true,
|
||||||
|
|
|
@ -23,6 +23,11 @@ export class InputDistributor {
|
||||||
/** @type {Array<function(any) : boolean>} */
|
/** @type {Array<function(any) : boolean>} */
|
||||||
this.filters = [];
|
this.filters = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All keys which are currently down
|
||||||
|
*/
|
||||||
|
this.keysDown = new Set();
|
||||||
|
|
||||||
this.bindToEvents();
|
this.bindToEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,6 +178,7 @@ export class InputDistributor {
|
||||||
*/
|
*/
|
||||||
handleBlur() {
|
handleBlur() {
|
||||||
this.forwardToReceiver("pageBlur", {});
|
this.forwardToReceiver("pageBlur", {});
|
||||||
|
this.keysDown.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -180,19 +186,24 @@ export class InputDistributor {
|
||||||
*/
|
*/
|
||||||
handleKeydown(event) {
|
handleKeydown(event) {
|
||||||
if (
|
if (
|
||||||
// TAB
|
event.keyCode === 9 || // TAB
|
||||||
event.keyCode === 9 ||
|
event.keyCode === 16 || // SHIFT
|
||||||
// F1 - F10
|
event.keyCode === 17 || // CTRL
|
||||||
(event.keyCode >= 112 && event.keyCode < 122)
|
event.keyCode === 18 || // ALT
|
||||||
|
(event.keyCode >= 112 && event.keyCode < 122) // F1 - F10
|
||||||
) {
|
) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isInitial = !this.keysDown.has(event.keyCode);
|
||||||
|
this.keysDown.add(event.keyCode);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.forwardToReceiver("keydown", {
|
this.forwardToReceiver("keydown", {
|
||||||
keyCode: event.keyCode,
|
keyCode: event.keyCode,
|
||||||
shift: event.shiftKey,
|
shift: event.shiftKey,
|
||||||
alt: event.altKey,
|
alt: event.altKey,
|
||||||
|
initial: isInitial,
|
||||||
event,
|
event,
|
||||||
}) === STOP_PROPAGATION
|
}) === STOP_PROPAGATION
|
||||||
) {
|
) {
|
||||||
|
@ -212,6 +223,8 @@ export class InputDistributor {
|
||||||
* @param {KeyboardEvent} event
|
* @param {KeyboardEvent} event
|
||||||
*/
|
*/
|
||||||
handleKeyup(event) {
|
handleKeyup(event) {
|
||||||
|
this.keysDown.delete(event.keyCode);
|
||||||
|
|
||||||
this.forwardToReceiver("keyup", {
|
this.forwardToReceiver("keyup", {
|
||||||
keyCode: event.keyCode,
|
keyCode: event.keyCode,
|
||||||
shift: event.shiftKey,
|
shift: event.shiftKey,
|
||||||
|
|
|
@ -873,19 +873,19 @@ export class Camera extends BasicSerializableObject {
|
||||||
let forceY = 0;
|
let forceY = 0;
|
||||||
|
|
||||||
const actionMapper = this.root.keyMapper;
|
const actionMapper = this.root.keyMapper;
|
||||||
if (actionMapper.getBinding(KEYMAPPINGS.ingame.mapMoveUp).currentlyDown) {
|
if (actionMapper.getBinding(KEYMAPPINGS.ingame.mapMoveUp).isCurrentlyPressed()) {
|
||||||
forceY -= 1;
|
forceY -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionMapper.getBinding(KEYMAPPINGS.ingame.mapMoveDown).currentlyDown) {
|
if (actionMapper.getBinding(KEYMAPPINGS.ingame.mapMoveDown).isCurrentlyPressed()) {
|
||||||
forceY += 1;
|
forceY += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionMapper.getBinding(KEYMAPPINGS.ingame.mapMoveLeft).currentlyDown) {
|
if (actionMapper.getBinding(KEYMAPPINGS.ingame.mapMoveLeft).isCurrentlyPressed()) {
|
||||||
forceX -= 1;
|
forceX -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionMapper.getBinding(KEYMAPPINGS.ingame.mapMoveRight).currentlyDown) {
|
if (actionMapper.getBinding(KEYMAPPINGS.ingame.mapMoveRight).isCurrentlyPressed()) {
|
||||||
forceX += 1;
|
forceX += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ export class GameHUD {
|
||||||
|
|
||||||
vignetteOverlay: new HUDVignetteOverlay(this.root),
|
vignetteOverlay: new HUDVignetteOverlay(this.root),
|
||||||
|
|
||||||
|
// Must always exist
|
||||||
pinnedShapes: new HUDPinnedShapes(this.root),
|
pinnedShapes: new HUDPinnedShapes(this.root),
|
||||||
|
|
||||||
notifications: new HUDNotifications(this.root),
|
notifications: new HUDNotifications(this.root),
|
||||||
|
|
|
@ -59,7 +59,7 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
|
||||||
const tile = worldPos.toTileSpace();
|
const tile = worldPos.toTileSpace();
|
||||||
if (blueprint.tryPlace(this.root, tile)) {
|
if (blueprint.tryPlace(this.root, tile)) {
|
||||||
// This actually feels weird
|
// This actually feels weird
|
||||||
// if (!this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeMultiple).currentlyDown) {
|
// if (!this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeMultiple).isCurrentlyPressed()) {
|
||||||
// this.currentBlueprint.set(null);
|
// this.currentBlueprint.set(null);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,11 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
|
||||||
|
|
||||||
rotateBlueprint() {
|
rotateBlueprint() {
|
||||||
if (this.currentBlueprint.get()) {
|
if (this.currentBlueprint.get()) {
|
||||||
if (this.root.keyMapper.getBinding(KEYMAPPINGS.placement.rotateInverseModifier).currentlyDown) {
|
if (
|
||||||
|
this.root.keyMapper
|
||||||
|
.getBinding(KEYMAPPINGS.placement.rotateInverseModifier)
|
||||||
|
.isCurrentlyPressed()
|
||||||
|
) {
|
||||||
this.currentBlueprint.get().rotateCcw();
|
this.currentBlueprint.get().rotateCcw();
|
||||||
} else {
|
} else {
|
||||||
this.currentBlueprint.get().rotateCw();
|
this.currentBlueprint.get().rotateCw();
|
||||||
|
|
|
@ -161,9 +161,9 @@ export class HUDBuildingPlacer extends BaseHUDPart {
|
||||||
if (
|
if (
|
||||||
metaBuilding &&
|
metaBuilding &&
|
||||||
metaBuilding.getRotateAutomaticallyWhilePlacing(this.currentVariant.get()) &&
|
metaBuilding.getRotateAutomaticallyWhilePlacing(this.currentVariant.get()) &&
|
||||||
!this.root.keyMapper.getBinding(
|
!this.root.keyMapper
|
||||||
KEYMAPPINGS.placementModifiers.placementDisableAutoOrientation
|
.getBinding(KEYMAPPINGS.placementModifiers.placementDisableAutoOrientation)
|
||||||
).currentlyDown
|
.isCurrentlyPressed()
|
||||||
) {
|
) {
|
||||||
const delta = newPos.sub(oldPos);
|
const delta = newPos.sub(oldPos);
|
||||||
const angleDeg = Math_degrees(delta.angle());
|
const angleDeg = Math_degrees(delta.angle());
|
||||||
|
@ -171,8 +171,9 @@ export class HUDBuildingPlacer extends BaseHUDPart {
|
||||||
|
|
||||||
// Holding alt inverts the placement
|
// Holding alt inverts the placement
|
||||||
if (
|
if (
|
||||||
this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeInverse)
|
this.root.keyMapper
|
||||||
.currentlyDown
|
.getBinding(KEYMAPPINGS.placementModifiers.placeInverse)
|
||||||
|
.isCurrentlyPressed()
|
||||||
) {
|
) {
|
||||||
this.currentBaseRotation = (180 + this.currentBaseRotation) % 360;
|
this.currentBaseRotation = (180 + this.currentBaseRotation) % 360;
|
||||||
}
|
}
|
||||||
|
@ -394,7 +395,11 @@ export class HUDBuildingPlacer extends BaseHUDPart {
|
||||||
tryRotate() {
|
tryRotate() {
|
||||||
const selectedBuilding = this.currentMetaBuilding.get();
|
const selectedBuilding = this.currentMetaBuilding.get();
|
||||||
if (selectedBuilding) {
|
if (selectedBuilding) {
|
||||||
if (this.root.keyMapper.getBinding(KEYMAPPINGS.placement.rotateInverseModifier).currentlyDown) {
|
if (
|
||||||
|
this.root.keyMapper
|
||||||
|
.getBinding(KEYMAPPINGS.placement.rotateInverseModifier)
|
||||||
|
.isCurrentlyPressed()
|
||||||
|
) {
|
||||||
this.currentBaseRotation = (this.currentBaseRotation + 270) % 360;
|
this.currentBaseRotation = (this.currentBaseRotation + 270) % 360;
|
||||||
} else {
|
} else {
|
||||||
this.currentBaseRotation = (this.currentBaseRotation + 90) % 360;
|
this.currentBaseRotation = (this.currentBaseRotation + 90) % 360;
|
||||||
|
@ -479,16 +484,18 @@ export class HUDBuildingPlacer extends BaseHUDPart {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
metaBuilding.getFlipOrientationAfterPlacement() &&
|
metaBuilding.getFlipOrientationAfterPlacement() &&
|
||||||
!this.root.keyMapper.getBinding(
|
!this.root.keyMapper
|
||||||
KEYMAPPINGS.placementModifiers.placementDisableAutoOrientation
|
.getBinding(KEYMAPPINGS.placementModifiers.placementDisableAutoOrientation)
|
||||||
).currentlyDown
|
.isCurrentlyPressed()
|
||||||
) {
|
) {
|
||||||
this.currentBaseRotation = (180 + this.currentBaseRotation) % 360;
|
this.currentBaseRotation = (180 + this.currentBaseRotation) % 360;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!metaBuilding.getStayInPlacementMode() &&
|
!metaBuilding.getStayInPlacementMode() &&
|
||||||
!this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeMultiple).currentlyDown &&
|
!this.root.keyMapper
|
||||||
|
.getBinding(KEYMAPPINGS.placementModifiers.placeMultiple)
|
||||||
|
.isCurrentlyPressed() &&
|
||||||
!this.root.app.settings.getAllSettings().alwaysMultiplace
|
!this.root.app.settings.getAllSettings().alwaysMultiplace
|
||||||
) {
|
) {
|
||||||
// Stop placement
|
// Stop placement
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { enumMouseButton } from "../../camera";
|
||||||
import { T } from "../../../translations";
|
import { T } from "../../../translations";
|
||||||
import { KEYMAPPINGS } from "../../key_action_mapper";
|
import { KEYMAPPINGS } from "../../key_action_mapper";
|
||||||
import { THEME } from "../../theme";
|
import { THEME } from "../../theme";
|
||||||
|
import { enumHubGoalRewards } from "../../tutorial_goals";
|
||||||
|
|
||||||
const logger = createLogger("hud/mass_selector");
|
const logger = createLogger("hud/mass_selector");
|
||||||
|
|
||||||
|
@ -30,9 +31,9 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||||
"ingame_HUD_MassSelector",
|
"ingame_HUD_MassSelector",
|
||||||
[],
|
[],
|
||||||
T.ingame.massSelect.infoText
|
T.ingame.massSelect.infoText
|
||||||
.replace("<keyDelete>", removalKeybinding)
|
.replace("<keyDelete>", `<code class='keybinding'>${removalKeybinding}</code>`)
|
||||||
.replace("<keyCopy>", copyKeybinding)
|
.replace("<keyCopy>", `<code class='keybinding'>${copyKeybinding}</code>`)
|
||||||
.replace("<keyCancel>", abortKeybinding)
|
.replace("<keyCancel>", `<code class='keybinding'>${abortKeybinding}</code>`)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +108,13 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||||
|
|
||||||
startCopy() {
|
startCopy() {
|
||||||
if (this.selectedUids.size > 0) {
|
if (this.selectedUids.size > 0) {
|
||||||
|
if (!this.root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_blueprints)) {
|
||||||
|
this.root.hud.parts.dialogs.showInfo(
|
||||||
|
T.dialogs.blueprintsNotUnlocked.title,
|
||||||
|
T.dialogs.blueprintsNotUnlocked.desc
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.root.hud.signals.buildingsSelectedForCopy.dispatch(Array.from(this.selectedUids));
|
this.root.hud.signals.buildingsSelectedForCopy.dispatch(Array.from(this.selectedUids));
|
||||||
this.selectedUids = new Set();
|
this.selectedUids = new Set();
|
||||||
this.root.soundProxy.playUiClick();
|
this.root.soundProxy.playUiClick();
|
||||||
|
@ -121,7 +129,7 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||||
* @param {enumMouseButton} mouseButton
|
* @param {enumMouseButton} mouseButton
|
||||||
*/
|
*/
|
||||||
onMouseDown(pos, mouseButton) {
|
onMouseDown(pos, mouseButton) {
|
||||||
if (!this.root.keyMapper.getBinding(KEYMAPPINGS.massSelect.massSelectStart).currentlyDown) {
|
if (!this.root.keyMapper.getBinding(KEYMAPPINGS.massSelect.massSelectStart).isCurrentlyPressed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +137,11 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.root.keyMapper.getBinding(KEYMAPPINGS.massSelect.massSelectSelectMultiple).currentlyDown) {
|
if (
|
||||||
|
!this.root.keyMapper
|
||||||
|
.getBinding(KEYMAPPINGS.massSelect.massSelectSelectMultiple)
|
||||||
|
.isCurrentlyPressed()
|
||||||
|
) {
|
||||||
// Start new selection
|
// Start new selection
|
||||||
this.selectedUids = new Set();
|
this.selectedUids = new Set();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,19 @@ export class HUDPinnedShapes extends BaseHUDPart {
|
||||||
this.element = makeDiv(parent, "ingame_HUD_PinnedShapes", []);
|
this.element = makeDiv(parent, "ingame_HUD_PinnedShapes", []);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serialize() {
|
||||||
|
return {
|
||||||
|
shapes: this.pinnedShapes,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
deserialize(data) {
|
||||||
|
if (!data || !data.shapes || !Array.isArray(data.shapes)) {
|
||||||
|
return "Invalid pinned shapes data";
|
||||||
|
}
|
||||||
|
this.pinnedShapes = data.shapes;
|
||||||
|
}
|
||||||
|
|
||||||
initialize() {
|
initialize() {
|
||||||
/** @type {Array<{ key: string, goal: number }>} */
|
/** @type {Array<{ key: string, goal: number }>} */
|
||||||
this.pinnedShapes = [];
|
this.pinnedShapes = [];
|
||||||
|
|
|
@ -89,9 +89,10 @@ export class HUDUnlockNotification extends BaseHUDPart {
|
||||||
clearTimeout(this.buttonShowTimeout);
|
clearTimeout(this.buttonShowTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.element.querySelector("button.close").classList.remove("unlocked");
|
||||||
this.buttonShowTimeout = setTimeout(
|
this.buttonShowTimeout = setTimeout(
|
||||||
() => this.element.querySelector("button.close").classList.add("unlocked"),
|
() => this.element.querySelector("button.close").classList.add("unlocked"),
|
||||||
G_IS_DEV ? 1000 : 10000
|
10000
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -235,12 +235,17 @@ export class Keybinding {
|
||||||
this.builtin = builtin;
|
this.builtin = builtin;
|
||||||
this.repeated = repeated;
|
this.repeated = repeated;
|
||||||
|
|
||||||
this.currentlyDown = false;
|
|
||||||
|
|
||||||
this.signal = new Signal();
|
this.signal = new Signal();
|
||||||
this.toggled = new Signal();
|
this.toggled = new Signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this binding is currently pressed
|
||||||
|
*/
|
||||||
|
isCurrentlyPressed() {
|
||||||
|
return this.app.inputMgr.keysDown.has(this.keyCode);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an event listener
|
* Adds an event listener
|
||||||
* @param {function() : void} receiver
|
* @param {function() : void} receiver
|
||||||
|
@ -350,7 +355,6 @@ export class KeyActionMapper {
|
||||||
for (const key in this.keybindings) {
|
for (const key in this.keybindings) {
|
||||||
/** @type {Keybinding} */
|
/** @type {Keybinding} */
|
||||||
const binding = this.keybindings[key];
|
const binding = this.keybindings[key];
|
||||||
binding.currentlyDown = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,17 +364,16 @@ export class KeyActionMapper {
|
||||||
* @param {number} param0.keyCode
|
* @param {number} param0.keyCode
|
||||||
* @param {boolean} param0.shift
|
* @param {boolean} param0.shift
|
||||||
* @param {boolean} param0.alt
|
* @param {boolean} param0.alt
|
||||||
|
* @param {boolean=} param0.initial
|
||||||
*/
|
*/
|
||||||
handleKeydown({ keyCode, shift, alt }) {
|
handleKeydown({ keyCode, shift, alt, initial }) {
|
||||||
let stop = false;
|
let stop = false;
|
||||||
|
|
||||||
// Find mapping
|
// Find mapping
|
||||||
for (const key in this.keybindings) {
|
for (const key in this.keybindings) {
|
||||||
/** @type {Keybinding} */
|
/** @type {Keybinding} */
|
||||||
const binding = this.keybindings[key];
|
const binding = this.keybindings[key];
|
||||||
if (binding.keyCode === keyCode && (!binding.currentlyDown || binding.repeated)) {
|
if (binding.keyCode === keyCode && (initial || binding.repeated)) {
|
||||||
binding.currentlyDown = true;
|
|
||||||
|
|
||||||
/** @type {Signal} */
|
/** @type {Signal} */
|
||||||
const signal = this.keybindings[key].signal;
|
const signal = this.keybindings[key].signal;
|
||||||
if (signal.dispatch() === STOP_PROPAGATION) {
|
if (signal.dispatch() === STOP_PROPAGATION) {
|
||||||
|
@ -392,13 +395,7 @@ export class KeyActionMapper {
|
||||||
* @param {boolean} param0.alt
|
* @param {boolean} param0.alt
|
||||||
*/
|
*/
|
||||||
handleKeyup({ keyCode, shift, alt }) {
|
handleKeyup({ keyCode, shift, alt }) {
|
||||||
for (const key in this.keybindings) {
|
// Empty
|
||||||
/** @type {Keybinding} */
|
|
||||||
const binding = this.keybindings[key];
|
|
||||||
if (binding.keyCode === keyCode) {
|
|
||||||
binding.currentlyDown = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,6 +23,7 @@ export const enumHubGoalRewards = {
|
||||||
reward_painter_quad: "reward_painter_quad",
|
reward_painter_quad: "reward_painter_quad",
|
||||||
reward_storage: "reward_storage",
|
reward_storage: "reward_storage",
|
||||||
|
|
||||||
|
reward_blueprints: "reward_blueprints",
|
||||||
reward_freeplay: "reward_freeplay",
|
reward_freeplay: "reward_freeplay",
|
||||||
|
|
||||||
no_reward: "no_reward",
|
no_reward: "no_reward",
|
||||||
|
@ -65,14 +66,14 @@ export const tutorialGoals = [
|
||||||
// Rotater
|
// Rotater
|
||||||
{
|
{
|
||||||
shape: "Cu----Cu", // belts t2
|
shape: "Cu----Cu", // belts t2
|
||||||
required: 300,
|
required: 200,
|
||||||
reward: enumHubGoalRewards.reward_tunnel,
|
reward: enumHubGoalRewards.reward_tunnel,
|
||||||
},
|
},
|
||||||
|
|
||||||
// 6
|
// 6
|
||||||
{
|
{
|
||||||
shape: "Cu------", // miners t2
|
shape: "Cu------", // miners t2
|
||||||
required: 500,
|
required: 400,
|
||||||
reward: enumHubGoalRewards.reward_painter,
|
reward: enumHubGoalRewards.reward_painter,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -80,14 +81,14 @@ export const tutorialGoals = [
|
||||||
// Painter
|
// Painter
|
||||||
{
|
{
|
||||||
shape: "CrCrCrCr", // unused
|
shape: "CrCrCrCr", // unused
|
||||||
required: 1000,
|
required: 800,
|
||||||
reward: enumHubGoalRewards.reward_rotater_ccw,
|
reward: enumHubGoalRewards.reward_rotater_ccw,
|
||||||
},
|
},
|
||||||
|
|
||||||
// 8
|
// 8
|
||||||
{
|
{
|
||||||
shape: "RbRb----", // painter t2
|
shape: "RbRb----", // painter t2
|
||||||
required: 1500,
|
required: 1250,
|
||||||
reward: enumHubGoalRewards.reward_mixer,
|
reward: enumHubGoalRewards.reward_mixer,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -95,7 +96,7 @@ export const tutorialGoals = [
|
||||||
// Mixing (purple)
|
// Mixing (purple)
|
||||||
{
|
{
|
||||||
shape: "CpCpCpCp", // belts t3
|
shape: "CpCpCpCp", // belts t3
|
||||||
required: 2500,
|
required: 1750,
|
||||||
reward: enumHubGoalRewards.reward_splitter_compact,
|
reward: enumHubGoalRewards.reward_splitter_compact,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -103,7 +104,7 @@ export const tutorialGoals = [
|
||||||
// Star shape + cyan
|
// Star shape + cyan
|
||||||
{
|
{
|
||||||
shape: "ScScScSc", // miners t3
|
shape: "ScScScSc", // miners t3
|
||||||
required: 5000,
|
required: 2250,
|
||||||
reward: enumHubGoalRewards.reward_stacker,
|
reward: enumHubGoalRewards.reward_stacker,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -111,46 +112,54 @@ export const tutorialGoals = [
|
||||||
// Stacker
|
// Stacker
|
||||||
{
|
{
|
||||||
shape: "CgScScCg", // processors t3
|
shape: "CgScScCg", // processors t3
|
||||||
required: 6000,
|
required: 3000,
|
||||||
reward: enumHubGoalRewards.reward_miner_chainable,
|
reward: enumHubGoalRewards.reward_miner_chainable,
|
||||||
},
|
},
|
||||||
|
|
||||||
// 12
|
// 12
|
||||||
|
// Blueprints
|
||||||
{
|
{
|
||||||
shape: "RpRpRpRp:CwCwCwCw", // painting t3
|
shape: "CbCbCbRb:CwCwCwCw",
|
||||||
required: 7000,
|
required: 4000,
|
||||||
reward: enumHubGoalRewards.reward_underground_belt_tier_2,
|
reward: enumHubGoalRewards.reward_blueprints,
|
||||||
},
|
},
|
||||||
|
|
||||||
// 13
|
// 13
|
||||||
{
|
{
|
||||||
shape: "SrSrSrSr:CyCyCyCy", // unused
|
shape: "RpRpRpRp:CwCwCwCw", // painting t3
|
||||||
required: 7850,
|
required: 9000,
|
||||||
reward: enumHubGoalRewards.reward_storage,
|
reward: enumHubGoalRewards.reward_underground_belt_tier_2,
|
||||||
},
|
},
|
||||||
|
|
||||||
// 14
|
// 14
|
||||||
{
|
{
|
||||||
shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", // belts t4 (two variants)
|
shape: "SrSrSrSr:CyCyCyCy", // unused
|
||||||
required: 8000,
|
required: 12000,
|
||||||
reward: enumHubGoalRewards.reward_cutter_quad,
|
reward: enumHubGoalRewards.reward_storage,
|
||||||
},
|
},
|
||||||
|
|
||||||
// 15
|
// 15
|
||||||
{
|
{
|
||||||
shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", // miner t4 (two variants)
|
shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", // belts t4 (two variants)
|
||||||
required: 9000,
|
required: 14000,
|
||||||
reward: enumHubGoalRewards.reward_painter_double,
|
reward: enumHubGoalRewards.reward_cutter_quad,
|
||||||
},
|
},
|
||||||
|
|
||||||
// 16
|
// 16
|
||||||
{
|
{
|
||||||
shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", // processors t4 (two varinats)
|
shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", // miner t4 (two variants)
|
||||||
required: 10000,
|
required: 17000,
|
||||||
reward: enumHubGoalRewards.reward_painter_quad,
|
reward: enumHubGoalRewards.reward_painter_double,
|
||||||
},
|
},
|
||||||
|
|
||||||
// 17
|
// 17
|
||||||
|
{
|
||||||
|
shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", // processors t4 (two varinats)
|
||||||
|
required: 30000,
|
||||||
|
reward: enumHubGoalRewards.reward_painter_quad,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 18
|
||||||
{
|
{
|
||||||
shape: finalGameShape,
|
shape: finalGameShape,
|
||||||
required: 50000,
|
required: 50000,
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { findNiceIntegerValue } from "../core/utils";
|
||||||
import { ShapeDefinition } from "./shape_definition";
|
import { ShapeDefinition } from "./shape_definition";
|
||||||
|
|
||||||
export const finalGameShape = "RuCw--Cw:----Ru--";
|
export const finalGameShape = "RuCw--Cw:----Ru--";
|
||||||
|
export const blueprintShape = "CbCbCbRb:CwCwCwCw";
|
||||||
|
|
||||||
export const UPGRADES = {
|
export const UPGRADES = {
|
||||||
belt: {
|
belt: {
|
||||||
|
|
|
@ -7,7 +7,6 @@ declare function assertAlways(condition: boolean | object | string, ...errorMess
|
||||||
|
|
||||||
declare const abstract: void;
|
declare const abstract: void;
|
||||||
|
|
||||||
declare const G_API_ENDPOINT: string;
|
|
||||||
declare const G_APP_ENVIRONMENT: string;
|
declare const G_APP_ENVIRONMENT: string;
|
||||||
declare const G_HAVE_ASSERT: boolean;
|
declare const G_HAVE_ASSERT: boolean;
|
||||||
declare const G_BUILD_TIME: number;
|
declare const G_BUILD_TIME: number;
|
||||||
|
|
|
@ -63,9 +63,7 @@ export class Savegame extends ReadWriteProxy {
|
||||||
return {
|
return {
|
||||||
version: this.getCurrentVersion(),
|
version: this.getCurrentVersion(),
|
||||||
dump: null,
|
dump: null,
|
||||||
stats: {
|
stats: {},
|
||||||
buildingsPlaced: 0,
|
|
||||||
},
|
|
||||||
lastUpdate: Date.now(),
|
lastUpdate: Date.now(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -79,7 +77,6 @@ export class Savegame extends ReadWriteProxy {
|
||||||
return ExplainedResult.bad("Can not migrate savegame, too old");
|
return ExplainedResult.bad("Can not migrate savegame, too old");
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("TODO: Migrate from", data.version);
|
|
||||||
if (data.version === 1000) {
|
if (data.version === 1000) {
|
||||||
SavegameInterface_V1001.migrate1000to1001(data);
|
SavegameInterface_V1001.migrate1000to1001(data);
|
||||||
data.version = 1001;
|
data.version = 1001;
|
||||||
|
@ -222,6 +219,12 @@ export class Savegame extends ReadWriteProxy {
|
||||||
saveMetadata() {
|
saveMetadata() {
|
||||||
this.metaDataRef.lastUpdate = new Date().getTime();
|
this.metaDataRef.lastUpdate = new Date().getTime();
|
||||||
this.metaDataRef.version = this.getCurrentVersion();
|
this.metaDataRef.version = this.getCurrentVersion();
|
||||||
|
if (!this.hasGameDump()) {
|
||||||
|
this.metaDataRef.level = 0;
|
||||||
|
} else {
|
||||||
|
this.metaDataRef.level = this.currentData.dump.hubGoals.level;
|
||||||
|
}
|
||||||
|
|
||||||
return this.app.savegameMgr.writeAsync();
|
return this.app.savegameMgr.writeAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,8 @@ export const enumLocalSavegameStatus = {
|
||||||
* @typedef {{
|
* @typedef {{
|
||||||
* lastUpdate: number,
|
* lastUpdate: number,
|
||||||
* version: number,
|
* version: number,
|
||||||
* internalId: string
|
* internalId: string,
|
||||||
|
* level: number
|
||||||
* }} SavegameMetadata
|
* }} SavegameMetadata
|
||||||
*
|
*
|
||||||
* @typedef {{
|
* @typedef {{
|
||||||
|
@ -48,7 +49,7 @@ export class SavegameManager extends ReadWriteProxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentVersion() {
|
getCurrentVersion() {
|
||||||
return 1000;
|
return 1001;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,6 +69,13 @@ export class SavegameManager extends ReadWriteProxy {
|
||||||
* @param {SavegamesData} data
|
* @param {SavegamesData} data
|
||||||
*/
|
*/
|
||||||
migrate(data) {
|
migrate(data) {
|
||||||
|
if (data.version < 1001) {
|
||||||
|
data.savegames.forEach(savegame => {
|
||||||
|
savegame.level = 0;
|
||||||
|
});
|
||||||
|
data.version = 1001;
|
||||||
|
}
|
||||||
|
|
||||||
return ExplainedResult.good();
|
return ExplainedResult.good();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ export class SavegameSerializer {
|
||||||
map: root.map.serialize(),
|
map: root.map.serialize(),
|
||||||
entityMgr: root.entityMgr.serialize(),
|
entityMgr: root.entityMgr.serialize(),
|
||||||
hubGoals: root.hubGoals.serialize(),
|
hubGoals: root.hubGoals.serialize(),
|
||||||
|
pinnedShapes: root.hud.parts.pinnedShapes.serialize(),
|
||||||
};
|
};
|
||||||
|
|
||||||
data.entities = this.internal.serializeEntityArray(root.entityMgr.entities);
|
data.entities = this.internal.serializeEntityArray(root.entityMgr.entities);
|
||||||
|
@ -118,7 +119,7 @@ export class SavegameSerializer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to load the savegame from a given dump
|
* Tries to load the savegame from a given dump
|
||||||
* @param {SerializedGame} savegame
|
* @param {import("./savegame_typedefs").SerializedGame} savegame
|
||||||
* @param {GameRoot} root
|
* @param {GameRoot} root
|
||||||
* @returns {ExplainedResult}
|
* @returns {ExplainedResult}
|
||||||
*/
|
*/
|
||||||
|
@ -135,6 +136,7 @@ export class SavegameSerializer {
|
||||||
errorReason = errorReason || root.camera.deserialize(savegame.camera);
|
errorReason = errorReason || root.camera.deserialize(savegame.camera);
|
||||||
errorReason = errorReason || root.map.deserialize(savegame.map);
|
errorReason = errorReason || root.map.deserialize(savegame.map);
|
||||||
errorReason = errorReason || root.hubGoals.deserialize(savegame.hubGoals);
|
errorReason = errorReason || root.hubGoals.deserialize(savegame.hubGoals);
|
||||||
|
errorReason = errorReason || root.hud.parts.pinnedShapes.deserialize(savegame.pinnedShapes);
|
||||||
errorReason = errorReason || this.internal.deserializeEntityArray(root, savegame.entities);
|
errorReason = errorReason || this.internal.deserializeEntityArray(root, savegame.entities);
|
||||||
|
|
||||||
// Check for errors
|
// Check for errors
|
||||||
|
@ -144,47 +146,4 @@ export class SavegameSerializer {
|
||||||
|
|
||||||
return ExplainedResult.good();
|
return ExplainedResult.good();
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////// MIGRATION HELPERS ///////////
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs a function on each component (useful to add / remove / alter properties for migration)
|
|
||||||
* @param {SerializedGame} savegame
|
|
||||||
* @param {typeof Component} componentHandle
|
|
||||||
* @param {function} modifier
|
|
||||||
*/
|
|
||||||
migration_migrateComponent(savegame, componentHandle, modifier) {
|
|
||||||
const targetId = componentHandle.getId();
|
|
||||||
for (const entityListId in savegame.entities) {
|
|
||||||
for (let i = 0; i < savegame.entities[entityListId].length; ++i) {
|
|
||||||
const list = savegame.entities[entityListId][i];
|
|
||||||
for (let k = 0; k < list.length; ++k) {
|
|
||||||
const entity = list[k];
|
|
||||||
const components = entity.components;
|
|
||||||
if (components[targetId]) {
|
|
||||||
modifier(components[targetId]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs an operation on each object which is a PooledObject (usually Projectiles). Useful to
|
|
||||||
* perform migrations
|
|
||||||
* @param {Array<any>} pools
|
|
||||||
* @param {string} targetClassKey
|
|
||||||
* @param {function} modifier
|
|
||||||
*/
|
|
||||||
migration_migrateGenericObjectPool(pools, targetClassKey, modifier) {
|
|
||||||
for (let i = 0; i < pools.length; ++i) {
|
|
||||||
const pool = pools[i];
|
|
||||||
if (pool.key === targetClassKey) {
|
|
||||||
const entries = pool.data.entries;
|
|
||||||
for (const uid in entries) {
|
|
||||||
modifier(entries[uid]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
|
import { Entity } from "../game/entity";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {{
|
* @typedef {{
|
||||||
* buildingsPlaced: number
|
|
||||||
* }} SavegameStats
|
* }} SavegameStats
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Entity } from "../game/entity";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {{
|
* @typedef {{
|
||||||
* camera: any,
|
* camera: any,
|
||||||
|
@ -13,6 +12,7 @@ import { Entity } from "../game/entity";
|
||||||
* entityMgr: any,
|
* entityMgr: any,
|
||||||
* map: any,
|
* map: any,
|
||||||
* hubGoals: any,
|
* hubGoals: any,
|
||||||
|
* pinnedShapes: any,
|
||||||
* entities: Array<Entity>
|
* entities: Array<Entity>
|
||||||
* }} SerializedGame
|
* }} SerializedGame
|
||||||
*/
|
*/
|
||||||
|
@ -22,6 +22,6 @@ import { Entity } from "../game/entity";
|
||||||
* version: number,
|
* version: number,
|
||||||
* dump: SerializedGame,
|
* dump: SerializedGame,
|
||||||
* stats: SavegameStats,
|
* stats: SavegameStats,
|
||||||
* lastUpdate: number
|
* lastUpdate: number,
|
||||||
* }} SavegameData
|
* }} SavegameData
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -24,6 +24,10 @@ export class SavegameInterface_V1001 extends SavegameInterface_V1000 {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dump.pinnedShapes = {
|
||||||
|
shapes: [],
|
||||||
|
};
|
||||||
|
|
||||||
const entities = dump.entities;
|
const entities = dump.entities;
|
||||||
for (let i = 0; i < entities.length; ++i) {
|
for (let i = 0; i < entities.length; ++i) {
|
||||||
const entity = entities[i];
|
const entity = entities[i];
|
||||||
|
|
|
@ -283,8 +283,10 @@ export class MainMenuState extends GameState {
|
||||||
makeDiv(
|
makeDiv(
|
||||||
elem,
|
elem,
|
||||||
null,
|
null,
|
||||||
["updateTime"],
|
["level"],
|
||||||
formatSecondsToTimeAgo((new Date().getTime() - games[i].lastUpdate) / 1000.0)
|
games[i].level
|
||||||
|
? T.mainMenu.savegameLevel.replace("<x>", "" + games[i].level)
|
||||||
|
: T.mainMenu.savegameLevelUnknown
|
||||||
);
|
);
|
||||||
|
|
||||||
const deleteButton = document.createElement("button");
|
const deleteButton = document.createElement("button");
|
||||||
|
|
|
@ -78,6 +78,9 @@ mainMenu:
|
||||||
browserWarning: >-
|
browserWarning: >-
|
||||||
Sorry, but the game is known to run slow on your browser! Get the standalone version or download chrome for the full experience.
|
Sorry, but the game is known to run slow on your browser! Get the standalone version or download chrome for the full experience.
|
||||||
|
|
||||||
|
savegameLevel: Level <x>
|
||||||
|
savegameLevelUnknown: Unknown Level
|
||||||
|
|
||||||
dialogs:
|
dialogs:
|
||||||
buttons:
|
buttons:
|
||||||
ok: OK
|
ok: OK
|
||||||
|
@ -177,6 +180,11 @@ dialogs:
|
||||||
desc: >-
|
desc: >-
|
||||||
You are deleting a lot of buildings (<count> to be exact)! Are you sure you want to do this?
|
You are deleting a lot of buildings (<count> to be exact)! Are you sure you want to do this?
|
||||||
|
|
||||||
|
blueprintsNotUnlocked:
|
||||||
|
title: Not unlocked yet
|
||||||
|
desc: >-
|
||||||
|
Blueprints have not been unlocked yet! Complete more levels to unlock them.
|
||||||
|
|
||||||
ingame:
|
ingame:
|
||||||
# This is shown in the top left corner and displays useful keybindings in
|
# This is shown in the top left corner and displays useful keybindings in
|
||||||
# every situation
|
# every situation
|
||||||
|
@ -447,6 +455,10 @@ storyRewards:
|
||||||
title: Freeplay
|
title: Freeplay
|
||||||
desc: You did it! You unlocked the <strong>free-play mode</strong>! This means that shapes are now randomly generated! (No worries, more content is planned for the standalone!)
|
desc: You did it! You unlocked the <strong>free-play mode</strong>! This means that shapes are now randomly generated! (No worries, more content is planned for the standalone!)
|
||||||
|
|
||||||
|
reward_blueprints:
|
||||||
|
title: Blueprints
|
||||||
|
desc: You can now <strong>copy and paste</strong> parts of your factory! Select an area (Hold ctrl, then drag), then press 'C' to copy it.<br><br>Pasting it is not free, you need to produce blueprint shapes to afford it! (Those you just delivered).
|
||||||
|
|
||||||
# Special reward, which is shown when there is no reward actually
|
# Special reward, which is shown when there is no reward actually
|
||||||
no_reward:
|
no_reward:
|
||||||
title: Next level
|
title: Next level
|
||||||
|
|
Loading…
Reference in New Issue