1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2024-10-27 20:34:29 +00:00

Merge branch 'master' of https://github.com/tobspr/shapez.io into gh-actions

Merge
This commit is contained in:
Modded Gamers 2020-05-26 07:44:24 -04:00
commit ea50dc9790
30 changed files with 201 additions and 52 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 904 KiB

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<title>Iframe test</title>
</head>
<body style="background: #333438; color: #eee;"></body>
<iframe
src="http://localhost:3005?embed=kongregate"
width="800"
height="600"
scrolling="auto"
frameborder="0"
border="0"
allowfullscreen
></iframe>
</html>

View File

@ -2,11 +2,11 @@
<html> <html>
<head> <head>
<title>Redirecting to shapez.io</title> <title>Redirecting to shapez.io</title>
<meta http-equiv="refresh" content="0; URL=https://shapez.io" /> <meta http-equiv="refresh" content="0; URL=https://shapez.io?embed=kongregate" />
</head> </head>
<body style="background: #333438; color: #eee;"> <body style="background: #333438; color: #eee;">
Redirecting you to Redirecting you to
<a href="https://shapez.io" style="color: #39f; text-decoration: none;">shapez.io</a> <a href="https://shapez.io?embed=kongregate" style="color: #39f; text-decoration: none;">shapez.io</a>
</body> </body>
</html> </html>

View File

@ -117,6 +117,10 @@
overflow-y: auto; overflow-y: auto;
pointer-events: all; pointer-events: all;
@include S(width, 350px); @include S(width, 350px);
> strong {
font-weight: bold;
}
} }
> .buttons { > .buttons {
@ -143,6 +147,32 @@
background-color: $colorRedBright; background-color: $colorRedBright;
color: #fff; color: #fff;
} }
&.timedButton {
pointer-events: none;
cursor: default;
position: relative;
overflow: hidden;
&::after {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: unset;
z-index: 5;
content: " ";
display: inline-block;
background: rgba(#fff, 0.6);
@include InlineAnimation(5s linear) {
0% {
width: 100%;
}
100% {
width: 0%;
}
}
}
}
} }
} }
} }

View File

@ -19,6 +19,13 @@
.changes { .changes {
@include SuperSmallText; @include SuperSmallText;
@include S(padding-left, 20px); @include S(padding-left, 20px);
strong {
background: $colorBlueBright;
color: #fff;
text-transform: uppercase;
@include S(padding, 1px, 2px);
@include S(margin-right, 3px);
}
} }
} }
} }

View File

@ -7,11 +7,14 @@
} }
.changelogDialogEntry { .changelogDialogEntry {
margin-top: 10px;
width: 100%; width: 100%;
flex-direction: column; flex-direction: column;
text-align: left; text-align: left;
padding: 10px; padding: 10px;
box-sizing: border-box; box-sizing: border-box;
background: #eef1f4;
.version { .version {
@include Heading; @include Heading;
} }
@ -25,7 +28,14 @@
.changes { .changes {
@include SuperSmallText; @include SuperSmallText;
@include S(padding-left, 20px); @include S(padding-left, 15px);
strong {
background: $colorBlueBright;
color: #fff;
text-transform: uppercase;
@include S(padding, 1px, 2px);
@include S(margin-right, 3px);
}
} }
} }

View File

@ -146,12 +146,8 @@ export class Application {
} }
this.analytics = new GoogleAnalyticsImpl(this); this.analytics = new GoogleAnalyticsImpl(this);
if (queryParamOptions.betaMode) {
this.gameAnalytics = new NoGameAnalytics(this);
} else {
this.gameAnalytics = new ShapezGameAnalytics(this); this.gameAnalytics = new ShapezGameAnalytics(this);
} }
}
/** /**
* Registers all game states * Registers all game states
@ -232,6 +228,7 @@ export class Application {
* @param {Event} event * @param {Event} event
*/ */
handleVisibilityChange(event) { handleVisibilityChange(event) {
window.focus();
const pageVisible = !document[pageHiddenPropName]; const pageVisible = !document[pageHiddenPropName];
if (pageVisible !== this.pageVisible) { if (pageVisible !== this.pageVisible) {
this.pageVisible = pageVisible; this.pageVisible = pageVisible;
@ -271,6 +268,7 @@ export class Application {
onAppRenderableStateChanged(renderable) { onAppRenderableStateChanged(renderable) {
logger.log("Application renderable:", renderable); logger.log("Application renderable:", renderable);
window.focus();
if (!renderable) { if (!renderable) {
this.stateMgr.getCurrentState().onAppPause(); this.stateMgr.getCurrentState().onAppPause();
} else { } else {
@ -301,8 +299,7 @@ export class Application {
logSection("BEFORE UNLOAD HANDLER", "#f77"); logSection("BEFORE UNLOAD HANDLER", "#f77");
if (!G_IS_DEV && this.stateMgr.getCurrentState().getHasUnloadConfirmation()) { if (!G_IS_DEV && this.stateMgr.getCurrentState().getHasUnloadConfirmation()) {
if (G_IS_STANDALONE) { if (!G_IS_STANDALONE) {
} else {
// Need to show a "Are you sure you want to exit" // Need to show a "Are you sure you want to exit"
event.preventDefault(); event.preventDefault();
event.returnValue = "Are you sure you want to exit?"; event.returnValue = "Are you sure you want to exit?";
@ -314,6 +311,7 @@ export class Application {
* Boots the application * Boots the application
*/ */
boot() { boot() {
console.log("Booting ...");
this.registerStates(); this.registerStates();
this.registerEventListeners(); this.registerEventListeners();
@ -330,6 +328,8 @@ export class Application {
this.ticker.frameEmitted.add(this.onFrameEmitted, this); this.ticker.frameEmitted.add(this.onFrameEmitted, this);
this.ticker.bgFrameEmitted.add(this.onBackgroundFrame, this); this.ticker.bgFrameEmitted.add(this.onBackgroundFrame, this);
this.ticker.start(); this.ticker.start();
window.focus();
} }
/** /**

View File

@ -1,4 +1,19 @@
export const CHANGELOG = [ export const CHANGELOG = [
{
version: "1.0.4",
date: "unreleased",
entries: [
"<strong>Balancing</strong> Reduce cost of first painting upgrade, and change 'Shape Processing' to 'Cutting, Rotating & Stacking'",
"<strong>Tutorial</strong> Add dialog after completing level 2 to check out the upgrades tab.",
],
},
{
version: "1.0.3",
date: "24.05.2020",
entries: [
"<strong>Balancing</strong> Reduced the amount of shapes required for the first 5 levels to make it easier to get into the game.",
],
},
{ {
version: "1.0.2", version: "1.0.2",
date: "23.05.2020", date: "23.05.2020",

View File

@ -155,6 +155,7 @@ export class ClickDetector {
* @param {Event} event * @param {Event} event
*/ */
internalPreventClick(event) { internalPreventClick(event) {
window.focus();
event.preventDefault(); event.preventDefault();
} }
@ -301,6 +302,8 @@ export class ClickDetector {
* @param {TouchEvent|MouseEvent} event * @param {TouchEvent|MouseEvent} event
*/ */
internalOnPointerDown(event) { internalOnPointerDown(event) {
window.focus();
if (!this.internalEventPreHandler(event, 1)) { if (!this.internalEventPreHandler(event, 1)) {
return false; return false;
} }
@ -369,6 +372,8 @@ export class ClickDetector {
* @param {TouchEvent|MouseEvent} event * @param {TouchEvent|MouseEvent} event
*/ */
internalOnPointerEnd(event) { internalOnPointerEnd(event) {
window.focus();
if (!this.internalEventPreHandler(event, 0)) { if (!this.internalEventPreHandler(event, 0)) {
return false; return false;
} }

View File

@ -101,7 +101,8 @@ export const globalConfig = {
// framePausesBetweenTicks: 40, // framePausesBetweenTicks: 40,
// testTranslations: true, // testTranslations: true,
// enableEntityInspector: true, // enableEntityInspector: true,
testAds: true, // testAds: true,
disableMapOverview: true,
/* dev:end */ /* dev:end */
}, },
@ -123,3 +124,8 @@ export const IS_MOBILE = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
// Automatic calculations // Automatic calculations
globalConfig.minerSpeedItemsPerSecond = globalConfig.beltSpeedItemsPerSecond / 5; globalConfig.minerSpeedItemsPerSecond = globalConfig.beltSpeedItemsPerSecond / 5;
if (globalConfig.debug.disableMapOverview) {
globalConfig.mapChunkOverviewMinZoom = 0;
globalConfig.mapChunkPrerenderMinZoom = 0;
}

View File

@ -201,7 +201,7 @@ export class InputDistributor {
// TAB // TAB
event.keyCode === 9 || event.keyCode === 9 ||
// F1 - F10 // F1 - F10
(event.keyCode >= 112 && event.keyCode < 122 && !G_IS_DEV) (event.keyCode >= 112 && event.keyCode < 122)
) { ) {
event.preventDefault(); event.preventDefault();
} }

View File

@ -84,7 +84,7 @@ class LoaderImpl {
return Promise.race([ return Promise.race([
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
setTimeout(reject, G_IS_DEV ? 3000 : 60000); setTimeout(reject, G_IS_DEV ? 500 : 10000);
}), }),
new Promise(resolve => { new Promise(resolve => {

View File

@ -3,13 +3,8 @@ const options = queryString.parse(location.search);
export let queryParamOptions = { export let queryParamOptions = {
embedProvider: null, embedProvider: null,
betaMode: null,
}; };
if (options.embed) { if (options.embed) {
queryParamOptions.embedProvider = options.embed; queryParamOptions.embedProvider = options.embed;
} }
if (!G_IS_RELEASE && options.betamode) {
queryParamOptions.betaMode = true;
}

View File

@ -715,10 +715,6 @@ export class Camera extends BasicSerializableObject {
if (G_IS_DEV && globalConfig.debug.disableZoomLimits) { if (G_IS_DEV && globalConfig.debug.disableZoomLimits) {
return; return;
} }
if (queryParamOptions.betaMode) {
return;
}
const wrapper = this.root.app.platformWrapper; const wrapper = this.root.app.platformWrapper;
assert(Number.isFinite(this.zoomLevel), "Invalid zoom level *before* clamp: " + this.zoomLevel); assert(Number.isFinite(this.zoomLevel), "Invalid zoom level *before* clamp: " + this.zoomLevel);

View File

@ -145,9 +145,6 @@ export class HubGoals extends BasicSerializableObject {
if (G_IS_DEV && globalConfig.debug.allBuildingsUnlocked) { if (G_IS_DEV && globalConfig.debug.allBuildingsUnlocked) {
return true; return true;
} }
if (queryParamOptions.betaMode) {
return true;
}
return !!this.gainedRewards[reward]; return !!this.gainedRewards[reward];
} }
@ -233,9 +230,6 @@ export class HubGoals extends BasicSerializableObject {
if (G_IS_DEV && globalConfig.debug.upgradesNoCost) { if (G_IS_DEV && globalConfig.debug.upgradesNoCost) {
return true; return true;
} }
if (queryParamOptions.betaMode) {
return true;
}
const tierData = handle.tiers[currentLevel]; const tierData = handle.tiers[currentLevel];
@ -282,8 +276,6 @@ export class HubGoals extends BasicSerializableObject {
if (G_IS_DEV && globalConfig.debug.upgradesNoCost) { if (G_IS_DEV && globalConfig.debug.upgradesNoCost) {
// Dont take resources // Dont take resources
} else if (queryParamOptions.betaMode) {
// Same
} else { } else {
for (let i = 0; i < tierData.required.length; ++i) { for (let i = 0; i < tierData.required.length; ++i) {
const requirement = tierData.required[i]; const requirement = tierData.required[i];

View File

@ -8,6 +8,7 @@ import { enumHubGoalRewards } from "../../tutorial_goals";
import { BaseHUDPart } from "../base_hud_part"; import { BaseHUDPart } from "../base_hud_part";
import { DynamicDomAttach } from "../dynamic_dom_attach"; import { DynamicDomAttach } from "../dynamic_dom_attach";
import { enumHubGoalRewardsToContentUnlocked } from "../../tutorial_goals_mappings"; import { enumHubGoalRewardsToContentUnlocked } from "../../tutorial_goals_mappings";
import { InputReceiver } from "../../../core/input_receiver";
export class HUDUnlockNotification extends BaseHUDPart { export class HUDUnlockNotification extends BaseHUDPart {
initialize() { initialize() {
@ -25,6 +26,8 @@ export class HUDUnlockNotification extends BaseHUDPart {
} }
createElements(parent) { createElements(parent) {
this.inputReciever = new InputReceiver("unlock-notification");
this.element = makeDiv(parent, "ingame_HUD_UnlockNotification", []); this.element = makeDiv(parent, "ingame_HUD_UnlockNotification", []);
const dialog = makeDiv(this.element, null, ["dialog"]); const dialog = makeDiv(this.element, null, ["dialog"]);
@ -47,6 +50,7 @@ export class HUDUnlockNotification extends BaseHUDPart {
* @param {enumHubGoalRewards} reward * @param {enumHubGoalRewards} reward
*/ */
showForLevel(level, reward) { showForLevel(level, reward) {
this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever);
this.elemTitle.innerText = T.ingame.levelCompleteNotification.levelTitle.replace( this.elemTitle.innerText = T.ingame.levelCompleteNotification.levelTitle.replace(
"<level>", "<level>",
("" + level).padStart(2, "0") ("" + level).padStart(2, "0")
@ -92,6 +96,7 @@ export class HUDUnlockNotification extends BaseHUDPart {
} }
cleanup() { cleanup() {
this.root.app.inputMgr.makeSureDetached(this.inputReciever);
if (this.buttonShowTimeout) { if (this.buttonShowTimeout) {
clearTimeout(this.buttonShowTimeout); clearTimeout(this.buttonShowTimeout);
this.buttonShowTimeout = null; this.buttonShowTimeout = null;
@ -101,10 +106,19 @@ export class HUDUnlockNotification extends BaseHUDPart {
requestClose() { requestClose() {
this.root.app.adProvider.showVideoAd().then(() => { this.root.app.adProvider.showVideoAd().then(() => {
this.close(); this.close();
if (this.root.hubGoals.level === 3) {
const { showUpgrades } = this.root.hud.parts.dialogs.showInfo(
T.dialogs.upgradesIntroduction.title,
T.dialogs.upgradesIntroduction.desc,
["showUpgrades:good:timeout"]
);
showUpgrades.add(() => this.root.hud.parts.shop.show());
}
}); });
} }
close() { close() {
this.root.app.inputMgr.makeSureDetached(this.inputReciever);
if (this.buttonShowTimeout) { if (this.buttonShowTimeout) {
clearTimeout(this.buttonShowTimeout); clearTimeout(this.buttonShowTimeout);
this.buttonShowTimeout = null; this.buttonShowTimeout = null;

View File

@ -30,20 +30,23 @@ export const enumHubGoalRewards = {
}; };
export const tutorialGoals = [ export const tutorialGoals = [
// 1
// Circle // Circle
{ {
shape: "CuCuCuCu", // belts t1 shape: "CuCuCuCu", // belts t1
required: 60, required: 35,
reward: enumHubGoalRewards.reward_cutter_and_trash, reward: enumHubGoalRewards.reward_cutter_and_trash,
}, },
// 2
// Cutter // Cutter
{ {
shape: "----CuCu", // shape: "----CuCu", //
required: 80, required: 50,
reward: enumHubGoalRewards.no_reward, reward: enumHubGoalRewards.no_reward,
}, },
// 3
// Rectangle // Rectangle
{ {
shape: "RuRuRuRu", // miners t1 shape: "RuRuRuRu", // miners t1
@ -51,12 +54,14 @@ export const tutorialGoals = [
reward: enumHubGoalRewards.reward_splitter, reward: enumHubGoalRewards.reward_splitter,
}, },
// 4
{ {
shape: "RuRu----", // processors t2 shape: "RuRu----", // processors t2
required: 350, required: 150,
reward: enumHubGoalRewards.reward_rotater, reward: enumHubGoalRewards.reward_rotater,
}, },
// 5
// Rotater // Rotater
{ {
shape: "Cu----Cu", // belts t2 shape: "Cu----Cu", // belts t2
@ -64,25 +69,29 @@ export const tutorialGoals = [
reward: enumHubGoalRewards.reward_tunnel, reward: enumHubGoalRewards.reward_tunnel,
}, },
// 6
{ {
shape: "Cu------", // miners t2 shape: "Cu------", // miners t2
required: 1000, required: 700,
reward: enumHubGoalRewards.reward_painter, reward: enumHubGoalRewards.reward_painter,
}, },
// 7
// Painter // Painter
{ {
shape: "CrCrCrCr", // unused shape: "CrCrCrCr", // unused
required: 1500, required: 1300,
reward: enumHubGoalRewards.reward_rotater_ccw, reward: enumHubGoalRewards.reward_rotater_ccw,
}, },
// 8
{ {
shape: "RbRb----", // painter t2 shape: "RbRb----", // painter t2
required: 2500, required: 2500,
reward: enumHubGoalRewards.reward_mixer, reward: enumHubGoalRewards.reward_mixer,
}, },
// 9
// Mixing (purple) // Mixing (purple)
{ {
shape: "CpCpCpCp", // belts t3 shape: "CpCpCpCp", // belts t3
@ -90,6 +99,7 @@ export const tutorialGoals = [
reward: enumHubGoalRewards.reward_splitter_compact, reward: enumHubGoalRewards.reward_splitter_compact,
}, },
// 10
// Star shape + cyan // Star shape + cyan
{ {
shape: "ScScScSc", // miners t3 shape: "ScScScSc", // miners t3
@ -97,6 +107,7 @@ export const tutorialGoals = [
reward: enumHubGoalRewards.reward_stacker, reward: enumHubGoalRewards.reward_stacker,
}, },
// 11
// Stacker // Stacker
{ {
shape: "CgScScCg", // processors t3 shape: "CgScScCg", // processors t3
@ -104,36 +115,42 @@ export const tutorialGoals = [
reward: enumHubGoalRewards.reward_miner_chainable, reward: enumHubGoalRewards.reward_miner_chainable,
}, },
// 12
{ {
shape: "RpRpRpRp:CwCwCwCw", // painting t3 shape: "RpRpRpRp:CwCwCwCw", // painting t3
required: 7000, required: 7000,
reward: enumHubGoalRewards.reward_underground_belt_tier_2, reward: enumHubGoalRewards.reward_underground_belt_tier_2,
}, },
// 13
{ {
shape: "SrSrSrSr:CyCyCyCy", // unused shape: "SrSrSrSr:CyCyCyCy", // unused
required: 7850, required: 7850,
reward: enumHubGoalRewards.reward_storage, reward: enumHubGoalRewards.reward_storage,
}, },
// 14
{ {
shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", // belts t4 (two variants) shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", // belts t4 (two variants)
required: 8000, required: 8000,
reward: enumHubGoalRewards.reward_cutter_quad, reward: enumHubGoalRewards.reward_cutter_quad,
}, },
// 15
{ {
shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", // miner t4 (two variants) shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", // miner t4 (two variants)
required: 9000, required: 9000,
reward: enumHubGoalRewards.reward_painter_double, reward: enumHubGoalRewards.reward_painter_double,
}, },
// 16
{ {
shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", // processors t4 (two varinats) shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", // processors t4 (two varinats)
required: 10000, required: 10000,
reward: enumHubGoalRewards.reward_painter_quad, reward: enumHubGoalRewards.reward_painter_quad,
}, },
// 17
{ {
shape: finalGameShape, shape: finalGameShape,
required: 50000, required: 50000,

View File

@ -97,7 +97,7 @@ export const UPGRADES = {
painting: { painting: {
tiers: [ tiers: [
{ {
required: [{ shape: "WrWrWrWr", amount: 2000 }], required: [{ shape: "WrWrWrWr", amount: 500 }],
improvement: 1, improvement: 1,
}, },
{ {

2
src/js/globals.d.ts vendored
View File

@ -107,8 +107,6 @@ declare interface Window {
assert(condition: boolean, failureMessage: string); assert(condition: boolean, failureMessage: string);
coreThreadLoadedCb(); coreThreadLoadedCb();
gameanalytics: typeof import("./game_analytics");
} }
declare interface Navigator { declare interface Navigator {

View File

@ -137,7 +137,8 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface {
ingameTime: root.time.now(), ingameTime: root.time.now(),
category, category,
value, value,
gameDump: this.generateGameDump(root), version: G_BUILD_VERSION,
gameDump: this.generateGameDump(root, category === "sync"),
}); });
} }
@ -152,14 +153,15 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface {
/** /**
* Generates a game dump * Generates a game dump
* @param {GameRoot} root * @param {GameRoot} root
* @param {boolean=} metaOnly
*/ */
generateGameDump(root) { generateGameDump(root, metaOnly = false) {
let staticEntities = []; let staticEntities = [];
const entities = root.entityMgr.getAllWithComponent(StaticMapEntityComponent); const entities = root.entityMgr.getAllWithComponent(StaticMapEntityComponent);
// Limit the entities // Limit the entities
if (entities.length < 5000) { if (!metaOnly && entities.length < 500) {
for (let i = 0; i < entities.length; ++i) { for (let i = 0; i < entities.length; ++i) {
const entity = entities[i]; const entity = entities[i];
const staticComp = entity.components.StaticMapEntity; const staticComp = entity.components.StaticMapEntity;

View File

@ -23,7 +23,7 @@ class SoundSpritesContainer {
} }
return (this.loadingPromise = Promise.race([ return (this.loadingPromise = Promise.race([
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
setTimeout(reject, G_IS_DEV ? 5000 : 60000); setTimeout(reject, G_IS_DEV ? 500 : 5000);
}), }),
new Promise(resolve => { new Promise(resolve => {
this.howl = new Howl({ this.howl = new Howl({
@ -100,7 +100,7 @@ class MusicInstance extends MusicInstanceInterface {
load() { load() {
return Promise.race([ return Promise.race([
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
setTimeout(reject, G_IS_DEV ? 5000 : 60000); setTimeout(reject, G_IS_DEV ? 500 : 5000);
}), }),
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
this.howl = new Howl({ this.howl = new Howl({

View File

@ -34,10 +34,12 @@ export class StorageImplBrowserIndexedDB extends StorageInterface {
reject("Indexed DB access error"); reject("Indexed DB access error");
}; };
// @ts-ignore
request.onsuccess = event => resolve(event.target.result); request.onsuccess = event => resolve(event.target.result);
request.onupgradeneeded = /** @type {IDBVersionChangeEvent} */ event => { request.onupgradeneeded = /** @type {IDBVersionChangeEvent} */ event => {
/** @type {IDBDatabase} */ /** @type {IDBDatabase} */
// @ts-ignore
const database = event.target.result; const database = event.target.result;
const objectStore = database.createObjectStore("files", { const objectStore = database.createObjectStore("files", {

View File

@ -1,5 +1,5 @@
import { Math_min } from "../../core/builtins"; import { Math_min } from "../../core/builtins";
import { globalConfig, IS_MOBILE } from "../../core/config"; import { globalConfig, IS_MOBILE, IS_DEBUG, IS_DEMO } from "../../core/config";
import { createLogger } from "../../core/logging"; import { createLogger } from "../../core/logging";
import { queryParamOptions } from "../../core/query_parameters"; import { queryParamOptions } from "../../core/query_parameters";
import { clamp } from "../../core/utils"; import { clamp } from "../../core/utils";
@ -19,6 +19,8 @@ export class PlatformWrapperImplBrowser extends PlatformWrapperInterface {
iframed: false, iframed: false,
externalLinks: true, externalLinks: true,
iogLink: true, iogLink: true,
unlimitedSavegames: IS_DEMO ? false : true,
showDemoBadge: IS_DEMO,
}; };
if (!G_IS_STANDALONE && queryParamOptions.embedProvider) { if (!G_IS_STANDALONE && queryParamOptions.embedProvider) {
@ -35,6 +37,8 @@ export class PlatformWrapperImplBrowser extends PlatformWrapperInterface {
case "iogames.space": { case "iogames.space": {
this.embedProvider.id = "iogames.space"; this.embedProvider.id = "iogames.space";
this.embedProvider.iogLink = true; this.embedProvider.iogLink = true;
this.embedProvider.unlimitedSavegames = true;
this.embedProvider.showDemoBadge = false;
break; break;
} }
@ -71,6 +75,14 @@ export class PlatformWrapperImplBrowser extends PlatformWrapperInterface {
return super.initialize().then(() => this.initializeAdProvider()); return super.initialize().then(() => this.initializeAdProvider());
} }
getHasUnlimitedSavegames() {
return this.embedProvider.unlimitedSavegames;
}
getShowDemoBadges() {
return this.embedProvider.showDemoBadge;
}
onSentryLoaded() { onSentryLoaded() {
logger.log("Initializing sentry"); logger.log("Initializing sentry");
window.Sentry.init({ window.Sentry.init({

View File

@ -29,6 +29,17 @@ export class PlatformWrapperInterface {
return false; return false;
} }
/**
* Whether the user has unlimited savegames
*/
getHasUnlimitedSavegames() {
return true;
}
getShowDemoBadges() {
return false;
}
/** /**
* Returns the strength of touch pans with the mouse * Returns the strength of touch pans with the mouse
*/ */

View File

@ -26,7 +26,6 @@ export class BaseSavegameInterface {
*/ */
getSchemaUncached() { getSchemaUncached() {
throw new Error("Implement get schema"); throw new Error("Implement get schema");
return {};
} }
getValidator() { getValidator() {

View File

@ -54,7 +54,11 @@ export class MainMenuState extends GameState {
<div class="logo"> <div class="logo">
<img src="${cachebust("res/logo.png")}" alt="shapez.io Logo"> <img src="${cachebust("res/logo.png")}" alt="shapez.io Logo">
${IS_DEMO ? `<div class="demoBadge"></div>` : ""} ${
IS_DEMO && this.app.platformWrapper.getShowDemoBadges()
? `<div class="demoBadge"></div>`
: ""
}
</div> </div>
@ -93,7 +97,7 @@ export class MainMenuState extends GameState {
G_IS_BROWSER && G_IS_BROWSER &&
this.app.platformWrapper instanceof PlatformWrapperImplBrowser && this.app.platformWrapper instanceof PlatformWrapperImplBrowser &&
this.app.platformWrapper.embedProvider.iogLink this.app.platformWrapper.embedProvider.iogLink
? `<a class="iogLink" target="_blank" href="https://iogames.space">More .io games</a>` ? `<a class="iogLink" target="_blank" href="https://iogames.space">.io games</a>`
: "" : ""
} }
@ -104,7 +108,11 @@ export class MainMenuState extends GameState {
} }
requestImportSavegame() { requestImportSavegame() {
if (IS_DEMO && this.app.savegameMgr.getSavegamesMetaData().length > 0) { if (
IS_DEMO &&
this.app.savegameMgr.getSavegamesMetaData().length > 0 &&
!this.app.platformWrapper.getHasUnlimitedSavegames()
) {
this.app.analytics.trackUiClick("importgame_slot_limit_show"); this.app.analytics.trackUiClick("importgame_slot_limit_show");
this.dialogs.showWarning(T.dialogs.oneSavegameLimit.title, T.dialogs.oneSavegameLimit.desc); this.dialogs.showWarning(T.dialogs.oneSavegameLimit.title, T.dialogs.oneSavegameLimit.desc);
return; return;
@ -122,6 +130,7 @@ export class MainMenuState extends GameState {
const closeLoader = this.dialogs.showLoadingDialog(); const closeLoader = this.dialogs.showLoadingDialog();
const reader = new FileReader(); const reader = new FileReader();
reader.addEventListener("load", event => { reader.addEventListener("load", event => {
// @ts-ignore
const contents = event.target.result; const contents = event.target.result;
let realContent; let realContent;
@ -372,7 +381,11 @@ export class MainMenuState extends GameState {
} }
onPlayButtonClicked() { onPlayButtonClicked() {
if (IS_DEMO && this.app.savegameMgr.getSavegamesMetaData().length > 0) { if (
IS_DEMO &&
this.app.savegameMgr.getSavegamesMetaData().length > 0 &&
!this.app.platformWrapper.getHasUnlimitedSavegames()
) {
this.app.analytics.trackUiClick("startgame_slot_limit_show"); this.app.analytics.trackUiClick("startgame_slot_limit_show");
this.dialogs.showWarning(T.dialogs.oneSavegameLimit.title, T.dialogs.oneSavegameLimit.desc); this.dialogs.showWarning(T.dialogs.oneSavegameLimit.title, T.dialogs.oneSavegameLimit.desc);
return; return;

View File

@ -186,7 +186,8 @@ export class PreloadState extends GameState {
return G_BUILD_VERSION; return G_BUILD_VERSION;
}) })
.then(version => { .then(version => {
this.app.storage.writeFileAsync("lastversion.bin", version); logger.log("Last version:", version, "App version:", G_BUILD_VERSION);
this.app.storage.writeFileAsync("lastversion.bin", G_BUILD_VERSION);
return version; return version;
}) })
.then(version => { .then(version => {

View File

@ -89,6 +89,7 @@ dialogs:
getStandalone: Get Standalone getStandalone: Get Standalone
deleteGame: I know what I do deleteGame: I know what I do
viewUpdate: View Update viewUpdate: View Update
showUpgrades: Show Upgrades
importSavegameError: importSavegameError:
title: Import Error title: Import Error
@ -165,6 +166,12 @@ dialogs:
desc: >- desc: >-
Whenever you need help or are stuck, check out the 'Show hint' button in the lower left and I'll give my best to help you! Whenever you need help or are stuck, check out the 'Show hint' button in the lower left and I'll give my best to help you!
upgradesIntroduction:
title: Unlock Upgrades
desc: >-
All shapes you produce can be used to unlock upgrades - <strong>Don't destroy your old factories!</strong>
The upgrades tab can be found on the top right corner of the screen.
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
@ -277,7 +284,7 @@ shopUpgrades:
name: Extraction name: Extraction
description: Speed +<gain>% description: Speed +<gain>%
processors: processors:
name: Shape Processing name: Cutting, Rotating & Stacking
description: Speed +<gain>% description: Speed +<gain>%
painting: painting:
name: Mixing & Painting name: Mixing & Painting

View File

@ -1 +1 @@
1.0.2 1.0.4