Update demo hint and lock demo to lvl 14
BIN
res/ui/icons/advantage_buildings.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
res/ui/icons/advantage_dark_mode.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
res/ui/icons/advantage_markers.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
res/ui/icons/advantage_new_levels.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
res/ui/icons/advantage_savegames.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
res/ui/icons/advantage_support.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
res/ui/icons/advantage_upgrades.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
res/ui/icons/advantage_wires.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
res/ui/icons/demo_steam_link_indicator.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
@ -1,39 +1,40 @@
|
||||
#ingame_HUD_BlueprintPlacer {
|
||||
position: absolute;
|
||||
@include S(top, 50px);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
color: #333;
|
||||
z-index: 9999;
|
||||
background: $ingameHudBg;
|
||||
@include S(padding, 5px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: #fff;
|
||||
@include S(width, 120px);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.label {
|
||||
@include PlainText;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.costContainer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@include Heading;
|
||||
|
||||
> canvas {
|
||||
@include S(margin-left, 5px);
|
||||
@include S(width, 30px);
|
||||
@include S(height, 30px);
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.canAfford) {
|
||||
background: rgba(98, 27, 41, 0.8);
|
||||
// .costContainer {
|
||||
color: rgb(255, 97, 128);
|
||||
// }
|
||||
}
|
||||
}
|
||||
#ingame_HUD_BlueprintPlacer {
|
||||
position: absolute;
|
||||
@include S(top, 70px);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
color: #333;
|
||||
z-index: 9999;
|
||||
background: $ingameHudBg;
|
||||
@include S(padding, 5px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: #fff;
|
||||
@include S(width, 120px);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@include S(border-radius, $globalBorderRadius);
|
||||
|
||||
.label {
|
||||
@include PlainText;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.costContainer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@include Heading;
|
||||
|
||||
> canvas {
|
||||
@include S(margin-left, 5px);
|
||||
@include S(width, 30px);
|
||||
@include S(height, 30px);
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.canAfford) {
|
||||
background: rgba(98, 27, 41, 0.8);
|
||||
// .costContainer {
|
||||
color: rgb(255, 97, 128);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
171
src/css/ingame_hud/standalone_advantages.scss
Normal file
@ -0,0 +1,171 @@
|
||||
#ingame_HUD_StandaloneAdvantages {
|
||||
.content {
|
||||
@include S(width, 440px);
|
||||
@include S(min-height, 300px);
|
||||
}
|
||||
p {
|
||||
@include PlainText;
|
||||
}
|
||||
|
||||
.points {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
@include S(grid-column-gap, 10px);
|
||||
@include S(grid-row-gap, 20px);
|
||||
@include S(margin, 10px, 0, 20px);
|
||||
grid-template-rows: #{D(40px)};
|
||||
align-items: center;
|
||||
}
|
||||
.lowerBar {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
|
||||
> button {
|
||||
transition: opacity 0.12s ease-in-out;
|
||||
&:hover {
|
||||
opacity: 0.85;
|
||||
}
|
||||
}
|
||||
|
||||
.otherCloseButton {
|
||||
@include SuperSmallText;
|
||||
@include S(margin-right, 30px);
|
||||
color: #aaa;
|
||||
@include S(margin, 0);
|
||||
@include IncreasedClickArea(0px);
|
||||
@include S(margin-top, 15px);
|
||||
|
||||
@include InlineAnimation(5s ease-in-out) {
|
||||
0% {
|
||||
opacity: 0.05;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.05;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.steamLinkButton {
|
||||
@include IncreasedClickArea(5px);
|
||||
@include S(margin, 0);
|
||||
@include S(width, 180px);
|
||||
@include S(height, 40px);
|
||||
& {
|
||||
/* @load-async */
|
||||
background: #171a23 uiResource("get_on_steam.png") center center / contain no-repeat;
|
||||
}
|
||||
|
||||
@include S(border-radius, $globalBorderRadius);
|
||||
}
|
||||
}
|
||||
|
||||
.point {
|
||||
display: grid;
|
||||
grid-template-columns: #{D(55px)} auto;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
|
||||
> strong {
|
||||
grid-column: 2 / 3;
|
||||
grid-row: 1 / 2;
|
||||
@include PlainText;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
> p {
|
||||
grid-column: 2 / 3;
|
||||
grid-row: 2 / 3;
|
||||
@include SuperSmallText;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
background: transparent #{D(10px)} center / #{D(30px)} no-repeat;
|
||||
|
||||
&.levels {
|
||||
& {
|
||||
/* @load-async */
|
||||
background-image: uiResource("res/ui/icons/advantage_new_levels.png");
|
||||
}
|
||||
> strong {
|
||||
color: #f13555;
|
||||
}
|
||||
}
|
||||
|
||||
&.upgrades {
|
||||
& {
|
||||
/* @load-async */
|
||||
background-image: uiResource("res/ui/icons/advantage_upgrades.png");
|
||||
}
|
||||
> strong {
|
||||
color: #8a00ff;
|
||||
}
|
||||
}
|
||||
|
||||
&.buildings {
|
||||
& {
|
||||
/* @load-async */
|
||||
background-image: uiResource("res/ui/icons/advantage_buildings.png");
|
||||
}
|
||||
> strong {
|
||||
color: #3fce8b;
|
||||
}
|
||||
}
|
||||
|
||||
&.wires {
|
||||
& {
|
||||
/* @load-async */
|
||||
background-image: uiResource("res/ui/icons/advantage_wires.png");
|
||||
}
|
||||
> strong {
|
||||
color: #ef2fdb;
|
||||
}
|
||||
}
|
||||
|
||||
&.markers {
|
||||
& {
|
||||
/* @load-async */
|
||||
background-image: uiResource("res/ui/icons/advantage_markers.png");
|
||||
}
|
||||
> strong {
|
||||
color: #4294ff;
|
||||
}
|
||||
}
|
||||
|
||||
&.savegames {
|
||||
& {
|
||||
/* @load-async */
|
||||
background-image: uiResource("res/ui/icons/advantage_savegames.png");
|
||||
}
|
||||
> strong {
|
||||
color: #ff9500;
|
||||
}
|
||||
}
|
||||
|
||||
&.darkmode {
|
||||
& {
|
||||
/* @load-async */
|
||||
background-image: uiResource("res/ui/icons/advantage_dark_mode.png");
|
||||
}
|
||||
> strong {
|
||||
color: #292c32;
|
||||
}
|
||||
}
|
||||
|
||||
&.support {
|
||||
& {
|
||||
/* @load-async */
|
||||
background-image: uiResource("res/ui/icons/advantage_support.png");
|
||||
}
|
||||
> strong {
|
||||
color: #e72d2d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +1,85 @@
|
||||
#ingame_HUD_Watermark {
|
||||
position: absolute;
|
||||
& {
|
||||
/* @load-async */
|
||||
background: uiResource("get_on_steam.png") center center / contain no-repeat;
|
||||
}
|
||||
|
||||
@include S(width, 110px);
|
||||
@include S(height, 40px);
|
||||
@include S(top, 10px);
|
||||
@include S(border-radius, $globalBorderRadius);
|
||||
@include S(top, 70px);
|
||||
pointer-events: all;
|
||||
cursor: pointer;
|
||||
@include S(left, 160px);
|
||||
left: 50%;
|
||||
text-align: center;
|
||||
|
||||
background: rgba(207, 65, 65, 0.8);
|
||||
color: #fff;
|
||||
transform: translateX(-50%);
|
||||
@include PlainText;
|
||||
@include S(padding, 10px);
|
||||
|
||||
transition: all 0.12s ease-in;
|
||||
transition-property: opacity, transform;
|
||||
transform: skewX(-0.5deg);
|
||||
&:hover {
|
||||
transform: skewX(-1deg) scale(1.02);
|
||||
opacity: 0.9;
|
||||
transform: translateX(-50%) scale(1.02) !important;
|
||||
}
|
||||
|
||||
> strong {
|
||||
@include PlainText;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
> p {
|
||||
@include SuperSmallText;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
opacity: 0;
|
||||
|
||||
&.visible {
|
||||
@include InlineAnimation(0.5s ease-in-out) {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&:not(.visible) {
|
||||
@include InlineAnimation(0.5s ease-in-out) {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ingame_HUD_WatermarkClicker {
|
||||
@include S(top, 55px);
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) !important;
|
||||
@include SuperSmallText;
|
||||
color: $colorBlueBright;
|
||||
text-transform: uppercase;
|
||||
pointer-events: all;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
&::after {
|
||||
@include S(margin-left, 4px);
|
||||
content: "";
|
||||
@include S(width, 10px);
|
||||
@include S(height, 10px);
|
||||
display: inline-flex;
|
||||
background: center center / contain no-repeat;
|
||||
& {
|
||||
/* @load-async */
|
||||
background-image: uiResource("res/ui/icons/demo_steam_link_indicator.png");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,7 @@
|
||||
@import "ingame_hud/color_blind_helper";
|
||||
@import "ingame_hud/shape_viewer";
|
||||
@import "ingame_hud/sandbox_controller";
|
||||
@import "ingame_hud/standalone_advantages";
|
||||
|
||||
// prettier-ignore
|
||||
$elements:
|
||||
@ -77,6 +78,7 @@ ingame_HUD_buildings_toolbar,
|
||||
ingame_HUD_wires_toolbar,
|
||||
ingame_HUD_BlueprintPlacer,
|
||||
ingame_HUD_Waypoints_Hint,
|
||||
ingame_HUD_WatermarkClicker,
|
||||
ingame_HUD_Watermark,
|
||||
ingame_HUD_ColorBlindBelowTileHelper,
|
||||
ingame_HUD_SandboxController,
|
||||
@ -88,6 +90,7 @@ ingame_HUD_BetaOverlay,
|
||||
ingame_HUD_Shop,
|
||||
ingame_HUD_Statistics,
|
||||
ingame_HUD_ShapeViewer,
|
||||
ingame_HUD_StandaloneAdvantages,
|
||||
ingame_HUD_UnlockNotification,
|
||||
ingame_HUD_SettingsMenu,
|
||||
ingame_HUD_ModalDialogs;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { globalConfig } from "../core/config";
|
||||
import { globalConfig, IS_DEMO } from "../core/config";
|
||||
import { RandomNumberGenerator } from "../core/rng";
|
||||
import { clamp, findNiceIntegerValue, randomChoice, randomInt } from "../core/utils";
|
||||
import { BasicSerializableObject, types } from "../savegame/serialization";
|
||||
@ -29,6 +29,10 @@ export class HubGoals extends BasicSerializableObject {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
if (IS_DEMO) {
|
||||
this.level = Math.min(this.level, tutorialGoals.length);
|
||||
}
|
||||
|
||||
// Compute gained rewards
|
||||
for (let i = 0; i < this.level - 1; ++i) {
|
||||
if (i < tutorialGoals.length) {
|
||||
@ -102,13 +106,23 @@ export class HubGoals extends BasicSerializableObject {
|
||||
if (ev.key === "b") {
|
||||
// root is not guaranteed to exist within ~0.5s after loading in
|
||||
if (this.root && this.root.app && this.root.app.gameAnalytics) {
|
||||
this.onGoalCompleted();
|
||||
if (!this.isEndOfDemoReached()) {
|
||||
this.onGoalCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the end of the demo is reached
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isEndOfDemoReached() {
|
||||
return IS_DEMO && this.level >= tutorialGoals.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how much of the current shape is stored
|
||||
* @param {ShapeDefinition} definition
|
||||
@ -190,7 +204,9 @@ export class HubGoals extends BasicSerializableObject {
|
||||
this.getCurrentGoalDelivered() >= this.currentGoal.required ||
|
||||
(G_IS_DEV && globalConfig.debug.rewardsInstant)
|
||||
) {
|
||||
this.onGoalCompleted();
|
||||
if (!this.isEndOfDemoReached()) {
|
||||
this.onGoalCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,6 +270,11 @@ export class HubGoals extends BasicSerializableObject {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IS_DEMO && currentLevel >= 4) {
|
||||
// DEMO
|
||||
return false;
|
||||
}
|
||||
|
||||
if (G_IS_DEV && globalConfig.debug.upgradesNoCost) {
|
||||
return true;
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ import { HUDLayerPreview } from "./parts/layer_preview";
|
||||
import { HUDMinerHighlight } from "./parts/miner_highlight";
|
||||
import { HUDBetaOverlay } from "./parts/beta_overlay";
|
||||
import { HUDPerformanceWarning } from "./parts/performance_warning";
|
||||
import { HUDStandaloneAdvantages } from "./parts/standalone_advantages";
|
||||
|
||||
export class GameHUD {
|
||||
/**
|
||||
@ -116,6 +117,7 @@ export class GameHUD {
|
||||
|
||||
if (IS_DEMO) {
|
||||
this.parts.watermark = new HUDWatermark(this.root);
|
||||
this.parts.standaloneAdvantages = new HUDStandaloneAdvantages(this.root);
|
||||
}
|
||||
|
||||
if (G_IS_DEV && globalConfig.debug.renderChanges) {
|
||||
@ -139,9 +141,9 @@ export class GameHUD {
|
||||
this.parts.sandboxController = new HUDSandboxController(this.root);
|
||||
}
|
||||
|
||||
// if (!G_IS_RELEASE) {
|
||||
this.parts.betaOverlay = new HUDBetaOverlay(this.root);
|
||||
// }
|
||||
if (!G_IS_RELEASE && !G_IS_DEV) {
|
||||
this.parts.betaOverlay = new HUDBetaOverlay(this.root);
|
||||
}
|
||||
|
||||
const frag = document.createDocumentFragment();
|
||||
for (const key in this.parts) {
|
||||
|
@ -122,7 +122,7 @@ export class HUDModalDialogs extends BaseHUDPart {
|
||||
|
||||
dialog.buttonSignals.getStandalone.add(() => {
|
||||
this.app.analytics.trackUiClick("demo_dialog_click");
|
||||
window.open(THIRDPARTY_URLS.standaloneStorePage);
|
||||
window.open(THIRDPARTY_URLS.standaloneStorePage + "?ref=ddc");
|
||||
});
|
||||
|
||||
return dialog.buttonSignals;
|
||||
|
@ -88,13 +88,8 @@ export class HUDSettingsMenu extends BaseHUDPart {
|
||||
this.close();
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
document.body.classList.remove("ingameDialogOpen");
|
||||
}
|
||||
|
||||
show() {
|
||||
this.visible = true;
|
||||
document.body.classList.add("ingameDialogOpen");
|
||||
this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever);
|
||||
|
||||
const totalMinutesPlayed = Math.ceil(this.root.time.now() / 60);
|
||||
@ -120,7 +115,6 @@ export class HUDSettingsMenu extends BaseHUDPart {
|
||||
|
||||
close() {
|
||||
this.visible = false;
|
||||
document.body.classList.remove("ingameDialogOpen");
|
||||
this.root.app.inputMgr.makeSureDetached(this.inputReciever);
|
||||
this.update();
|
||||
}
|
||||
|
@ -67,7 +67,6 @@ export class HUDShapeViewer extends BaseHUDPart {
|
||||
*/
|
||||
close() {
|
||||
this.visible = false;
|
||||
document.body.classList.remove("ingameDialogOpen");
|
||||
this.root.app.inputMgr.makeSureDetached(this.inputReciever);
|
||||
this.update();
|
||||
}
|
||||
@ -78,7 +77,6 @@ export class HUDShapeViewer extends BaseHUDPart {
|
||||
*/
|
||||
renderForShape(definition) {
|
||||
this.visible = true;
|
||||
document.body.classList.add("ingameDialogOpen");
|
||||
this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever);
|
||||
|
||||
removeAllChildren(this.renderArea);
|
||||
@ -124,13 +122,6 @@ export class HUDShapeViewer extends BaseHUDPart {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up everything
|
||||
*/
|
||||
cleanup() {
|
||||
document.body.classList.remove("ingameDialogOpen");
|
||||
}
|
||||
|
||||
update() {
|
||||
this.domAttach.update(this.visible);
|
||||
}
|
||||
|
@ -205,8 +205,6 @@ export class HUDShop extends BaseHUDPart {
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
document.body.classList.remove("ingameDialogOpen");
|
||||
|
||||
// Cleanup detectors
|
||||
for (const upgradeId in this.upgradeToElements) {
|
||||
const handle = this.upgradeToElements[upgradeId];
|
||||
@ -222,15 +220,12 @@ export class HUDShop extends BaseHUDPart {
|
||||
|
||||
show() {
|
||||
this.visible = true;
|
||||
document.body.classList.add("ingameDialogOpen");
|
||||
// this.background.classList.add("visible");
|
||||
this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever);
|
||||
this.rerenderFull();
|
||||
}
|
||||
|
||||
close() {
|
||||
this.visible = false;
|
||||
document.body.classList.remove("ingameDialogOpen");
|
||||
this.root.app.inputMgr.makeSureDetached(this.inputReciever);
|
||||
this.update();
|
||||
}
|
||||
|
84
src/js/game/hud/parts/standalone_advantages.js
Normal file
@ -0,0 +1,84 @@
|
||||
import { THIRDPARTY_URLS } from "../../../core/config";
|
||||
import { InputReceiver } from "../../../core/input_receiver";
|
||||
import { makeDiv } from "../../../core/utils";
|
||||
import { T } from "../../../translations";
|
||||
import { BaseHUDPart } from "../base_hud_part";
|
||||
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||
|
||||
const showIntervalSeconds = 30 * 60;
|
||||
|
||||
export class HUDStandaloneAdvantages extends BaseHUDPart {
|
||||
createElements(parent) {
|
||||
this.background = makeDiv(parent, "ingame_HUD_StandaloneAdvantages", ["ingameDialog"]);
|
||||
|
||||
// DIALOG Inner / Wrapper
|
||||
this.dialogInner = makeDiv(this.background, null, ["dialogInner"]);
|
||||
this.title = makeDiv(this.dialogInner, null, ["title"], T.ingame.standaloneAdvantages.title);
|
||||
this.contentDiv = makeDiv(
|
||||
this.dialogInner,
|
||||
null,
|
||||
["content"],
|
||||
`
|
||||
<div class="points">
|
||||
${Object.entries(T.ingame.standaloneAdvantages.points)
|
||||
.map(
|
||||
([key, trans]) => `
|
||||
<div class="point ${key}">
|
||||
<strong>${trans.title}</strong>
|
||||
<p>${trans.desc}</p>
|
||||
</div>`
|
||||
)
|
||||
.join("")}
|
||||
|
||||
</div>
|
||||
|
||||
<div class="lowerBar">
|
||||
<button class="steamLinkButton">
|
||||
<button class="otherCloseButton">${T.ingame.standaloneAdvantages.no_thanks}</button>
|
||||
</button>
|
||||
</div>
|
||||
`
|
||||
);
|
||||
|
||||
this.trackClicks(this.contentDiv.querySelector("button.steamLinkButton"), () => {
|
||||
this.root.app.analytics.trackUiClick("standalone_advantage_visit_steam");
|
||||
this.root.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.standaloneStorePage + "?ref=savs");
|
||||
this.close();
|
||||
});
|
||||
this.trackClicks(this.contentDiv.querySelector("button.otherCloseButton"), () => {
|
||||
this.root.app.analytics.trackUiClick("standalone_advantage_no_thanks");
|
||||
this.close();
|
||||
});
|
||||
}
|
||||
|
||||
initialize() {
|
||||
this.domAttach = new DynamicDomAttach(this.root, this.background, {
|
||||
attachClass: "visible",
|
||||
});
|
||||
|
||||
this.inputReciever = new InputReceiver("standalone-advantages");
|
||||
this.close();
|
||||
|
||||
this.lastShown = this.root.gameIsFresh ? this.root.time.now() : 0;
|
||||
}
|
||||
|
||||
show() {
|
||||
this.lastShown = this.root.time.now();
|
||||
this.visible = true;
|
||||
this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever);
|
||||
}
|
||||
|
||||
close() {
|
||||
this.visible = false;
|
||||
this.root.app.inputMgr.makeSureDetached(this.inputReciever);
|
||||
this.update();
|
||||
}
|
||||
|
||||
update() {
|
||||
if (!this.visible && this.root.time.now() - this.lastShown > showIntervalSeconds) {
|
||||
this.show();
|
||||
}
|
||||
|
||||
this.domAttach.update(this.visible);
|
||||
}
|
||||
}
|
@ -151,17 +151,12 @@ export class HUDStatistics extends BaseHUDPart {
|
||||
}
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
document.body.classList.remove("ingameDialogOpen");
|
||||
}
|
||||
|
||||
isBlockingOverlay() {
|
||||
return this.visible;
|
||||
}
|
||||
|
||||
show() {
|
||||
this.visible = true;
|
||||
document.body.classList.add("ingameDialogOpen");
|
||||
this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever);
|
||||
this.rerenderFull();
|
||||
this.update();
|
||||
@ -169,7 +164,6 @@ export class HUDStatistics extends BaseHUDPart {
|
||||
|
||||
close() {
|
||||
this.visible = false;
|
||||
document.body.classList.remove("ingameDialogOpen");
|
||||
this.root.app.inputMgr.makeSureDetached(this.inputReciever);
|
||||
this.update();
|
||||
}
|
||||
|
@ -1,109 +1,106 @@
|
||||
import { InputReceiver } from "../../../core/input_receiver";
|
||||
import { TrackedState } from "../../../core/tracked_state";
|
||||
import { makeDiv } from "../../../core/utils";
|
||||
import { KeyActionMapper, KEYMAPPINGS } from "../../key_action_mapper";
|
||||
import { BaseHUDPart } from "../base_hud_part";
|
||||
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||
import { T } from "../../../translations";
|
||||
|
||||
const tutorialVideos = [2, 3, 4, 5, 6, 7, 9, 10, 11];
|
||||
|
||||
export class HUDPartTutorialHints extends BaseHUDPart {
|
||||
createElements(parent) {
|
||||
this.element = makeDiv(
|
||||
parent,
|
||||
"ingame_HUD_TutorialHints",
|
||||
[],
|
||||
`
|
||||
<div class="header">
|
||||
<span>${T.ingame.tutorialHints.title}</span>
|
||||
<button class="styledButton toggleHint">
|
||||
<span class="show">${T.ingame.tutorialHints.showHint}</span>
|
||||
<span class="hide">${T.ingame.tutorialHints.hideHint}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<video autoplay muted loop class="fullscreenBackgroundVideo">
|
||||
<source type="video/webm">
|
||||
</video>
|
||||
`
|
||||
);
|
||||
|
||||
this.videoElement = this.element.querySelector("video");
|
||||
}
|
||||
|
||||
shouldPauseGame() {
|
||||
return this.enlarged;
|
||||
}
|
||||
|
||||
initialize() {
|
||||
this.trackClicks(this.element.querySelector(".toggleHint"), this.toggleHintEnlarged);
|
||||
|
||||
this.videoAttach = new DynamicDomAttach(this.root, this.videoElement, {
|
||||
timeToKeepSeconds: 0.3,
|
||||
});
|
||||
|
||||
this.videoAttach.update(false);
|
||||
this.enlarged = false;
|
||||
|
||||
this.inputReciever = new InputReceiver("tutorial_hints");
|
||||
this.keyActionMapper = new KeyActionMapper(this.root, this.inputReciever);
|
||||
this.keyActionMapper.getBinding(KEYMAPPINGS.general.back).add(this.close, this);
|
||||
|
||||
this.domAttach = new DynamicDomAttach(this.root, this.element);
|
||||
|
||||
this.currentShownLevel = new TrackedState(this.updateVideoUrl, this);
|
||||
}
|
||||
|
||||
updateVideoUrl(level) {
|
||||
if (tutorialVideos.indexOf(level) < 0) {
|
||||
this.videoElement.querySelector("source").setAttribute("src", "");
|
||||
this.videoElement.pause();
|
||||
} else {
|
||||
this.videoElement
|
||||
.querySelector("source")
|
||||
.setAttribute("src", "https://static.shapez.io/tutorial_videos/level_" + level + ".webm");
|
||||
this.videoElement.currentTime = 0;
|
||||
this.videoElement.load();
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
this.enlarged = false;
|
||||
document.body.classList.remove("ingameDialogOpen");
|
||||
this.element.classList.remove("enlarged", "noBlur");
|
||||
this.root.app.inputMgr.makeSureDetached(this.inputReciever);
|
||||
this.update();
|
||||
}
|
||||
|
||||
show() {
|
||||
this.root.app.analytics.trackUiClick("tutorial_hint_show");
|
||||
this.root.app.analytics.trackUiClick("tutorial_hint_show_lvl_" + this.root.hubGoals.level);
|
||||
|
||||
document.body.classList.add("ingameDialogOpen");
|
||||
this.element.classList.add("enlarged", "noBlur");
|
||||
this.enlarged = true;
|
||||
this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever);
|
||||
this.update();
|
||||
|
||||
this.videoElement.currentTime = 0;
|
||||
this.videoElement.play();
|
||||
}
|
||||
|
||||
update() {
|
||||
this.videoAttach.update(this.enlarged);
|
||||
|
||||
this.currentShownLevel.set(this.root.hubGoals.level);
|
||||
|
||||
const tutorialVisible = tutorialVideos.indexOf(this.root.hubGoals.level) >= 0;
|
||||
this.domAttach.update(tutorialVisible);
|
||||
}
|
||||
|
||||
toggleHintEnlarged() {
|
||||
if (this.enlarged) {
|
||||
this.close();
|
||||
} else {
|
||||
this.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
import { InputReceiver } from "../../../core/input_receiver";
|
||||
import { TrackedState } from "../../../core/tracked_state";
|
||||
import { makeDiv } from "../../../core/utils";
|
||||
import { KeyActionMapper, KEYMAPPINGS } from "../../key_action_mapper";
|
||||
import { BaseHUDPart } from "../base_hud_part";
|
||||
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||
import { T } from "../../../translations";
|
||||
|
||||
const tutorialVideos = [2, 3, 4, 5, 6, 7, 9, 10, 11];
|
||||
|
||||
export class HUDPartTutorialHints extends BaseHUDPart {
|
||||
createElements(parent) {
|
||||
this.element = makeDiv(
|
||||
parent,
|
||||
"ingame_HUD_TutorialHints",
|
||||
[],
|
||||
`
|
||||
<div class="header">
|
||||
<span>${T.ingame.tutorialHints.title}</span>
|
||||
<button class="styledButton toggleHint">
|
||||
<span class="show">${T.ingame.tutorialHints.showHint}</span>
|
||||
<span class="hide">${T.ingame.tutorialHints.hideHint}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<video autoplay muted loop class="fullscreenBackgroundVideo">
|
||||
<source type="video/webm">
|
||||
</video>
|
||||
`
|
||||
);
|
||||
|
||||
this.videoElement = this.element.querySelector("video");
|
||||
}
|
||||
|
||||
shouldPauseGame() {
|
||||
return this.enlarged;
|
||||
}
|
||||
|
||||
initialize() {
|
||||
this.trackClicks(this.element.querySelector(".toggleHint"), this.toggleHintEnlarged);
|
||||
|
||||
this.videoAttach = new DynamicDomAttach(this.root, this.videoElement, {
|
||||
timeToKeepSeconds: 0.3,
|
||||
});
|
||||
|
||||
this.videoAttach.update(false);
|
||||
this.enlarged = false;
|
||||
|
||||
this.inputReciever = new InputReceiver("tutorial_hints");
|
||||
this.keyActionMapper = new KeyActionMapper(this.root, this.inputReciever);
|
||||
this.keyActionMapper.getBinding(KEYMAPPINGS.general.back).add(this.close, this);
|
||||
|
||||
this.domAttach = new DynamicDomAttach(this.root, this.element);
|
||||
|
||||
this.currentShownLevel = new TrackedState(this.updateVideoUrl, this);
|
||||
}
|
||||
|
||||
updateVideoUrl(level) {
|
||||
if (tutorialVideos.indexOf(level) < 0) {
|
||||
this.videoElement.querySelector("source").setAttribute("src", "");
|
||||
this.videoElement.pause();
|
||||
} else {
|
||||
this.videoElement
|
||||
.querySelector("source")
|
||||
.setAttribute("src", "https://static.shapez.io/tutorial_videos/level_" + level + ".webm");
|
||||
this.videoElement.currentTime = 0;
|
||||
this.videoElement.load();
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
this.enlarged = false;
|
||||
this.element.classList.remove("enlarged", "noBlur");
|
||||
this.root.app.inputMgr.makeSureDetached(this.inputReciever);
|
||||
this.update();
|
||||
}
|
||||
|
||||
show() {
|
||||
this.root.app.analytics.trackUiClick("tutorial_hint_show");
|
||||
this.root.app.analytics.trackUiClick("tutorial_hint_show_lvl_" + this.root.hubGoals.level);
|
||||
this.element.classList.add("enlarged", "noBlur");
|
||||
this.enlarged = true;
|
||||
this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever);
|
||||
this.update();
|
||||
|
||||
this.videoElement.currentTime = 0;
|
||||
this.videoElement.play();
|
||||
}
|
||||
|
||||
update() {
|
||||
this.videoAttach.update(this.enlarged);
|
||||
|
||||
this.currentShownLevel.set(this.root.hubGoals.level);
|
||||
|
||||
const tutorialVisible = tutorialVideos.indexOf(this.root.hubGoals.level) >= 0;
|
||||
this.domAttach.update(tutorialVisible);
|
||||
}
|
||||
|
||||
toggleHintEnlarged() {
|
||||
if (this.enlarged) {
|
||||
this.close();
|
||||
} else {
|
||||
this.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,44 +1,67 @@
|
||||
import { BaseHUDPart } from "../base_hud_part";
|
||||
import { DrawParameters } from "../../../core/draw_parameters";
|
||||
import { makeDiv } from "../../../core/utils";
|
||||
import { THIRDPARTY_URLS } from "../../../core/config";
|
||||
import { T } from "../../../translations";
|
||||
|
||||
export class HUDWatermark extends BaseHUDPart {
|
||||
createElements(parent) {
|
||||
this.element = makeDiv(parent, "ingame_HUD_Watermark");
|
||||
}
|
||||
|
||||
initialize() {
|
||||
this.trackClicks(this.element, this.onWatermarkClick);
|
||||
}
|
||||
|
||||
onWatermarkClick() {
|
||||
this.root.app.analytics.trackUiClick("watermark_click_2");
|
||||
this.root.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.standaloneStorePage);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {DrawParameters} parameters
|
||||
*/
|
||||
drawOverlays(parameters) {
|
||||
const w = this.root.gameWidth;
|
||||
const x = 280 * this.root.app.getEffectiveUiScale();
|
||||
|
||||
parameters.context.fillStyle = "#f77";
|
||||
parameters.context.font = "bold " + this.root.app.getEffectiveUiScale() * 17 + "px GameFont";
|
||||
// parameters.context.textAlign = "center";
|
||||
parameters.context.fillText(
|
||||
T.demoBanners.title.toUpperCase(),
|
||||
x,
|
||||
this.root.app.getEffectiveUiScale() * 27
|
||||
);
|
||||
|
||||
parameters.context.font = "bold " + this.root.app.getEffectiveUiScale() * 12 + "px GameFont";
|
||||
// parameters.context.textAlign = "center";
|
||||
parameters.context.fillText(T.demoBanners.intro, x, this.root.app.getEffectiveUiScale() * 45);
|
||||
|
||||
// parameters.context.textAlign = "left";
|
||||
}
|
||||
}
|
||||
import { THIRDPARTY_URLS } from "../../../core/config";
|
||||
import { makeDiv } from "../../../core/utils";
|
||||
import { T } from "../../../translations";
|
||||
import { BaseHUDPart } from "../base_hud_part";
|
||||
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||
|
||||
export class HUDWatermark extends BaseHUDPart {
|
||||
createElements(parent) {
|
||||
this.element = makeDiv(
|
||||
parent,
|
||||
"ingame_HUD_Watermark",
|
||||
[],
|
||||
`
|
||||
<strong>${T.ingame.watermark.title}</strong>
|
||||
<p>${T.ingame.watermark.desc}</p>
|
||||
`
|
||||
);
|
||||
|
||||
this.linkElement = makeDiv(
|
||||
parent,
|
||||
"ingame_HUD_WatermarkClicker",
|
||||
[],
|
||||
T.ingame.watermark.get_on_steam
|
||||
);
|
||||
this.trackClicks(this.linkElement, () => {
|
||||
this.root.app.analytics.trackUiClick("watermark_click_2_direct");
|
||||
this.root.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.standaloneStorePage + "?ref=wtmd");
|
||||
});
|
||||
}
|
||||
|
||||
initialize() {
|
||||
this.trackClicks(this.element, this.onWatermarkClick);
|
||||
|
||||
this.domAttach = new DynamicDomAttach(this.root, this.element, {
|
||||
attachClass: "visible",
|
||||
timeToKeepSeconds: 0.5,
|
||||
});
|
||||
}
|
||||
|
||||
update() {
|
||||
this.domAttach.update(this.root.time.realtimeNow() % (G_IS_DEV ? 20 : 180) < 5);
|
||||
}
|
||||
|
||||
onWatermarkClick() {
|
||||
this.root.app.analytics.trackUiClick("watermark_click_2_new");
|
||||
this.root.hud.parts.standaloneAdvantages.show();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import("../../../core/draw_utils").DrawParameters} parameters
|
||||
*/
|
||||
drawOverlays(parameters) {
|
||||
const w = this.root.gameWidth;
|
||||
|
||||
parameters.context.fillStyle = "rgba(230, 230, 230, 0.9)";
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { globalConfig } from "../../core/config";
|
||||
import { globalConfig, IS_DEMO } from "../../core/config";
|
||||
import { smoothenDpi } from "../../core/dpi_manager";
|
||||
import { DrawParameters } from "../../core/draw_parameters";
|
||||
import { drawSpriteClipped } from "../../core/draw_utils";
|
||||
@ -65,6 +65,17 @@ export class HubSystem extends GameSystemWithFilter {
|
||||
|
||||
this.hubSprite.draw(context, 0, 0, w, h);
|
||||
|
||||
if (this.root.hubGoals.isEndOfDemoReached()) {
|
||||
// End of demo
|
||||
context.font = "bold 12px GameFont";
|
||||
context.fillStyle = "#fd0752";
|
||||
context.textAlign = "center";
|
||||
context.fillText(T.buildings.hub.endOfDemo.toUpperCase(), w / 2, h / 2 + 6);
|
||||
context.textAlign = "left";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const definition = this.root.hubGoals.currentGoal.definition;
|
||||
definition.drawCentered(45, 58, parameters, 36);
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { IS_DEMO } from "../core/config";
|
||||
import { ShapeDefinition } from "./shape_definition";
|
||||
import { finalGameShape } from "./upgrades";
|
||||
|
||||
@ -31,6 +32,8 @@ export const enumHubGoalRewards = {
|
||||
reward_virtual_processing: "reward_virtual_processing",
|
||||
reward_filter: "reward_filter",
|
||||
|
||||
reward_demo_end: "reward_demo_end",
|
||||
|
||||
reward_blueprints: "reward_blueprints",
|
||||
reward_freeplay: "reward_freeplay",
|
||||
|
||||
@ -140,107 +143,118 @@ export const tutorialGoals = [
|
||||
reward: enumHubGoalRewards.reward_underground_belt_tier_2,
|
||||
},
|
||||
|
||||
// 14
|
||||
// Belt reader
|
||||
{
|
||||
shape: "--Cg----:--Cr----", // unused
|
||||
required: 16, // Per second!
|
||||
reward: enumHubGoalRewards.reward_belt_reader,
|
||||
throughputOnly: true,
|
||||
},
|
||||
// DEMO STOPS HERE
|
||||
...(IS_DEMO
|
||||
? [
|
||||
{
|
||||
shape: "RpRpRpRp:CwCwCwCw",
|
||||
required: 0,
|
||||
reward: enumHubGoalRewards.reward_demo_end,
|
||||
},
|
||||
]
|
||||
: [
|
||||
// 14
|
||||
// Belt reader
|
||||
{
|
||||
shape: "--Cg----:--Cr----", // unused
|
||||
required: 16, // Per second!
|
||||
reward: enumHubGoalRewards.reward_belt_reader,
|
||||
throughputOnly: true,
|
||||
},
|
||||
|
||||
// 15
|
||||
// Storage
|
||||
{
|
||||
shape: "SrSrSrSr:CyCyCyCy", // unused
|
||||
required: 10000,
|
||||
reward: enumHubGoalRewards.reward_storage,
|
||||
},
|
||||
// 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,
|
||||
},
|
||||
// 16
|
||||
// Quad Cutter
|
||||
{
|
||||
shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", // belts t4 (two variants)
|
||||
required: 6000,
|
||||
reward: enumHubGoalRewards.reward_cutter_quad,
|
||||
},
|
||||
|
||||
// 17
|
||||
// Double painter
|
||||
{
|
||||
shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", // miner t4 (two variants)
|
||||
required: 20000,
|
||||
reward: enumHubGoalRewards.reward_painter_double,
|
||||
},
|
||||
// 17
|
||||
// Double painter
|
||||
{
|
||||
shape: "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,
|
||||
},
|
||||
// 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,
|
||||
},
|
||||
// 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,
|
||||
},
|
||||
// 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,
|
||||
},
|
||||
// 21
|
||||
// Filter
|
||||
{
|
||||
shape: "CrCwCrCw:CwCrCwCr:CrCwCrCw:CwCrCwCr",
|
||||
required: 25000,
|
||||
reward: enumHubGoalRewards.reward_filter,
|
||||
},
|
||||
|
||||
// 22
|
||||
// Constant signal
|
||||
{
|
||||
shape: "Cg----Cr:Cw----Cw:Sy------:Cy----Cy",
|
||||
required: 25000,
|
||||
reward: enumHubGoalRewards.reward_constant_signal,
|
||||
},
|
||||
// 22
|
||||
// Constant signal
|
||||
{
|
||||
shape: "Cg----Cr:Cw----Cw:Sy------:Cy----Cy",
|
||||
required: 25000,
|
||||
reward: enumHubGoalRewards.reward_constant_signal,
|
||||
},
|
||||
|
||||
// 23
|
||||
// Display
|
||||
{
|
||||
shape: "CcSyCcSy:SyCcSyCc:CcSyCcSy",
|
||||
required: 25000,
|
||||
reward: enumHubGoalRewards.reward_display,
|
||||
},
|
||||
// 23
|
||||
// Display
|
||||
{
|
||||
shape: "CcSyCcSy:SyCcSyCc:CcSyCcSy",
|
||||
required: 25000,
|
||||
reward: enumHubGoalRewards.reward_display,
|
||||
},
|
||||
|
||||
// 24 Logic gates
|
||||
{
|
||||
shape: "CcRcCcRc:RwCwRwCw:Sr--Sw--:CyCyCyCy",
|
||||
required: 25000,
|
||||
reward: enumHubGoalRewards.reward_logic_gates,
|
||||
},
|
||||
// 24 Logic gates
|
||||
{
|
||||
shape: "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,
|
||||
},
|
||||
// 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,
|
||||
},
|
||||
// 26 Freeplay
|
||||
{
|
||||
shape: "CbCuCbCu:Sr------:--CrSrCr:CwCwCwCw",
|
||||
required: 50000,
|
||||
reward: enumHubGoalRewards.reward_freeplay,
|
||||
},
|
||||
]),
|
||||
];
|
||||
|
||||
if (G_IS_DEV) {
|
||||
|
@ -64,6 +64,7 @@ export const enumHubGoalRewardsToContentUnlocked = {
|
||||
[enumHubGoalRewards.reward_blueprints]: null,
|
||||
[enumHubGoalRewards.no_reward]: null,
|
||||
[enumHubGoalRewards.no_reward_freeplay]: null,
|
||||
[enumHubGoalRewards.reward_demo_end]: null,
|
||||
};
|
||||
|
||||
if (G_IS_DEV) {
|
||||
|
@ -312,7 +312,7 @@ export class MainMenuState extends GameState {
|
||||
|
||||
onSteamLinkClicked() {
|
||||
this.app.analytics.trackUiClick("main_menu_steam_link_2");
|
||||
this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.standaloneStorePage);
|
||||
this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.standaloneStorePage + "?ref=mmsl2");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -537,7 +537,7 @@ export class MainMenuState extends GameState {
|
||||
);
|
||||
getStandalone.add(() => {
|
||||
this.app.analytics.trackUiClick("visit_steampage_from_slot_limit");
|
||||
this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.standaloneStorePage);
|
||||
this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.standaloneStorePage + "?reF=ssll");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ export class MobileWarningState extends GameState {
|
||||
|
||||
|
||||
<a href="${
|
||||
THIRDPARTY_URLS.standaloneStorePage
|
||||
THIRDPARTY_URLS.standaloneStorePage + "?ref=mobile"
|
||||
}" class="standaloneLink" target="_blank">Get the shapez.io standalone!</a>
|
||||
`;
|
||||
}
|
||||
|
@ -449,6 +449,49 @@ ingame:
|
||||
n_miners: <amount> Miners
|
||||
limited_items: Limited to <max_throughput>
|
||||
|
||||
# Pops up in the demo every few minutes
|
||||
watermark:
|
||||
title: Demo version
|
||||
desc: Click here to see the Steam version advantages!
|
||||
get_on_steam: Get on steam
|
||||
|
||||
standaloneAdvantages:
|
||||
title: Get the full version!
|
||||
no_thanks: No, thanks!
|
||||
|
||||
points:
|
||||
levels:
|
||||
title: 12 New Levels
|
||||
desc: For a total of 26 levels!
|
||||
|
||||
buildings:
|
||||
title: 18 New Buildings
|
||||
desc: Fully automate your factory!
|
||||
|
||||
savegames:
|
||||
title: ∞ Savegames
|
||||
desc: As many as your heart desires!
|
||||
|
||||
upgrades:
|
||||
title: 20 Upgrade Tiers
|
||||
desc: This demo version has only 5!
|
||||
|
||||
markers:
|
||||
title: ∞ Markers
|
||||
desc: Never get lost in your factory!
|
||||
|
||||
wires:
|
||||
title: Wires
|
||||
desc: An entirely new dimension!
|
||||
|
||||
darkmode:
|
||||
title: Dark Mode
|
||||
desc: Stop hurting your eyes!
|
||||
|
||||
support:
|
||||
title: Support me
|
||||
desc: I develop it in my spare time!
|
||||
|
||||
# All shop upgrades
|
||||
shopUpgrades:
|
||||
belt:
|
||||
@ -470,6 +513,7 @@ buildings:
|
||||
deliver: Deliver
|
||||
toUnlock: to unlock
|
||||
levelShortcut: LVL
|
||||
endOfDemo: End of Demo
|
||||
|
||||
belt:
|
||||
default:
|
||||
@ -817,6 +861,11 @@ storyRewards:
|
||||
Since the hub will require a <strong>throughput</strong> from now on, I highly recommend to build a machine which automatically delivers the requested shape!<br><br>
|
||||
The HUB outputs the requested shape on the wires layer, so all you have to do is to analyze it and automatically configure your factory based on that.
|
||||
|
||||
reward_demo_end:
|
||||
title: End of Demo
|
||||
desc: >-
|
||||
You have reached the end of the demo version!
|
||||
|
||||
settings:
|
||||
title: Settings
|
||||
categories:
|
||||
|