From 97f52f509b7e8c192641fd25e52f74a333287a0e Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 17 May 2020 14:46:33 +0200 Subject: [PATCH] Rebalance whole game --- res/ui/icons/pin.png | Bin 1664 -> 806 bytes src/css/ingame_hud/shop.scss | 13 +-- src/js/core/config.js | 10 +- src/js/game/buildings/cutter.js | 9 +- src/js/game/buildings/miner.js | 10 +- src/js/game/buildings/painter.js | 12 ++- src/js/game/buildings/rotater.js | 9 +- src/js/game/buildings/splitter.js | 12 ++- src/js/game/buildings/underground_belt.js | 8 +- src/js/game/camera.js | 2 +- src/js/game/hud/parts/building_placer.js | 2 + src/js/game/map_chunk.js | 16 ++- src/js/game/tutorial_goals.js | 120 +++++++++------------- src/js/game/upgrades.js | 82 +++++++++++---- translations/base-en.yaml | 10 ++ 15 files changed, 204 insertions(+), 111 deletions(-) diff --git a/res/ui/icons/pin.png b/res/ui/icons/pin.png index 768599f39aa9b5781f06aadd50751d498c2974d8..004d1e7262e0aa1ae018e12f04cc5db918b8e670 100644 GIT binary patch delta 624 zcmZqRUB;%^8Q|y6%O%Cdz`(%k>ERN@z`&pY!W_&D3=A$yx{gg$w5w;>9^ez=$^Zr? zCYDAf7RC@{YHn<7Y;JCDVgh0q8yiE!O-)UWjV&O`3=ABMO)LxzZMC(vt*xz%Of1dK z%^_08rXX`bicKtxjLbmFOsznIrk2L07A7XS{a#`gA|!q z7#mv}n^>5bSZHfI7#oAkf`}L!n}f{)$ucl7e5!fBfq{X+x+KUin1Lzj==YOZtbE5r z_)lDuD5}3Ma7mPnw^Y3E>C5S|pKV{;b?ki?>|V*}_2ZlTj0LZBUwHD&=X%ur)#k19 zGM2B&lckw;>jimq^ndMptjoZ_@Y>VGF~s8Z+)3AknhXS7!;dzJZtUL6Dq3Cs|Nnj; zhhz`Q^gaAG1?TSE%wbxfGSMe8%xW@ga8YK;#?Nkx19*Cae#S3;RMWHS+6o1$2X4hz zUPb9ilsTVfRX*&w`M^HiBRc|nGIn2f{ZdtXZl@u~&jOLZTLkJ|o97-)uCZ~5Ra=vM z>Y9;rZN%|8raC%%9bWAHkzm$QP&L;v>31NnQf`1*ik`Fgq$Gw!@|YCQAOPu{~*+&1|wtE`B5h@p{{iHVhoxwe6Um4Sip(fsq1<=8MKY-U_9 Jp6t(N2mtUL*J%I% literal 1664 zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4rT@hhPm4t-!L#Ru%tWsIx;Y9?C1WI$jZRL zppfhlT9}xa8$%ppYHn%@GR?@;!q5=J0GSL{Z)5~g zV`5@yU}0edRc~%+Xlrb0X>4k#t?d9(X>4q4YHkAZCdg7_V+&J|EXe!%mX=V9jLnUW zL4GtgF*i20G&MD~wzdZ8HL)->Gcz^@xfvV+<{(#rtp+1jZ8saHU0OgNv(LB4spNPv4wo%gCO7s#ci0_}S+!u@CvolH1N|J3p`a zH**u`^8K4xn$`q)_592-{gxoV>+8N;y)$tN*)QLV*0uAz7AdK|cE{Xm;$-RYh{lyG z&g&}io_lE0{mU~r9kD0|RG)M`SSr z1K$x4W}K?cC(XdXz+U3%>&pIwm5-al^3(Qb(-;_-CVIL!hD01*Iz2P`vV%ygKI>(N zz{1Sci<)j}ak&N@5#wH@utQ9@^!Qpm)>S*A3l8&^AE-TAyW9S*u_DxXU zmr=+nwW{c3(CR&hTbD&W`#k&T^z{zjp=(XftzWh6oboBV#WlVS>g!ibi)p)mRx*6c zuD%o3KR*||?xR?d{rRNwy4(|tYZgB@UB}-x>xI>m9Q)Y)yqWrUe5!PF>K0F)b9vTH z*-Lkh%wd0@R>hb*>#pDK=r3pA7_10+7G5TGBU=44>+K^9x64x)tOI!(cAMB=Qsr84 zXYH@*0Fj2ktMA3wk6en))9+#~n4k21JF`W?E+#&Q?U#-+l`&KZ@GaCmkoaOF`-?{9 zZw&4aC5*H5Z0edqW0*}+Y;*cI{e7r1=MuZ`@<#8(W$rs0GF8)md}2_vecaMw_u?rl z%U2(!l-di&xnEp2Hd6WOsI32B%{;}di6TjtmG3TxPms@yX z!>ix#JDA?xyR3FcoYm$;Oy9)zqz3oW$=6Q{3ou!H;f``Se`3!gn`L*^&+yhuDKEFV z9P?{Ms7-qHkrxt{o^K5jXKp$cpHe3;qC zj?lP?|8JL9DGJ*w$rOgpy*S_Uxqg6@)KlN=u0Oy2K3_j&3cL4`Rln;0w%tGTpYh=L z%L}W&-#Em;z@S><8c~vxSdwa$T$GwvlFDFYU}T_cV5)0q5@Kj*Wnf`tYOZZyU}a#i zze6PvMMG|WN@iLmZVl(I&biCLz#s{-Aviy+q&%@Gm7%=6TrV>(yEr+qAXP8FD1G)j S8z}|`1_n=8KbLh*2~7Y)tXb&* diff --git a/src/css/ingame_hud/shop.scss b/src/css/ingame_hud/shop.scss index 41834d06..f995cfa8 100644 --- a/src/css/ingame_hud/shop.scss +++ b/src/css/ingame_hud/shop.scss @@ -42,7 +42,7 @@ color: #fff; text-align: center; font-weight: bold; - @include S(width, 45px); + @include S(width, 50px); @include S(padding, 0px, 5px); &[data-tier="0"] { @@ -61,10 +61,10 @@ background-color: rgb(243, 77, 48); } &[data-tier="5"] { - background-color: rgb(219, 184, 29); + background-color: rgb(255, 209, 6); } &[data-tier="6"] { - background-color: rgb(190, 73, 73); + background-color: rgb(44, 41, 46); } } } @@ -105,15 +105,16 @@ display: flex; flex-direction: column; align-items: center; - @include S(width, 75px); + @include S(width, 70px); + overflow: hidden; button.pin { @include S(width, 12px); @include S(height, 12px); background: uiResource("icons/pin.png") center center / 95% no-repeat; position: absolute; - @include S(top, -2px); - @include S(right, -2px); + @include S(top, 2px); + @include S(right, 2px); opacity: 0.6; cursor: pointer; pointer-events: all; diff --git a/src/js/core/config.js b/src/js/core/config.js index 10495e4f..ba851fce 100644 --- a/src/js/core/config.js +++ b/src/js/core/config.js @@ -38,7 +38,7 @@ export const globalConfig = { // Belt speeds // NOTICE: Update webpack.production.config too! - beltSpeedItemsPerSecond: 1, + beltSpeedItemsPerSecond: 5, itemSpacingOnBelts: 0.63, minerSpeedItemsPerSecond: 0, // COMPUTED @@ -76,8 +76,8 @@ export const globalConfig = { debug: { /* dev:start */ - // fastGameEnter: true, - // noArtificialDelays: true, + fastGameEnter: true, + noArtificialDelays: true, // disableSavegameWrite: true, showEntityBounds: false, showAcceptorEjectors: false, @@ -87,9 +87,9 @@ export const globalConfig = { disableZoomLimits: false, showChunkBorders: false, rewardsInstant: false, - allBuildingsUnlocked: true, + // allBuildingsUnlocked: true, upgradesNoCost: true, - disableUnlockDialog: false, + disableUnlockDialog: true, // testTranslations: true, /* dev:end */ }, diff --git a/src/js/game/buildings/cutter.js b/src/js/game/buildings/cutter.js index ce83b8f5..de5c0556 100644 --- a/src/js/game/buildings/cutter.js +++ b/src/js/game/buildings/cutter.js @@ -19,6 +19,7 @@ export class MetaCutterBuilding extends MetaBuilding { getSilhouetteColor() { return "#7dcda2"; } + getDimensions(variant) { switch (variant) { case defaultBuildingVariant: @@ -30,8 +31,14 @@ export class MetaCutterBuilding extends MetaBuilding { } } + /** + * @param {GameRoot} root + */ getAvailableVariants(root) { - return [defaultBuildingVariant, enumCutterVariants.quad]; + if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_cutter_quad)) { + return [defaultBuildingVariant, enumCutterVariants.quad]; + } + return super.getAvailableVariants(root); } /** diff --git a/src/js/game/buildings/miner.js b/src/js/game/buildings/miner.js index 14d41ed5..bc3474bd 100644 --- a/src/js/game/buildings/miner.js +++ b/src/js/game/buildings/miner.js @@ -4,6 +4,7 @@ import { MinerComponent } from "../components/miner"; import { Entity } from "../entity"; import { MetaBuilding, defaultBuildingVariant } from "../meta_building"; import { GameRoot } from "../root"; +import { enumHubGoalRewards } from "../tutorial_goals"; /** @enum {string} */ export const enumMinerVariants = { chainable: "chainable" }; @@ -17,8 +18,15 @@ export class MetaMinerBuilding extends MetaBuilding { return "#b37dcd"; } + /** + * + * @param {GameRoot} root + */ getAvailableVariants(root) { - return [defaultBuildingVariant, enumMinerVariants.chainable]; + if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_miner_chainable)) { + return [defaultBuildingVariant, enumMinerVariants.chainable]; + } + return super.getAvailableVariants(root); } /** diff --git a/src/js/game/buildings/painter.js b/src/js/game/buildings/painter.js index 420b4de1..bdf9b554 100644 --- a/src/js/game/buildings/painter.js +++ b/src/js/game/buildings/painter.js @@ -33,8 +33,18 @@ export class MetaPainterBuilding extends MetaBuilding { return "#cd9b7d"; } + /** + * @param {GameRoot} root + */ getAvailableVariants(root) { - return [defaultBuildingVariant, enumPainterVariants.double, enumPainterVariants.quad]; + let variants = [defaultBuildingVariant]; + if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_painter_double)) { + variants.push(enumPainterVariants.double); + } + if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_painter_quad)) { + variants.push(enumPainterVariants.quad); + } + return variants; } /** diff --git a/src/js/game/buildings/rotater.js b/src/js/game/buildings/rotater.js index 95d3dc7c..ba582766 100644 --- a/src/js/game/buildings/rotater.js +++ b/src/js/game/buildings/rotater.js @@ -20,8 +20,15 @@ export class MetaRotaterBuilding extends MetaBuilding { return "#7dc6cd"; } + /** + * + * @param {GameRoot} root + */ getAvailableVariants(root) { - return [defaultBuildingVariant, enumRotaterVariants.ccw]; + if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_rotater_ccw)) { + return [defaultBuildingVariant, enumRotaterVariants.ccw]; + } + return super.getAvailableVariants(root); } /** diff --git a/src/js/game/buildings/splitter.js b/src/js/game/buildings/splitter.js index 1bc0a779..a48d1d6c 100644 --- a/src/js/game/buildings/splitter.js +++ b/src/js/game/buildings/splitter.js @@ -32,8 +32,18 @@ export class MetaSplitterBuilding extends MetaBuilding { return "#444"; } + /** + * @param {GameRoot} root + */ getAvailableVariants(root) { - return [defaultBuildingVariant, enumSplitterVariants.compact, enumSplitterVariants.compactInverse]; + if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_splitter_compact)) { + return [ + defaultBuildingVariant, + enumSplitterVariants.compact, + enumSplitterVariants.compactInverse, + ]; + } + return super.getAvailableVariants(root); } /** diff --git a/src/js/game/buildings/underground_belt.js b/src/js/game/buildings/underground_belt.js index 6512245e..bdda2ca6 100644 --- a/src/js/game/buildings/underground_belt.js +++ b/src/js/game/buildings/underground_belt.js @@ -40,8 +40,14 @@ export class MetaUndergroundBeltBuilding extends MetaBuilding { return true; } + /** + * @param {GameRoot} root + */ getAvailableVariants(root) { - return [defaultBuildingVariant, enumUndergroundBeltVariants.tier2]; + if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_underground_belt_tier_2)) { + return [defaultBuildingVariant, enumUndergroundBeltVariants.tier2]; + } + return super.getAvailableVariants(root); } getPreviewSprite(rotationVariant, variant) { diff --git a/src/js/game/camera.js b/src/js/game/camera.js index 1fd235e5..c0326fbd 100644 --- a/src/js/game/camera.js +++ b/src/js/game/camera.js @@ -53,7 +53,7 @@ export class Camera extends BasicSerializableObject { this.clampZoomLevel(); /** @type {Vector} */ - this.center = new Vector(2 * globalConfig.tileSize, 2 * globalConfig.tileSize); + this.center = new Vector(0, 0); // Input handling this.currentlyMoving = false; diff --git a/src/js/game/hud/parts/building_placer.js b/src/js/game/hud/parts/building_placer.js index 0f49571e..45ca06c6 100644 --- a/src/js/game/hud/parts/building_placer.js +++ b/src/js/game/hud/parts/building_placer.js @@ -69,6 +69,8 @@ export class HUDBuildingPlacer extends BaseHUDPart { * @type {Vector} */ this.initialDragTile = null; + + this.root.signals.storyGoalCompleted.add(this.rerenderVariants, this); } createElements(parent) { diff --git a/src/js/game/map_chunk.js b/src/js/game/map_chunk.js index a2305991..b56836e8 100644 --- a/src/js/game/map_chunk.js +++ b/src/js/game/map_chunk.js @@ -159,11 +159,11 @@ export class MapChunk { weights = { [enumSubShape.rect]: 100, [enumSubShape.circle]: Math_round(50 + clamp(distanceToOriginInChunks * 2, 0, 50)), - [enumSubShape.star]: Math_round(9 + clamp(distanceToOriginInChunks, 0, 30)), + [enumSubShape.star]: Math_round(20 + clamp(distanceToOriginInChunks, 0, 30)), [enumSubShape.windmill]: Math_round(6 + clamp(distanceToOriginInChunks / 2, 0, 20)), }; - if (distanceToOriginInChunks < 5) { + if (distanceToOriginInChunks < 4) { // Initial chunks can not spawn the good stuff weights[enumSubShape.star] = 0; weights[enumSubShape.windmill] = 0; @@ -188,6 +188,18 @@ export class MapChunk { ]; } + // Makes sure windmills never spawn as whole + let windmillCount = 0; + for (let i = 0; i < subShapes.length; ++i) { + if (subShapes[i] === enumSubShape.windmill) { + ++windmillCount; + } + } + if (windmillCount > 1) { + subShapes[0] = enumSubShape.rect; + subShapes[1] = enumSubShape.rect; + } + const definition = this.root.shapeDefinitionMgr.getDefinitionFromSimpleShapes(subShapes); this.internalGeneratePatch(rng, shapePatchSize, new ShapeItem(definition)); } diff --git a/src/js/game/tutorial_goals.js b/src/js/game/tutorial_goals.js index 42cc2e83..47f9a325 100644 --- a/src/js/game/tutorial_goals.js +++ b/src/js/game/tutorial_goals.js @@ -12,142 +12,122 @@ export const enumHubGoalRewards = { reward_splitter: "reward_splitter", reward_tunnel: "reward_tunnel", + reward_rotater_ccw: "reward_rotater_ccw", + reward_miner_chainable: "reward_miner_chainable", + reward_underground_belt_tier_2: "reward_underground_belt_tier_2", + reward_splitter_compact: "reward_splitter_compact", + reward_cutter_quad: "reward_cutter_quad", + reward_painter_double: "reward_painter_double", + reward_painter_quad: "reward_painter_quad", + + reward_freeplay: "reward_freeplay", + no_reward: "no_reward", }; export const tutorialGoals = [ // Circle { - shape: "CuCuCuCu", - required: 40, + shape: "CuCuCuCu", // belts t1 + required: 60, reward: enumHubGoalRewards.reward_cutter_and_trash, }, // Cutter { - shape: "CuCu----", - required: 150, - reward: enumHubGoalRewards.no_reward, - }, - - { - shape: "----CuCu", - required: 200, - reward: enumHubGoalRewards.reward_splitter, - }, - - // Rectangle - { - shape: "RuRuRuRu", + shape: "----CuCu", // required: 80, reward: enumHubGoalRewards.no_reward, }, + // Rectangle { - shape: "RuRu----", - required: 250, + shape: "RuRuRuRu", // miners t1 + required: 100, + reward: enumHubGoalRewards.reward_splitter, + }, + + { + shape: "RuRu----", // processors t2 + required: 350, reward: enumHubGoalRewards.reward_rotater, }, // Rotater { - shape: "--CuCu--", + shape: "--CuCu--", // belts t2 required: 300, - reward: enumHubGoalRewards.no_reward, - }, - - { - shape: "Ru----Ru", - required: 400, reward: enumHubGoalRewards.reward_tunnel, }, { - shape: "Cu------", - required: 800, - reward: enumHubGoalRewards.no_reward, - }, - - { - shape: "------Ru", + shape: "Cu------", // miners t2 required: 1000, reward: enumHubGoalRewards.reward_painter, }, // Painter { - shape: "CrCrCrCr", + shape: "CrCrCrCr", // unused required: 1500, - reward: enumHubGoalRewards.no_reward, + reward: enumHubGoalRewards.reward_rotater_ccw, }, { - shape: "RbRb----", + shape: "RbRb----", // painter t2 required: 2500, reward: enumHubGoalRewards.reward_mixer, }, // Mixing (purple) { - shape: "CpCpCpCp", + shape: "CpCpCpCp", // belts t3 required: 4000, - reward: enumHubGoalRewards.no_reward, + reward: enumHubGoalRewards.reward_splitter_compact, }, // Star shape + cyan { - shape: "ScScScSc", - required: 500, + shape: "ScScScSc", // miners t3 + required: 5000, reward: enumHubGoalRewards.reward_stacker, }, // Stacker { - shape: "CgScScCg", - required: 3000, - reward: enumHubGoalRewards.no_reward, - }, - - { - shape: "RpRpRpRp:CcCcCcCc", - required: 4000, - reward: enumHubGoalRewards.no_reward, - }, - - { - shape: "RgCwRgCw:CpCpCpCp", + shape: "CgScScCg", // processors t3 required: 6000, - reward: enumHubGoalRewards.no_reward, + reward: enumHubGoalRewards.reward_miner_chainable, }, { - shape: "CwSwCwSw:CpCrCpCr", - required: 6000, - reward: enumHubGoalRewards.no_reward, + shape: "RpRpRpRp:CwCwCwCw", // painting t3 + required: 7000, + reward: enumHubGoalRewards.reward_underground_belt_tier_2, }, { - shape: "WyWyWyWy", - required: 2000, - reward: enumHubGoalRewards.no_reward, + shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", // belts t4 (two variants) + required: 8000, + reward: enumHubGoalRewards.reward_cutter_quad, }, { - shape: "WyWgWyWg:CbCpCbCp", - required: 4000, - reward: enumHubGoalRewards.no_reward, - }, - - { - shape: "WyRgWyRg:CbCpCbCp:CpCgCpCg", + shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", // miner t4 (two variants) required: 9000, - reward: enumHubGoalRewards.no_reward, + reward: enumHubGoalRewards.reward_painter_double, }, { - shape: "CwRrCbRy:ScSrSpSb:CwCwCwCw:RgRgRgRg", - required: 15000, - reward: enumHubGoalRewards.no_reward, + shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", // processors t4 (two varinats) + required: 10000, + reward: enumHubGoalRewards.reward_painter_quad, + }, + + { + shape: "RuCw--Cw:----Ru--", + required: 50000, + reward: enumHubGoalRewards.reward_freeplay, }, ]; diff --git a/src/js/game/upgrades.js b/src/js/game/upgrades.js index 958c917e..1a7b9416 100644 --- a/src/js/game/upgrades.js +++ b/src/js/game/upgrades.js @@ -1,94 +1,132 @@ import { findNiceIntegerValue } from "../core/utils"; import { ShapeDefinition } from "./shape_definition"; +const finalShape = "RuCw--Cw:----Ru--"; + export const UPGRADES = { belt: { tiers: [ { - required: [{ shape: "CuCuCuCu", amount: 80 }], + required: [{ shape: "CuCuCuCu", amount: 150 }], improvement: 1, }, { - required: [{ shape: "Ru----Ru", amount: 4000 }], + required: [{ shape: "--CuCu--", amount: 1500 }], improvement: 2, }, { - required: [{ shape: "CwSwCwSw", amount: 30000 }], + required: [{ shape: "CpCpCpCp", amount: 15000 }], improvement: 4, }, { - required: [{ shape: "RgRgSpSp:CwSwCwSw:Cr--Sw--", amount: 80000 }], + required: [{ shape: "SrSrSrSr:CyCyCyCy", amount: 40000 }], improvement: 4, }, + { + required: [{ shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", amount: 40000 }], + improvement: 4, + }, + { + required: [{ shape: finalShape, amount: 150000 }], + improvement: 4, + excludePrevious: true, + }, ], }, miner: { tiers: [ { - required: [{ shape: "RuRuRuRu", amount: 200 }], + required: [{ shape: "RuRuRuRu", amount: 400 }], improvement: 1, }, { - required: [{ shape: "Cu------", amount: 4000 }], + required: [{ shape: "Cu------", amount: 5500 }], improvement: 2, }, { - required: [{ shape: "WyWgWyWg:CbCpCbCp", amount: 30000 }], + required: [{ shape: "ScScScSc", amount: 20000 }], improvement: 4, }, { - required: [{ shape: "WyWgWyWg:CbCpCbCp:Rp----Rp", amount: 90000 }], + required: [{ shape: "CwCwCwCw:WbWbWbWb", amount: 40000 }], improvement: 4, }, + { + required: [{ shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", amount: 40000 }], + improvement: 4, + }, + { + required: [{ shape: finalShape, amount: 150000 }], + improvement: 4, + excludePrevious: true, + }, ], }, processors: { tiers: [ { - required: [{ shape: "SuSuSuSu", amount: 200 }], + required: [{ shape: "SuSuSuSu", amount: 1000 }], improvement: 1, }, { - required: [{ shape: "Cu------", amount: 4000 }], + required: [{ shape: "RuRu----", amount: 2000 }], improvement: 2, }, { - required: [{ shape: "WyWgWyWg:CbCpCbCp", amount: 30000 }], + required: [{ shape: "CgScScCg", amount: 25000 }], improvement: 4, }, { - required: [{ shape: "WyWgWyWg:CbCpCbCp:Rp----Rp", amount: 90000 }], + required: [{ shape: "CwCrCwCr:SgSgSgSg", amount: 40000 }], improvement: 4, }, + { + required: [{ shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", amount: 40000 }], + improvement: 4, + }, + { + required: [{ shape: finalShape, amount: 150000 }], + improvement: 4, + excludePrevious: true, + }, ], }, painting: { tiers: [ { - required: [{ shape: "WuWuWuWu", amount: 200 }], + required: [{ shape: "WrWrWrWr", amount: 2000 }], improvement: 1, }, { - required: [{ shape: "Cu------", amount: 4000 }], + required: [{ shape: "RbRb----", amount: 4000 }], improvement: 2, }, { - required: [{ shape: "WyWgWyWg:CbCpCbCp", amount: 30000 }], + required: [{ shape: "RpRpRpRp:CwCwCwCw", amount: 30000 }], improvement: 4, }, { - required: [{ shape: "WyWgWyWg:CbCpCbCp:Rp----Rp", amount: 90000 }], + required: [{ shape: "WpWpWpWp:CwCwCwCw:WpWpWpWp", amount: 40000 }], improvement: 4, }, + { + required: [{ shape: "WpWpWpWp:CwCwCwCw:WpWpWpWp:CwCwCwCw", amount: 40000 }], + improvement: 4, + }, + { + required: [{ shape: finalShape, amount: 150000 }], + improvement: 4, + excludePrevious: true, + }, ], }, }; // Tiers need % of the previous tier as requirement too -const tierGrowth = 2; +const tierGrowth = 2.5; // Automatically generate tier levels for (const upgradeId in UPGRADES) { @@ -101,10 +139,12 @@ for (const upgradeId in UPGRADES) { for (let k = currentTierRequirements.length - 1; k >= 0; --k) { const oldTierRequirement = currentTierRequirements[k]; - tierHandle.required.unshift({ - shape: oldTierRequirement.shape, - amount: oldTierRequirement.amount, - }); + if (!tierHandle.excludePrevious) { + tierHandle.required.unshift({ + shape: oldTierRequirement.shape, + amount: oldTierRequirement.amount, + }); + } } currentTierRequirements.push( ...originalRequired.map(req => ({ diff --git a/translations/base-en.yaml b/translations/base-en.yaml index 9d3bac7c..82e3fb72 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -266,6 +266,16 @@ storyRewards: reward_splitter: Splitter/Merger reward_tunnel: Tunnel + reward_rotater_ccw: CCW Rotating + reward_miner_chainable: Chaining Extractor + reward_underground_belt_tier_2: Tunnel Tier II + reward_splitter_compact: Compact Balancer + reward_cutter_quad: Quad Cutting + reward_painter_double: Double Painting + reward_painter_quad: Quad Painting + + reward_freeplay: Freeplay + # Special reward, which is shown when there is no reward actually no_reward: Next level