1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2026-03-02 03:39:21 +00:00

Puzzle DLC (#1172)

* Puzzle mode (#1135)

* Add mode button to main menu

* [WIP] Add mode menu. Add factory-based gameMode creation

* Add savefile migration, serialize, deserialize

* Add hidden HUD elements, zone, and zoom, boundary constraints

* Clean up lint issues

* Add building, HUD exclusion, building exclusion, and refactor

- [WIP] Add ConstantProducer building that combines ConstantSignal
and ItemProducer functionality. Currently using temp assets.
- Add pre-placement check to the zone
- Use Rectangles for zone and boundary
- Simplify zone drawing
- Account for exclusion in savegame data
- [WIP] Add puzzle play and edit buttons in puzzle mode menu

* [WIP] Add building, component, and systems for producing and
accepting user-specified items and checking goal criteria

* Add ingame puzzle mode UI elements

- Add minimal menus in puzzle mode for back, next navigation
- Add lower menu for changing zone dimenensions

Co-authored-by: Greg Considine <gconsidine@users.noreply.github.com>

* Performance optimizations (#1154)

* 1.3.1 preparations

* Minor fixes, update translations

* Fix achievements not working

* Lots of belt optimizations, ~15% performance boost

* Puzzle mode, part 1

* Puzzle mode, part 2

* Fix missing import

* Puzzle mode, part 3

* Fix typo

* Puzzle mode, part 4

* Puzzle Mode fixes: Correct zone restrictions and more (#1155)

* Hide Puzzle Editor Controls in regular game mode, fix typo

* Disallow shrinking zone if there are buildings

* Fix multi-tile buildings for shrinking

* Puzzle mode, Refactor hud

* Puzzle mode

* Fixed typo in latest puzzle commit (#1156)

* Allow completing puzzles

* Puzzle mode, almost done

* Bump version to 1.4.0

* Fixes

* [puzzle] Prevent pipette cheats (miners, emitters) (#1158)

* Puzzle mode, almost done

* Allow clearing belts with 'B'

* Multiple users for the puzzle dlc

* Bump api key

* Minor adjustments

* Update

* Minor fixes

* Fix throughput

* Fix belts

* Minor puzzle adjustments

* New difficulty

* Minor puzzle improvements

* Fix belt path

* Update translations

* Added a button to return to the menu after a puzzle is completed (#1170)

* added another button to return to the menu

* improved menu return

* fixed continue button to not go back to menu

* [Puzzle] Added ability to lock buildings in the puzzle editor! (#1164)

* initial test

* tried to get it to work

* added icon

* added test exclusion

* reverted css

* completed flow for building locking

* added lock option

* finalized look and changed locked building to same sprite

* removed unused art

* added clearing every goal acceptor on lock to prevent creating impossible puzzles

* heavily improved validation and prevented autocompletion

* validation only checks every 100 ticks to improve performance

* validation only checks every 100 ticks to improve performance

* removed clearing goal acceptors as it isn't needed because of validation

* Add soundtrack, puzzle dlc fixes

Co-authored-by: Greg Considine <gconsidine@users.noreply.github.com>
Co-authored-by: dengr1065 <dengr1065@gmail.com>
Co-authored-by: Sense101 <67970865+Sense101@users.noreply.github.com>
This commit is contained in:
tobspr
2021-05-23 16:32:05 +02:00
committed by GitHub
parent 5f0a95ba11
commit 931c8a5821
167 changed files with 14001 additions and 8193 deletions

View File

@@ -51,9 +51,12 @@ export class AnimationFrame {
dt = resetDtMs;
}
this.frameEmitted.dispatch(dt);
try {
this.frameEmitted.dispatch(dt);
} catch (ex) {
console.error(ex);
}
this.lastTime = time;
window.requestAnimationFrame(this.boundMethod);
}
}

View File

@@ -71,6 +71,13 @@ export const globalConfig = {
readerAnalyzeIntervalSeconds: 10,
goalAcceptorMinimumDurationSeconds: 5,
goalAcceptorsPerProducer: 4.5,
puzzleModeSpeed: 3,
puzzleMinBoundsSize: 2,
puzzleMaxBoundsSize: 20,
puzzleValidationDurationSeconds: 30,
buildingSpeeds: {
cutter: 1 / 4,
cutterQuad: 1 / 4,
@@ -93,7 +100,7 @@ export const globalConfig = {
gameSpeed: 1,
warmupTimeSecondsFast: 0.5,
warmupTimeSecondsRegular: 3,
warmupTimeSecondsRegular: 1.5,
smoothing: {
smoothMainCanvas: smoothCanvas && true,

View File

@@ -62,6 +62,9 @@ export default {
// Allows unlocked achievements to be logged to console in the local build
// testAchievements: true,
// -----------------------------------------------------------------------------------
// Enables use of (some) existing flags within the puzzle mode context
// testPuzzleMode: true,
// -----------------------------------------------------------------------------------
// Disables the automatic switch to an overview when zooming out
// disableMapOverview: true,
// -----------------------------------------------------------------------------------

View File

@@ -123,4 +123,6 @@ function catchErrors(message, source, lineno, colno, error) {
return true;
}
window.onerror = catchErrors;
if (!G_IS_DEV) {
window.onerror = catchErrors;
}

View File

@@ -5,6 +5,7 @@ import { Factory } from "./factory";
* @typedef {import("../game/time/base_game_speed").BaseGameSpeed} BaseGameSpeed
* @typedef {import("../game/component").Component} Component
* @typedef {import("../game/base_item").BaseItem} BaseItem
* @typedef {import("../game/game_mode").GameMode} GameMode
* @typedef {import("../game/meta_building").MetaBuilding} MetaBuilding
@@ -19,6 +20,9 @@ export let gBuildingsByCategory = null;
/** @type {FactoryTemplate<Component>} */
export let gComponentRegistry = new Factory("component");
/** @type {FactoryTemplate<GameMode>} */
export let gGameModeRegistry = new Factory("gameMode");
/** @type {FactoryTemplate<BaseGameSpeed>} */
export let gGameSpeedRegistry = new Factory("gamespeed");

View File

@@ -267,7 +267,7 @@ export class Dialog {
* Dialog which simply shows a loading spinner
*/
export class DialogLoading extends Dialog {
constructor(app) {
constructor(app, text = "") {
super({
app,
title: "",
@@ -279,6 +279,8 @@ export class DialogLoading extends Dialog {
// Loading dialog can not get closed with back button
this.inputReciever.backButton.removeAll();
this.inputReciever.context = "dialog-loading";
this.text = text;
}
createElement() {
@@ -287,6 +289,13 @@ export class DialogLoading extends Dialog {
elem.classList.add("loadingDialog");
this.element = elem;
if (this.text) {
const text = document.createElement("div");
text.classList.add("text");
text.innerText = this.text;
elem.appendChild(text);
}
const loader = document.createElement("div");
loader.classList.add("prefab_LoadingTextWithAnim");
loader.classList.add("loadingIndicator");
@@ -309,7 +318,7 @@ export class DialogOptionChooser extends Dialog {
<div class='option ${value === options.active ? "active" : ""} ${
iconPrefix ? "hasIcon" : ""
}' data-optionvalue='${value}'>
${iconHtml}
${iconHtml}
<span class='title'>${text}</span>
${descHtml}
</div>
@@ -444,7 +453,7 @@ export class DialogWithForm extends Dialog {
for (let i = 0; i < this.formElements.length; ++i) {
const elem = this.formElements[i];
elem.bindEvents(div, this.clickDetectors);
elem.valueChosen.add(this.closeRequested.dispatch, this.closeRequested);
// elem.valueChosen.add(this.closeRequested.dispatch, this.closeRequested);
elem.valueChosen.add(this.valueChosen.dispatch, this.valueChosen);
}

View File

@@ -117,6 +117,11 @@ export class FormElementInput extends FormElement {
return this.element.value;
}
setValue(value) {
this.element.value = value;
this.updateErrorState();
}
focus() {
this.element.focus();
}

View File

@@ -44,6 +44,15 @@ export class Rectangle {
return new Rectangle(left, top, right - left, bottom - top);
}
/**
*
* @param {number} width
* @param {number} height
*/
static centered(width, height) {
return new Rectangle(-Math.ceil(width / 2), -Math.ceil(height / 2), width, height);
}
/**
* Returns if a intersects b
* @param {Rectangle} a
@@ -72,7 +81,7 @@ export class Rectangle {
/**
* Returns if this rectangle is equal to the other while taking an epsilon into account
* @param {Rectangle} other
* @param {number} epsilon
* @param {number} [epsilon]
*/
equalsEpsilon(other, epsilon) {
return (
@@ -287,6 +296,15 @@ export class Rectangle {
return Rectangle.fromTRBL(top, right, bottom, left);
}
/**
* Returns whether the rectangle fully intersects the given rectangle
* @param {Rectangle} rect
*/
intersectsFully(rect) {
const intersection = this.getIntersection(rect);
return intersection && Math.abs(intersection.w * intersection.h - rect.w * rect.h) < 0.001;
}
/**
* Returns the union of this rectangle with another
* @param {Rectangle} rect

View File

@@ -17,6 +17,17 @@ export class Signal {
++this.modifyCount;
}
/**
* Adds a new signal listener
* @param {function} receiver
* @param {object} scope
*/
addToTop(receiver, scope = null) {
assert(receiver, "receiver is null");
this.receivers.unshift({ receiver, scope });
++this.modifyCount;
}
/**
* Dispatches the signal
* @param {...any} payload

View File

@@ -90,9 +90,9 @@ export class StateManager {
dialogParent.classList.add("modalDialogParent");
document.body.appendChild(dialogParent);
this.currentState.internalEnterCallback(payload);
this.app.sound.playThemeMusic(this.currentState.getThemeMusic());
this.currentState.internalEnterCallback(payload);
this.currentState.onResized(this.app.screenWidth, this.app.screenHeight);
this.app.analytics.trackStateEnter(key);