1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2025-06-13 13:04:03 +00:00
tobspr_shapez.io/src/js/states/puzzle_menu.js

260 lines
7.9 KiB
JavaScript
Raw Normal View History

2021-04-29 20:31:06 +00:00
import { globalConfig } from "../core/config";
2021-04-29 16:27:46 +00:00
import { TextualGameState } from "../core/textual_game_state";
import { formatBigNumberFull } from "../core/utils";
import { enumGameModeIds } from "../game/game_mode";
import { ShapeDefinition } from "../game/shape_definition";
import { T } from "../translations";
const categories = ["levels", "new", "topRated", "myPuzzles"];
const SAMPLE_PUZZLE = {
shortKey: "CuCuCuCu",
upvotes: 10000,
playcount: 1000,
title: "Level 1",
author: "verylongsteamnamewhichbreaks",
completed: false,
};
2021-04-30 18:06:37 +00:00
2021-04-29 16:27:46 +00:00
const BUILTIN_PUZZLES = [
{ ...SAMPLE_PUZZLE, completed: true },
{ ...SAMPLE_PUZZLE, completed: true },
SAMPLE_PUZZLE,
SAMPLE_PUZZLE,
SAMPLE_PUZZLE,
SAMPLE_PUZZLE,
SAMPLE_PUZZLE,
SAMPLE_PUZZLE,
SAMPLE_PUZZLE,
SAMPLE_PUZZLE,
SAMPLE_PUZZLE,
SAMPLE_PUZZLE,
SAMPLE_PUZZLE,
];
export class PuzzleMenuState extends TextualGameState {
constructor() {
super("PuzzleMenuState");
this.loading = false;
this.activeCategory = "";
}
getStateHeaderTitle() {
return T.puzzleMenu.title;
}
/**
* Overrides the GameState implementation to provide our own html
*/
internalGetFullHtml() {
let headerHtml = `
<div class="headerBar">
<h1><button class="backButton"></button> ${this.getStateHeaderTitle()}</h1>
<div class="actions">
<button class="styledButton createPuzzle">+ ${T.puzzleMenu.createPuzzle}</button>
</div>
</div>`;
return `
${headerHtml}
<div class="container">
${this.getInnerHTML()}
</div>
`;
}
getMainContentHTML() {
let html = `
<div class="categoryChooser">
${categories
.map(
category => `
<button data-category="${category}" class="styledButton category">${T.puzzleMenu.categories[category]}</button>
`
)
.join("")}
</div>
<div class="puzzles" id="mainContainer">
<div class="puzzle"></div>
<div class="puzzle"></div>
<div class="puzzle"></div>
<div class="puzzle"></div>
</div>
`;
return html;
}
selectCategory(category) {
if (category === this.activeCategory) {
return;
}
if (this.loading) {
return;
}
this.loading = true;
this.activeCategory = category;
const activeCategory = this.htmlElement.querySelector(".active[data-category]");
if (activeCategory) {
activeCategory.classList.remove("active");
}
this.htmlElement.querySelector(`[data-category="${category}"]`).classList.add("active");
const container = this.htmlElement.querySelector("#mainContainer");
while (container.firstChild) {
container.removeChild(container.firstChild);
}
const loadingElement = document.createElement("div");
loadingElement.classList.add("loader");
loadingElement.innerText = T.global.loading + "...";
container.appendChild(loadingElement);
this.asyncChannel
.watch(this.getPuzzlesForCategory(category))
.then(
puzzles => this.renderPuzzles(puzzles),
error => {
this.dialogs.showWarning(
T.dialogs.puzzleLoadFailed.title,
T.dialogs.puzzleLoadFailed.desc + " " + error
);
}
)
.then(() => (this.loading = false));
}
/**
*
2021-04-30 18:06:37 +00:00
* @param {import("../savegame/savegame_typedefs").PuzzleMetadata[]} puzzles
2021-04-29 16:27:46 +00:00
*/
renderPuzzles(puzzles) {
const container = this.htmlElement.querySelector("#mainContainer");
while (container.firstChild) {
container.removeChild(container.firstChild);
}
for (const puzzle of puzzles) {
const elem = document.createElement("div");
elem.classList.add("puzzle");
elem.classList.toggle("completed", puzzle.completed);
if (puzzle.title) {
const title = document.createElement("div");
title.classList.add("title");
title.innerText = puzzle.title;
elem.appendChild(title);
}
if (puzzle.author) {
const author = document.createElement("div");
author.classList.add("author");
author.innerText = "by " + puzzle.author;
elem.appendChild(author);
}
if (puzzle.upvotes) {
const upvotes = document.createElement("div");
upvotes.classList.add("upvotes");
upvotes.innerText = formatBigNumberFull(puzzle.upvotes);
elem.appendChild(upvotes);
}
if (puzzle.playcount) {
const playcount = document.createElement("div");
playcount.classList.add("playcount");
playcount.innerText = String(puzzle.playcount) + " plays";
elem.appendChild(playcount);
}
const definition = ShapeDefinition.fromShortKey(puzzle.shortKey);
const canvas = definition.generateAsCanvas(100 * this.app.getEffectiveUiScale());
const icon = document.createElement("div");
icon.classList.add("icon");
icon.appendChild(canvas);
elem.appendChild(icon);
container.appendChild(elem);
2021-04-30 18:06:37 +00:00
this.trackClicks(elem, () => this.playPuzzle(puzzle));
2021-04-29 16:27:46 +00:00
}
}
getPuzzlesForCategory(category) {
return new Promise(resolve => setTimeout(() => resolve(BUILTIN_PUZZLES), 100));
}
2021-04-30 18:06:37 +00:00
/**
*
* @param {import("../savegame/savegame_typedefs").PuzzleMetadata} puzzle
*/
playPuzzle(puzzle) {
/**
* @type {import("../savegame/savegame_typedefs").PuzzleGameData}
*/
const puzzleData = {
version: 1,
buildings: [
{
type: "emitter",
item: "CuCuCuCu",
2021-04-30 19:09:23 +00:00
pos: { x: -2, y: 2, r: 0 },
2021-04-30 18:06:37 +00:00
},
{
type: "emitter",
item: "red",
2021-04-30 19:09:23 +00:00
pos: { x: 1, y: 2, r: 0 },
2021-04-30 18:06:37 +00:00
},
{
type: "goal",
item: "CrCrCrCr",
2021-04-30 19:09:23 +00:00
pos: { x: 0, y: -3, r: 0 },
2021-04-30 18:06:37 +00:00
},
],
2021-04-30 19:09:23 +00:00
bounds: { w: 4, h: 6 },
2021-04-30 18:06:37 +00:00
};
const savegame = this.app.savegameMgr.createNewSavegame();
this.moveToState("InGameState", {
gameModeId: enumGameModeIds.puzzlePlay,
gameModeParameters: {
puzzle: {
meta: puzzle,
game: puzzleData,
},
},
savegame,
});
}
2021-04-29 16:27:46 +00:00
onEnter() {
this.selectCategory("levels");
for (const category of categories) {
const button = this.htmlElement.querySelector(`[data-category="${category}"]`);
this.trackClicks(button, () => this.selectCategory(category));
}
this.trackClicks(this.htmlElement.querySelector("button.createPuzzle"), this.createNewPuzzle);
2021-04-29 20:31:06 +00:00
if (G_IS_DEV && globalConfig.debug.testPuzzleMode) {
2021-04-30 18:06:37 +00:00
// this.createNewPuzzle();
this.playPuzzle(SAMPLE_PUZZLE);
2021-04-29 20:31:06 +00:00
}
2021-04-29 16:27:46 +00:00
}
createNewPuzzle() {
const savegame = this.app.savegameMgr.createNewSavegame();
this.moveToState("InGameState", {
gameModeId: enumGameModeIds.puzzleEdit,
savegame,
});
}
}