Do not allow saving in the demo version

pull/33/head
tobspr 4 years ago
parent 8abe84b120
commit 9c4fe248db

@ -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 {

@ -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;
}
}

@ -1,5 +1,5 @@
#state_AboutState {
.content {
> .container .content {
@include PlainText;
}
}

@ -21,4 +21,11 @@
right: 0;
bottom: 0;
}
#ingame_HUD_ModalDialogs {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
}

@ -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);

@ -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 {

@ -6,7 +6,7 @@
$padding: 15px;
.headerBar,
.content {
> .container .content {
@include S(width, 500px);
}

@ -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!

@ -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);
}

@ -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();
}

@ -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<string>} 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<string>} 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>", 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,

@ -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";
}

@ -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,
}),
];

@ -7,6 +7,8 @@ import { T } from "../translations";
const logger = createLogger("setting_types");
const standaloneOnlySettingHtml = `<span class="standaloneOnlyHint">${T.demo.settingNotAvailable}</span>`;
export class BaseSetting {
/**
*
@ -113,6 +115,7 @@ export class EnumSetting extends BaseSetting {
getHtml() {
return `
<div class="setting cardbox ${this.enabled ? "enabled" : "disabled"}">
${this.enabled ? "" : standaloneOnlySettingHtml}
<div class="row">
<label>${T.settings.labels[this.id].title}</label>
<div class="value enum" data-setting="${this.id}"></div>
@ -186,6 +189,8 @@ export class BoolSetting extends BaseSetting {
getHtml() {
return `
<div class="setting cardbox ${this.enabled ? "enabled" : "disabled"}">
${this.enabled ? "" : standaloneOnlySettingHtml}
<div class="row">
<label>${T.settings.labels[this.id].title}</label>
<div class="value checkbox checked" data-setting="${this.id}">

@ -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 <a href="https://github.com/tobspr" target="_blank">Tobias Springer</a> (this is me).
<br><br>
If you want to contribute, check out <a href="https://github.com/tobspr/shapez.io" target="_blank">shapez.io on github</a>.
If you want to contribute, check out <a href="${THIRDPARTY_URLS.github}" target="_blank">shapez.io on github</a>.
<br><br>
This game wouldn't have been possible without the great discord community arround my games - You should really join the <a href="https://discord.gg/HN7EVzV" target="_blank">discord server</a>!
This game wouldn't have been possible without the great discord community arround my games - You should really join the <a href="${THIRDPARTY_URLS.discord}" target="_blank">discord server</a>!
<br><br>
The soundtrack was made by <a href="https://soundcloud.com/pettersumelius" target="_blank">Peppsen</a> - He's awesome.
<br><br>

@ -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,

@ -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 {
<div class="logo">
<img src="${cachebust("res/logo.png")}" alt="shapez.io Logo">
${
G_IS_STANDALONE
? ""
: `
<div class="demoBadge"></div>
`
}
${IS_DEMO ? `<div class="demoBadge"></div>` : ""}
</div>
<div class="mainWrapper">
<div class="mainWrapper ${IS_DEMO ? "demo" : "noDemo"}">
${
G_IS_STANDALONE
? ""
: `
<div class="standaloneBanner leftSide">${bannerHtml}</div>
`
}
${IS_DEMO ? `<div class="standaloneBanner leftSide">${bannerHtml}</div>` : ""}
<div class="mainContainer">
${
isSupportedBrowser()
? ""
: `
<div class="browserWarning">${T.mainMenu.browserWarning}</div>
`
}
${
isSupportedBrowser()
? ""
: `<div class="browserWarning">${T.mainMenu.browserWarning}</div>`
}
<button class="playButton styledButton">${T.mainMenu.play}</button>
<button class="importButton styledButton">${T.mainMenu.importSavegame}</button>
</div>
${
G_IS_STANDALONE
? ""
: `
<div class="standaloneBanner rightSide">${bannerHtml}</div>
`
}
${IS_DEMO ? `<div class="standaloneBanner leftSide">${bannerHtml}</div>` : ""}
</div>
<div class="footer">
<a href="https://github.com/tobspr/shapez.io" target="_blank">
<a href="${THIRDPARTY_URLS.github}" target="_blank">
${T.mainMenu.openSourceHint}
<span class="thirdpartyLogo githubLogo"></span>
</a>
<a href="https://discord.gg/HN7EVzV" target="_blank">
<a href="${THIRDPARTY_URLS.discord}" target="_blank">
${T.mainMenu.discordLink}
<span class="thirdpartyLogo discordLogo"></span>
</a>
@ -101,6 +80,11 @@ export class MainMenuState extends GameState {
}
requestImportSavegame() {
if (IS_DEMO) {
this.dialogs.showFeatureRestrictionInfo(T.demo.features.importingGames);
return;
}
var input = document.createElement("input");
input.type = "file";
input.accept = ".bin";
@ -260,6 +244,12 @@ export class MainMenuState extends GameState {
*/
resumeGame(game) {
this.app.analytics.trackUiClick("resume_game");
if (IS_DEMO) {
this.dialogs.showFeatureRestrictionInfo(T.demo.features.restoringGames);
return;
}
const savegame = this.app.savegameMgr.getSavegameById(game.internalId);
savegame.readAsync().then(() => {
this.moveToState("InGameState", {

@ -59,11 +59,11 @@ demoBanners:
# This is the "advertisement" shown in the main menu and other various places
title: This is a demo version
intro: >-
Get <strong>shapez.io on steam</strong> for:
Get <strong>shapez.io on steam</strong> to:
advantages:
- Save and resume your games.
- No advertisements.
- Unlimited savegame slots.
- Supporting the developer ❤️
- Support the developer ❤️
mainMenu:
play: Play
@ -83,6 +83,7 @@ dialogs:
later: Later
restart: Restart
reset: Reset
getStandalone: Get Standalone
importSavegameError:
title: Import Error
@ -126,6 +127,13 @@ dialogs:
title: Keybindings reset
desc: The keybindings have been reset to their respective defaults!
featureRestriction:
title: Demo Version
desc: You tried to access a feature (<feature>) which is not available in the demo. Consider to get the standalone for the full experience!
saveNotPossibleInDemo:
desc: Your game has been saved, but restoring it is only possible in the standalone version. Consider to get the standalone for the full experience!
ingame:
# This is shown in the top left corner and displays useful keybindings in
# every situation
@ -337,7 +345,7 @@ settings:
theme:
title: Game theme
description: >-
Choose the game theme which mainly affects the map background. Notice that everything except the light theme may lead to graphical issues.
Choose the game theme (light / dark).
refreshRate:
title: Simulation Target
@ -399,3 +407,11 @@ keybindings:
about:
title: About this Game
demo:
features:
restoringGames: Restoring savegames
importingGames: Importing savegames
customizeKeybindings: Customizing Keybindings
settingNotAvailable: Not available in the demo.

Loading…
Cancel
Save