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

Merge branch 'master' of https://github.com/tobspr/shapez.io into modloader

This commit is contained in:
DJ1TJOO 2021-03-11 17:43:14 +01:00
commit 42ba0d1340
8 changed files with 89 additions and 38 deletions

View File

@ -42,6 +42,7 @@ jobs:
run: | run: |
cd gulp cd gulp
yarn gulp translations.fullBuild yarn gulp translations.fullBuild
yarn gulp localConfig.findOrCreate
cd .. cd ..
yarn tslint yarn tslint

View File

@ -46,7 +46,7 @@ export class AchievementProxy {
} }
initialize() { initialize() {
this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.darkMode); this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.darkMode, null);
if (this.has(ACHIEVEMENTS.mam)) { if (this.has(ACHIEVEMENTS.mam)) {
this.root.signals.entityAdded.add(this.onMamFailure, this); this.root.signals.entityAdded.add(this.onMamFailure, this);
@ -136,7 +136,7 @@ export class AchievementProxy {
this.root.signals.entityDestroyed.add(this.onMamFailure, this); this.root.signals.entityDestroyed.add(this.onMamFailure, this);
} }
this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.mam); this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.mam, null);
// reset on every level // reset on every level
this.root.savegame.currentData.stats.failedMam = false; this.root.savegame.currentData.stats.failedMam = false;

View File

@ -110,6 +110,12 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
// KEYBINDINGS // KEYBINDINGS
const keyActionMapper = this.root.keyMapper; const keyActionMapper = this.root.keyMapper;
keyActionMapper.getBinding(KEYMAPPINGS.placement.rotateWhilePlacing).add(this.tryRotate, this); keyActionMapper.getBinding(KEYMAPPINGS.placement.rotateWhilePlacing).add(this.tryRotate, this);
keyActionMapper.getBinding(KEYMAPPINGS.placement.rotateToUp).add(this.trySetRotate, this);
keyActionMapper.getBinding(KEYMAPPINGS.placement.rotateToDown).add(this.trySetRotate, this);
keyActionMapper.getBinding(KEYMAPPINGS.placement.rotateToRight).add(this.trySetRotate, this);
keyActionMapper.getBinding(KEYMAPPINGS.placement.rotateToLeft).add(this.trySetRotate, this);
keyActionMapper.getBinding(KEYMAPPINGS.placement.cycleBuildingVariants).add(this.cycleVariants, this); keyActionMapper.getBinding(KEYMAPPINGS.placement.cycleBuildingVariants).add(this.cycleVariants, this);
keyActionMapper keyActionMapper
.getBinding(KEYMAPPINGS.placement.switchDirectionLockSide) .getBinding(KEYMAPPINGS.placement.switchDirectionLockSide)
@ -290,6 +296,28 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
staticComp.rotation = this.currentBaseRotation; staticComp.rotation = this.currentBaseRotation;
} }
} }
/**
* Rotates the current building to the specified direction.
*/
trySetRotate() {
const selectedBuilding = this.currentMetaBuilding.get();
if (selectedBuilding) {
if (this.root.keyMapper.getBinding(KEYMAPPINGS.placement.rotateToUp).pressed) {
this.currentBaseRotation = 0;
} else if (this.root.keyMapper.getBinding(KEYMAPPINGS.placement.rotateToDown).pressed) {
this.currentBaseRotation = 180;
} else if (this.root.keyMapper.getBinding(KEYMAPPINGS.placement.rotateToRight).pressed) {
this.currentBaseRotation = 90;
} else if (this.root.keyMapper.getBinding(KEYMAPPINGS.placement.rotateToLeft).pressed) {
this.currentBaseRotation = 270;
}
const staticComp = this.fakeEntity.components.StaticMapEntity;
staticComp.rotation = this.currentBaseRotation;
}
}
/** /**
* Tries to delete the building under the mouse * Tries to delete the building under the mouse
*/ */

View File

@ -12,6 +12,11 @@ function key(str) {
return str.toUpperCase().charCodeAt(0); return str.toUpperCase().charCodeAt(0);
} }
const KEYCODE_UP_ARROW = 38;
const KEYCODE_DOWN_ARROW = 40;
const KEYCODE_LEFT_ARROW = 37;
const KEYCODE_RIGHT_ARROW = 39;
export const KEYMAPPINGS = { export const KEYMAPPINGS = {
general: { general: {
confirm: { keyCode: 13 }, // enter confirm: { keyCode: 13 }, // enter
@ -82,6 +87,10 @@ export const KEYMAPPINGS = {
pipette: { keyCode: key("Q") }, pipette: { keyCode: key("Q") },
rotateWhilePlacing: { keyCode: key("R") }, rotateWhilePlacing: { keyCode: key("R") },
rotateInverseModifier: { keyCode: 16 }, // SHIFT rotateInverseModifier: { keyCode: 16 }, // SHIFT
rotateToUp: { keyCode: KEYCODE_UP_ARROW },
rotateToDown: { keyCode: KEYCODE_DOWN_ARROW },
rotateToRight: { keyCode: KEYCODE_RIGHT_ARROW },
rotateToLeft: { keyCode: KEYCODE_LEFT_ARROW },
cycleBuildingVariants: { keyCode: key("T") }, cycleBuildingVariants: { keyCode: key("T") },
cycleBuildings: { keyCode: 9 }, // TAB cycleBuildings: { keyCode: 9 }, // TAB
switchDirectionLockSide: { keyCode: key("R") }, switchDirectionLockSide: { keyCode: key("R") },
@ -163,13 +172,13 @@ export function getStringForKeyCode(code) {
return "END"; return "END";
case 36: case 36:
return "HOME"; return "HOME";
case 37: case KEYCODE_LEFT_ARROW:
return "⬅"; return "⬅";
case 38: case KEYCODE_UP_ARROW:
return "⬆"; return "⬆";
case 39: case KEYCODE_RIGHT_ARROW:
return "➡"; return "➡";
case 40: case KEYCODE_DOWN_ARROW:
return "⬇"; return "⬇";
case 44: case 44:
return "PRNT"; return "PRNT";

View File

@ -181,7 +181,7 @@ export class GameRoot {
freeEntityAreaBeforeBuild: /** @type {TypedSignal<[Entity]>} */ (new Signal()), freeEntityAreaBeforeBuild: /** @type {TypedSignal<[Entity]>} */ (new Signal()),
// Called with an achievement key and necessary args to validate it can be unlocked. // Called with an achievement key and necessary args to validate it can be unlocked.
achievementCheck: /** @type {TypedSignal<(string|any)[]>} */ (new Signal()), achievementCheck: /** @type {TypedSignal<[string, any]>} */ (new Signal()),
bulkAchievementCheck: /** @type {TypedSignal<(string|any)[]>} */ (new Signal()), bulkAchievementCheck: /** @type {TypedSignal<(string|any)[]>} */ (new Signal()),
}; };

View File

@ -97,7 +97,7 @@ export class ShapeDefinitionManager extends BasicSerializableObject {
const rightSide = definition.cloneFilteredByQuadrants([2, 3]); const rightSide = definition.cloneFilteredByQuadrants([2, 3]);
const leftSide = definition.cloneFilteredByQuadrants([0, 1]); const leftSide = definition.cloneFilteredByQuadrants([0, 1]);
this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.cutShape); this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.cutShape, null);
return /** @type {[ShapeDefinition, ShapeDefinition]} */ (this.operationCache[key] = [ return /** @type {[ShapeDefinition, ShapeDefinition]} */ (this.operationCache[key] = [
this.registerOrReturnHandle(rightSide), this.registerOrReturnHandle(rightSide),
@ -140,7 +140,7 @@ export class ShapeDefinitionManager extends BasicSerializableObject {
const rotated = definition.cloneRotateCW(); const rotated = definition.cloneRotateCW();
this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.rotateShape); this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.rotateShape, null);
return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle( return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle(
rotated rotated
@ -195,7 +195,7 @@ export class ShapeDefinitionManager extends BasicSerializableObject {
return /** @type {ShapeDefinition} */ (this.operationCache[key]); return /** @type {ShapeDefinition} */ (this.operationCache[key]);
} }
this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.stackShape); this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.stackShape, null);
const stacked = lowerDefinition.cloneAndStackWith(upperDefinition); const stacked = lowerDefinition.cloneAndStackWith(upperDefinition);
return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle( return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle(
@ -215,7 +215,7 @@ export class ShapeDefinitionManager extends BasicSerializableObject {
return /** @type {ShapeDefinition} */ (this.operationCache[key]); return /** @type {ShapeDefinition} */ (this.operationCache[key]);
} }
this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.paintShape); this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.paintShape, null);
const colorized = definition.cloneAndPaintWith(color); const colorized = definition.cloneAndPaintWith(color);
return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle( return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle(

View File

@ -2,11 +2,11 @@
import { Application } from "../application"; import { Application } from "../application";
import { Entity } from "../game/entity"; import { Entity } from "../game/entity";
import { GameRoot } from "../game/root"; import { GameRoot } from "../game/root";
import { ShapeDefinition } from "../game/shape_definition";
import { VANILLA_THEMES } from "../game/theme"; import { VANILLA_THEMES } from "../game/theme";
/* typehints:end */ /* typehints:end */
import { enumAnalyticsDataSource } from "../game/production_analytics"; import { enumAnalyticsDataSource } from "../game/production_analytics";
import { ShapeDefinition } from "../game/shape_definition";
import { ShapeItem } from "../game/items/shape_item"; import { ShapeItem } from "../game/items/shape_item";
import { globalConfig } from "../core/config"; import { globalConfig } from "../core/config";
import { codes } from "../modloader/old_buildings_codes"; import { codes } from "../modloader/old_buildings_codes";
@ -172,14 +172,8 @@ export class AchievementCollection {
isValid: this.isBelt500TilesValid, isValid: this.isBelt500TilesValid,
signal: "entityAdded", signal: "entityAdded",
}); });
this.add(ACHIEVEMENTS.blueprint100k, { this.add(ACHIEVEMENTS.blueprint100k, this.createBlueprintOptions(100000));
isValid: this.isBlueprint100kValid, this.add(ACHIEVEMENTS.blueprint1m, this.createBlueprintOptions(1000000));
signal: "shapeDelivered",
});
this.add(ACHIEVEMENTS.blueprint1m, {
isValid: this.isBlueprint1mValid,
signal: "shapeDelivered",
});
this.add(ACHIEVEMENTS.completeLvl26, this.createLevelOptions(26)); this.add(ACHIEVEMENTS.completeLvl26, this.createLevelOptions(26));
this.add(ACHIEVEMENTS.cutShape); this.add(ACHIEVEMENTS.cutShape);
this.add(ACHIEVEMENTS.darkMode, { this.add(ACHIEVEMENTS.darkMode, {
@ -244,10 +238,12 @@ export class AchievementCollection {
}); });
this.add(ACHIEVEMENTS.stackShape); this.add(ACHIEVEMENTS.stackShape);
this.add(ACHIEVEMENTS.store100Unique, { this.add(ACHIEVEMENTS.store100Unique, {
init: this.initStore100Unique,
isValid: this.isStore100UniqueValid, isValid: this.isStore100UniqueValid,
signal: "shapeDelivered", signal: "shapeDelivered",
}); });
this.add(ACHIEVEMENTS.storeShape, { this.add(ACHIEVEMENTS.storeShape, {
init: this.initStoreShape,
isValid: this.isStoreShapeValid, isValid: this.isStoreShapeValid,
}); });
this.add(ACHIEVEMENTS.throughputBp25, this.createRateOptions(SHAPE_BP, 25)); this.add(ACHIEVEMENTS.throughputBp25, this.createRateOptions(SHAPE_BP, 25));
@ -272,14 +268,14 @@ export class AchievementCollection {
this.root.signals.bulkAchievementCheck.add(this.bulkUnlock, this); this.root.signals.bulkAchievementCheck.add(this.bulkUnlock, this);
for (let [key, achievement] of this.map.entries()) { for (let [key, achievement] of this.map.entries()) {
if (achievement.init) {
achievement.init();
}
if (achievement.signal) { if (achievement.signal) {
achievement.receiver = this.unlock.bind(this, key); achievement.receiver = this.unlock.bind(this, key);
this.root.signals[achievement.signal].add(achievement.receiver); this.root.signals[achievement.signal].add(achievement.receiver);
} }
if (achievement.init) {
achievement.init();
}
} }
if (!this.hasDefaultReceivers()) { if (!this.hasDefaultReceivers()) {
@ -327,7 +323,7 @@ export class AchievementCollection {
/** /**
* @param {string} key - Maps to an Achievement * @param {string} key - Maps to an Achievement
* @param {?*} data - Data received from signal dispatches for validation * @param {any} data - Data received from signal dispatches for validation
*/ */
unlock(key, data) { unlock(key, data) {
if (!this.map.has(key)) { if (!this.map.has(key)) {
@ -420,8 +416,18 @@ export class AchievementCollection {
return item.getItemType() === ITEM_SHAPE && item.definition.getHash() === shape; return item.getItemType() === ITEM_SHAPE && item.definition.getHash() === shape;
} }
createBlueprintOptions(count) {
return {
init: ({ key }) => this.unlock(key, ShapeDefinition.fromShortKey(SHAPE_BP)),
isValid: definition =>
definition.cachedHash === SHAPE_BP && this.root.hubGoals.storedShapes[SHAPE_BP] >= count,
signal: "shapeDelivered",
};
}
createLevelOptions(level) { createLevelOptions(level) {
return { return {
init: ({ key }) => this.unlock(key, this.root.hubGoals.level),
isValid: currentLevel => currentLevel >= level, isValid: currentLevel => currentLevel >= level,
signal: "storyGoalCompleted", signal: "storyGoalCompleted",
}; };
@ -464,6 +470,7 @@ export class AchievementCollection {
createUpgradeOptions(tier) { createUpgradeOptions(tier) {
return { return {
init: ({ key }) => this.unlock(key, null),
isValid: () => this.hasAllUpgradesAtLeastAtTier(tier), isValid: () => this.hasAllUpgradesAtLeastAtTier(tier),
signal: "upgradePurchased", signal: "upgradePurchased",
}; };
@ -474,16 +481,6 @@ export class AchievementCollection {
return entity.components.Belt && entity.components.Belt.assignedPath.totalLength >= 500; return entity.components.Belt && entity.components.Belt.assignedPath.totalLength >= 500;
} }
/** @param {ShapeDefinition} definition @returns {boolean} */
isBlueprint100kValid(definition) {
return definition.cachedHash === SHAPE_BP && this.root.hubGoals.storedShapes[SHAPE_BP] >= 100000;
}
/** @param {ShapeDefinition} definition @returns {boolean} */
isBlueprint1mValid(definition) {
return definition.cachedHash === SHAPE_BP && this.root.hubGoals.storedShapes[SHAPE_BP] >= 1000000;
}
/** @returns {boolean} */ /** @returns {boolean} */
isDarkModeValid() { isDarkModeValid() {
return this.root.app.settings.currentData.settings.theme === DARK_MODE; return this.root.app.settings.currentData.settings.theme === DARK_MODE;
@ -524,7 +521,7 @@ export class AchievementCollection {
return this.root.hubGoals.level < 18 && this.isShape(item, SHAPE_LOGO); return this.root.hubGoals.level < 18 && this.isShape(item, SHAPE_LOGO);
} }
/** @params {number} level @returns {boolean} */ /** @returns {boolean} */
isMamValid() { isMamValid() {
return this.root.hubGoals.level > 27 && !this.root.savegame.currentData.stats.failedMam; return this.root.hubGoals.level > 27 && !this.root.savegame.currentData.stats.failedMam;
} }
@ -596,11 +593,21 @@ export class AchievementCollection {
return item.getItemType() === ITEM_SHAPE && item.definition.layers.length === 4; return item.getItemType() === ITEM_SHAPE && item.definition.layers.length === 4;
} }
/** @param {Achievement} achievement */
initStore100Unique({ key }) {
this.unlock(key, null);
}
/** @returns {boolean} */ /** @returns {boolean} */
isStore100UniqueValid() { isStore100UniqueValid() {
return Object.keys(this.root.hubGoals.storedShapes).length >= 100; return Object.keys(this.root.hubGoals.storedShapes).length >= 100;
} }
/** @param {Achievement} achievement */
initStoreShape({ key }) {
this.unlock(key, null);
}
/** @returns {boolean} */ /** @returns {boolean} */
isStoreShapeValid() { isStoreShapeValid() {
const entities = this.root.systemMgr.systems.storage.allEntities; const entities = this.root.systemMgr.systems.storage.allEntities;
@ -618,15 +625,17 @@ export class AchievementCollection {
return false; return false;
} }
initTrash1000() { /** @param {Achievement} achievement */
initTrash1000({ key }) {
if (Number(this.root.savegame.currentData.stats.trashedCount)) { if (Number(this.root.savegame.currentData.stats.trashedCount)) {
this.unlock(key, 0);
return; return;
} }
this.root.savegame.currentData.stats.trashedCount = 0; this.root.savegame.currentData.stats.trashedCount = 0;
} }
/** @params {number} count @returns {boolean} */ /** @param {number} count @returns {boolean} */
isTrash1000Valid(count) { isTrash1000Valid(count) {
this.root.savegame.currentData.stats.trashedCount += count; this.root.savegame.currentData.stats.trashedCount += count;

View File

@ -1138,6 +1138,10 @@ keybindings:
rotateWhilePlacing: Rotate rotateWhilePlacing: Rotate
rotateInverseModifier: >- rotateInverseModifier: >-
Modifier: Rotate CCW instead Modifier: Rotate CCW instead
rotateToUp: "Rotate: Point Up"
rotateToDown: "Rotate: Point Down"
rotateToRight: "Rotate: Point Right"
rotateToLeft: "Rotate: Point Left"
cycleBuildingVariants: Cycle Variants cycleBuildingVariants: Cycle Variants
confirmMassDelete: Delete area confirmMassDelete: Delete area
pasteLastBlueprint: Paste last blueprint pasteLastBlueprint: Paste last blueprint