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

Add sandbox building, restructure levels, show pinned shapes in constant signal dialog

This commit is contained in:
tobspr
2020-09-29 10:52:25 +02:00
parent fd3bbcdc20
commit db6db7caca
36 changed files with 499 additions and 312 deletions

View File

@@ -23,7 +23,7 @@ export class MetaFilterBuilding extends MetaBuilding {
* @param {GameRoot} root
*/
getIsUnlocked(root) {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_filters_and_levers);
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_filter);
}
getDimensions() {

View File

@@ -0,0 +1,40 @@
import { enumDirection, Vector } from "../../core/vector";
import { ItemEjectorComponent } from "../components/item_ejector";
import { ItemProducerComponent } from "../components/item_producer";
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
export class MetaItemProducerBuilding extends MetaBuilding {
constructor() {
super("item_producer");
}
getSilhouetteColor() {
return "#b37dcd";
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
entity.addComponent(
new ItemEjectorComponent({
slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }],
})
);
entity.addComponent(
new WiredPinsComponent({
slots: [
{
pos: new Vector(0, 0),
type: enumPinSlotType.logicalAcceptor,
direction: enumDirection.bottom,
},
],
})
);
entity.addComponent(new ItemProducerComponent());
}
}

View File

@@ -20,7 +20,7 @@ export class MetaLeverBuilding extends MetaBuilding {
* @param {GameRoot} root
*/
getIsUnlocked(root) {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_filters_and_levers);
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_painter_and_levers);
}
getDimensions() {

View File

@@ -71,7 +71,7 @@ export class MetaPainterBuilding extends MetaBuilding {
if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_painter_double)) {
variants.push(enumPainterVariants.double);
}
if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_painter_quad)) {
if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_painter_and_levers)) {
variants.push(enumPainterVariants.quad);
}
return variants;

View File

@@ -4,6 +4,7 @@ import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins";
import { Entity } from "../entity";
import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
import { GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals";
import { MetaCutterBuilding } from "./cutter";
import { MetaPainterBuilding } from "./painter";
import { MetaRotaterBuilding } from "./rotater";
@@ -47,8 +48,7 @@ export class MetaVirtualProcessorBuilding extends MetaBuilding {
* @param {GameRoot} root
*/
getIsUnlocked(root) {
// @todo
return true;
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_virtual_processing);
}
/** @returns {"wires"} **/

View File

@@ -82,7 +82,7 @@ export class MetaWireBuilding extends MetaBuilding {
* @param {GameRoot} root
*/
getIsUnlocked(root) {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_filters_and_levers);
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_painter_and_levers);
}
/**

View File

@@ -21,7 +21,7 @@ export class MetaWireTunnelBuilding extends MetaBuilding {
* @param {GameRoot} root
*/
getIsUnlocked(root) {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_filters_and_levers);
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_painter_and_levers);
}
/**

View File

@@ -18,6 +18,7 @@ import { WireTunnelComponent } from "./components/wire_tunnel";
import { DisplayComponent } from "./components/display";
import { BeltReaderComponent } from "./components/belt_reader";
import { FilterComponent } from "./components/filter";
import { ItemProducerComponent } from "./components/item_producer";
export function initComponentRegistry() {
gComponentRegistry.register(StaticMapEntityComponent);
@@ -39,6 +40,7 @@ export function initComponentRegistry() {
gComponentRegistry.register(DisplayComponent);
gComponentRegistry.register(BeltReaderComponent);
gComponentRegistry.register(FilterComponent);
gComponentRegistry.register(ItemProducerComponent);
// IMPORTANT ^^^^^ UPDATE ENTITY COMPONENT STORAGE AFTERWARDS

View File

@@ -0,0 +1,7 @@
import { Component } from "../component";
export class ItemProducerComponent extends Component {
static getId() {
return "ItemProducer";
}
}

View File

@@ -18,6 +18,7 @@ import { WireTunnelComponent } from "./components/wire_tunnel";
import { DisplayComponent } from "./components/display";
import { BeltReaderComponent } from "./components/belt_reader";
import { FilterComponent } from "./components/filter";
import { ItemProducerComponent } from "./components/item_producer";
/* typehints:end */
/**
@@ -85,6 +86,9 @@ export class EntityComponentStorage {
/** @type {FilterComponent} */
this.Filter;
/** @type {ItemProducerComponent} */
this.ItemProducer;
/* typehints:end */
}
}

View File

@@ -23,6 +23,7 @@ import { DisplaySystem } from "./systems/display";
import { ItemProcessorOverlaysSystem } from "./systems/item_processor_overlays";
import { BeltReaderSystem } from "./systems/belt_reader";
import { FilterSystem } from "./systems/filter";
import { ItemProducerSystem } from "./systems/item_producer";
const logger = createLogger("game_system_manager");
@@ -96,6 +97,9 @@ export class GameSystemManager {
/** @type {FilterSystem} */
filter: null,
/** @type {ItemProducerSystem} */
itemProducer: null,
/* typehints:end */
};
this.systemUpdateOrder = [];
@@ -130,6 +134,8 @@ export class GameSystemManager {
add("filter", FilterSystem);
add("itemProducer", ItemProducerSystem);
add("itemEjector", ItemEjectorSystem);
add("mapResources", MapResourcesSystem);

View File

@@ -210,9 +210,7 @@ export class HubGoals extends BasicSerializableObject {
}
const required = 4 + (this.level - 27) * 0.25;
this.currentGoal = {
/** @type {ShapeDefinition} */
definition: this.computeFreeplayShape(this.level),
required,
reward: enumHubGoalRewards.no_reward_freeplay,

View File

@@ -14,6 +14,8 @@ import { MetaTrashBuilding } from "../../buildings/trash";
import { MetaUndergroundBeltBuilding } from "../../buildings/underground_belt";
import { HUDBaseToolbar } from "./base_toolbar";
import { MetaStorageBuilding } from "../../buildings/storage";
import { MetaItemProducerBuilding } from "../../buildings/item_producer";
import { queryParamOptions } from "../../../core/query_parameters";
export class HUDBuildingsToolbar extends HUDBaseToolbar {
constructor(root) {
@@ -29,6 +31,7 @@ export class HUDBuildingsToolbar extends HUDBaseToolbar {
MetaMixerBuilding,
MetaPainterBuilding,
MetaTrashBuilding,
...(queryParamOptions.sandboxMode || G_IS_DEV ? [MetaItemProducerBuilding] : []),
],
secondaryBuildings: [
MetaStorageBuilding,

View File

@@ -259,7 +259,7 @@ export class HUDKeybindingOverlay extends BaseHUDPart {
label: T.ingame.keybindingsOverlay.switchLayers,
keys: [k.ingame.switchLayers],
condition: () =>
this.root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_filters_and_levers),
this.root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_painter_and_levers),
},
];

View File

@@ -51,6 +51,8 @@ export class HUDUnlockNotification extends BaseHUDPart {
* @param {enumHubGoalRewards} reward
*/
showForLevel(level, reward) {
this.root.soundProxy.playUi(SOUNDS.levelComplete);
if (level > tutorialGoals.length) {
this.root.hud.signals.notification.dispatch(
T.ingame.notifications.freeplayLevelComplete.replace("<level>", String(level)),
@@ -92,7 +94,6 @@ export class HUDUnlockNotification extends BaseHUDPart {
this.elemContents.innerHTML = html;
this.visible = true;
this.root.soundProxy.playUi(SOUNDS.levelComplete);
if (this.buttonShowTimeout) {
clearTimeout(this.buttonShowTimeout);

View File

@@ -29,7 +29,7 @@ export class HUDWiresOverlay extends BaseHUDPart {
*/
switchLayers() {
if (this.root.currentLayer === "regular") {
if (this.root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_filters_and_levers)) {
if (this.root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_painter_and_levers)) {
this.root.currentLayer = "wires";
}
} else {

View File

@@ -56,6 +56,9 @@ export const KEYMAPPINGS = {
painter: { keyCode: key("9") },
trash: { keyCode: key("0") },
// Sandbox
item_producer: { keyCode: key("L") },
// Secondary toolbar
storage: { keyCode: key("Y") },
reader: { keyCode: key("U") },

View File

@@ -10,6 +10,7 @@ import { enumCutterVariants, MetaCutterBuilding } from "./buildings/cutter";
import { MetaDisplayBuilding } from "./buildings/display";
import { MetaFilterBuilding } from "./buildings/filter";
import { MetaHubBuilding } from "./buildings/hub";
import { MetaItemProducerBuilding } from "./buildings/item_producer";
import { MetaLeverBuilding } from "./buildings/lever";
import { enumLogicGateVariants, MetaLogicGateBuilding } from "./buildings/logic_gate";
import { enumMinerVariants, MetaMinerBuilding } from "./buildings/miner";
@@ -19,7 +20,7 @@ import { MetaReaderBuilding } from "./buildings/reader";
import { enumRotaterVariants, MetaRotaterBuilding } from "./buildings/rotater";
import { MetaStackerBuilding } from "./buildings/stacker";
import { MetaStorageBuilding } from "./buildings/storage";
import { MetaTransistorBuilding, enumTransistorVariants } from "./buildings/transistor";
import { enumTransistorVariants, MetaTransistorBuilding } from "./buildings/transistor";
import { MetaTrashBuilding } from "./buildings/trash";
import { enumUndergroundBeltVariants, MetaUndergroundBeltBuilding } from "./buildings/underground_belt";
import { enumVirtualProcessorVariants, MetaVirtualProcessorBuilding } from "./buildings/virtual_processor";
@@ -57,6 +58,7 @@ export function initMetaBuildingRegistry() {
gMetaBuildingRegistry.register(MetaTransistorBuilding);
gMetaBuildingRegistry.register(MetaAnalyzerBuilding);
gMetaBuildingRegistry.register(MetaComparatorBuilding);
gMetaBuildingRegistry.register(MetaItemProducerBuilding);
// Belt
registerBuildingVariant(1, MetaBeltBuilding, defaultBuildingVariant, 0);
@@ -160,6 +162,9 @@ export function initMetaBuildingRegistry() {
// Reader
registerBuildingVariant(49, MetaReaderBuilding);
// Item producer
registerBuildingVariant(61, MetaItemProducerBuilding);
// Propagate instances
for (const key in gBuildingVariants) {
gBuildingVariants[key].metaInstance = gMetaBuildingRegistry.findByClass(

View File

@@ -58,7 +58,13 @@ export class ConstantSignalSystem extends GameSystemWithFilter {
BOOL_FALSE_SINGLETON,
BOOL_TRUE_SINGLETON,
...Object.values(COLOR_ITEM_SINGLETONS),
this.root.shapeDefinitionMgr.getShapeItemFromDefinition(
this.root.hubGoals.currentGoal.definition
),
this.root.shapeDefinitionMgr.getShapeItemFromShortKey(blueprintShape),
...this.root.hud.parts.pinnedShapes.pinnedShapes.map(key =>
this.root.shapeDefinitionMgr.getShapeItemFromShortKey(key)
),
],
});

View File

@@ -0,0 +1,24 @@
import { ItemProducerComponent } from "../components/item_producer";
import { GameSystemWithFilter } from "../game_system_with_filter";
export class ItemProducerSystem extends GameSystemWithFilter {
constructor(root) {
super(root, [ItemProducerComponent]);
}
update() {
for (let i = 0; i < this.allEntities.length; ++i) {
const entity = this.allEntities[i];
const pinsComp = entity.components.WiredPins;
const pin = pinsComp.slots[0];
const network = pin.linkedNetwork;
if (!network || !network.hasValue()) {
continue;
}
const ejectorComp = entity.components.ItemEjector;
ejectorComp.tryEject(0, network.currentValue);
}
}
}

View File

@@ -22,14 +22,14 @@ export const enumHubGoalRewards = {
reward_splitter: "reward_splitter",
reward_cutter_quad: "reward_cutter_quad",
reward_painter_double: "reward_painter_double",
reward_painter_quad: "reward_painter_quad",
reward_storage: "reward_storage",
reward_merger: "reward_merger",
reward_wires_filters_and_levers: "reward_wires_filters_and_levers",
reward_wires_painter_and_levers: "reward_wires_painter_and_levers",
reward_display: "reward_display",
reward_constant_signal: "reward_constant_signal",
reward_logic_gates: "reward_logic_gates",
reward_virtual_processing: "reward_virtual_processing",
reward_filter: "reward_filter",
reward_blueprints: "reward_blueprints",
reward_freeplay: "reward_freeplay",
@@ -194,15 +194,15 @@ export const tutorialGoals = [
{
shape: finalGameShape,
required: 25000,
reward: enumHubGoalRewards.reward_wires_filters_and_levers,
reward: enumHubGoalRewards.reward_wires_painter_and_levers,
},
// 21
// Display
// Filter
{
shape: "CrCrCrCr:CwCwCwCw:CrCrCrCr:CwCwCwCw",
shape: "CrCwCrCw:CwCrCwCr:CrCwCrCw:CwCrCwCr",
required: 25000,
reward: enumHubGoalRewards.reward_display,
reward: enumHubGoalRewards.reward_filter,
},
// 22
@@ -214,11 +214,11 @@ export const tutorialGoals = [
},
// 23
// Quad Painter
// Display
{
shape: "CcSyCcSy:SyCcSyCc:CcSyCcSy",
required: 5000,
reward: enumHubGoalRewards.reward_painter_quad,
reward: enumHubGoalRewards.reward_display,
},
// 24 Logic gates
@@ -238,7 +238,7 @@ export const tutorialGoals = [
// 26 Freeplay
{
shape: "CbCuCbCu:Sr------:--CrSrCr:CwCwCwCw",
required: 10000,
required: 50000,
reward: enumHubGoalRewards.reward_freeplay,
},
];

View File

@@ -3,7 +3,7 @@ import { enumBalancerVariants, MetaBalancerBuilding } from "./buildings/balancer
import { MetaConstantSignalBuilding } from "./buildings/constant_signal";
import { enumCutterVariants, MetaCutterBuilding } from "./buildings/cutter";
import { MetaDisplayBuilding } from "./buildings/display";
import { MetaLeverBuilding } from "./buildings/lever";
import { MetaFilterBuilding } from "./buildings/filter";
import { MetaLogicGateBuilding } from "./buildings/logic_gate";
import { enumMinerVariants, MetaMinerBuilding } from "./buildings/miner";
import { MetaMixerBuilding } from "./buildings/mixer";
@@ -46,7 +46,6 @@ export const enumHubGoalRewardsToContentUnlocked = {
[enumHubGoalRewards.reward_merger]: typed([[MetaBalancerBuilding, enumBalancerVariants.merger]]),
[enumHubGoalRewards.reward_cutter_quad]: typed([[MetaCutterBuilding, enumCutterVariants.quad]]),
[enumHubGoalRewards.reward_painter_double]: typed([[MetaPainterBuilding, enumPainterVariants.double]]),
[enumHubGoalRewards.reward_painter_quad]: typed([[MetaPainterBuilding, enumPainterVariants.quad]]),
[enumHubGoalRewards.reward_storage]: typed([[MetaStorageBuilding, defaultBuildingVariant]]),
[enumHubGoalRewards.reward_belt_reader]: typed([[MetaReaderBuilding, defaultBuildingVariant]]),
@@ -55,10 +54,11 @@ export const enumHubGoalRewardsToContentUnlocked = {
[MetaConstantSignalBuilding, defaultBuildingVariant],
]),
[enumHubGoalRewards.reward_logic_gates]: typed([[MetaLogicGateBuilding, defaultBuildingVariant]]),
[enumHubGoalRewards.reward_filter]: typed([[MetaFilterBuilding, defaultBuildingVariant]]),
[enumHubGoalRewards.reward_virtual_processing]: null, // @TODO!
[enumHubGoalRewards.reward_wires_filters_and_levers]: typed([
[MetaLeverBuilding, defaultBuildingVariant],
[enumHubGoalRewards.reward_wires_painter_and_levers]: typed([
[MetaPainterBuilding, enumPainterVariants.quad],
]),
[enumHubGoalRewards.reward_freeplay]: null,
[enumHubGoalRewards.reward_blueprints]: null,

View File

@@ -1,18 +1,19 @@
import { findNiceIntegerValue } from "../core/utils";
import { ShapeDefinition } from "./shape_definition";
export const preparementShape = "CpRpCp--:SwSwSwSw";
export const finalGameShape = "RuCw--Cw:----Ru--";
export const rocketShape = "CbCuCbCu:Sr------:--CrSrCr:CwCwCwCw";
export const blueprintShape = "CbCbCbRb:CwCwCwCw";
const fixedImprovements = [0.5, 0.5, 1, 1, 2, 2];
const fixedImprovements = [0.5, 0.5, 1, 1, 2, 1, 1];
const numEndgameUpgrades = G_IS_DEV || G_IS_STANDALONE ? 20 - fixedImprovements.length - 1 : 0;
function generateEndgameUpgrades() {
return new Array(numEndgameUpgrades).fill(null).map((_, i) => ({
required: [
{ shape: blueprintShape, amount: 30000 + i * 10000 },
{ shape: preparementShape, amount: 30000 + i * 10000 },
{ shape: finalGameShape, amount: 20000 + i * 5000 },
{ shape: rocketShape, amount: 20000 + i * 5000 },
],
@@ -56,7 +57,14 @@ export const UPGRADES = {
required: [{ shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", amount: 25000 }],
},
{
required: [{ shape: finalGameShape, amount: 50000 }],
required: [{ shape: preparementShape, amount: 25000 }],
excludePrevious: true,
},
{
required: [
{ shape: preparementShape, amount: 25000 },
{ shape: finalGameShape, amount: 50000 },
],
excludePrevious: true,
},
...generateEndgameUpgrades(),
@@ -79,7 +87,14 @@ export const UPGRADES = {
required: [{ shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", amount: 50000 }],
},
{
required: [{ shape: finalGameShape, amount: 50000 }],
required: [{ shape: preparementShape, amount: 25000 }],
excludePrevious: true,
},
{
required: [
{ shape: preparementShape, amount: 25000 },
{ shape: finalGameShape, amount: 50000 },
],
excludePrevious: true,
},
...generateEndgameUpgrades(),
@@ -102,7 +117,14 @@ export const UPGRADES = {
required: [{ shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", amount: 50000 }],
},
{
required: [{ shape: finalGameShape, amount: 50000 }],
required: [{ shape: preparementShape, amount: 25000 }],
excludePrevious: true,
},
{
required: [
{ shape: preparementShape, amount: 25000 },
{ shape: finalGameShape, amount: 50000 },
],
excludePrevious: true,
},
...generateEndgameUpgrades(),
@@ -125,7 +147,14 @@ export const UPGRADES = {
required: [{ shape: "WpWpWpWp:CwCwCwCw:WpWpWpWp:CwCwCwCw", amount: 50000 }],
},
{
required: [{ shape: finalGameShape, amount: 50000 }],
required: [{ shape: preparementShape, amount: 25000 }],
excludePrevious: true,
},
{
required: [
{ shape: preparementShape, amount: 25000 },
{ shape: finalGameShape, amount: 50000 },
],
excludePrevious: true,
},
...generateEndgameUpgrades(),