mirror of
https://github.com/tobspr/shapez.io.git
synced 2024-10-27 20:34:29 +00:00
Allow downloading savegame in demo
This commit is contained in:
parent
7c77944d43
commit
34764eca16
@ -84,10 +84,33 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.playtimeDisclaimer {
|
.playtimeDisclaimer {
|
||||||
@include S(margin-bottom, 10px);
|
@include S(margin-bottom, 15px);
|
||||||
@include PlainText;
|
@include PlainText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.playtimeDisclaimerDownload {
|
||||||
|
@include SuperSmallText;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
text-align: center;
|
||||||
|
background: #b3f2c5;
|
||||||
|
@include S(border-radius, $globalBorderRadius);
|
||||||
|
@include S(padding, 7px, 10px);
|
||||||
|
@include S(margin-bottom, 15px);
|
||||||
|
pointer-events: all;
|
||||||
|
transition: background-color 0.12s ease-in-out;
|
||||||
|
color: rgba(#000, 0.5);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: darken(#b3f2c5, 3);
|
||||||
|
}
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.steamLinkButton {
|
.steamLinkButton {
|
||||||
@include IncreasedClickArea(5px);
|
@include IncreasedClickArea(5px);
|
||||||
@include S(margin, 0);
|
@include S(margin, 0);
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
#ingame_HUD_SteamCapsule {
|
|
||||||
position: absolute;
|
|
||||||
@include S(width, 150px);
|
|
||||||
@include S(height, 119px);
|
|
||||||
background: transparent center center / cover no-repeat;
|
|
||||||
|
|
||||||
pointer-events: all;
|
|
||||||
overflow: hidden;
|
|
||||||
@include S(right, 10px);
|
|
||||||
|
|
||||||
border: D(2px) solid #000;
|
|
||||||
@include S(border-radius, $globalBorderRadius);
|
|
||||||
cursor: pointer;
|
|
||||||
@include S(bottom, 150px);
|
|
||||||
|
|
||||||
& {
|
|
||||||
/* @load-async */
|
|
||||||
background-image: uiResource("res/ui/memes/cat1.png") !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
opacity: 0.95;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include InlineAnimation(0.5s ease-in-out) {
|
|
||||||
0% {
|
|
||||||
transform: translateX(100%);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -57,7 +57,6 @@
|
|||||||
@import "ingame_hud/shape_viewer";
|
@import "ingame_hud/shape_viewer";
|
||||||
@import "ingame_hud/sandbox_controller";
|
@import "ingame_hud/sandbox_controller";
|
||||||
@import "ingame_hud/standalone_advantages";
|
@import "ingame_hud/standalone_advantages";
|
||||||
@import "ingame_hud/steam_capsule";
|
|
||||||
@import "ingame_hud/puzzle_back_to_menu";
|
@import "ingame_hud/puzzle_back_to_menu";
|
||||||
@import "ingame_hud/puzzle_editor_review";
|
@import "ingame_hud/puzzle_editor_review";
|
||||||
@import "ingame_hud/puzzle_dlc_logo";
|
@import "ingame_hud/puzzle_dlc_logo";
|
||||||
@ -105,7 +104,6 @@ ingame_HUD_Waypoints_Hint,
|
|||||||
ingame_HUD_WatermarkClicker,
|
ingame_HUD_WatermarkClicker,
|
||||||
ingame_HUD_Watermark,
|
ingame_HUD_Watermark,
|
||||||
ingame_HUD_ColorBlindBelowTileHelper,
|
ingame_HUD_ColorBlindBelowTileHelper,
|
||||||
ingame_HUD_SteamCapsule,
|
|
||||||
ingame_HUD_SandboxController,
|
ingame_HUD_SandboxController,
|
||||||
|
|
||||||
// Overlays
|
// Overlays
|
||||||
|
@ -197,6 +197,13 @@ export class HubGoals extends BasicSerializableObject {
|
|||||||
if (G_IS_DEV && globalConfig.debug.allBuildingsUnlocked) {
|
if (G_IS_DEV && globalConfig.debug.allBuildingsUnlocked) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
reward === enumHubGoalRewards.reward_blueprints &&
|
||||||
|
this.root.app.restrictionMgr.isLimitedVersion()
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.root.gameMode.getLevelDefinitions().length < 1) {
|
if (this.root.gameMode.getLevelDefinitions().length < 1) {
|
||||||
// no story, so always unlocked
|
// no story, so always unlocked
|
||||||
return true;
|
return true;
|
||||||
|
@ -87,10 +87,8 @@ export class GameHUD {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.root.app.restrictionMgr.getIsStandaloneMarketingActive()) {
|
if (this.root.app.restrictionMgr.getIsStandaloneMarketingActive()) {
|
||||||
if (["1", "2"].includes(this.root.app.gameAnalytics.abtVariant)) {
|
|
||||||
this.parts.demoTimer = new HUDDemoTimer(this.root);
|
this.parts.demoTimer = new HUDDemoTimer(this.root);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const additionalParts = this.root.gameMode.additionalHudParts;
|
const additionalParts = this.root.gameMode.additionalHudParts;
|
||||||
for (const [partId, part] of Object.entries(additionalParts)) {
|
for (const [partId, part] of Object.entries(additionalParts)) {
|
||||||
@ -219,7 +217,7 @@ export class GameHUD {
|
|||||||
* @param {DrawParameters} parameters
|
* @param {DrawParameters} parameters
|
||||||
*/
|
*/
|
||||||
drawOverlays(parameters) {
|
drawOverlays(parameters) {
|
||||||
const partsOrder = ["waypoints", "watermark", "wireInfo"];
|
const partsOrder = ["waypoints", "wireInfo"];
|
||||||
|
|
||||||
for (let i = 0; i < partsOrder.length; ++i) {
|
for (let i = 0; i < partsOrder.length; ++i) {
|
||||||
if (this.parts[partsOrder[i]]) {
|
if (this.parts[partsOrder[i]]) {
|
||||||
|
@ -13,7 +13,7 @@ export class HUDDemoTimer extends BaseHUDPart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get totalTime() {
|
get totalTime() {
|
||||||
return this.root.app.gameAnalytics.abtVariant === "1" ? 15 : 30;
|
return G_IS_STEAM_DEMO ? 15 : 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize() {}
|
initialize() {}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { globalConfig } from "../../../core/config";
|
import { globalConfig } from "../../../core/config";
|
||||||
import { DrawParameters } from "../../../core/draw_parameters";
|
import { DrawParameters } from "../../../core/draw_parameters";
|
||||||
import { gMetaBuildingRegistry } from "../../../core/global_registries";
|
|
||||||
import { createLogger } from "../../../core/logging";
|
import { createLogger } from "../../../core/logging";
|
||||||
import { STOP_PROPAGATION } from "../../../core/signal";
|
import { STOP_PROPAGATION } from "../../../core/signal";
|
||||||
import { formatBigNumberFull } from "../../../core/utils";
|
import { formatBigNumberFull } from "../../../core/utils";
|
||||||
@ -8,10 +7,7 @@ import { Vector } from "../../../core/vector";
|
|||||||
import { ACHIEVEMENTS } from "../../../platform/achievement_provider";
|
import { ACHIEVEMENTS } from "../../../platform/achievement_provider";
|
||||||
import { T } from "../../../translations";
|
import { T } from "../../../translations";
|
||||||
import { Blueprint } from "../../blueprint";
|
import { Blueprint } from "../../blueprint";
|
||||||
import { MetaBlockBuilding } from "../../buildings/block";
|
|
||||||
import { MetaConstantProducerBuilding } from "../../buildings/constant_producer";
|
|
||||||
import { enumMouseButton } from "../../camera";
|
import { enumMouseButton } from "../../camera";
|
||||||
import { Component } from "../../component";
|
|
||||||
import { Entity } from "../../entity";
|
import { Entity } from "../../entity";
|
||||||
import { KEYMAPPINGS } from "../../key_action_mapper";
|
import { KEYMAPPINGS } from "../../key_action_mapper";
|
||||||
import { THEME } from "../../theme";
|
import { THEME } from "../../theme";
|
||||||
@ -128,13 +124,17 @@ export class HUDMassSelector extends BaseHUDPart {
|
|||||||
this.selectedUids = new Set();
|
this.selectedUids = new Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
startCopy() {
|
showBlueprintsNotUnlocked() {
|
||||||
if (this.selectedUids.size > 0) {
|
|
||||||
if (!this.root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_blueprints)) {
|
|
||||||
this.root.hud.parts.dialogs.showInfo(
|
this.root.hud.parts.dialogs.showInfo(
|
||||||
T.dialogs.blueprintsNotUnlocked.title,
|
T.dialogs.blueprintsNotUnlocked.title,
|
||||||
T.dialogs.blueprintsNotUnlocked.desc
|
T.dialogs.blueprintsNotUnlocked.desc
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
startCopy() {
|
||||||
|
if (this.selectedUids.size > 0) {
|
||||||
|
if (!this.root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_blueprints)) {
|
||||||
|
this.showBlueprintsNotUnlocked();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.root.hud.signals.buildingsSelectedForCopy.dispatch(Array.from(this.selectedUids));
|
this.root.hud.signals.buildingsSelectedForCopy.dispatch(Array.from(this.selectedUids));
|
||||||
@ -157,10 +157,7 @@ export class HUDMassSelector extends BaseHUDPart {
|
|||||||
|
|
||||||
confirmCut() {
|
confirmCut() {
|
||||||
if (!this.root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_blueprints)) {
|
if (!this.root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_blueprints)) {
|
||||||
this.root.hud.parts.dialogs.showInfo(
|
this.showBlueprintsNotUnlocked();
|
||||||
T.dialogs.blueprintsNotUnlocked.title,
|
|
||||||
T.dialogs.blueprintsNotUnlocked.desc
|
|
||||||
);
|
|
||||||
} else if (
|
} else if (
|
||||||
!this.root.app.settings.getAllSettings().disableCutDeleteWarnings &&
|
!this.root.app.settings.getAllSettings().disableCutDeleteWarnings &&
|
||||||
this.selectedUids.size > 100
|
this.selectedUids.size > 100
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { globalConfig, openStandaloneLink } from "../../../core/config";
|
import { globalConfig, openStandaloneLink } from "../../../core/config";
|
||||||
import { InputReceiver } from "../../../core/input_receiver";
|
import { InputReceiver } from "../../../core/input_receiver";
|
||||||
import { makeDiv } from "../../../core/utils";
|
import { ReadWriteProxy } from "../../../core/read_write_proxy";
|
||||||
|
import { generateFileDownload, makeDiv } from "../../../core/utils";
|
||||||
import { T } from "../../../translations";
|
import { T } from "../../../translations";
|
||||||
import { BaseHUDPart } from "../base_hud_part";
|
import { BaseHUDPart } from "../base_hud_part";
|
||||||
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||||
@ -11,23 +12,8 @@ export class HUDStandaloneAdvantages extends BaseHUDPart {
|
|||||||
|
|
||||||
// DIALOG Inner / Wrapper
|
// DIALOG Inner / Wrapper
|
||||||
this.dialogInner = makeDiv(this.background, null, ["dialogInner"]);
|
this.dialogInner = makeDiv(this.background, null, ["dialogInner"]);
|
||||||
this.title = makeDiv(
|
this.title = makeDiv(this.dialogInner, null, ["title"], T.ingame.standaloneAdvantages.title_expired);
|
||||||
this.dialogInner,
|
this.subTitle = makeDiv(this.dialogInner, null, ["subTitle"], T.ingame.standaloneAdvantages.title);
|
||||||
null,
|
|
||||||
["title"],
|
|
||||||
|
|
||||||
["1", "2"].includes(this.root.app.gameAnalytics.abtVariant)
|
|
||||||
? T.ingame.standaloneAdvantages.title_expired
|
|
||||||
: T.ingame.standaloneAdvantages.title
|
|
||||||
);
|
|
||||||
if (["1", "2"].includes(this.root.app.gameAnalytics.abtVariant)) {
|
|
||||||
this.subTitle = makeDiv(
|
|
||||||
this.dialogInner,
|
|
||||||
null,
|
|
||||||
["subTitle"],
|
|
||||||
T.ingame.standaloneAdvantages.title
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.contentDiv = makeDiv(
|
this.contentDiv = makeDiv(
|
||||||
this.dialogInner,
|
this.dialogInner,
|
||||||
@ -49,6 +35,9 @@ export class HUDStandaloneAdvantages extends BaseHUDPart {
|
|||||||
|
|
||||||
<div class="lowerBar">
|
<div class="lowerBar">
|
||||||
<div class="playtimeDisclaimer">${T.demoBanners.playtimeDisclaimer}</div>
|
<div class="playtimeDisclaimer">${T.demoBanners.playtimeDisclaimer}</div>
|
||||||
|
|
||||||
|
<div class="playtimeDisclaimerDownload">${T.demoBanners.playtimeDisclaimerDownload}</div>
|
||||||
|
|
||||||
<button class="steamLinkButton steam_dlbtn_0">
|
<button class="steamLinkButton steam_dlbtn_0">
|
||||||
${
|
${
|
||||||
globalConfig.currentDiscount > 0
|
globalConfig.currentDiscount > 0
|
||||||
@ -70,6 +59,13 @@ export class HUDStandaloneAdvantages extends BaseHUDPart {
|
|||||||
this.trackClicks(this.contentDiv.querySelector("button.otherCloseButton"), () => {
|
this.trackClicks(this.contentDiv.querySelector("button.otherCloseButton"), () => {
|
||||||
this.close();
|
this.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.trackClicks(this.contentDiv.querySelector(".playtimeDisclaimerDownload"), () => {
|
||||||
|
this.root.gameState.savegame.updateData(this.root);
|
||||||
|
const data = ReadWriteProxy.serializeObject(this.root.gameState.savegame.currentData);
|
||||||
|
const filename = "shapez-demo-savegame.bin";
|
||||||
|
generateFileDownload(filename, data);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get showIntervalSeconds() {
|
get showIntervalSeconds() {
|
||||||
@ -116,13 +112,6 @@ export class HUDStandaloneAdvantages extends BaseHUDPart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
if (this.root.app.gameAnalytics.abtVariant === "0") {
|
|
||||||
// only show in original variant
|
|
||||||
if (!this.visible && this.root.time.now() - this.lastShown > this.showIntervalSeconds) {
|
|
||||||
this.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.domAttach.update(this.visible);
|
this.domAttach.update(this.visible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
import { openStandaloneLink } from "../../../core/config";
|
|
||||||
import { makeDiv } from "../../../core/utils";
|
|
||||||
import { BaseHUDPart } from "../base_hud_part";
|
|
||||||
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
|
||||||
|
|
||||||
const showCapsuleAfter = 30 * 60;
|
|
||||||
|
|
||||||
export class HUDSteamCapsule extends BaseHUDPart {
|
|
||||||
createElements(parent) {
|
|
||||||
this.element = makeDiv(parent, "ingame_HUD_SteamCapsule");
|
|
||||||
}
|
|
||||||
|
|
||||||
initialize() {
|
|
||||||
this.domAttach = new DynamicDomAttach(this.root, this.element);
|
|
||||||
|
|
||||||
this.trackClicks(this.element, () => {
|
|
||||||
openStandaloneLink(this.root.app, "shapez_steamcapsule");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
update() {
|
|
||||||
if (this.root.app.gameAnalytics.abtVariant === "0") {
|
|
||||||
// only show in original variant
|
|
||||||
this.domAttach.update(this.root.time.now() > showCapsuleAfter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -135,13 +135,6 @@ export class HUDUnlockNotification extends BaseHUDPart {
|
|||||||
|
|
||||||
this.root.hud.signals.unlockNotificationFinished.dispatch();
|
this.root.hud.signals.unlockNotificationFinished.dispatch();
|
||||||
|
|
||||||
if (
|
|
||||||
this.root.hubGoals.level === 7 &&
|
|
||||||
this.root.app.restrictionMgr.getIsStandaloneMarketingActive()
|
|
||||||
) {
|
|
||||||
this.root.hud.parts.standaloneAdvantages.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.root.app.settings.getAllSettings().offerHints) {
|
if (!this.root.app.settings.getAllSettings().offerHints) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -41,26 +41,4 @@ export class HUDWatermark extends BaseHUDPart {
|
|||||||
initialize() {}
|
initialize() {}
|
||||||
|
|
||||||
update() {}
|
update() {}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {import("../../../core/draw_utils").DrawParameters} parameters
|
|
||||||
*/
|
|
||||||
drawOverlays(parameters) {
|
|
||||||
if (this.root.app.gameAnalytics.abtVariant !== "0") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const w = this.root.gameWidth;
|
|
||||||
|
|
||||||
parameters.context.fillStyle = "rgba(20, 30, 40, 0.25)";
|
|
||||||
parameters.context.font = "bold " + this.root.app.getEffectiveUiScale() * 40 + "px GameFont";
|
|
||||||
parameters.context.textAlign = "center";
|
|
||||||
parameters.context.fillText(
|
|
||||||
T.demoBanners.title.toUpperCase(),
|
|
||||||
w / 2,
|
|
||||||
this.root.app.getEffectiveUiScale() * 50
|
|
||||||
);
|
|
||||||
|
|
||||||
parameters.context.textAlign = "left";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
249
src/js/game/modes/levels.js
Normal file
249
src/js/game/modes/levels.js
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
import { enumHubGoalRewards } from "../tutorial_goals";
|
||||||
|
|
||||||
|
export const LevelSetVariant = {
|
||||||
|
NoRestrictions: "NoRestrictions",
|
||||||
|
LimitedLevel8: "LimitedLevel8",
|
||||||
|
LimitedLevelBlueprints: "LimitedLevelBlueprints",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const finalGameShape = "RuCw--Cw:----Ru--";
|
||||||
|
const chinaShapes = G_WEGAME_VERSION || G_CHINA_VERSION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the level definitions
|
||||||
|
* @param {keyof typeof LevelSetVariant} variant
|
||||||
|
*/
|
||||||
|
export function generateLevelsForVariant(variant) {
|
||||||
|
const levelDefinitions = [
|
||||||
|
// 1
|
||||||
|
// Circle
|
||||||
|
{
|
||||||
|
shape: "CuCuCuCu", // belts t1
|
||||||
|
required: 30,
|
||||||
|
reward: enumHubGoalRewards.reward_cutter_and_trash,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 2
|
||||||
|
// Cutter
|
||||||
|
{
|
||||||
|
shape: "----CuCu", //
|
||||||
|
required: 40,
|
||||||
|
reward: enumHubGoalRewards.no_reward,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 3
|
||||||
|
// Rectangle
|
||||||
|
{
|
||||||
|
shape: "RuRuRuRu", // miners t1
|
||||||
|
required: 70,
|
||||||
|
reward: enumHubGoalRewards.reward_balancer,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 4
|
||||||
|
{
|
||||||
|
shape: "RuRu----", // processors t2
|
||||||
|
required: 70,
|
||||||
|
reward: enumHubGoalRewards.reward_rotater,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 5
|
||||||
|
// Rotater
|
||||||
|
{
|
||||||
|
shape: "Cu----Cu", // belts t2
|
||||||
|
required: 170,
|
||||||
|
reward: enumHubGoalRewards.reward_tunnel,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 6
|
||||||
|
{
|
||||||
|
shape: "Cu------", // miners t2
|
||||||
|
required: 270,
|
||||||
|
reward: enumHubGoalRewards.reward_painter,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 7
|
||||||
|
// Painter
|
||||||
|
{
|
||||||
|
shape: "CrCrCrCr", // unused
|
||||||
|
required: 300,
|
||||||
|
reward: enumHubGoalRewards.reward_rotater_ccw,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
if (variant === LevelSetVariant.LimitedLevel8) {
|
||||||
|
// Variant: End of Demo (level 8)
|
||||||
|
levelDefinitions.push({
|
||||||
|
shape: "CrCrCrCr",
|
||||||
|
required: 0,
|
||||||
|
reward: enumHubGoalRewards.reward_demo_end,
|
||||||
|
});
|
||||||
|
return levelDefinitions;
|
||||||
|
}
|
||||||
|
|
||||||
|
levelDefinitions.push(
|
||||||
|
// 8
|
||||||
|
{
|
||||||
|
shape: "RbRb----", // painter t2
|
||||||
|
required: 480,
|
||||||
|
reward: enumHubGoalRewards.reward_mixer,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 9
|
||||||
|
// Mixing (purple)
|
||||||
|
{
|
||||||
|
shape: "CpCpCpCp", // belts t3
|
||||||
|
required: 600,
|
||||||
|
reward: enumHubGoalRewards.reward_merger,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 10
|
||||||
|
// STACKER: Star shape + cyan
|
||||||
|
{
|
||||||
|
shape: "ScScScSc", // miners t3
|
||||||
|
required: 800,
|
||||||
|
reward: enumHubGoalRewards.reward_stacker,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 11
|
||||||
|
// Chainable miner
|
||||||
|
{
|
||||||
|
shape: "CgScScCg", // processors t3
|
||||||
|
required: 1000,
|
||||||
|
reward: enumHubGoalRewards.reward_miner_chainable,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 12
|
||||||
|
// Blueprints
|
||||||
|
{
|
||||||
|
shape: "CbCbCbRb:CwCwCwCw",
|
||||||
|
required: 1000,
|
||||||
|
reward: enumHubGoalRewards.reward_blueprints,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (variant === LevelSetVariant.LimitedLevelBlueprints) {
|
||||||
|
// Variant: End of Demo (before blueprints)
|
||||||
|
levelDefinitions.push({
|
||||||
|
shape: "CbCbCbRb:CwCwCwCw",
|
||||||
|
required: 0,
|
||||||
|
reward: enumHubGoalRewards.reward_demo_end,
|
||||||
|
});
|
||||||
|
return levelDefinitions;
|
||||||
|
}
|
||||||
|
|
||||||
|
levelDefinitions.push(
|
||||||
|
// 13
|
||||||
|
// Tunnel Tier 2
|
||||||
|
{
|
||||||
|
shape: chinaShapes ? "CuCuCuCu:CwCwCwCw:Sb--Sr--" : "RpRpRpRp:CwCwCwCw", // painting t3
|
||||||
|
required: 3800,
|
||||||
|
reward: enumHubGoalRewards.reward_underground_belt_tier_2,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 14
|
||||||
|
// Belt reader
|
||||||
|
{
|
||||||
|
shape: "--Cg----:--Cr----", // unused
|
||||||
|
required: 8, // Per second!
|
||||||
|
reward: enumHubGoalRewards.reward_belt_reader,
|
||||||
|
throughputOnly: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 15
|
||||||
|
// Storage
|
||||||
|
{
|
||||||
|
shape: "SrSrSrSr:CyCyCyCy", // unused
|
||||||
|
required: 10000,
|
||||||
|
reward: enumHubGoalRewards.reward_storage,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 16
|
||||||
|
// Quad Cutter
|
||||||
|
{
|
||||||
|
shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", // belts t4 (two variants)
|
||||||
|
required: 6000,
|
||||||
|
reward: enumHubGoalRewards.reward_cutter_quad,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 17
|
||||||
|
// Double painter
|
||||||
|
{
|
||||||
|
shape: chinaShapes ? "CyCyCyCy:CyCyCyCy:RyRyRyRy:RuRuRuRu" : "CbRbRbCb:CwCwCwCw:WbWbWbWb", // miner t4 (two variants)
|
||||||
|
required: 20000,
|
||||||
|
reward: enumHubGoalRewards.reward_painter_double,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 18
|
||||||
|
// Rotater (180deg)
|
||||||
|
{
|
||||||
|
shape: "Sg----Sg:CgCgCgCg:--CyCy--", // unused
|
||||||
|
required: 20000,
|
||||||
|
reward: enumHubGoalRewards.reward_rotater_180,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 19
|
||||||
|
// Compact splitter
|
||||||
|
{
|
||||||
|
shape: "CpRpCp--:SwSwSwSw",
|
||||||
|
required: 25000,
|
||||||
|
reward: enumHubGoalRewards.reward_splitter,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 20
|
||||||
|
// WIRES
|
||||||
|
{
|
||||||
|
shape: finalGameShape,
|
||||||
|
required: 25000,
|
||||||
|
reward: enumHubGoalRewards.reward_wires_painter_and_levers,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 21
|
||||||
|
// Filter
|
||||||
|
{
|
||||||
|
shape: "CrCwCrCw:CwCrCwCr:CrCwCrCw:CwCrCwCr",
|
||||||
|
required: 25000,
|
||||||
|
reward: enumHubGoalRewards.reward_filter,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 22
|
||||||
|
// Constant signal
|
||||||
|
{
|
||||||
|
shape: chinaShapes ? "RrSySrSy:RyCrCwCr:CyCyRyCy" : "Cg----Cr:Cw----Cw:Sy------:Cy----Cy",
|
||||||
|
required: 25000,
|
||||||
|
reward: enumHubGoalRewards.reward_constant_signal,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 23
|
||||||
|
// Display
|
||||||
|
{
|
||||||
|
shape: chinaShapes ? "CrCrCrCr:CwCwCwCw:WwWwWwWw:CrCrCrCr" : "CcSyCcSy:SyCcSyCc:CcSyCcSy",
|
||||||
|
required: 25000,
|
||||||
|
reward: enumHubGoalRewards.reward_display,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 24 Logic gates
|
||||||
|
{
|
||||||
|
shape: chinaShapes
|
||||||
|
? "Su----Su:RwRwRwRw:Cu----Cu:CwCwCwCw"
|
||||||
|
: "CcRcCcRc:RwCwRwCw:Sr--Sw--:CyCyCyCy",
|
||||||
|
required: 25000,
|
||||||
|
reward: enumHubGoalRewards.reward_logic_gates,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 25 Virtual Processing
|
||||||
|
{
|
||||||
|
shape: "Rg--Rg--:CwRwCwRw:--Rg--Rg",
|
||||||
|
required: 25000,
|
||||||
|
reward: enumHubGoalRewards.reward_virtual_processing,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 26 Freeplay
|
||||||
|
{
|
||||||
|
shape: "CbCuCbCu:Sr------:--CrSrCr:CwCwCwCw",
|
||||||
|
required: 50000,
|
||||||
|
reward: enumHubGoalRewards.reward_freeplay,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return levelDefinitions;
|
||||||
|
}
|
@ -31,12 +31,12 @@ import { IS_MOBILE } from "../../core/config";
|
|||||||
import { HUDKeybindingOverlay } from "../hud/parts/keybinding_overlay";
|
import { HUDKeybindingOverlay } from "../hud/parts/keybinding_overlay";
|
||||||
import { HUDWatermark } from "../hud/parts/watermark";
|
import { HUDWatermark } from "../hud/parts/watermark";
|
||||||
import { HUDStandaloneAdvantages } from "../hud/parts/standalone_advantages";
|
import { HUDStandaloneAdvantages } from "../hud/parts/standalone_advantages";
|
||||||
import { HUDSteamCapsule } from "../hud/parts/steam_capsule";
|
|
||||||
import { HUDPartTutorialHints } from "../hud/parts/tutorial_hints";
|
import { HUDPartTutorialHints } from "../hud/parts/tutorial_hints";
|
||||||
import { HUDInteractiveTutorial } from "../hud/parts/interactive_tutorial";
|
import { HUDInteractiveTutorial } from "../hud/parts/interactive_tutorial";
|
||||||
import { MetaBlockBuilding } from "../buildings/block";
|
import { MetaBlockBuilding } from "../buildings/block";
|
||||||
import { MetaItemProducerBuilding } from "../buildings/item_producer";
|
import { MetaItemProducerBuilding } from "../buildings/item_producer";
|
||||||
import { MOD_SIGNALS } from "../../mods/mod_signals";
|
import { MOD_SIGNALS } from "../../mods/mod_signals";
|
||||||
|
import { finalGameShape, generateLevelsForVariant, LevelSetVariant } from "./levels";
|
||||||
|
|
||||||
/** @typedef {{
|
/** @typedef {{
|
||||||
* shape: string,
|
* shape: string,
|
||||||
@ -59,7 +59,6 @@ import { MOD_SIGNALS } from "../../mods/mod_signals";
|
|||||||
* }} LevelDefinition */
|
* }} LevelDefinition */
|
||||||
|
|
||||||
export const rocketShape = "CbCuCbCu:Sr------:--CrSrCr:CwCwCwCw";
|
export const rocketShape = "CbCuCbCu:Sr------:--CrSrCr:CwCwCwCw";
|
||||||
export const finalGameShape = "RuCw--Cw:----Ru--";
|
|
||||||
const preparementShape = "CpRpCp--:SwSwSwSw";
|
const preparementShape = "CpRpCp--:SwSwSwSw";
|
||||||
|
|
||||||
// Tiers need % of the previous tier as requirement too
|
// Tiers need % of the previous tier as requirement too
|
||||||
@ -298,235 +297,14 @@ const levelDefinitionsCache = {};
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the level definitions
|
* Generates the level definitions
|
||||||
* @param {boolean} limitedVersion
|
* @param {keyof typeof LevelSetVariant} variant
|
||||||
*/
|
*/
|
||||||
export function generateLevelDefinitions(limitedVersion = false, difficulty = 1) {
|
export function generateLevelDefinitions(variant, difficulty = 1) {
|
||||||
if (levelDefinitionsCache[limitedVersion]) {
|
if (levelDefinitionsCache[variant]) {
|
||||||
return levelDefinitionsCache[limitedVersion];
|
return levelDefinitionsCache[variant];
|
||||||
}
|
}
|
||||||
const levelDefinitions = [
|
|
||||||
// 1
|
|
||||||
// Circle
|
|
||||||
{
|
|
||||||
shape: "CuCuCuCu", // belts t1
|
|
||||||
required: 30,
|
|
||||||
reward: enumHubGoalRewards.reward_cutter_and_trash,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 2
|
const levelDefinitions = generateLevelsForVariant(variant);
|
||||||
// Cutter
|
|
||||||
{
|
|
||||||
shape: "----CuCu", //
|
|
||||||
required: 40,
|
|
||||||
reward: enumHubGoalRewards.no_reward,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 3
|
|
||||||
// Rectangle
|
|
||||||
{
|
|
||||||
shape: "RuRuRuRu", // miners t1
|
|
||||||
required: 70,
|
|
||||||
reward: enumHubGoalRewards.reward_balancer,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 4
|
|
||||||
{
|
|
||||||
shape: "RuRu----", // processors t2
|
|
||||||
required: 70,
|
|
||||||
reward: enumHubGoalRewards.reward_rotater,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 5
|
|
||||||
// Rotater
|
|
||||||
{
|
|
||||||
shape: "Cu----Cu", // belts t2
|
|
||||||
required: 170,
|
|
||||||
reward: enumHubGoalRewards.reward_tunnel,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 6
|
|
||||||
{
|
|
||||||
shape: "Cu------", // miners t2
|
|
||||||
required: 270,
|
|
||||||
reward: enumHubGoalRewards.reward_painter,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 7
|
|
||||||
// Painter
|
|
||||||
{
|
|
||||||
shape: "CrCrCrCr", // unused
|
|
||||||
required: 300,
|
|
||||||
reward: enumHubGoalRewards.reward_rotater_ccw,
|
|
||||||
},
|
|
||||||
|
|
||||||
// DEMO STOPS HERE
|
|
||||||
...(limitedVersion
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
shape: "CrCrCrCr",
|
|
||||||
required: 0,
|
|
||||||
reward: enumHubGoalRewards.reward_demo_end,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: [
|
|
||||||
// 8
|
|
||||||
{
|
|
||||||
shape: "RbRb----", // painter t2
|
|
||||||
required: 480,
|
|
||||||
reward: enumHubGoalRewards.reward_mixer,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 9
|
|
||||||
// Mixing (purple)
|
|
||||||
{
|
|
||||||
shape: "CpCpCpCp", // belts t3
|
|
||||||
required: 600,
|
|
||||||
reward: enumHubGoalRewards.reward_merger,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 10
|
|
||||||
// STACKER: Star shape + cyan
|
|
||||||
{
|
|
||||||
shape: "ScScScSc", // miners t3
|
|
||||||
required: 800,
|
|
||||||
reward: enumHubGoalRewards.reward_stacker,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 11
|
|
||||||
// Chainable miner
|
|
||||||
{
|
|
||||||
shape: "CgScScCg", // processors t3
|
|
||||||
required: 1000,
|
|
||||||
reward: enumHubGoalRewards.reward_miner_chainable,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 12
|
|
||||||
// Blueprints
|
|
||||||
{
|
|
||||||
shape: "CbCbCbRb:CwCwCwCw",
|
|
||||||
required: 1000,
|
|
||||||
reward: enumHubGoalRewards.reward_blueprints,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 13
|
|
||||||
// Tunnel Tier 2
|
|
||||||
{
|
|
||||||
shape: chinaShapes ? "CuCuCuCu:CwCwCwCw:Sb--Sr--" : "RpRpRpRp:CwCwCwCw", // painting t3
|
|
||||||
required: 3800,
|
|
||||||
reward: enumHubGoalRewards.reward_underground_belt_tier_2,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 14
|
|
||||||
// Belt reader
|
|
||||||
{
|
|
||||||
shape: "--Cg----:--Cr----", // unused
|
|
||||||
required: 8, // Per second!
|
|
||||||
reward: enumHubGoalRewards.reward_belt_reader,
|
|
||||||
throughputOnly: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 15
|
|
||||||
// Storage
|
|
||||||
{
|
|
||||||
shape: "SrSrSrSr:CyCyCyCy", // unused
|
|
||||||
required: 10000,
|
|
||||||
reward: enumHubGoalRewards.reward_storage,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 16
|
|
||||||
// Quad Cutter
|
|
||||||
{
|
|
||||||
shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", // belts t4 (two variants)
|
|
||||||
required: 6000,
|
|
||||||
reward: enumHubGoalRewards.reward_cutter_quad,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 17
|
|
||||||
// Double painter
|
|
||||||
{
|
|
||||||
shape: chinaShapes
|
|
||||||
? "CyCyCyCy:CyCyCyCy:RyRyRyRy:RuRuRuRu"
|
|
||||||
: "CbRbRbCb:CwCwCwCw:WbWbWbWb", // miner t4 (two variants)
|
|
||||||
required: 20000,
|
|
||||||
reward: enumHubGoalRewards.reward_painter_double,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 18
|
|
||||||
// Rotater (180deg)
|
|
||||||
{
|
|
||||||
shape: "Sg----Sg:CgCgCgCg:--CyCy--", // unused
|
|
||||||
required: 20000,
|
|
||||||
reward: enumHubGoalRewards.reward_rotater_180,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 19
|
|
||||||
// Compact splitter
|
|
||||||
{
|
|
||||||
shape: "CpRpCp--:SwSwSwSw",
|
|
||||||
required: 25000,
|
|
||||||
reward: enumHubGoalRewards.reward_splitter,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 20
|
|
||||||
// WIRES
|
|
||||||
{
|
|
||||||
shape: finalGameShape,
|
|
||||||
required: 25000,
|
|
||||||
reward: enumHubGoalRewards.reward_wires_painter_and_levers,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 21
|
|
||||||
// Filter
|
|
||||||
{
|
|
||||||
shape: "CrCwCrCw:CwCrCwCr:CrCwCrCw:CwCrCwCr",
|
|
||||||
required: 25000,
|
|
||||||
reward: enumHubGoalRewards.reward_filter,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 22
|
|
||||||
// Constant signal
|
|
||||||
{
|
|
||||||
shape: chinaShapes
|
|
||||||
? "RrSySrSy:RyCrCwCr:CyCyRyCy"
|
|
||||||
: "Cg----Cr:Cw----Cw:Sy------:Cy----Cy",
|
|
||||||
required: 25000,
|
|
||||||
reward: enumHubGoalRewards.reward_constant_signal,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 23
|
|
||||||
// Display
|
|
||||||
{
|
|
||||||
shape: chinaShapes
|
|
||||||
? "CrCrCrCr:CwCwCwCw:WwWwWwWw:CrCrCrCr"
|
|
||||||
: "CcSyCcSy:SyCcSyCc:CcSyCcSy",
|
|
||||||
required: 25000,
|
|
||||||
reward: enumHubGoalRewards.reward_display,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 24 Logic gates
|
|
||||||
{
|
|
||||||
shape: chinaShapes
|
|
||||||
? "Su----Su:RwRwRwRw:Cu----Cu:CwCwCwCw"
|
|
||||||
: "CcRcCcRc:RwCwRwCw:Sr--Sw--:CyCyCyCy",
|
|
||||||
required: 25000,
|
|
||||||
reward: enumHubGoalRewards.reward_logic_gates,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 25 Virtual Processing
|
|
||||||
{
|
|
||||||
shape: "Rg--Rg--:CwRwCwRw:--Rg--Rg",
|
|
||||||
required: 25000,
|
|
||||||
reward: enumHubGoalRewards.reward_virtual_processing,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 26 Freeplay
|
|
||||||
{
|
|
||||||
shape: "CbCuCbCu:Sr------:--CrSrCr:CwCwCwCw",
|
|
||||||
required: 50000,
|
|
||||||
reward: enumHubGoalRewards.reward_freeplay,
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
];
|
|
||||||
|
|
||||||
MOD_SIGNALS.modifyLevelDefinitions.dispatch(levelDefinitions);
|
MOD_SIGNALS.modifyLevelDefinitions.dispatch(levelDefinitions);
|
||||||
|
|
||||||
@ -544,7 +322,7 @@ export function generateLevelDefinitions(limitedVersion = false, difficulty = 1)
|
|||||||
definition.required = Math.round(definition.required * difficulty);
|
definition.required = Math.round(definition.required * difficulty);
|
||||||
});
|
});
|
||||||
|
|
||||||
levelDefinitionsCache[limitedVersion] = levelDefinitions;
|
levelDefinitionsCache[variant] = levelDefinitions;
|
||||||
|
|
||||||
return levelDefinitions;
|
return levelDefinitions;
|
||||||
}
|
}
|
||||||
@ -590,7 +368,6 @@ export class RegularGameMode extends GameMode {
|
|||||||
if (this.root.app.restrictionMgr.getIsStandaloneMarketingActive()) {
|
if (this.root.app.restrictionMgr.getIsStandaloneMarketingActive()) {
|
||||||
this.additionalHudParts.watermark = HUDWatermark;
|
this.additionalHudParts.watermark = HUDWatermark;
|
||||||
this.additionalHudParts.standaloneAdvantages = HUDStandaloneAdvantages;
|
this.additionalHudParts.standaloneAdvantages = HUDStandaloneAdvantages;
|
||||||
this.additionalHudParts.catMemes = HUDSteamCapsule;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.root.app.settings.getAllSettings().offerHints) {
|
if (this.root.app.settings.getAllSettings().offerHints) {
|
||||||
@ -635,10 +412,14 @@ export class RegularGameMode extends GameMode {
|
|||||||
* @returns {Array<LevelDefinition>}
|
* @returns {Array<LevelDefinition>}
|
||||||
*/
|
*/
|
||||||
getLevelDefinitions() {
|
getLevelDefinitions() {
|
||||||
|
if (this.root.app.restrictionMgr.isLimitedVersion()) {
|
||||||
return generateLevelDefinitions(
|
return generateLevelDefinitions(
|
||||||
!this.root.app.restrictionMgr.getHasExtendedLevelsAndFreeplay(),
|
this.root.app.gameAnalytics.abtVariant === "0" ? "LimitedLevel8" : "LimitedLevelBlueprints",
|
||||||
this.difficultyMultiplicator
|
this.difficultyMultiplicator
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
return generateLevelDefinitions("NoRestrictions", this.difficultyMultiplicator);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,8 +28,8 @@ const analyticsUrl = G_IS_DEV ? "http://localhost:8001" : "https://analytics.sha
|
|||||||
// Be sure to increment the ID whenever it changes
|
// Be sure to increment the ID whenever it changes
|
||||||
const analyticsLocalFile = G_IS_STEAM_DEMO ? "shapez_token_steamdemo.bin" : "shapez_token_123.bin";
|
const analyticsLocalFile = G_IS_STEAM_DEMO ? "shapez_token_steamdemo.bin" : "shapez_token_123.bin";
|
||||||
|
|
||||||
const CURRENT_ABT = "abt_dmtm";
|
const CURRENT_ABT = "abt_unl";
|
||||||
const CURRENT_ABT_COUNT = 3;
|
const CURRENT_ABT_COUNT = 2;
|
||||||
|
|
||||||
export class ShapezGameAnalytics extends GameAnalyticsInterface {
|
export class ShapezGameAnalytics extends GameAnalyticsInterface {
|
||||||
constructor(app) {
|
constructor(app) {
|
||||||
|
@ -108,6 +108,10 @@ demoBanners:
|
|||||||
</ul>
|
</ul>
|
||||||
playtimeDisclaimer: >-
|
playtimeDisclaimer: >-
|
||||||
The full version contains more than <strong>20 hours of content</strong>.
|
The full version contains more than <strong>20 hours of content</strong>.
|
||||||
|
|
||||||
|
playtimeDisclaimerDownload: >-
|
||||||
|
You can continue your savegame in the full version! Click <strong>here</strong> to download your savegame.
|
||||||
|
|
||||||
playerCount: >-
|
playerCount: >-
|
||||||
<playerCount> players like you are playing shapez on Steam right now
|
<playerCount> players like you are playing shapez on Steam right now
|
||||||
untilEndOfDemo: Until end of demo
|
untilEndOfDemo: Until end of demo
|
||||||
|
Loading…
Reference in New Issue
Block a user