From 9c4fe248db3662344b50c4e10eaf5d6f5f4f0fe1 Mon Sep 17 00:00:00 2001 From: tobspr Date: Tue, 19 May 2020 15:03:13 +0200 Subject: [PATCH] Do not allow saving in the demo version --- src/css/ingame_hud/dialogs.scss | 3 +- src/css/main.scss | 3 +- src/css/states/about.scss | 2 +- src/css/states/ingame.scss | 7 +++ src/css/states/main_menu.scss | 16 +++++-- src/css/states/settings.scss | 18 +++++++- src/css/textual_game_state.scss | 2 +- src/js/core/config.js | 10 +++++ src/js/game/hud/hud.js | 7 ++- src/js/game/hud/parts/game_menu.js | 8 ++++ src/js/game/hud/parts/modal_dialogs.js | 50 +++++++++++++++++++-- src/js/game/hud/parts/watermark.js | 8 +--- src/js/profile/application_settings.js | 5 ++- src/js/profile/setting_types.js | 5 +++ src/js/states/about.js | 5 ++- src/js/states/keybindings.js | 6 +++ src/js/states/main_menu.js | 60 +++++++++++--------------- translations/base-en.yaml | 24 +++++++++-- 18 files changed, 177 insertions(+), 62 deletions(-) diff --git a/src/css/ingame_hud/dialogs.scss b/src/css/ingame_hud/dialogs.scss index 45015115..d2315063 100644 --- a/src/css/ingame_hud/dialogs.scss +++ b/src/css/ingame_hud/dialogs.scss @@ -53,8 +53,6 @@ > .dialogInner { background: #fff; - @include S(min-width, 300px); - max-width: calc(100vw - #{D(40px)}); max-height: calc(100vh - #{D(40px)}); @include S(border-radius, $globalBorderRadius); display: flex; @@ -118,6 +116,7 @@ @include PlainText; overflow-y: auto; pointer-events: all; + @include S(width, 350px); } > .buttons { diff --git a/src/css/main.scss b/src/css/main.scss index c5fe6305..e4ee1b24 100644 --- a/src/css/main.scss +++ b/src/css/main.scss @@ -71,6 +71,7 @@ ingame_HUD_BetaOverlay, ingame_HUD_UnlockNotification, ingame_HUD_Shop, ingame_HUD_Statistics, +ingame_HUD_ModalDialogs, ingame_HUD_SettingsMenu; $zindex: 100; @@ -96,7 +97,7 @@ body.uiHidden { body.modalDialogActive, body.ingameDialogOpen { - > *:not(.ingameDialog):not(.modalDialogParent):not(.loadingDialog):not(.gameLoadingOverlay) { + > *:not(.ingameDialog):not(.modalDialogParent):not(.loadingDialog):not(.gameLoadingOverlay):not(#ingame_HUD_ModalDialogs) { filter: blur(5px) !important; } } diff --git a/src/css/states/about.scss b/src/css/states/about.scss index 1875804e..f2b234fb 100644 --- a/src/css/states/about.scss +++ b/src/css/states/about.scss @@ -1,5 +1,5 @@ #state_AboutState { - .content { + > .container .content { @include PlainText; } } diff --git a/src/css/states/ingame.scss b/src/css/states/ingame.scss index e131c1d7..8b0a614c 100644 --- a/src/css/states/ingame.scss +++ b/src/css/states/ingame.scss @@ -21,4 +21,11 @@ right: 0; bottom: 0; } + #ingame_HUD_ModalDialogs { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + } } diff --git a/src/css/states/main_menu.scss b/src/css/states/main_menu.scss index d933bbde..42f24c15 100644 --- a/src/css/states/main_menu.scss +++ b/src/css/states/main_menu.scss @@ -53,12 +53,22 @@ } .mainWrapper { - display: grid; - grid-template-columns: 1fr 1fr 1fr; @include S(padding, 0, 10px); align-items: center; justify-items: center; - @include S(grid-column-gap, 10px); + + &.noDemo { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + } + + &.demo { + @include S(grid-column-gap, 10px); + display: grid; + grid-template-columns: 1fr 1fr 1fr; + } .standaloneBanner { background: rgb(255, 225, 238); diff --git a/src/css/states/settings.scss b/src/css/states/settings.scss index 61deac4e..e52152c3 100644 --- a/src/css/states/settings.scss +++ b/src/css/states/settings.scss @@ -41,12 +41,28 @@ } &.disabled { - opacity: 0.3; + // opacity: 0.3; pointer-events: none; * { pointer-events: none !important; cursor: default !important; } + position: relative; + .standaloneOnlyHint { + @include PlainText; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + pointer-events: all; + display: flex; + align-items: center; + justify-content: center; + background: rgba(#fff, 0.5); + text-transform: uppercase; + color: $colorRedBright; + } } .value.enum { diff --git a/src/css/textual_game_state.scss b/src/css/textual_game_state.scss index deac7faf..897c379a 100644 --- a/src/css/textual_game_state.scss +++ b/src/css/textual_game_state.scss @@ -6,7 +6,7 @@ $padding: 15px; .headerBar, - .content { + > .container .content { @include S(width, 500px); } diff --git a/src/js/core/config.js b/src/js/core/config.js index e32d6ffb..31ced8c2 100644 --- a/src/js/core/config.js +++ b/src/js/core/config.js @@ -5,8 +5,18 @@ export const IS_DEBUG = (window.location.host.indexOf("localhost:") >= 0 || window.location.host.indexOf("192.168.0.") >= 0) && window.location.search.indexOf("nodebug") < 0; +// export const IS_DEMO = G_IS_PROD; +export const IS_DEMO = G_IS_RELEASE; + const smoothCanvas = true; +export const THIRDPARTY_URLS = { + discord: "https://discord.gg/HN7EVzV", + github: "https://github.com/tobspr/shapez.io", + + standaloneStorePage: "https://steam.shapez.io", +}; + export const globalConfig = { // Size of a single tile in Pixels. // NOTICE: Update webpack.production.config too! diff --git a/src/js/game/hud/hud.js b/src/js/game/hud/hud.js index 4c2a53a6..cb591687 100644 --- a/src/js/game/hud/hud.js +++ b/src/js/game/hud/hud.js @@ -12,7 +12,7 @@ import { HUDKeybindingOverlay } from "./parts/keybinding_overlay"; import { HUDUnlockNotification } from "./parts/unlock_notification"; import { HUDGameMenu } from "./parts/game_menu"; import { HUDShop } from "./parts/shop"; -import { IS_MOBILE, globalConfig } from "../../core/config"; +import { IS_MOBILE, globalConfig, IS_DEMO } from "../../core/config"; import { HUDMassSelector } from "./parts/mass_selector"; import { HUDVignetteOverlay } from "./parts/vignette_overlay"; import { HUDStatistics } from "./parts/statistics"; @@ -25,6 +25,7 @@ import { HUDDebugInfo } from "./parts/debug_info"; import { HUDEntityDebugger } from "./parts/entity_debugger"; import { KEYMAPPINGS } from "../key_action_mapper"; import { HUDWatermark } from "./parts/watermark"; +import { HUDModalDialogs } from "./parts/modal_dialogs"; export class GameHUD { /** @@ -62,6 +63,8 @@ export class GameHUD { // betaOverlay: new HUDBetaOverlay(this.root), debugInfo: new HUDDebugInfo(this.root), + + dialogs: new HUDModalDialogs(this.root), }; this.signals = { @@ -78,7 +81,7 @@ export class GameHUD { this.parts.entityDebugger = new HUDEntityDebugger(this.root); } - if (!G_IS_STANDALONE && G_IS_RELEASE) { + if (IS_DEMO) { this.parts.watermark = new HUDWatermark(this.root); } diff --git a/src/js/game/hud/parts/game_menu.js b/src/js/game/hud/parts/game_menu.js index 5877a5bd..86ad2564 100644 --- a/src/js/game/hud/parts/game_menu.js +++ b/src/js/game/hud/parts/game_menu.js @@ -4,6 +4,7 @@ import { SOUNDS } from "../../../platform/sound"; import { enumNotificationType } from "./notifications"; import { T } from "../../../translations"; import { KEYMAPPINGS } from "../../key_action_mapper"; +import { IS_DEMO } from "../../../core/config"; export class HUDGameMenu extends BaseHUDPart { initialize() {} @@ -117,6 +118,13 @@ export class HUDGameMenu extends BaseHUDPart { } startSave() { + if (IS_DEMO) { + this.root.hud.parts.dialogs.showFeatureRestrictionInfo( + null, + T.dialogs.saveNotPossibleInDemo.desc + ); + } + this.root.gameState.doSave(); } diff --git a/src/js/game/hud/parts/modal_dialogs.js b/src/js/game/hud/parts/modal_dialogs.js index 67f8f1a2..95428691 100644 --- a/src/js/game/hud/parts/modal_dialogs.js +++ b/src/js/game/hud/parts/modal_dialogs.js @@ -7,6 +7,8 @@ import { DynamicDomAttach } from "../dynamic_dom_attach"; import { BaseHUDPart } from "../base_hud_part"; import { Dialog, DialogLoading, DialogOptionChooser } from "../../../core/modal_dialog_elements"; import { makeDiv } from "../../../core/utils"; +import { T } from "../../../translations"; +import { THIRDPARTY_URLS } from "../../../core/config"; export class HUDModalDialogs extends BaseHUDPart { constructor(root, app) { @@ -14,7 +16,7 @@ export class HUDModalDialogs extends BaseHUDPart { super(root); /** @type {Application} */ - this.app = app; + this.app = root ? root.app : app; this.dialogParent = null; this.dialogStack = []; @@ -22,7 +24,7 @@ export class HUDModalDialogs extends BaseHUDPart { // For use inside of the game, implementation of base hud part initialize() { - this.dialogParent = document.getElementById("rg_HUD_ModalDialogs"); + this.dialogParent = document.getElementById("ingame_HUD_ModalDialogs"); this.domWatcher = new DynamicDomAttach(this.root, this.dialogParent); } @@ -35,7 +37,7 @@ export class HUDModalDialogs extends BaseHUDPart { } createElements(parent) { - return makeDiv(parent, "rg_HUD_ModalDialogs"); + return makeDiv(parent, "ingame_HUD_ModalDialogs"); } // For use outside of the game @@ -46,6 +48,11 @@ export class HUDModalDialogs extends BaseHUDPart { // Methods + /** + * @param {string} title + * @param {string} text + * @param {Array} buttons + */ showInfo(title, text, buttons = ["ok:good"]) { const dialog = new Dialog({ app: this.app, @@ -63,6 +70,11 @@ export class HUDModalDialogs extends BaseHUDPart { return dialog.buttonSignals; } + /** + * @param {string} title + * @param {string} text + * @param {Array} buttons + */ showWarning(title, text, buttons = ["ok:good"]) { const dialog = new Dialog({ app: this.app, @@ -80,6 +92,38 @@ export class HUDModalDialogs extends BaseHUDPart { return dialog.buttonSignals; } + /** + * @param {string} feature + * @param {string} textPrefab + */ + showFeatureRestrictionInfo(feature, textPrefab = T.dialogs.featureRestriction.desc) { + const dialog = new Dialog({ + app: this.app, + title: T.dialogs.featureRestriction.title, + contentHTML: textPrefab.replace("", feature), + buttons: ["cancel:bad", "getStandalone:good"], + type: "warning", + }); + this.internalShowDialog(dialog); + + if (this.app) { + this.app.sound.playUiSound(SOUNDS.dialogOk); + } + + this.app.analytics.trackUiClick("demo_dialog_show"); + + dialog.buttonSignals.cancel.add(() => { + this.app.analytics.trackUiClick("demo_dialog_cancel"); + }); + + dialog.buttonSignals.getStandalone.add(() => { + this.app.analytics.trackUiClick("demo_dialog_click"); + window.open(THIRDPARTY_URLS.standaloneStorePage); + }); + + return dialog.buttonSignals; + } + showOptionChooser(title, options) { const dialog = new DialogOptionChooser({ app: this.app, diff --git a/src/js/game/hud/parts/watermark.js b/src/js/game/hud/parts/watermark.js index 2ba1a6e3..b5d7c164 100644 --- a/src/js/game/hud/parts/watermark.js +++ b/src/js/game/hud/parts/watermark.js @@ -14,13 +14,9 @@ export class HUDWatermark extends BaseHUDPart { const w = this.root.gameWidth; parameters.context.fillStyle = "#f77"; - parameters.context.font = "50px GameFont"; + parameters.context.font = "bold " + this.root.app.getEffectiveUiScale() * 15 + "px GameFont"; parameters.context.textAlign = "center"; - parameters.context.fillText("DEMO VERSION", w / 2, 100); - - parameters.context.fillStyle = "#aaaca9"; - parameters.context.font = "20px GameFont"; - parameters.context.fillText("Get shapez.io on steam for the full experience!", w / 2, 140); + parameters.context.fillText("DEMO VERSION", w / 2, 50); parameters.context.textAlign = "left"; } diff --git a/src/js/profile/application_settings.js b/src/js/profile/application_settings.js index 95222f35..ac5f60e9 100644 --- a/src/js/profile/application_settings.js +++ b/src/js/profile/application_settings.js @@ -7,6 +7,7 @@ import { BoolSetting, EnumSetting, BaseSetting } from "./setting_types"; import { createLogger } from "../core/logging"; import { ExplainedResult } from "../core/explained_result"; import { THEMES, THEME, applyGameTheme } from "../game/theme"; +import { IS_DEMO } from "../core/config"; const logger = createLogger("application_settings"); @@ -66,7 +67,7 @@ export const allApplicationSettings = [ app.platformWrapper.setFullscreen(value); } }, - G_IS_STANDALONE + !IS_DEMO ), new BoolSetting( @@ -101,6 +102,7 @@ export const allApplicationSettings = [ applyGameTheme(id); document.body.setAttribute("data-theme", id); }, + enabled: !IS_DEMO, }), new EnumSetting("refreshRate", { @@ -114,6 +116,7 @@ export const allApplicationSettings = [ * @param {Application} app */ (app, id) => {}, + enabled: !IS_DEMO, }), ]; diff --git a/src/js/profile/setting_types.js b/src/js/profile/setting_types.js index f2f29bc9..3b1b3dd7 100644 --- a/src/js/profile/setting_types.js +++ b/src/js/profile/setting_types.js @@ -7,6 +7,8 @@ import { T } from "../translations"; const logger = createLogger("setting_types"); +const standaloneOnlySettingHtml = `${T.demo.settingNotAvailable}`; + export class BaseSetting { /** * @@ -113,6 +115,7 @@ export class EnumSetting extends BaseSetting { getHtml() { return `
+ ${this.enabled ? "" : standaloneOnlySettingHtml}
@@ -186,6 +189,8 @@ export class BoolSetting extends BaseSetting { getHtml() { return `
+ ${this.enabled ? "" : standaloneOnlySettingHtml} +
diff --git a/src/js/states/about.js b/src/js/states/about.js index b112335c..81d556e0 100644 --- a/src/js/states/about.js +++ b/src/js/states/about.js @@ -3,6 +3,7 @@ import { SOUNDS } from "../platform/sound"; import { T } from "../translations"; import { KEYMAPPINGS, getStringForKeyCode } from "../game/key_action_mapper"; import { Dialog } from "../core/modal_dialog_elements"; +import { THIRDPARTY_URLS } from "../core/config"; export class AboutState extends TextualGameState { constructor() { @@ -17,9 +18,9 @@ export class AboutState extends TextualGameState { return ` This game is open source and developed by Tobias Springer (this is me).

- If you want to contribute, check out shapez.io on github. + If you want to contribute, check out shapez.io on github.

- This game wouldn't have been possible without the great discord community arround my games - You should really join the discord server! + This game wouldn't have been possible without the great discord community arround my games - You should really join the discord server!

The soundtrack was made by Peppsen - He's awesome.

diff --git a/src/js/states/keybindings.js b/src/js/states/keybindings.js index f7997850..aa6ec2d6 100644 --- a/src/js/states/keybindings.js +++ b/src/js/states/keybindings.js @@ -3,6 +3,7 @@ import { SOUNDS } from "../platform/sound"; import { T } from "../translations"; import { KEYMAPPINGS, getStringForKeyCode } from "../game/key_action_mapper"; import { Dialog } from "../core/modal_dialog_elements"; +import { IS_DEMO } from "../core/config"; export class KeybindingsState extends TextualGameState { constructor() { @@ -81,6 +82,11 @@ export class KeybindingsState extends TextualGameState { } editKeybinding(id) { + if (IS_DEMO) { + this.dialogs.showFeatureRestrictionInfo(T.demo.features.customizeKeybindings); + return; + } + const dialog = new Dialog({ app: this.app, title: T.dialogs.editKeybinding.title, diff --git a/src/js/states/main_menu.js b/src/js/states/main_menu.js index ad8f38a1..cb93156b 100644 --- a/src/js/states/main_menu.js +++ b/src/js/states/main_menu.js @@ -1,6 +1,6 @@ import { GameState } from "../core/game_state"; import { cachebust } from "../core/cachebust"; -import { globalConfig } from "../core/config"; +import { globalConfig, IS_DEBUG, IS_DEMO, THIRDPARTY_URLS } from "../core/config"; import { makeDiv, formatSecondsToTimeAgo, @@ -41,57 +41,36 @@ export class MainMenuState extends GameState { -
+
- ${ - G_IS_STANDALONE - ? "" - : ` -
${bannerHtml}
- ` - } + ${IS_DEMO ? `
${bannerHtml}
` : ""} +
- ${ - isSupportedBrowser() - ? "" - : ` -
${T.mainMenu.browserWarning}
- ` - } - + ${ + isSupportedBrowser() + ? "" + : `
${T.mainMenu.browserWarning}
` + }
- - ${ - G_IS_STANDALONE - ? "" - : ` -
${bannerHtml}
- ` - } + + ${IS_DEMO ? `
${bannerHtml}
` : ""}