diff --git a/artwork/buildings/furnace.svg b/artwork/buildings/furnace.svg
index f7dc3f34..d3ec89aa 100644
--- a/artwork/buildings/furnace.svg
+++ b/artwork/buildings/furnace.svg
@@ -9,9 +9,9 @@
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
- inkscape:export-filename="C:\Users\Jasper\WebstormProjects\shapez.io\res_raw\sprites\buildings\furnace.png"
+ inkscape:export-filename="/home/dualhexagon/Desktop/shapezio/shapez.io/res_raw/sprites/buildings/mixer-incinerator.png"
sodipodi:docname="furnace.svg"
- inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
id="svg8"
version="1.1"
viewBox="0 0 384 192"
@@ -21,10 +21,10 @@
id="defs2" />
+ position="9,183"
+ inkscape:locked="false" />
+ position="9,183"
+ inkscape:locked="false" />
+ position="375,183"
+ inkscape:locked="false" />
+ position="9,9"
+ inkscape:locked="false" />
diff --git a/res/ui/building_tutorials/mixer-incinerator.png b/res/ui/building_tutorials/mixer-incinerator.png
new file mode 100644
index 00000000..ef4eb6a2
Binary files /dev/null and b/res/ui/building_tutorials/mixer-incinerator.png differ
diff --git a/res_raw/sprites/blueprints/mixer-incinerator.png b/res_raw/sprites/blueprints/mixer-incinerator.png
new file mode 100644
index 00000000..3f9af7cd
Binary files /dev/null and b/res_raw/sprites/blueprints/mixer-incinerator.png differ
diff --git a/res_raw/sprites/buildings/mixer-incinerator.png b/res_raw/sprites/buildings/mixer-incinerator.png
new file mode 100644
index 00000000..0d1bdf6c
Binary files /dev/null and b/res_raw/sprites/buildings/mixer-incinerator.png differ
diff --git a/src/css/icons.scss b/src/css/icons.scss
index 2128fde3..5b6c135d 100644
--- a/src/css/icons.scss
+++ b/src/css/icons.scss
@@ -7,7 +7,7 @@ $buildings: belt, cutter, miner, mixer, painter, rotater, splitter, stacker, tra
}
$buildingsAndVariants: belt, splitter, splitter-compact, splitter-compact-inverse, underground_belt,
- underground_belt-tier2, miner, miner-chainable, cutter, cutter-quad, rotater, rotater-ccw, stacker, mixer,
+ underground_belt-tier2, miner, miner-chainable, cutter, cutter-quad, rotater, rotater-ccw, stacker, mixer, mixer-incinerator,
painter, painter-double, painter-quad, trash, trash-storage;
@each $building in $buildingsAndVariants {
[data-icon="building_tutorials/#{$building}.png"] {
diff --git a/src/js/core/config.js b/src/js/core/config.js
index 6825e762..2e0bdfd7 100644
--- a/src/js/core/config.js
+++ b/src/js/core/config.js
@@ -65,6 +65,7 @@ export const globalConfig = {
painterDouble: 1 / 8,
painterQuad: 1 / 8,
mixer: 1 / 5,
+ dyeIncinerator: 1 / 4,
stacker: 1 / 6,
},
diff --git a/src/js/game/buildings/mixer.js b/src/js/game/buildings/mixer.js
index a20bff82..c624e42a 100644
--- a/src/js/game/buildings/mixer.js
+++ b/src/js/game/buildings/mixer.js
@@ -4,19 +4,28 @@ import { ItemAcceptorComponent, enumItemAcceptorItemFilter } from "../components
import { ItemEjectorComponent } from "../components/item_ejector";
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
import { Entity } from "../entity";
-import { MetaBuilding } from "../meta_building";
+import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
import { GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals";
import { T } from "../../translations";
import { formatItemsPerSecond } from "../../core/utils";
+/** @enum {string} */
+export const enumMixerVariants = { incinerator: "incinerator" };
+
export class MetaMixerBuilding extends MetaBuilding {
constructor() {
super("mixer");
}
- getDimensions() {
- return new Vector(2, 1);
+ getDimensions(variant) {
+ switch (variant) {
+ case defaultBuildingVariant:
+ case enumMixerVariants.incinerator:
+ return new Vector(2, 1);
+ default:
+ assertAlways(false, "Unknown mixer variant: " + variant);
+ }
}
getSilhouetteColor() {
@@ -36,8 +45,24 @@ export class MetaMixerBuilding extends MetaBuilding {
* @returns {Array<[string, string]>}
*/
getAdditionalStatistics(root, variant) {
- const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.mixer);
- return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
+ switch (variant) {
+ case defaultBuildingVariant: {
+ const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.mixer);
+ return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
+ }
+ case enumMixerVariants.incinerator: {
+ const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.dyeIncinerator);
+ return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
+ }
+ }
+ }
+
+ getAvailableVariants(root) {
+ let variants = [defaultBuildingVariant];
+ if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_dye_incinerator)) {
+ variants.push(enumMixerVariants.incinerator);
+ }
+ return variants;
}
/**
@@ -51,12 +76,7 @@ export class MetaMixerBuilding extends MetaBuilding {
processorType: enumItemProcessorTypes.mixer,
})
);
-
- entity.addComponent(
- new ItemEjectorComponent({
- slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }],
- })
- );
+ entity.addComponent(new ItemEjectorComponent({}));
entity.addComponent(
new ItemAcceptorComponent({
slots: [
@@ -74,4 +94,39 @@ export class MetaMixerBuilding extends MetaBuilding {
})
);
}
+
+ /**
+ *
+ * @param {Entity} entity
+ * @param {number} rotationVariant
+ * @param {string} variant
+ */
+ updateVariants(entity, rotationVariant, variant) {
+ switch (variant) {
+ case defaultBuildingVariant: {
+ entity.components.ItemEjector.setSlots([
+ { pos: new Vector(0, 0), direction: enumDirection.top },
+ ]);
+ break;
+ }
+ case enumMixerVariants.incinerator: {
+ entity.components.ItemProcessor.type = enumItemProcessorTypes.dyeIncinerator;
+ entity.components.ItemProcessor.inputsPerCharge = 1;
+ entity.components.ItemAcceptor.setSlots([
+ {
+ pos: new Vector(0, 0),
+ directions: [enumDirection.left],
+ filter: enumItemAcceptorItemFilter.color,
+ },
+ ]);
+ entity.components.ItemEjector.setSlots([
+ { pos: new Vector(1, 0), direction: enumDirection.right },
+ ]);
+ break;
+ }
+ default: {
+ assertAlways(false, "Unknown mixer variant: " + variant);
+ }
+ }
+ }
}
diff --git a/src/js/game/components/item_processor.js b/src/js/game/components/item_processor.js
index eab51ae2..3e8af7fa 100644
--- a/src/js/game/components/item_processor.js
+++ b/src/js/game/components/item_processor.js
@@ -14,6 +14,7 @@ export const enumItemProcessorTypes = {
stacker: "stacker",
trash: "trash",
mixer: "mixer",
+ dyeIncinerator: "dyeIncinerator",
painter: "painter",
painterDouble: "painterDouble",
painterQuad: "painterQuad",
diff --git a/src/js/game/hub_goals.js b/src/js/game/hub_goals.js
index 9f65dc4c..90a31440 100644
--- a/src/js/game/hub_goals.js
+++ b/src/js/game/hub_goals.js
@@ -395,6 +395,7 @@ export class HubGoals extends BasicSerializableObject {
return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt * 2;
case enumItemProcessorTypes.mixer:
+ case enumItemProcessorTypes.dyeIncinerator:
case enumItemProcessorTypes.painter:
case enumItemProcessorTypes.painterDouble:
case enumItemProcessorTypes.painterQuad: {
diff --git a/src/js/game/systems/item_processor.js b/src/js/game/systems/item_processor.js
index ae7a4568..bf87ea06 100644
--- a/src/js/game/systems/item_processor.js
+++ b/src/js/game/systems/item_processor.js
@@ -240,6 +240,16 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
break;
}
+ // DYE INCINERATOR
+
+ case enumItemProcessorTypes.dyeIncinerator: {
+ outItems.push({
+ item: new ColorItem("uncolored"),
+ });
+
+ break;
+ }
+
// PAINTER
case enumItemProcessorTypes.painter: {
diff --git a/src/js/game/tutorial_goals.js b/src/js/game/tutorial_goals.js
index c7fa581b..627fc681 100644
--- a/src/js/game/tutorial_goals.js
+++ b/src/js/game/tutorial_goals.js
@@ -22,6 +22,7 @@ export const enumHubGoalRewards = {
reward_painter_double: "reward_painter_double",
reward_painter_quad: "reward_painter_quad",
reward_storage: "reward_storage",
+ reward_dye_incinerator: "reward_dye_incinerator",
reward_blueprints: "reward_blueprints",
reward_freeplay: "reward_freeplay",
@@ -160,6 +161,13 @@ export const tutorialGoals = [
},
// 18
+ {
+ shape: "WpWpWpWp:CwCwCwCw:WpWpWpWp:CwCwCwCw", // painting t4 (two variants)
+ required: 150000,
+ reward: enumHubGoalRewards.reward_dye_incinerator,
+ },
+
+ // 19
{
shape: finalGameShape,
required: 250000,
diff --git a/src/js/game/tutorial_goals_mappings.js b/src/js/game/tutorial_goals_mappings.js
index 905a623a..790ace89 100644
--- a/src/js/game/tutorial_goals_mappings.js
+++ b/src/js/game/tutorial_goals_mappings.js
@@ -2,7 +2,7 @@ import { MetaBuilding, defaultBuildingVariant } from "./meta_building";
import { MetaCutterBuilding, enumCutterVariants } from "./buildings/cutter";
import { MetaRotaterBuilding, enumRotaterVariants } from "./buildings/rotater";
import { MetaPainterBuilding, enumPainterVariants } from "./buildings/painter";
-import { MetaMixerBuilding } from "./buildings/mixer";
+import { MetaMixerBuilding, enumMixerVariants } from "./buildings/mixer";
import { MetaStackerBuilding } from "./buildings/stacker";
import { MetaSplitterBuilding, enumSplitterVariants } from "./buildings/splitter";
import { MetaUndergroundBeltBuilding, enumUndergroundBeltVariants } from "./buildings/underground_belt";
@@ -44,6 +44,7 @@ export const enumHubGoalRewardsToContentUnlocked = {
[enumHubGoalRewards.reward_painter_double]: typed([[MetaPainterBuilding, enumPainterVariants.double]]),
[enumHubGoalRewards.reward_painter_quad]: typed([[MetaPainterBuilding, enumPainterVariants.quad]]),
[enumHubGoalRewards.reward_storage]: typed([[MetaTrashBuilding, enumTrashVariants.storage]]),
+ [enumHubGoalRewards.reward_dye_incinerator]: typed([[MetaMixerBuilding, enumMixerVariants.incinerator]]),
[enumHubGoalRewards.reward_freeplay]: null,
[enumHubGoalRewards.no_reward]: null,
diff --git a/translations/base-en.yaml b/translations/base-en.yaml
index 39eb3cd3..9dc417f1 100644
--- a/translations/base-en.yaml
+++ b/translations/base-en.yaml
@@ -496,6 +496,9 @@ buildings:
default:
name: &mixer Color Mixer
description: Mixes two colors using additive blending.
+ incinerator:
+ name: Dye Incinerator
+ description: Produce gray dye from any dye you put in.
painter:
default:
@@ -586,6 +589,10 @@ storyRewards:
title: Storage Buffer
desc: You have unlocked a variant of the trash - It allows to store items up to a given capacity!
+ reward_dye_incinerator:
+ title: Dye Incinerator
+ desc: You have unlocked a variant of the mixer - It allows you to make gray dye by inputting any dye you have. Very useful with the quad painter!
+
reward_freeplay:
title: Freeplay
desc: You did it! You unlocked the free-play mode! This means that shapes are now randomly generated! (No worries, more content is planned for the standalone!)