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!)