-
-
+
+
+
@@ -101,12 +108,13 @@
+
-
+
@@ -124,6 +132,7 @@
import { mapState } from 'vuex';
import TabIconText from '../partial/render/TabIconText.vue';
import BuildingStatBar from '../partial/village/BuildingStatBar.vue';
+import CraftingList from '../partial/village/CraftingList.vue';
import JobList from '../partial/village/JobList.vue';
import OfferingInventory from '../partial/village/OfferingInventory.vue';
import OfferingList from '../partial/village/OfferingList.vue';
@@ -135,13 +144,14 @@ import UpgradeList from '../render/UpgradeList.vue';
import UpgradeQueue from '../render/UpgradeQueue.vue';
export default {
- components: { UpgradeList, Resources, JobList, PrestigeStatus, PrestigeInventory, UpgradeQueue, OfferingInventory, OfferingList, PolicyList, TabIconText, BuildingStatBar },
+ components: { UpgradeList, Resources, JobList, PrestigeStatus, PrestigeInventory, UpgradeQueue, OfferingInventory, OfferingList, PolicyList, TabIconText, BuildingStatBar, CraftingList },
data: () => ({
tab: 'village'
}),
computed: {
...mapState({
- isFrozen: state => state.cryolab.village.active
+ isFrozen: state => state.cryolab.village.active,
+ subfeature: state => state.system.features.village.currentSubfeature
}),
canSeeUpgrades() {
return this.$store.state.unlock.villageCoinUpgrades.see;
@@ -150,13 +160,13 @@ export default {
return this.$store.state.unlock.villagePrestige.see;
},
canSeeOffering() {
- return this.$store.state.unlock.villageOffering1.see;
+ return this.subfeature === 0 && this.$store.state.unlock.villageOffering1.see;
},
canSeePolicies() {
- return this.$store.getters['mult/get']('villagePolicyTaxes') >= 1;
+ return this.subfeature === 0 && this.$store.getters['mult/get']('villagePolicyTaxes') >= 1;
},
upgradeNextRequired() {
- const nextBuild = ['localGovernment', 'government'].find(build => {
+ const nextBuild = ['campfire', 'communityCenter', 'townHall', 'localGovernment', 'government', 'steamEngine', 'ecoCouncil'].find(build => {
return this.$store.state.upgrade.item[`village_${build}`].highestLevel < 1;
});
return nextBuild ? [{value: 1, text:
diff --git a/src/js/autoplay.js b/src/js/autoplay.js
index 0e88830c..c5862265 100644
--- a/src/js/autoplay.js
+++ b/src/js/autoplay.js
@@ -470,7 +470,7 @@ function autoplayTicks(newTime, oldTime) {
if (store.state.unlock.hordeFeature.use) {
let hasMonsterPartGoal = false;
- const monsterPartFarmZone = Math.max(store.state.stat.horde_maxZone.value - 3, 10);
+ const monsterPartFarmZone = Math.max(store.state.stat.horde_maxZone.value - 6, 10);
if (store.state.stat.horde_maxZone.value >= 13) {
const maxMonsterPartGoal = Math.min(
store.state.currency.horde_monsterPart.cap, // Requirement cannot exceed resource cap
@@ -603,7 +603,7 @@ function autoplayTicks(newTime, oldTime) {
// Determine needed resource based on which currency has the lowest amount
let chosenType = 'vegetable';
let chosenAmount = store.getters['currency/value']('farm_vegetable');
- ['fruit', 'grain', 'flower'].forEach((elem, index) => {
+ ['berry', 'grain', 'flower'].forEach((elem, index) => {
const seedValue = store.getters['currency/value']('farm_' + elem);
if (store.state.upgrade.item.farm_seedBox.level > index && seedValue < chosenAmount) {
chosenType = elem;
diff --git a/src/js/constants.js b/src/js/constants.js
index b386c5c3..b3e87bcc 100644
--- a/src/js/constants.js
+++ b/src/js/constants.js
@@ -29,6 +29,8 @@ export const MINING_COAL_DEPTH = 90;
export const MINING_SULFUR_DEPTH = 110;
export const MINING_NITER_DEPTH = 130;
export const MINING_OBSIDIAN_DEPTH = 150;
+export const MINING_DEEPROCK_DEPTH = 275;
+export const MINING_GLOWSHARD_DEPTH = 9999;//400;
export const MINING_SMELTERY_TEMPERATURE_SPEED = 0.004;
export const MINING_ENHANCEMENT_BARS = 50;
export const MINING_ENHANCEMENT_FINAL = 10;
@@ -64,6 +66,16 @@ export const HORDE_KEYS_PER_TOWER = 3;
export const HORDE_HEIRLOOM_TOWER_FLOORS = 5;
export const HORDE_HEIRLOOM_CHANCE_PER_NOSTALGIA = 0.001;
export const HORDE_MASTERY_MINIBOSS_MULT = 0.05;
+export const HORDE_DAMAGE_INCREASE_PER_STRENGTH = 0.05;
+export const HORDE_LEVEL_MIN_SECONDS = 600;
+export const HORDE_SHARD_CHANCE_REDUCTION = 1.075;
+
+export const GALLERY_SHAPES_GRID_WIDTH = 9;
+export const GALLERY_SHAPES_GRID_HEIGHT = 6;
+export const GALLERY_REROLL_COST = 35;
+export const GALLERY_CONVERTER_EXPONENT = 0.0025;
+export const GALLERY_MOTIVATION_BUY_COST = 20;
+export const GALLERY_MOTIVATION_BUY_AMOUNT = 500;
export const TREASURE_TIER_UPGRADE_MULT = 5;
export const TREASURE_TIER_DESTROY_MULT = 4;
diff --git a/src/js/init.js b/src/js/init.js
index c4ff5fa5..71a3cc44 100644
--- a/src/js/init.js
+++ b/src/js/init.js
@@ -36,7 +36,12 @@ function newGame(startTick = true) {
store.commit('upgrade/initCache');
store.commit('system/generatePlayerId');
- store.dispatch('system/updateCurrentDay');
+
+ // Update current day
+ const newDay = getDay();
+ store.commit('system/updateKey', {key: 'currentDay', value: newDay});
+ store.commit('system/updateKey', {key: 'lastPlayedDays', value: [newDay]});
+
store.dispatch('farm/applyEarlyGameBuff');
if (startTick) {
@@ -125,6 +130,11 @@ function prepare() {
store.commit('consumable/init', {feature: module.name, name: key, ...elem});
}
}
+ if (module.tag) {
+ for (const [key, elem] of Object.entries(module.tag)) {
+ store.commit('tag/init', {name: key, ...elem});
+ }
+ }
// Module init functions
if (module.init) {
diff --git a/src/js/modules/achievement.js b/src/js/modules/achievement.js
index 89b9b3f8..12752ff6 100644
--- a/src/js/modules/achievement.js
+++ b/src/js/modules/achievement.js
@@ -7,51 +7,26 @@ export default {
tickspeed: 1,
unlockNeeded: 'achievementFeature',
tick() {
- for (let [key, elem] of Object.entries(store.state.achievement)) {
-
- let oldLevel = elem.level;
- const value = elem.value();
- let gainedRelic = false;
- while ((elem.cap === null || elem.level < elem.cap) && value >= elem.milestones(elem.level)) {
-
- // Award relic if one is the reward
- if (elem.relic[elem.level]) {
- store.dispatch('relic/find', elem.relic[elem.level]);
- gainedRelic = true;
- }
- store.commit('achievement/updateKey', {name: key, key: 'level', value: elem.level + 1});
- elem = store.state.achievement[key];
- }
-
- // Create a notification if setting is on, also group multiple of the same achievement
- if (store.state.system.settings.notification.items.achievement.value && elem.level > oldLevel) {
- store.commit('system/addNotification', {color: elem.secret ? 'purple' : 'success', timeout: gainedRelic ? -1 : 5000, message: {
- type: 'achievement',
- name: key,
- value: elem.level,
- oldValue: oldLevel
- }});
- }
- }
+ store.dispatch('achievement/check');
},
unlock: ['achievementFeature'],
relic: {
- excavator: {icon: 'mdi-excavator', color: 'orange', effect: [
+ excavator: {icon: 'mdi-excavator', feature: ['achievement', 'mining'], color: 'orange', effect: [
{name: 'currencyMiningScrapGain', type: 'mult', value: 2},
{name: 'currencyMiningScrapCap', type: 'mult', value: 2}
]},
- redCard: {icon: 'mdi-cards', color: 'red', effect: [
+ redCard: {icon: 'mdi-cards', feature: ['achievement', 'horde'], color: 'red', effect: [
{name: 'currencyHordeMonsterPartCap', type: 'bonus', value: buildNum(10, 'K')},
{name: 'hordeCardCap', type: 'base', value: 1}
]},
- briefcase: {icon: 'mdi-briefcase', color: 'pale-blue', effect: [
+ briefcase: {icon: 'mdi-briefcase', feature: ['achievement', 'treasure'], color: 'pale-blue', effect: [
{name: 'treasureSlots', type: 'base', value: 8}
]},
- strangePlant: {icon: 'mdi-sprout', color: 'pale-purple', effect: [
+ strangePlant: {icon: 'mdi-sprout', feature: ['achievement', 'village', 'farm'], color: 'pale-purple', effect: [
{name: 'villageMaterialGain', type: 'mult', value: 2},
{name: 'farmCropGain', type: 'mult', value: 2}
]},
- beneficialVirus: {icon: 'mdi-virus', color: 'pale-green', effect: [
+ beneficialVirus: {icon: 'mdi-virus', feature: ['achievement', 'mining', 'horde'], color: 'pale-green', effect: [
{name: 'miningToughness', type: 'mult', value: 0.5},
{name: 'hordeCorruption', type: 'bonus', value: -0.5}
]}
@@ -71,16 +46,9 @@ export default {
loadGame(data) {
for (const [key, elem] of Object.entries(data)) {
if (store.state.achievement[key] !== undefined) {
- store.commit('achievement/updateKey', {name: key, key: 'level', value: elem});
-
- // Recover "lost" relics
- for (let i = 0; i < elem; i++) {
- let relic = store.state.achievement[key].relic[i];
- if (relic && !store.state.relic[relic].found) {
- store.dispatch('relic/find', relic);
- }
- }
+ store.commit('achievement/updateKey', {name: key, key: 'cacheHideNotification', value: elem});
}
}
+ store.dispatch('achievement/check');
}
}
diff --git a/src/js/modules/card.js b/src/js/modules/card.js
index 9d026774..a9d87dd9 100644
--- a/src/js/modules/card.js
+++ b/src/js/modules/card.js
@@ -11,7 +11,13 @@ import { buildArray } from "../utils/array";
export default {
name: 'card',
unlockNeeded: 'cardFeature',
- unlock: ['cardFeature'],
+ unlock: ['cardFeature', 'cardShiny'],
+ mult: {
+ cardShinyChance: {display: 'percent', baseValue: 0.1},
+ },
+ currency: {
+ shinyDust: {color: 'pale-light-blue', icon: 'mdi-shimmer'}
+ },
note: buildArray(2).map(() => 'g'),
init() {
for (const [name, feature] of Object.entries({
@@ -52,6 +58,12 @@ export default {
if (elem.amount > 0) {
obj.card[key] = elem.amount;
}
+ if (elem.foundShiny) {
+ if (obj.shiny === undefined) {
+ obj.shiny = [];
+ }
+ obj.shiny.push(key);
+ }
}
for (const [key, elem] of Object.entries(store.state.card.feature)) {
if (elem.cardSelected.length > 0 || elem.cardEquipped.length > 0) {
@@ -77,6 +89,11 @@ export default {
}
}
}
+ if (data.shiny) {
+ data.shiny.forEach(elem => {
+ store.commit('card/updateKey', {type: 'card', name: elem, key: 'foundShiny', value: true});
+ });
+ }
store.dispatch('card/calculateCaches');
}
}
diff --git a/src/js/modules/cryolab.js b/src/js/modules/cryolab.js
index 8654bac4..7088af62 100644
--- a/src/js/modules/cryolab.js
+++ b/src/js/modules/cryolab.js
@@ -8,11 +8,12 @@ const data = {
{mining_crystalYellow: 'mining_bestPrestige1'},
],
village: [
- {village_blessing: 'village_bestPrestige'},
- {village_blessing: 'village_bestPrestige'},
+ {village_blessing: 'village_bestPrestige0'},
+ {village_shares: 'village_bestPrestige1'},
],
horde: [
- {horde_soulEmpowered: 'horde_bestPrestige'},
+ {horde_soulEmpowered: 'horde_bestPrestige0'},
+ {horde_courage: 'horde_bestPrestige1'},
],
farm: [
{farm_exp: 'farm_bestPrestige'},
@@ -32,13 +33,18 @@ const effect = {
{name: 'currencyVillageFaithGain', type: 'mult', value: lvl => lvl * 0.1 + 1},
{name: 'currencyVillageFaithCap', type: 'mult', value: lvl => lvl * 0.1 + 1}
],
- [],
+ [
+ {name: 'currencyVillageSharesGain', type: 'mult', value: lvl => lvl * 0.1 + 1}
+ ],
],
horde: [
[
{name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: lvl => lvl * 0.1 + 1},
{name: 'currencyHordeSoulCorruptedCap', type: 'mult', value: lvl => lvl * 0.1 + 1}
],
+ [
+ {name: 'currencyHordeCourageGain', type: 'mult', value: lvl => lvl * 0.1 + 1},
+ ],
],
farm: [
[{name: 'farmExperience', type: 'mult', value: lvl => lvl * 0.1 + 1}],
diff --git a/src/js/modules/event.js b/src/js/modules/event.js
index c67c2f10..d789a8f6 100644
--- a/src/js/modules/event.js
+++ b/src/js/modules/event.js
@@ -63,6 +63,10 @@ export default {
eventTicks[stats.startEvent](newTicks - oldTime, oldTime, newTicks);
}
+ if (oldDay !== newDay) {
+ store.dispatch('event/dayChange', {start: oldDay, end: newDay});
+ }
+
// Tick new event
if (stats.isBigEvent) {
const oldTicks = Math.floor(Math.max(
@@ -83,7 +87,13 @@ export default {
bloomMaxPoppy: {type: 'bloom'},
bloomMaxIris: {type: 'bloom'},
bloomMaxLily: {type: 'bloom'},
- summerFestivalMaxStage: {type: 'summerFestival'}
+ summerFestivalMaxStage: {type: 'summerFestival'},
+ cindersHighscore: {type: 'cinders'},
+ bloomHighscore: {type: 'bloom'},
+ weatherChaosHighscore: {type: 'weatherChaos'},
+ summerFestivalHighscore: {type: 'summerFestival'},
+ nightHuntHighscore: {type: 'nightHunt'},
+ snowdownHighscore: {type: 'snowdown'},
},
mult: {
// shop mults
@@ -149,7 +159,8 @@ export default {
// night hunt mults
nightHuntFindableIngredients: {baseValue: 4, round: true},
- nightHuntIngredientSize: {baseValue: 1},
+ nightHuntIngredientSize: {baseValue: 8, round: true},
+ nightHuntFavouriteIngredientSize: {round: true},
nightHuntMaxIngredients: {baseValue: 1, round: true},
nightHuntBonusIngredientCount: {round: true},
nightHuntBonusIngredientAmount: {baseValue: 1, round: true},
@@ -500,6 +511,9 @@ export default {
if (Object.keys(store.state.nightHunt.ritualHint).length > 0) {
obj.nightHunt_ritualHint = store.state.nightHunt.ritualHint;
}
+ if (store.state.nightHunt.favouriteIngredient !== 'copy') {
+ obj.nightHunt_favouriteIngredient = store.state.nightHunt.favouriteIngredient;
+ }
let potions = {};
let hasPotions = false;
@@ -707,6 +721,9 @@ export default {
if (data.nightHunt_ritualHint !== undefined) {
store.commit('nightHunt/updateKey', {key: 'ritualHint', value: data.nightHunt_ritualHint});
}
+ if (data.nightHunt_favouriteIngredient !== undefined) {
+ store.commit('nightHunt/updateKey', {key: 'favouriteIngredient', value: data.nightHunt_favouriteIngredient});
+ }
if (data.nightHunt_potion !== undefined) {
for (const [key, elem] of Object.entries(data.nightHunt_potion)) {
store.commit('nightHunt/updatePotionKey', {name: key, key: 'recipe', value: elem.recipe});
diff --git a/src/js/modules/event/bloom/prize.js b/src/js/modules/event/bloom/prize.js
index 9cade59e..6a1a181d 100644
--- a/src/js/modules/event/bloom/prize.js
+++ b/src/js/modules/event/bloom/prize.js
@@ -38,7 +38,7 @@ export default {
farm_superFlower: {
type: 'consumable',
item: 'farm_superFlower',
- amount: 5,
+ amount: 20,
requirement() {
return store.state.unlock.farmFertilizer.see;
},
diff --git a/src/js/modules/event/card.js b/src/js/modules/event/card.js
index 17a4eda0..8ff5a9af 100644
--- a/src/js/modules/event/card.js
+++ b/src/js/modules/event/card.js
@@ -7,7 +7,12 @@ const summerTable = {'EV-0014': 0.6, 'EV-0015': 0.6, 'EV-0016': 0.6, 'EV-0017':
const winterTable = {'EV-0024': 0.6, 'EV-0025': 0.6, 'EV-0026': 0.6, 'EV-0027': 0.6};
export default {
- feature: {prefix: 'EV', reward: [{name: 'currencyGemTopazCap', type: 'base', value: lvl => lvl * 5}], unlock: 'eventFeature'},
+ feature: {
+ prefix: 'EV',
+ reward: [{name: 'currencyGemTopazCap', type: 'base', value: lvl => lvl * 5}],
+ shinyReward: [{name: 'currencyGemTopazCap', type: 'base', value: lvl => lvl * 5}],
+ unlock: 'eventFeature'
+ },
collection: {
weekendTrip: {reward: [
{name: 'currencyGemTopazCap', type: 'base', value: 50}
diff --git a/src/js/modules/event/cinders/prize.js b/src/js/modules/event/cinders/prize.js
index 966d54eb..8d2b3981 100644
--- a/src/js/modules/event/cinders/prize.js
+++ b/src/js/modules/event/cinders/prize.js
@@ -35,7 +35,7 @@ export default {
farm_sunshine: {
type: 'consumable',
item: 'farm_sunshine',
- amount: 5,
+ amount: 20,
requirement() {
return store.state.unlock.farmFertilizer.see;
},
diff --git a/src/js/modules/event/cinders/tick.js b/src/js/modules/event/cinders/tick.js
index 03141a11..b1d79678 100644
--- a/src/js/modules/event/cinders/tick.js
+++ b/src/js/modules/event/cinders/tick.js
@@ -31,11 +31,7 @@ export default function(seconds) {
const totalTokens = Math.floor(store.getters['mult/get']('currencyEventCindersTokenGain', logBase(lightGained / buildNum(10, 'K'), 1.2)));
const collectedTokens = store.state.stat.event_cindersToken.value;
if (totalTokens > collectedTokens) {
- store.dispatch('currency/gain', {
- feature: 'event',
- name: 'cindersToken',
- amount: totalTokens - collectedTokens
- });
+ store.dispatch('event/giveTokens', {event: 'cinders', amount: totalTokens - collectedTokens});
store.dispatch('note/find', 'event_10');
}
}
diff --git a/src/js/modules/event/nightHunt/prize.js b/src/js/modules/event/nightHunt/prize.js
index 13aba926..8cb4aa3b 100644
--- a/src/js/modules/event/nightHunt/prize.js
+++ b/src/js/modules/event/nightHunt/prize.js
@@ -38,7 +38,7 @@ export default {
farm_fieldBlessing: {
type: 'consumable',
item: 'farm_fieldBlessing',
- amount: 5,
+ amount: 20,
requirement() {
return store.state.unlock.farmFertilizer.see;
},
diff --git a/src/js/modules/event/nightHunt/tick.js b/src/js/modules/event/nightHunt/tick.js
index e47b086f..0c096c6e 100644
--- a/src/js/modules/event/nightHunt/tick.js
+++ b/src/js/modules/event/nightHunt/tick.js
@@ -3,25 +3,40 @@ import { NIGHT_HUNT_GL_BOOST } from "../../../constants";
import { chance } from "../../../utils/random";
export default function(seconds) {
- const changeAmount = Math.min(20, Math.floor(Math.sqrt(store.state.currency.event_magic.value))) - Object.keys(store.state.nightHunt.changedCurrency).length;
+ let magicValue = store.state.currency.event_magic.value / 10;
let addAmount = 0;
+ let sackAmount = 0;
let secondsLeft = seconds;
- while (secondsLeft > 0 && addAmount < changeAmount) {
- const percent = 0.01 * (changeAmount - addAmount);
- const secondsNeeded = Math.ceil(1 / percent);
- if (secondsLeft >= secondsNeeded) {
- addAmount++;
+ while (secondsLeft > 0) {
+ const changeAmount = Math.min(20, Math.floor(Math.sqrt(magicValue))) - Object.keys(store.state.nightHunt.changedCurrency).length - addAmount - sackAmount;
+ const percent = 0.002 * changeAmount;
+ const sackPercent = 0.002 * magicValue - 0.2;
+ const secondsNeeded = percent > 0 ? Math.ceil(1 / percent) : Infinity;
+ if (changeAmount <= 0) {
+ secondsLeft = 0;
+ } else if (secondsLeft >= secondsNeeded) {
+ if (chance(sackPercent)) {
+ sackAmount++;
+ magicValue -= 10;
+ } else {
+ addAmount++;
+ magicValue--;
+ }
secondsLeft -= secondsNeeded;
} else {
if (chance(percent)) {
- addAmount++;
+ if (chance(sackPercent)) {
+ sackAmount++;
+ } else {
+ addAmount++;
+ }
}
secondsLeft = 0;
}
}
- if (addAmount > 0) {
- store.dispatch('nightHunt/addChangedCurrency', addAmount);
- store.dispatch('currency/spend', {feature: 'event', name: 'magic', amount: addAmount});
+ if (addAmount > 0 || sackAmount > 0) {
+ store.dispatch('nightHunt/addChangedCurrency', {random: addAmount, sack: sackAmount});
+ store.dispatch('currency/spend', {feature: 'event', name: 'magic', amount: addAmount * 10 + sackAmount * 100});
}
const essenceGain = store.getters['mult/get']('currencyEventEssenceGain') * Math.pow(NIGHT_HUNT_GL_BOOST, store.getters['meta/globalEventLevel']);
diff --git a/src/js/modules/event/nightHunt/upgrade.js b/src/js/modules/event/nightHunt/upgrade.js
index faa41fca..563580e1 100644
--- a/src/js/modules/event/nightHunt/upgrade.js
+++ b/src/js/modules/event/nightHunt/upgrade.js
@@ -23,7 +23,8 @@ export default {
}, price(lvl) {
return {event_essence: Math.pow(1000 * Math.pow(10, lvl), lvl) * buildNum(100, 'K')};
}, effect: [
- {name: 'nightHuntFindableIngredients', type: 'base', value: lvl => lvl}
+ {name: 'nightHuntFindableIngredients', type: 'base', value: lvl => lvl},
+ {name: 'nightHuntFavouriteIngredientSize', type: 'base', value: lvl => lvl},
]},
ritualChalk: {type: 'nightHunt', cap: 3, requirement() {
return store.state.upgrade.item.event_biggerCauldron.level > 0;
@@ -48,22 +49,22 @@ export default {
]},
// topaz upgrades
- mystifier: {type: 'nightHunt', cap: 5, price(lvl) {
- return {gem_topaz: lvl * 100 + 250};
+ mystifier: {type: 'nightHunt', price(lvl) {
+ return {gem_topaz: lvl * 125 + 100};
}, effect: [
{name: 'currencyEventEssenceGain', type: 'mult', value: lvl => Math.pow(3, lvl)}
]},
- bundle: {type: 'nightHunt', cap: 2, price(lvl) {
- return {gem_topaz: lvl * 600 + 400};
+ bundle: {type: 'nightHunt', price(lvl) {
+ return {gem_topaz: lvl * 250 + 350};
}, effect: [
- {name: 'nightHuntIngredientSize', type: 'base', value: lvl => lvl}
+ {name: 'nightHuntIngredientSize', type: 'base', value: lvl => lvl * 3},
+ {name: 'nightHuntFavouriteIngredientSize', type: 'base', value: lvl => lvl},
]},
- bagOfCandy: {type: 'nightHunt', cap: 3, requirement() {
+ bagOfCandy: {type: 'nightHunt', requirement() {
return store.state.upgrade.item.event_ritualChalk.level > 0;
}, price(lvl) {
- return {gem_topaz: lvl * 200 + 300};
+ return {gem_topaz: lvl * 200 + 200};
}, effect: [
- {name: 'nightHuntBonusIngredientCount', type: 'base', value: lvl => lvl},
{name: 'nightHuntBonusIngredientAmount', type: 'base', value: lvl => lvl}
]},
}
diff --git a/src/js/modules/event/prize.js b/src/js/modules/event/prize.js
index fa87d20c..c6f87c32 100644
--- a/src/js/modules/event/prize.js
+++ b/src/js/modules/event/prize.js
@@ -64,7 +64,7 @@ export default {
treasure_empoweredN5: {
type: 'treasure',
item: 'empowered',
- bonusTier: -5,
+ bonusTier: -10,
requirement() {
return store.state.unlock.treasureFeature.see;
},
@@ -77,7 +77,7 @@ export default {
treasure_empoweredN4: {
type: 'treasure',
item: 'empowered',
- bonusTier: -4,
+ bonusTier: -9,
requirement() {
return store.state.unlock.treasureFeature.see;
},
@@ -90,7 +90,7 @@ export default {
treasure_empoweredN3: {
type: 'treasure',
item: 'empowered',
- bonusTier: -3,
+ bonusTier: -8,
requirement() {
return store.state.unlock.treasureFeature.see;
},
@@ -105,7 +105,7 @@ export default {
treasure_empoweredN2: {
type: 'treasure',
item: 'empowered',
- bonusTier: -2,
+ bonusTier: -7,
requirement() {
return store.state.unlock.treasureFeature.see;
},
@@ -118,7 +118,7 @@ export default {
treasure_empoweredN1: {
type: 'treasure',
item: 'empowered',
- bonusTier: -1,
+ bonusTier: -6,
requirement() {
return store.state.unlock.treasureFeature.see;
},
@@ -134,6 +134,7 @@ export default {
treasure_empowered: {
type: 'treasure',
item: 'empowered',
+ bonusTier: -5,
requirement() {
return store.state.unlock.treasureFeature.see;
},
@@ -147,7 +148,7 @@ export default {
treasure_empoweredP1: {
type: 'treasure',
item: 'empowered',
- bonusTier: 1,
+ bonusTier: -4,
requirement() {
return store.state.unlock.treasureFeature.see;
},
@@ -163,7 +164,7 @@ export default {
treasure_empoweredP2: {
type: 'treasure',
item: 'empowered',
- bonusTier: 2,
+ bonusTier: -3,
requirement() {
return store.state.unlock.treasureFeature.see;
},
@@ -177,7 +178,7 @@ export default {
treasure_empoweredP3: {
type: 'treasure',
item: 'empowered',
- bonusTier: 3,
+ bonusTier: -2,
requirement() {
return store.state.unlock.treasureFeature.see;
},
@@ -191,7 +192,7 @@ export default {
treasure_empoweredP4: {
type: 'treasure',
item: 'empowered',
- bonusTier: 4,
+ bonusTier: -1,
requirement() {
return store.state.unlock.treasureFeature.see;
},
@@ -202,7 +203,6 @@ export default {
treasure_empoweredP5: {
type: 'treasure',
item: 'empowered',
- bonusTier: 5,
requirement() {
return store.state.unlock.treasureFeature.see;
},
@@ -676,7 +676,7 @@ export default {
requirement() {
return store.state.stat.village_prestigeCount.total >= 1;
},
- amountMult: () => store.state.stat.village_bestPrestige.total,
+ amountMult: () => store.state.stat.village_bestPrestige0.total,
pool: {
bingo1: {amount: 0.1},
bingo2: {amount: 0.4},
@@ -693,7 +693,7 @@ export default {
requirement() {
return store.state.stat.horde_prestigeCount.total >= 1;
},
- amountMult: () => store.state.stat.horde_bestPrestige.total,
+ amountMult: () => store.state.stat.horde_bestPrestige0.total,
pool: {
bingo1: {amount: 0.1},
bingo2: {amount: 0.4},
diff --git a/src/js/modules/event/relic.js b/src/js/modules/event/relic.js
index 72c6dfc4..bbde8608 100644
--- a/src/js/modules/event/relic.js
+++ b/src/js/modules/event/relic.js
@@ -1,105 +1,105 @@
export default {
// Generic small event
- tinfoilHat: {icon: 'mdi-hat-fedora', color: 'blue-grey', effect: [
+ tinfoilHat: {icon: 'mdi-hat-fedora', feature: ['event', 'mining'], color: 'blue-grey', effect: [
{name: 'currencyMiningOreAluminiumGain', type: 'mult', value: 1.12}
]},
- cupOfWater: {icon: 'mdi-cup-water', color: 'blue', effect: [
+ cupOfWater: {icon: 'mdi-cup-water', feature: ['event', 'village'], color: 'blue', effect: [
{name: 'currencyVillageWaterGain', type: 'mult', value: 1.12},
{name: 'currencyVillageGlassGain', type: 'mult', value: 1.05}
]},
- combatStrategy: {icon: 'mdi-clipboard-list', color: 'pale-green', effect: [
+ combatStrategy: {icon: 'mdi-clipboard-list', feature: ['event', 'horde'], color: 'pale-green', effect: [
{name: 'hordeItemMasteryGain', type: 'mult', value: 1.18}
]},
// Merchant
- hundredDollarBill: {icon: 'mdi-cash-100', color: 'green', effect: [
+ hundredDollarBill: {icon: 'mdi-cash-100', feature: ['event', 'village'], color: 'green', effect: [
{name: 'currencyVillageCoinGain', type: 'mult', value: 1.1}
]},
- hotAirBalloon: {icon: 'mdi-airballoon', color: 'orange-red', effect: [
+ hotAirBalloon: {icon: 'mdi-airballoon', feature: ['event', 'mining'], color: 'orange-red', effect: [
{name: 'miningSmelterySpeed', type: 'mult', value: 1.1}
]},
// Bingo
- largeClover: {icon: 'mdi-clover', color: 'light-green', effect: [
+ largeClover: {icon: 'mdi-clover', feature: ['event', 'horde'], color: 'light-green', effect: [
{name: 'hordeItemChance', type: 'mult', value: 1.15}
]},
- eightBall: {icon: 'mdi-billiards', color: 'darker-grey', effect: [
+ eightBall: {icon: 'mdi-billiards', feature: ['event', 'mining'], color: 'darker-grey', effect: [
{name: 'miningDamage', type: 'mult', value: 1.08}
]},
// Wheel of fortune
- youngPig: {icon: 'mdi-pig-variant', color: 'pale-pink', effect: [
+ youngPig: {icon: 'mdi-pig-variant', feature: ['event', 'horde'], color: 'pale-pink', effect: [
{name: 'hordeNostalgia', type: 'base', value: 5}
]},
- silverHorseshoe: {icon: 'mdi-horseshoe', color: 'lighter-grey', effect: [
+ silverHorseshoe: {icon: 'mdi-horseshoe', feature: ['event', 'farm'], color: 'lighter-grey', effect: [
{name: 'farmRareDropChance', type: 'mult', value: 1.05}
]},
// Generic big event
- bronzeTools: {icon: 'mdi-tools', color: 'amber', effect: [
+ bronzeTools: {icon: 'mdi-tools', feature: ['event', 'mining'], color: 'amber', effect: [
{name: 'currencyMiningOreCopperGain', type: 'mult', value: 1.12},
{name: 'currencyMiningOreTinGain', type: 'mult', value: 1.12}
]},
- minersHat: {icon: 'mdi-hard-hat', color: 'yellow', effect: [
+ minersHat: {icon: 'mdi-hard-hat', feature: ['event', 'mining'], color: 'yellow', effect: [
{name: 'currencyMiningOreIronGain', type: 'mult', value: 1.12},
{name: 'currencyMiningOreTitaniumGain', type: 'mult', value: 1.12}
]},
- dictionary: {icon: 'mdi-book-alphabet', color: 'brown', effect: [
+ dictionary: {icon: 'mdi-book-alphabet', feature: ['event', 'village'], color: 'brown', effect: [
{name: 'currencyVillageKnowledgeGain', type: 'mult', value: 1.1}
]},
- expertTools: {icon: 'mdi-toolbox', color: 'cherry', effect: [
+ expertTools: {icon: 'mdi-toolbox', feature: ['event', 'village'], color: 'cherry', effect: [
{name: 'currencyVillageHardwoodGain', type: 'mult', value: 1.07},
{name: 'currencyVillageGemGain', type: 'mult', value: 1.07}
]},
- bloodBag: {icon: 'mdi-blood-bag', color: 'red', effect: [
+ bloodBag: {icon: 'mdi-blood-bag', feature: ['event', 'gallery'], color: 'red', effect: [
{name: 'currencyGalleryRedGain', type: 'mult', value: 1.15}
]},
// Cinders
- geode: {icon: 'mdi-circle-double', color: 'indigo', effect: [
+ geode: {icon: 'mdi-circle-double', feature: ['event', 'mining'], color: 'indigo', effect: [
{name: 'miningOreGain', type: 'mult', value: 1.06}
]},
- birthdayCake: {icon: 'mdi-cake', color: 'red', effect: [
+ birthdayCake: {icon: 'mdi-cake', feature: ['event', 'treasure'], color: 'red', effect: [
{name: 'treasureSlots', type: 'base', value: 2}
]},
// Bloom
- colorfulFlower: {icon: 'mdi-flower', color: 'red-pink', effect: [
+ colorfulFlower: {icon: 'mdi-flower', feature: ['event', 'farm'], color: 'red-pink', effect: [
{name: 'currencyFarmFlowerGain', type: 'mult', value: 1.15}
]},
- heatingBulb: {icon: 'mdi-lightbulb-on', color: 'orange', effect: [
+ heatingBulb: {icon: 'mdi-lightbulb-on', feature: ['event', 'gallery'], color: 'orange', effect: [
{name: 'galleryInspirationStart', type: 'base', value: 1}
]},
// Weather chaos
- trashCan: {icon: 'mdi-trash-can', color: 'dark-grey', effect: [
- {name: 'currencyMiningScrapGain', type: 'mult', value: 1.08}
+ trashCan: {icon: 'mdi-trash-can', feature: ['event', 'mining'], color: 'dark-grey', effect: [
+ {name: 'currencyMiningScrapGain', type: 'mult', value: 1.1}
]},
- suitcase: {icon: 'mdi-bag-carry-on', color: 'dark-blue', effect: [
- {name: 'hordeMaxItems', type: 'base', value: 1}
+ suitcase: {icon: 'mdi-bag-carry-on', feature: ['event', 'horde'], color: 'dark-blue', effect: [
+ {name: 'currencyHordeBoneCap', type: 'mult', value: 1.1}
]},
// Summer festival
- tropicalTent: {icon: 'mdi-tent', color: 'green', effect: [
+ tropicalTent: {icon: 'mdi-tent', feature: ['event', 'village'], color: 'green', effect: [
{name: 'villageWorker', type: 'base', value: 3}
]},
- fruitBasket: {icon: 'mdi-basket', color: 'red', effect: [
- {name: 'currencyFarmFruitGain', type: 'mult', value: 1.15}
+ fruitBasket: {icon: 'mdi-basket', feature: ['event', 'farm'], color: 'red', effect: [
+ {name: 'currencyFarmBerryGain', type: 'mult', value: 1.15}
]},
// Night hunt
- massiveGrain: {icon: 'mdi-barley', color: 'pale-yellow', effect: [
+ massiveGrain: {icon: 'mdi-barley', feature: ['event', 'farm'], color: 'pale-yellow', effect: [
{name: 'currencyFarmGrainGain', type: 'mult', value: 1.15}
]},
- enchantedBottle: {icon: 'mdi-flask-round-bottom', color: 'purple', effect: [
+ enchantedBottle: {icon: 'mdi-flask-round-bottom', feature: ['event', 'mining'], color: 'purple', effect: [
{name: 'currencyMiningResinCap', type: 'base', value: 1}
]},
// Snowdown
- moneyGift: {icon: 'mdi-gift', color: 'green', effect: [
+ moneyGift: {icon: 'mdi-gift', feature: ['event', 'village'], color: 'green', effect: [
{name: 'currencyVillageCoinGain', type: 'mult', value: 1.1}
]},
- frozenCarrot: {icon: 'mdi-carrot', color: 'light-blue', effect: [
+ frozenCarrot: {icon: 'mdi-carrot', feature: ['event', 'farm'], color: 'light-blue', effect: [
{name: 'currencyFarmVegetableGain', type: 'mult', value: 1.15}
]},
}
diff --git a/src/js/modules/event/snowdown/prize.js b/src/js/modules/event/snowdown/prize.js
index dbf905f6..39074288 100644
--- a/src/js/modules/event/snowdown/prize.js
+++ b/src/js/modules/event/snowdown/prize.js
@@ -38,7 +38,7 @@ export default {
farm_cinnamonBag: {
type: 'consumable',
item: 'farm_cinnamonBag',
- amount: 5,
+ amount: 20,
requirement() {
return store.state.unlock.farmFertilizer.see;
},
diff --git a/src/js/modules/event/summerFestival/prize.js b/src/js/modules/event/summerFestival/prize.js
index 882879b9..7be11c80 100644
--- a/src/js/modules/event/summerFestival/prize.js
+++ b/src/js/modules/event/summerFestival/prize.js
@@ -38,7 +38,7 @@ export default {
farm_tropicalWater: {
type: 'consumable',
item: 'farm_tropicalWater',
- amount: 5,
+ amount: 20,
requirement() {
return store.state.unlock.farmFertilizer.see;
},
diff --git a/src/js/modules/event/weatherChaos/prize.js b/src/js/modules/event/weatherChaos/prize.js
index c9522bc9..d804ef70 100644
--- a/src/js/modules/event/weatherChaos/prize.js
+++ b/src/js/modules/event/weatherChaos/prize.js
@@ -19,7 +19,7 @@ export default {
type: 'relic',
item: 'suitcase',
requirement() {
- return store.state.unlock.hordeItems.see;
+ return store.state.unlock.hordeHeirlooms.see;
},
pool: {
weatherChaos: {price: {event_weatherChaosToken: 155}}
@@ -35,7 +35,7 @@ export default {
farm_smellyMud: {
type: 'consumable',
item: 'farm_smellyMud',
- amount: 5,
+ amount: 20,
requirement() {
return store.state.unlock.farmFertilizer.see;
},
diff --git a/src/js/modules/event/weatherChaos/tick.js b/src/js/modules/event/weatherChaos/tick.js
index b9a54716..81cc0d97 100644
--- a/src/js/modules/event/weatherChaos/tick.js
+++ b/src/js/modules/event/weatherChaos/tick.js
@@ -16,33 +16,35 @@ export default function(seconds, oldTime, newTime) {
}
function singleTick(seconds) {
- const timeNeeded = store.getters['mult/get']('weatherChaosFishingTime');
- let newTime = store.state.weatherChaos.fishingProgress + seconds;
- let catches = Math.floor(newTime / timeNeeded);
- if (catches > 0) {
- // Catch with bait first
- const currentBait = store.state.weatherChaos.currentBait;
- const bait = currentBait ? store.state.weatherChaos.bait[currentBait] : null;
- if (bait) {
- const baitCatches = Math.min(catches, bait.owned);
- store.dispatch('weatherChaos/getCatch', baitCatches);
- store.commit('weatherChaos/updateSubkey', {name: 'bait', key: currentBait, subkey: 'owned', value: bait.owned - baitCatches});
- newTime -= baitCatches * timeNeeded;
+ if (store.getters['weatherChaos/currentWeather'] !== undefined) {
+ const timeNeeded = store.getters['mult/get']('weatherChaosFishingTime');
+ let newTime = store.state.weatherChaos.fishingProgress + seconds;
+ let catches = Math.floor(newTime / timeNeeded);
+ if (catches > 0) {
+ // Catch with bait first
+ const currentBait = store.state.weatherChaos.currentBait;
+ const bait = currentBait ? store.state.weatherChaos.bait[currentBait] : null;
+ if (bait) {
+ const baitCatches = Math.min(catches, bait.owned);
+ store.dispatch('weatherChaos/getCatch', baitCatches);
+ store.commit('weatherChaos/updateSubkey', {name: 'bait', key: currentBait, subkey: 'owned', value: bait.owned - baitCatches});
+ newTime -= baitCatches * timeNeeded;
- // Unequip bait if none is left
- if (store.state.weatherChaos.bait[currentBait].owned <= 0) {
- store.dispatch('weatherChaos/resetBaitEffects', currentBait);
- store.commit('weatherChaos/updateKey', {key: 'currentBait', value: null});
+ // Unequip bait if none is left
+ if (store.state.weatherChaos.bait[currentBait].owned <= 0) {
+ store.dispatch('weatherChaos/resetBaitEffects', currentBait);
+ store.commit('weatherChaos/updateKey', {key: 'currentBait', value: null});
+ }
}
- }
- // Then catch without bait
- const timeNeededNew = store.getters['mult/get']('weatherChaosFishingTime');
- catches = Math.floor(newTime / timeNeededNew);
- if (catches > 0) {
- store.dispatch('weatherChaos/getCatch', catches);
- newTime -= catches * timeNeededNew;
+ // Then catch without bait
+ const timeNeededNew = store.getters['mult/get']('weatherChaosFishingTime');
+ catches = Math.floor(newTime / timeNeededNew);
+ if (catches > 0) {
+ store.dispatch('weatherChaos/getCatch', catches);
+ newTime -= catches * timeNeededNew;
+ }
}
+ store.commit('weatherChaos/updateKey', {key: 'fishingProgress', value: newTime});
}
- store.commit('weatherChaos/updateKey', {key: 'fishingProgress', value: newTime});
}
diff --git a/src/js/modules/farm.js b/src/js/modules/farm.js
index a1c89b51..c5b2e9cd 100644
--- a/src/js/modules/farm.js
+++ b/src/js/modules/farm.js
@@ -1,4 +1,5 @@
import store from "../../store"
+import { SECONDS_PER_DAY } from "../constants";
import { buildArray } from "../utils/array";
import achievement from "./farm/achievement";
import building from "./farm/building";
@@ -14,8 +15,19 @@ export default {
name: 'farm',
tickspeed: 5,
unlockNeeded: 'farmFeature',
+ forceTick(ticks, oldTime, newTime) {
+ const dayDiff = Math.floor(newTime / SECONDS_PER_DAY) - Math.floor(oldTime / SECONDS_PER_DAY);
+ if (dayDiff > 0) {
+ for (const [key, elem] of Object.entries(store.state.farm.crop)) {
+ if (elem.genes.includes('patient') && elem.patientStacks < 60) {
+ store.commit('farm/updateCropKey', {name: key, key: 'patientStacks', value: Math.min(elem.patientStacks + dayDiff, 60)});
+ }
+ }
+ }
+ },
tick(ticks) {
const decoration = store.state.farm.building.gardenGnome.cacheAmount + store.state.farm.building.gardenGnome.cachePremium;
+ let highestGrow = 0;
store.state.farm.field.forEach((row, y) => {
row.forEach((cell, x) => {
if (cell !== null && cell.type === 'crop') {
@@ -34,6 +46,9 @@ export default {
amt -= given * stageMult;
stage++;
}
+ if (grow > highestGrow) {
+ highestGrow = grow;
+ }
store.commit('farm/updateFieldKey', {x, y, key: 'grow', value: grow});
}
store.commit('farm/updateFieldKey', {x, y, key: 'time', value: cell.time + ticks});
@@ -55,28 +70,35 @@ export default {
}
});
});
+ if (highestGrow > 1) {
+ store.commit('stat/increaseTo', {feature: 'farm', name: 'maxOvergrow', value: highestGrow});
+ }
store.dispatch('farm/updateGrownHint');
},
unlock: ['farmFeature', 'farmDisableEarlyGame', 'farmCropExp', 'farmFertilizer', 'farmAdvancedCardPack', 'farmLuxuryCardPack'],
stat: {
- harvests: {},
- maxOvergrow: {},
- bestPrestige: {},
- totalMystery: {}
+ harvests: {showInStatistics: true},
+ maxOvergrow: {showInStatistics: true},
+ bestPrestige: {showInStatistics: true},
+ totalMystery: {showInStatistics: true}
},
mult: {
farmExperience: {baseValue: 1},
farmGoldChance: {display: 'percent'},
farmGrow: {display: 'time'},
farmOvergrow: {display: 'percent'},
- farmRareDropChance: {display: 'percent'},
+ farmHuntChance: {display: 'percent'},
+ farmRareDropChance: {display: 'percent', group: ['farmHuntChance']},
farmMystery: {},
- farmCropGain: {group: ['currencyFarmVegetableGain', 'currencyFarmFruitGain', 'currencyFarmGrainGain', 'currencyFarmFlowerGain']},
- farmAllGain: {group: ['farmCropGain', 'farmExperience', 'farmGoldChance', 'farmRareDropChance']}
+ farmCropGain: {group: ['currencyFarmVegetableGain', 'currencyFarmBerryGain', 'currencyFarmGrainGain', 'currencyFarmFlowerGain']},
+ farmAllGain: {group: ['farmCropGain', 'farmExperience', 'farmGoldChance', 'farmRareDropChance']},
+ farmCropCost: {},
+ farmFertilizerCost: {},
+ farmLuckyHarvestMult: {display: 'mult', baseValue: 8},
},
currency: {
vegetable: {color: 'orange', icon: 'mdi-carrot', gainMult: {}},
- fruit: {color: 'red', icon: 'mdi-food-apple', gainMult: {}},
+ berry: {color: 'purple', icon: 'mdi-fruit-grapes', gainMult: {}},
grain: {color: 'yellow', icon: 'mdi-barley', gainMult: {}},
flower: {color: 'pink', icon: 'mdi-flower', gainMult: {}},
gold: {color: 'amber', icon: 'mdi-gold'},
@@ -86,7 +108,7 @@ export default {
currencyFarmFlowerGain: {type: 'mult', value: val => val * 0.03 + 1}
}, capMult: {baseValue: 50}},
bug: {color: 'brown', icon: 'mdi-bug', overcapMult: 0, capMult: {baseValue: 50}},
- butterfly: {color: 'pink', icon: 'mdi-butterfly', overcapMult: 0, capMult: {baseValue: 30}},
+ butterfly: {color: 'babypink', icon: 'mdi-butterfly', overcapMult: 0, capMult: {baseValue: 30}},
ladybug: {color: 'pale-red', icon: 'mdi-ladybug', overcapMult: 0, currencyMult: {
farmRareDropChance: {type: 'base', value: val => val * 0.0001}
}, capMult: {baseValue: 150}},
@@ -96,12 +118,13 @@ export default {
currencyFarmLadybugCap: {type: 'base', value: val => val * 5}
}, capMult: {baseValue: 20}},
bee: {color: 'yellow', icon: 'mdi-bee', overcapMult: 0, currencyMult: {
- currencyFarmFruitGain: {type: 'mult', value: val => val * 0.001 + 1}
+ currencyFarmBerryGain: {type: 'mult', value: val => val * 0.001 + 1}
}, capMult: {baseValue: 1000}},
mysteryStone: {color: 'pale-purple', icon: 'mdi-eye-circle-outline', overcapMult: 0, capMult: {baseValue: 1337}},
goldenPetal: {color: 'amber', icon: 'mdi-leaf', overcapMult: 0, currencyMult: {
- currencyFarmPetalCap: {type: 'base', value: val => val * 5}
- }, capMult: {baseValue: 10}}
+ currencyFarmPetalCap: {type: 'base', value: val => val * 25}
+ }, capMult: {baseValue: 10}},
+ smallSeed: {color: 'brown', icon: 'mdi-grain', overcapMult: 0, capMult: {baseValue: 800}},
},
note: buildArray(22).map(() => 'g'),
upgrade: {
@@ -127,6 +150,8 @@ export default {
}
store.commit('farm/initField');
+
+ store.dispatch('mult/setMult', {name: 'farmHuntChance', key: 'farmGene_hunter', value: 0.01});
},
saveGame() {
let obj = {
@@ -134,6 +159,13 @@ export default {
crop: {}
};
+ if (store.state.farm.showColors) {
+ obj.showColors = true;
+ }
+ if (store.state.farm.selectedColor) {
+ obj.selectedColor = store.state.farm.selectedColor;
+ }
+
store.state.farm.field.forEach((row, y) => {
row.forEach((cell, x) => {
if (cell !== null && (cell.type !== null || cell.color !== null)) {
@@ -145,10 +177,10 @@ export default {
});
for (const [key, elem] of Object.entries(store.state.farm.crop)) {
if (elem.found) {
- let rareDrops = [];
+ let rareDrops = {};
elem.rareDrop.forEach((drop, index) => {
if (drop.found) {
- rareDrops.push(index);
+ rareDrops[index] = drop.hunter;
}
});
obj.crop[key] = {
@@ -162,9 +194,12 @@ export default {
cardEquipped: elem.cardEquipped,
upgrades: elem.upgrades
};
- if (rareDrops.length > 0) {
+ if (Object.keys(rareDrops).length > 0) {
obj.crop[key].rareDrop = rareDrops;
}
+ if (elem.patientStacks > 0) {
+ obj.patientStacks = elem.patientStacks;
+ }
}
}
@@ -187,9 +222,12 @@ export default {
store.commit('farm/updateCropKey', {name: key, key: 'level', value: elem.level});
store.commit('farm/updateCropKey', {name: key, key: 'levelMax', value: elem.levelMax});
if (elem.rareDrop) {
- elem.rareDrop.forEach(index => {
- store.commit('farm/findCropRareDrop', {name: key, index});
- });
+ for (const [index, value] of Object.entries(elem.rareDrop)) {
+ if (store.state.farm.crop[key].rareDrop[index] !== undefined) {
+ store.commit('farm/findCropRareDrop', {name: key, index});
+ store.commit('farm/huntCropRareDrop', {name: key, index, value});
+ }
+ }
}
store.commit('farm/updateCropKey', {name: key, key: 'dna', value: elem.dna});
store.commit('farm/updateCropKey', {name: key, key: 'genes', value: elem.genes});
@@ -198,11 +236,22 @@ export default {
store.commit('farm/updateCropKey', {name: key, key: 'cardEquipped', value: elem.cardEquipped});
store.commit('farm/updateCropKey', {name: key, key: 'upgrades', value: elem.upgrades});
+ if (elem.patientStacks !== undefined) {
+ store.commit('farm/updateCropKey', {name: key, key: 'patientStacks', value: elem.patientStacks});
+ }
+
// Apply level ups
store.dispatch('farm/getCropExp', {crop: key, value: 0});
}
}
+ if (data.showColors) {
+ store.commit('farm/updateKey', {key: 'showColors', value: true});
+ }
+ if (data.selectedColor) {
+ store.commit('farm/updateKey', {key: 'selectedColor', value: data.selectedColor});
+ }
store.commit('farm/calculateCropBuildingCaches');
+ store.dispatch('farm/applyGeneEffects');
store.dispatch('farm/applyCropPrestige');
store.dispatch('farm/updateGrownHint');
}
diff --git a/src/js/modules/farm/achievement.js b/src/js/modules/farm/achievement.js
index a2a9739e..790d8004 100644
--- a/src/js/modules/farm/achievement.js
+++ b/src/js/modules/farm/achievement.js
@@ -6,7 +6,7 @@ export default {
maxOvergrow: {value: () => store.state.stat.farm_maxOvergrow.total, display: 'percent', milestones: lvl => getSequence(1, lvl + 1), relic: {2: 'trellis', 4: 'brickWall'}},
bestPrestige: {value: () => store.state.stat.farm_bestPrestige.total, milestones: lvl => lvl * 2 + 4},
vegetable: {value: () => store.state.stat.farm_vegetable.total, milestones: lvl => Math.pow(81, lvl) * 250, relic: {2: 'goldenCarrot'}},
- fruit: {value: () => store.state.stat.farm_fruit.total, milestones: lvl => Math.pow(81, lvl) * 750, relic: {3: 'goldenApple'}},
+ berry: {value: () => store.state.stat.farm_berry.total, milestones: lvl => Math.pow(81, lvl) * 750, relic: {3: 'goldenApple'}},
grain: {value: () => store.state.stat.farm_grain.total, milestones: lvl => Math.pow(81, lvl) * 2250, relic: {4: 'popcorn'}},
flower: {value: () => store.state.stat.farm_flower.total, milestones: lvl => Math.pow(81, lvl) * 6750, relic: {5: 'roseQuartz'}},
gold: {value: () => store.state.stat.farm_gold.total, milestones: lvl => Math.round(Math.pow(lvl + 2, 2) * Math.pow(2.25, lvl) * 2.5), relic: {6: 'goldenSeed'}}
diff --git a/src/js/modules/farm/card.js b/src/js/modules/farm/card.js
index acc2ef90..f86fee84 100644
--- a/src/js/modules/farm/card.js
+++ b/src/js/modules/farm/card.js
@@ -1,7 +1,16 @@
import cardList from "./cardList";
export default {
- feature: {prefix: 'FA', reward: [{name: 'farmCropGain', type: 'mult', value: lvl => lvl * 0.05 + 1}], unlock: 'farmFeature'},
+ feature: {
+ prefix: 'FA',
+ reward: [{name: 'farmCropGain', type: 'mult', value: lvl => lvl * 0.05 + 1}],
+ shinyReward: [{name: 'farmExperience', type: 'mult', value: lvl => lvl * 0.05 + 1}],
+ powerReward: [
+ {name: 'farmCropGain', type: 'mult', value: lvl => Math.pow(1.08, lvl)},
+ {name: 'farmExperience', type: 'base', value: lvl => lvl * 0.08},
+ ],
+ unlock: 'farmFeature'
+ },
collection: {
feedingTheWorld: {reward: [
{name: 'currencyFarmGrainGain', type: 'mult', value: 1.25},
@@ -9,25 +18,25 @@ export default {
]},
organicDyes: {reward: [
{name: 'galleryCardCap', type: 'base', value: 1},
- {name: 'currencyFarmFruitGain', type: 'mult', value: 1.25}
+ {name: 'currencyFarmBerryGain', type: 'mult', value: 1.25}
]},
},
pack: {
- bountifulHarvest: {unlock: 'farmCropExp', amount: 4, price: 35, content: {
+ bountifulHarvest: {unlock: 'farmCropExp', amount: 3, price: 30, content: {
'FA-0001': 1.5, 'FA-0002': 1.5, 'FA-0003': 0.9, 'FA-0004': 1.5, 'FA-0005': 1.5,
'FA-0006': 0.6, 'FA-0007': 0.6, 'FA-0008': 0.6, 'FA-0009': 0.6,
'FA-0010': 0.5, 'FA-0011': 0.2,
}},
- juicyYields: {unlock: 'farmFertilizer', amount: 4, price: 60, content: {
+ juicyYields: {unlock: 'farmFertilizer', amount: 4, price: 80, content: {
'FA-0006': 1.2, 'FA-0007': 1.2, 'FA-0008': 1.2, 'FA-0009': 1.2,
'FA-0010': 1.5, 'FA-0011': 1,
'FA-0012': 0.9, 'FA-0013': 0.6, 'FA-0014': 0.4, 'FA-0015': 0.4, 'FA-0016': 0.4,
}},
- insectWorld: {unlock: 'farmAdvancedCardPack', amount: 2, price: 55, content: {
+ insectWorld: {unlock: 'farmAdvancedCardPack', amount: 2, price: 90, content: {
'FA-0010': 2, 'FA-0011': 1.8,
'FA-0017': 1.4, 'FA-0019': 1.4, 'FA-0020': 1.4, 'FA-0021': 1.2, 'FA-0025': 0.8,
}},
- beesAndFlowers: {unlock: 'farmLuxuryCardPack', amount: 3, price: 100, content: {
+ beesAndFlowers: {unlock: 'farmLuxuryCardPack', amount: 3, price: 200, content: {
'FA-0012': 0.7, 'FA-0013': 0.6, 'FA-0014': 0.4, 'FA-0015': 0.4, 'FA-0016': 0.4,
'FA-0017': 1, 'FA-0018': 0.1,
'FA-0019': 1, 'FA-0020': 1, 'FA-0021': 0.9,
diff --git a/src/js/modules/farm/cardList.js b/src/js/modules/farm/cardList.js
index 2e83a70f..f53cbc1f 100644
--- a/src/js/modules/farm/cardList.js
+++ b/src/js/modules/farm/cardList.js
@@ -1,7 +1,5 @@
export default [
- {id: 1, group: 'fruit', collection: 'plantsInTheCity', reward: [
- {name: 'farmAllGain', type: 'mult', value: 1.15}
- ], color: 'red', icons: [
+ {id: 1, group: 'berry', collection: 'plantsInTheCity', power: 3, color: 'red', icons: [
{"x": -0.4, "y": -0.15, "rotate": 0, "size": 3, "icon": "mdi-tree"},
{"x": -0.37, "y": 0.55, "rotate": 90, "size": 3, "icon": "mdi-minus"},
{"x": -0.65, "y": 0.35, "rotate": 0, "size": 0.6, "icon": "mdi-food-apple"},
@@ -12,9 +10,7 @@ export default [
{"x": 0.75, "y": 0.67, "rotate": 0, "size": 1.6, "icon": "mdi-human-greeting"},
{"x": 0.2, "y": 0.85, "rotate": 0, "size": 1, "icon": "mdi-basket"}
]},
- {id: 2, group: 'vegetable', collection: 'plantsInTheCity', reward: [
- {name: 'farmAllGain', type: 'mult', value: 1.15}
- ], color: 'orange', icons: [
+ {id: 2, group: 'vegetable', collection: 'plantsInTheCity', power: 3, color: 'orange', icons: [
{"x": -0.7, "y": 0.9, "rotate": 0, "size": 2, "icon": "mdi-train-car-flatbed"},
{"x": -0.7, "y": 0.7, "rotate": 0, "size": 1.65, "icon": "mdi-pumpkin"},
{"x": 0.5, "y": 1, "rotate": 0, "size": 1.1, "icon": "mdi-pumpkin"},
@@ -23,8 +19,8 @@ export default [
{"x": 0.8, "y": 0.1, "rotate": 0, "size": 1.3, "icon": "mdi-human-greeting"},
{"x": 0.4, "y": -0.15, "rotate": 20, "size": 0.6, "icon": "mdi-trophy"}
]},
- {id: 3, collection: 'plantsInTheCity', reward: [
- {name: 'farmGoldChance', type: 'mult', value: 1.75}
+ {id: 3, collection: 'plantsInTheCity', power: 2, reward: [
+ {name: 'farmGoldChance', type: 'mult', value: 1.15}
], color: 'pale-purple', icons: [
{"x": -0.75, "y": 0.65, "rotate": 0, "size": 1.5, "icon": "mdi-pot"},
{"x": 0, "y": 0.65, "rotate": 0, "size": 1.5, "icon": "mdi-pot"},
@@ -33,18 +29,14 @@ export default [
{"x": 0.8, "y": 0.68, "rotate": 0, "size": 1.35, "icon": "mdi-watering-can"},
{"x": 0.45, "y": -0.65, "rotate": 0, "size": 2, "icon": "mdi-cash-register"}
]},
- {id: 4, group: 'flower', collection: 'plantsInTheCity', reward: [
- {name: 'farmAllGain', type: 'mult', value: 1.15}
- ], color: 'pale-blue', icons: [
+ {id: 4, group: 'flower', collection: 'plantsInTheCity', power: 3, color: 'pale-blue', icons: [
{"x": 0, "y": 0.25, "rotate": 0, "size": 2, "icon": "mdi-desk"},
{"x": 0, "y": -0.3, "rotate": 0, "size": 1.5, "icon": "mdi-desktop-tower-monitor"},
{"x": -0.9, "y": 0.2, "rotate": 0, "size": 1.5, "icon": "mdi-chair-rolling"},
{"x": 0.95, "y": 0.45, "rotate": 0, "size": 1.25, "icon": "mdi-pot"},
{"x": 0.95, "y": 0.15, "rotate": 0, "size": 1, "icon": "mdi-flower"}
]},
- {id: 5, group: 'grain', collection: 'plantsInTheCity', reward: [
- {name: 'farmAllGain', type: 'mult', value: 1.15}
- ], color: 'pale-yellow', icons: [
+ {id: 5, group: 'grain', collection: 'plantsInTheCity', power: 3, color: 'pale-yellow', icons: [
{"x": 0, "y": 0.3, "rotate": 0, "size": 1, "icon": "mdi-tshirt-crew"},
{"x": 0, "y": -0.15, "rotate": 0, "size": 1, "icon": "mdi-hat-fedora"},
{"x": 0, "y": 0.65, "rotate": 90, "size": 1, "icon": "mdi-minus-thick"},
@@ -55,9 +47,8 @@ export default [
{"x": 0.75, "y": 0.45, "rotate": 0, "size": 1.4, "icon": "mdi-barley"}
]},
- {id: 6, group: 'fruit', collection: 'supplyAndSupport', reward: [
- {name: 'farmCropGain', type: 'mult', value: 1.35},
- {name: 'farmExperience', type: 'mult', value: 1.25}
+ {id: 6, group: 'berry', collection: 'supplyAndSupport', power: 1, reward: [
+ {name: 'farmCropGain', type: 'mult', value: 1.35}
], color: 'light-blue', icons: [
{"x": 0.05, "y": -0.45, "rotate": 45, "size": 2, "icon": "mdi-airplane"},
{"x": -0.2, "y": 0, "rotate": 0, "size": 0.6, "icon": "mdi-water"},
@@ -69,27 +60,24 @@ export default [
{"x": 0, "y": 1, "rotate": 0, "size": 1.5, "icon": "mdi-grass"},
{"x": -0.65, "y": 1.1, "rotate": 0, "size": 1, "icon": "mdi-flower"}
]},
- {id: 7, group: 'vegetable', collection: 'supplyAndSupport', reward: [
- {name: 'farmCropGain', type: 'mult', value: 1.35},
- {name: 'farmExperience', type: 'mult', value: 1.25}
+ {id: 7, group: 'vegetable', collection: 'supplyAndSupport', power: 1, reward: [
+ {name: 'farmCropGain', type: 'mult', value: 1.35}
], color: 'blue-grey', icons: [
{"x": -1.05, "y": 0, "rotate": 0, "size": 1.25, "icon": "mdi-train-car-centerbeam-full"},
{"x": -0.35, "y": 0, "rotate": 0, "size": 1.25, "icon": "mdi-train-car-container"},
{"x": 0.35, "y": 0, "rotate": 0, "size": 1.25, "icon": "mdi-train-car-flatbed-tank"},
{"x": 1.05, "y": 0, "rotate": 0, "size": 1.25, "icon": "mdi-train-car-hopper-full"}
]},
- {id: 8, group: 'grain', collection: 'supplyAndSupport', reward: [
- {name: 'farmCropGain', type: 'mult', value: 1.35},
- {name: 'farmExperience', type: 'mult', value: 1.25}
+ {id: 8, group: 'grain', collection: 'supplyAndSupport', power: 1, reward: [
+ {name: 'farmCropGain', type: 'mult', value: 1.35}
], color: 'beige', icons: [
{"x": -0.6, "y": -0.3, "rotate": 0, "size": 1.5, "icon": "mdi-home-silo"},
{"x": 0.25, "y": -0.3, "rotate": 0, "size": 1.5, "icon": "mdi-silo"},
{"x": 0.15, "y": 0.7, "rotate": 0, "size": 2, "icon": "mdi-car-lifted-pickup"},
{"x": -0.15, "y": 0.5, "rotate": 0, "size": 0.75, "icon": "mdi-land-rows-horizontal"}
]},
- {id: 9, group: 'flower', collection: 'supplyAndSupport', reward: [
- {name: 'farmCropGain', type: 'mult', value: 1.35},
- {name: 'farmExperience', type: 'mult', value: 1.25}
+ {id: 9, group: 'flower', collection: 'supplyAndSupport', power: 1, reward: [
+ {name: 'farmCropGain', type: 'mult', value: 1.35}
], color: 'deep-orange', icons: [
{"x": 0, "y": 0, "rotate": 0, "size": 4.5, "icon": "mdi-hoop-house"},
{"x": 0, "y": 0.6, "rotate": 0, "size": 0.75, "icon": "mdi-radiator"},
@@ -98,16 +86,16 @@ export default [
{"x": 0.65, "y": 0.6, "rotate": 0, "size": 0.75, "icon": "mdi-flower"}
]},
- {id: 10, collection: 'feedingTheWorld', reward: [
- {name: 'farmCropGain', type: 'mult', value: 1.4}
+ {id: 10, collection: 'feedingTheWorld', power: 2, reward: [
+ {name: 'farmCropGain', type: 'mult', value: 1.1}
], color: 'lime', icons: [
{"x": 0.2, "y": 0, "rotate": 0, "size": 2.25, "icon": "mdi-blender"},
{"x": 0.95, "y": 0.23, "rotate": 0, "size": 1.3, "icon": "mdi-beer"},
{"x": -0.85, "y": 0.32, "rotate": 0, "size": 1, "icon": "mdi-food-apple"},
{"x": -0.5, "y": 0.32, "rotate": 0, "size": 1, "icon": "mdi-fruit-pear"}
]},
- {id: 11, collection: 'feedingTheWorld', reward: [
- {name: 'farm_gold', type: 'addRareDrop', value: 10}
+ {id: 11, collection: 'feedingTheWorld', power: 0, reward: [
+ {name: 'farmGoldChance', type: 'mult', value: 1.25}
], color: 'pale-pink', icons: [
{"x": -0.5, "y": 0.6, "rotate": 0, "size": 3, "icon": "mdi-minus"},
{"x": 0.5, "y": 0.6, "rotate": 0, "size": 3, "icon": "mdi-minus"},
@@ -120,24 +108,24 @@ export default [
{"x": -0.15, "y": -0.5, "rotate": 0, "size": 1, "icon": "mdi-cupcake"},
{"x": 0.45, "y": -0.5, "rotate": 0, "size": 1, "icon": "mdi-muffin"}
]},
- {id: 12, collection: 'feedingTheWorld', reward: [
- {name: 'farmExperience', type: 'base', value: 0.3}
+ {id: 12, collection: 'feedingTheWorld', power: 3, reward: [
+ {name: 'farmExperience', type: 'base', value: 0.2}
], color: 'pale-blue', icons: [
{"x": 0, "y": 0.25, "rotate": 0, "size": 2, "icon": "mdi-truck"},
{"x": -0.12, "y": -0.4, "rotate": 0, "size": 1.25, "icon": "mdi-ice-cream"},
{"x": 0.85, "y": 0.7, "rotate": 0, "size": 1, "icon": "mdi-human-handsdown"},
{"x": -0.7, "y": 0.9, "rotate": 0, "size": 0.7, "icon": "mdi-human-child"}
]},
- {id: 13, collection: 'feedingTheWorld', reward: [
- {name: 'farmRareDropChance', type: 'mult', value: 1.2}
+ {id: 13, collection: 'feedingTheWorld', power: 3, reward: [
+ {name: 'farmRareDropChance', type: 'mult', value: 1.1}
], color: 'orange', icons: [
{"x": -0.3, "y": 0.2, "rotate": 0, "size": 2, "icon": "mdi-tray"},
{"x": 0.55, "y": 0.35, "rotate": 0, "size": 2, "icon": "mdi-human-handsdown"},
{"x": -0.45, "y": 0.2, "rotate": 0, "size": 0.75, "icon": "mdi-food"},
{"x": -0.1, "y": 0.25, "rotate": 0, "size": 0.7, "icon": "mdi-french-fries"}
]},
- {id: 14, collection: 'feedingTheWorld', reward: [
- {name: 'farm_grass', type: 'addRareDrop', value: 10}
+ {id: 14, collection: 'feedingTheWorld', power: 3, reward: [
+ {name: 'farm_grass', type: 'addRareDrop', value: 4, chance: 0.2, mult: 0.4}
], color: 'brown', icons: [
{"x": 0, "y": 0.5, "rotate": 0, "size": 3, "icon": "mdi-table-furniture"},
{"x": 0, "y": -0.05, "rotate": 0, "size": 1, "icon": "mdi-food-turkey"},
@@ -146,9 +134,9 @@ export default [
{"x": 0.4, "y": -0.05, "rotate": -10, "size": 0.65, "icon": "mdi-carrot"},
{"x": 0.55, "y": -0.1, "rotate": 15, "size": 0.65, "icon": "mdi-carrot"}
]},
- {id: 15, collection: 'feedingTheWorld', reward: [
- {name: 'farmCropGain', type: 'mult', value: 1.25},
- {name: 'farmGoldChance', type: 'mult', value: 1.5}
+ {id: 15, collection: 'feedingTheWorld', power: 3, reward: [
+ {name: 'farmCropGain', type: 'mult', value: 1.1},
+ {name: 'farmGoldChance', type: 'mult', value: 1.1}
], color: 'light-blue', icons: [
{"x": 0, "y": 0.4, "rotate": 0, "size": 1.7, "icon": "mdi-human-handsup"},
{"x": -0.3, "y": -0.05, "rotate": 0, "size": 0.85, "icon": "mdi-candy"},
@@ -159,9 +147,9 @@ export default [
{"x": 0.25, "y": -0.2, "rotate": 0, "size": 0.7, "icon": "mdi-ice-pop"},
{"x": -0.85, "y": -0.2, "rotate": 0, "size": 0.8, "icon": "mdi-ice-cream"}
]},
- {id: 16, collection: 'feedingTheWorld', reward: [
- {name: 'farmRareDropChance', type: 'mult', value: 1.15},
- {name: 'farmExperience', type: 'base', value: 0.2}
+ {id: 16, collection: 'feedingTheWorld', power: 3, reward: [
+ {name: 'farmRareDropChance', type: 'mult', value: 1.05},
+ {name: 'farmExperience', type: 'base', value: 0.1}
], color: 'light-green', icons: [
{"x": -0.9, "y": 0.3, "rotate": 0, "size": 1, "icon": "mdi-coffee"},
{"x": -0.4, "y": 0.3, "rotate": 0, "size": 1, "icon": "mdi-coffee"},
@@ -169,8 +157,8 @@ export default [
{"x": 0.3, "y": 0.22, "rotate": 0, "size": 1.2, "icon": "mdi-kettle-steam"},
{"x": 0.95, "y": 0.3, "rotate": 0, "size": 1, "icon": "mdi-tea"}
]},
- {id: 17, group: 'flower', collection: 'feedingTheWorld', reward: [
- {name: 'farm_petal', type: 'addRareDrop', value: 5}
+ {id: 17, group: 'flower', collection: 'feedingTheWorld', power: 4, reward: [
+ {name: 'farm_petal', type: 'addRareDrop', value: 2, chance: 0.1, mult: 0.1}
], color: 'cherry', icons: [
{"x": -0.6, "y": 0.15, "rotate": 0, "size": 2, "icon": "mdi-bowl"},
{"x": -0.4, "y": 0.05, "rotate": 60, "size": 1, "icon": "mdi-fruit-grapes"},
@@ -181,18 +169,18 @@ export default [
{"x": 0.75, "y": 0.3, "rotate": 0, "size": 1.25, "icon": "mdi-bottle-wine"},
{"x": 1.1, "y": 0.37, "rotate": 0, "size": 1, "icon": "mdi-glass-wine"}
]},
- {id: 18, collection: 'feedingTheWorld', reward: [
- {name: 'farm_petal', type: 'addRareDrop', value: 3},
- {name: 'farm_seedHull', type: 'addRareDrop', value: 4},
- {name: 'farm_bug', type: 'addRareDrop', value: 2}
+ {id: 18, collection: 'feedingTheWorld', power: 0, reward: [
+ {name: 'farm_petal', type: 'addRareDrop', value: 2, chance: -0.05, mult: 0.02},
+ {name: 'farm_seedHull', type: 'addRareDrop', value: 3, chance: -0.05, mult: 0.02},
+ {name: 'farm_bug', type: 'addRareDrop', value: 1, chance: -0.05, mult: 0.02}
], color: 'wooden', icons: [
{"x": -0.55, "y": 0, "rotate": 0, "size": 2, "icon": "mdi-coffee-maker"},
{"x": 0.6, "y": 0.2, "rotate": 0, "size": 1.25, "icon": "mdi-coffee"},
{"x": 0.65, "y": -0.2, "rotate": 65, "size": 1, "icon": "mdi-cookie"}
]},
- {id: 19, group: 'grain', collection: 'organicDyes', reward: [
- {name: 'farm_seedHull', type: 'addRareDrop', value: 8}
+ {id: 19, group: 'grain', collection: 'organicDyes', power: 3, reward: [
+ {name: 'farm_seedHull', type: 'addRareDrop', value: 6, chance: 0.15, mult: 0.1}
], color: 'amber', icons: [
{"x": -0.6, "y": 0.75, "rotate": 0, "size": 1, "icon": "mdi-carrot"},
{"x": -0.35, "y": 0.75, "rotate": 0, "size": 1, "icon": "mdi-carrot"},
@@ -200,8 +188,8 @@ export default [
{"x": 0.2, "y": -0.05, "rotate": 0, "size": 1.8, "icon": "mdi-pumpkin"},
{"x": -0.1, "y": -0.65, "rotate": 0, "size": 1.4, "icon": "mdi-circular-saw"}
]},
- {id: 20, group: 'vegetable', collection: 'organicDyes', reward: [
- {name: 'farm_bug', type: 'addRareDrop', value: 4}
+ {id: 20, group: 'vegetable', collection: 'organicDyes', power: 3, reward: [
+ {name: 'farm_bug', type: 'addRareDrop', value: 2, chance: 0.1, mult: 0.1}
], color: 'orange-red', icons: [
{"x": 0, "y": 0, "rotate": 0, "size": 4, "icon": "mdi-tray"},
{"x": -0.45, "y": 0.25, "rotate": 0, "size": 1, "icon": "mdi-fruit-cherries"},
@@ -210,8 +198,8 @@ export default [
{"x": 0.3, "y": -0.1, "rotate": 35, "size": 1, "icon": "mdi-chili-hot"},
{"x": -0.25, "y": -0.15, "rotate": -70, "size": 1, "icon": "mdi-chili-medium"}
]},
- {id: 21, group: 'fruit', collection: 'organicDyes', reward: [
- {name: 'farm_butterfly', type: 'addRareDrop', value: 2}
+ {id: 21, group: 'berry', collection: 'organicDyes', power: 3, reward: [
+ {name: 'farm_butterfly', type: 'addRareDrop', value: 1, chance: 0, mult: 0.1}
], color: 'pale-yellow', icons: [
{"x": -0.7, "y": 0, "rotate": 0, "size": 1.25, "icon": "mdi-flower"},
{"x": 0.7, "y": 0, "rotate": 0, "size": 1.25, "icon": "mdi-flower"},
@@ -220,10 +208,7 @@ export default [
{"x": 0.2, "y": 0.5, "rotate": 0, "size": 1, "icon": "mdi-grain"},
{"x": 0, "y": 0.45, "rotate": 0, "size": 2.25, "icon": "mdi-tray"}
]},
- {id: 22, collection: 'organicDyes', reward: [
- {name: 'farmGoldChance', type: 'mult', value: 1.5},
- {name: 'farmExperience', type: 'base', value: 0.2}
- ], color: 'light-green', icons: [
+ {id: 22, collection: 'organicDyes', power: 6, color: 'light-green', icons: [
{"x": -0.9, "y": 0.4, "rotate": 0, "size": 1.25, "icon": "mdi-grass"},
{"x": -0.3, "y": 0.4, "rotate": 0, "size": 1.25, "icon": "mdi-grass"},
{"x": 0.3, "y": 0.4, "rotate": 0, "size": 1.25, "icon": "mdi-grass"},
@@ -234,7 +219,7 @@ export default [
{"x": -0.55, "y": -0.15, "rotate": -30, "size": 0.8, "icon": "mdi-leaf"},
{"x": 0.65, "y": 0.1, "rotate": 50, "size": 0.9, "icon": "mdi-leaf"}
]},
- {id: 23, collection: 'organicDyes', reward: [
+ {id: 23, collection: 'organicDyes', power: 4, reward: [
{name: 'farmOvergrow', type: 'base', value: 1.75}
], color: 'dark-blue', icons: [
{"x": -0.4, "y": 0.2, "rotate": 0, "size": 2, "icon": "mdi-image-filter-drama"},
@@ -244,9 +229,8 @@ export default [
{"x": 1.05, "y": 0.3, "rotate": 0, "size": 0.7, "icon": "mdi-fruit-grapes"},
{"x": 0.45, "y": 0.3, "rotate": 0, "size": 0.7, "icon": "mdi-basket"}
]},
- {id: 24, collection: 'organicDyes', reward: [
- {name: 'farmAllGain', type: 'mult', value: 1.12},
- {name: 'farmOvergrow', type: 'base', value: 0.5}
+ {id: 24, collection: 'organicDyes', power: 5, reward: [
+ {name: 'farmOvergrow', type: 'base', value: 0.6}
], color: 'purple', icons: [
{"x": -0.7, "y": 0, "rotate": 0, "size": 3, "icon": "mdi-tree"},
{"x": 0.6, "y": -0.4, "rotate": 0, "size": 2.5, "icon": "mdi-pine-tree"},
@@ -256,16 +240,16 @@ export default [
{"x": 0.5, "y": 0.45, "rotate": 0, "size": 0.8, "icon": "mdi-mushroom"},
{"x": 0, "y": 0.25, "rotate": 0, "size": 0.7, "icon": "mdi-mushroom"}
]},
- {id: 25, collection: 'organicDyes', reward: [
- {name: 'farm_ladybug', type: 'addRareDrop', value: 2}
+ {id: 25, collection: 'organicDyes', power: 3, reward: [
+ {name: 'farm_ladybug', type: 'addRareDrop', value: 4, chance: -0.05, mult: 0.1}
], color: 'brown', icons: [
{"x": 0, "y": 0.1, "rotate": 0, "size": 2, "icon": "mdi-bowl-mix"},
{"x": -0.25, "y": 0, "rotate": -15, "size": 0.7, "icon": "mdi-bug"},
{"x": 0.3, "y": 0.1, "rotate": 70, "size": 0.7, "icon": "mdi-bug"},
{"x": 0.05, "y": 0.05, "rotate": 0, "size": 0.7, "icon": "mdi-ladybug"}
]},
- {id: 26, collection: 'organicDyes', reward: [
- {name: 'farm_spider', type: 'addRareDrop', value: 1}
+ {id: 26, collection: 'organicDyes', power: 0, reward: [
+ {name: 'farm_spider', type: 'addRareDrop', value: 1, chance: -0.15, mult: 0.05}
], color: 'lime', icons: [
{"x": 0.4, "y": 0, "rotate": -5, "size": 1.5, "icon": "mdi-fruit-pineapple"},
{"x": 0.9, "y": 0, "rotate": 15, "size": 1.5, "icon": "mdi-fruit-pineapple"},
@@ -273,8 +257,8 @@ export default [
{"x": -0.55, "y": 0.1, "rotate": 45, "size": 1.2, "icon": "mdi-corn"},
{"x": -0.2, "y": -0.35, "rotate": 0, "size": 1, "icon": "mdi-fruit-citrus"}
]},
- {id: 27, collection: 'organicDyes', reward: [
- {name: 'farm_bee', type: 'addRareDrop', value: 15}
+ {id: 27, collection: 'organicDyes', power: 5, reward: [
+ {name: 'farm_bee', type: 'addRareDrop', value: 10, chance: -0.15, mult: 0.1}
], color: 'pink', icons: [
{"x": 0.55, "y": -0.55, "rotate": 0, "size": 1.5, "icon": "mdi-bee-flower"},
{"x": 0, "y": 1, "rotate": 0, "size": 1.4, "icon": "mdi-flower"},
diff --git a/src/js/modules/farm/crop.js b/src/js/modules/farm/crop.js
index 439ea70e..1c0f8c70 100644
--- a/src/js/modules/farm/crop.js
+++ b/src/js/modules/farm/crop.js
@@ -1,4 +1,5 @@
import { MINUTES_PER_HOUR } from "../../constants";
+import { buildNum } from "../../utils/format";
export default {
carrot: {
@@ -6,6 +7,7 @@ export default {
icon: 'mdi-carrot',
color: 'orange',
grow: MINUTES_PER_HOUR,
+ yield: 40,
tier: 0,
type: 'vegetable'
},
@@ -13,13 +15,15 @@ export default {
icon: 'mdi-fruit-grapes',
color: 'blue',
grow: 2 * MINUTES_PER_HOUR,
+ yield: 70,
tier: 1,
- type: 'fruit'
+ type: 'berry'
},
wheat: {
icon: 'mdi-barley',
color: 'yellow',
grow: 4 * MINUTES_PER_HOUR,
+ yield: 120,
tier: 2,
type: 'grain'
},
@@ -27,16 +31,18 @@ export default {
icon: 'mdi-flower-tulip',
color: 'red',
grow: 8 * MINUTES_PER_HOUR,
+ yield: 200,
tier: 3,
type: 'flower'
},
potato: {
icon: 'mdi-circle',
color: 'brown',
- cost: 1,
+ cost: {farm_gold: 1},
grow: 20 * MINUTES_PER_HOUR,
+ yield: 640,
rareDrop: [
- {name: 'farm_potatoWater', type: 'consumable', chance: 0.15, value: 5}
+ {name: 'farm_potatoWater', type: 'consumable', chance: 0.15, value: 3}
],
tier: 4,
type: 'vegetable'
@@ -44,20 +50,22 @@ export default {
raspberry: {
icon: 'mdi-fruit-grapes',
color: 'pink',
- cost: 1,
+ cost: {farm_gold: 1},
grow: 6 * MINUTES_PER_HOUR,
+ yield: 300,
rareDrop: [
- {name: 'farm_seedHull', type: 'currency', chance: 0.35, value: 3}
+ {name: 'farm_seedHull', type: 'currency', chance: 0.2, value: 6}
],
tier: 5,
- type: 'fruit'
+ type: 'berry'
},
barley: {
icon: 'mdi-barley',
color: 'amber',
grow: 10 * MINUTES_PER_HOUR,
+ yield: 230,
rareDrop: [
- {name: 'farm_seedHull', type: 'currency', chance: 0.08, value: 1}
+ {name: 'farm_seedHull', type: 'currency', chance: 0.06, value: 1}
],
tier: 6,
type: 'grain'
@@ -65,10 +73,11 @@ export default {
dandelion: {
icon: 'mdi-flower',
color: 'pale-yellow',
- cost: 1,
+ cost: {farm_gold: 1},
grow: 1 * MINUTES_PER_HOUR + 30,
+ yield: 160,
rareDrop: [
- {name: 'farm_petal', type: 'currency', chance: 0.24, value: 1}
+ {name: 'farm_petal', type: 'currency', chance: 0.15, value: 2}
],
tier: 7,
type: 'flower'
@@ -76,9 +85,11 @@ export default {
corn: {
icon: 'mdi-corn',
color: 'amber',
+ cost: {farm_grass: 10},
grow: 30 * MINUTES_PER_HOUR,
+ yield: 550,
rareDrop: [
- {name: 'farm_bug', type: 'currency', chance: 0.05, value: 2}
+ {name: 'farm_bug', type: 'currency', chance: 0.02, value: 2}
],
tier: 8,
type: 'vegetable'
@@ -86,23 +97,25 @@ export default {
watermelon: {
icon: 'mdi-fruit-watermelon',
color: 'red',
- cost: 4,
+ cost: {farm_gold: 4},
grow: 12 * MINUTES_PER_HOUR,
+ yield: 1100,
rareDrop: [
- {name: 'farm_bug', type: 'currency', chance: 0.16, value: 5},
- {name: 'farm_butterfly', type: 'currency', chance: 0.18, value: 1}
+ {name: 'farm_bug', type: 'currency', chance: 0.1, value: 10},
+ {name: 'farm_butterfly', type: 'currency', chance: -0.02, value: 2}
],
tier: 9,
- type: 'fruit'
+ type: 'berry'
},
rice: {
icon: 'mdi-rice',
color: 'light-grey',
- cost: 2,
+ cost: {farm_gold: 2},
grow: 24 * MINUTES_PER_HOUR,
+ yield: 1200,
rareDrop: [
- {name: 'farm_seedHull', type: 'currency', chance: 0.22, value: 7},
- {name: 'farm_ladybug', type: 'currency', chance: 0.4, value: 2}
+ {name: 'farm_seedHull', type: 'currency', chance: 0.05, value: 12},
+ {name: 'farm_ladybug', type: 'currency', chance: -0.05, value: 4}
],
tier: 10,
type: 'grain'
@@ -110,12 +123,13 @@ export default {
rose: {
icon: 'mdi-flower',
color: 'red',
- cost: 10,
+ cost: {farm_gold: 10},
grow: 48 * MINUTES_PER_HOUR,
+ yield: 4500,
rareDrop: [
- {name: 'farm_petal', type: 'currency', chance: 0.16, value: 8},
- {name: 'farm_ladybug', type: 'currency', chance: 0.65, value: 5},
- {name: 'farm_roseWater', type: 'consumable', chance: 0.1, value: 10}
+ {name: 'farm_petal', type: 'currency', chance: 0, value: 12},
+ {name: 'farm_ladybug', type: 'currency', chance: -0.08, value: 10},
+ {name: 'farm_roseWater', type: 'consumable', chance: -0.12, value: 8}
],
tier: 11,
type: 'flower'
@@ -123,11 +137,12 @@ export default {
leek: {
icon: 'mdi-leek',
color: 'light-green',
- cost: 5,
+ cost: {farm_gold: 5},
grow: 3 * MINUTES_PER_HOUR,
+ yield: 780,
rareDrop: [
- {name: 'farm_bug', type: 'currency', chance: 0.225, value: 1},
- {name: 'farm_ladybug', type: 'currency', chance: 0.2, value: 1}
+ {name: 'farm_bug', type: 'currency', chance: -0.1, value: 3},
+ {name: 'farm_ladybug', type: 'currency', chance: -0.15, value: 3}
],
tier: 12,
type: 'vegetable'
@@ -136,21 +151,23 @@ export default {
icon: 'mdi-fruit-watermelon',
color: 'amber',
grow: 42 * MINUTES_PER_HOUR,
+ yield: 800,
rareDrop: [
- {name: 'farm_butterfly', type: 'currency', chance: 0.06, value: 1},
- {name: 'farm_spider', type: 'currency', chance: -0.08, value: 1}
+ {name: 'farm_butterfly', type: 'currency', chance: -0.12, value: 2},
+ {name: 'farm_spider', type: 'currency', chance: -0.3, value: 1, mult: 0.5}
],
tier: 13,
- type: 'fruit'
+ type: 'berry'
},
rye: {
icon: 'mdi-barley',
color: 'pale-orange',
- cost: 3,
+ cost: {farm_gold: 3},
grow: 7 * MINUTES_PER_HOUR,
+ yield: 875,
rareDrop: [
- {name: 'farm_seedHull', type: 'currency', chance: 0.19, value: 12},
- {name: 'farm_spider', type: 'currency', chance: -0.02, value: 1}
+ {name: 'farm_seedHull', type: 'currency', chance: -0.16, value: 20},
+ {name: 'farm_spider', type: 'currency', chance: -0.25, value: 1, mult: 0.5}
],
tier: 14,
type: 'grain'
@@ -158,12 +175,13 @@ export default {
daisy: {
icon: 'mdi-flower',
color: 'yellow',
- cost: 8,
+ cost: {farm_gold: 8},
grow: 14 * MINUTES_PER_HOUR,
+ yield: 2350,
rareDrop: [
- {name: 'farm_petal', type: 'currency', chance: 0.13, value: 6},
- {name: 'farm_butterfly', type: 'currency', chance: 0.14, value: 5},
- {name: 'farm_bee', type: 'currency', chance: 0.5, value: 1}
+ {name: 'farm_petal', type: 'currency', chance: -0.18, value: 12},
+ {name: 'farm_butterfly', type: 'currency', chance: -0.21, value: 10},
+ {name: 'farm_bee', type: 'currency', chance: -0.25, value: 10}
],
tier: 15,
type: 'flower'
@@ -171,10 +189,11 @@ export default {
cucumber: {
icon: 'mdi-ruler',
color: 'pale-green',
- cost: 6,
+ cost: {farm_gold: 6},
grow: 2 * MINUTES_PER_HOUR + 30,
+ yield: 1000,
rareDrop: [
- {name: 'farm_bug', type: 'currency', chance: 0.33, value: 1}
+ {name: 'farm_bug', type: 'currency', chance: -0.24, value: 4}
],
tier: 16,
type: 'vegetable'
@@ -182,23 +201,24 @@ export default {
grapes: {
icon: 'mdi-fruit-grapes',
color: 'purple',
- cost: 9,
+ cost: {farm_gold: 9},
grow: 5 * MINUTES_PER_HOUR,
+ yield: 1700,
rareDrop: [
- {name: 'farm_ladybug', type: 'currency', chance: 0.25, value: 3},
- {name: 'farm_bee', type: 'currency', chance: 0.2, value: 1}
+ {name: 'farm_ladybug', type: 'currency', chance: -0.23, value: 7},
+ {name: 'farm_bee', type: 'currency', chance: -0.28, value: 10}
],
tier: 17,
- type: 'fruit'
+ type: 'berry'
},
hops: {
icon: 'mdi-hops',
color: 'green',
- cost: 5,
+ cost: {farm_gold: 5},
grow: 1 * MINUTES_PER_HOUR + 15,
+ yield: 550,
rareDrop: [
- {name: 'farm_bee', type: 'currency', chance: 0.12, value: 1},
- {name: 'farm_spider', type: 'currency', chance: -0.01, value: 1}
+ {name: 'farm_spider', type: 'currency', chance: -0.32, value: 1, mult: 0.5}
],
tier: 18,
type: 'grain'
@@ -206,10 +226,12 @@ export default {
violet: {
icon: 'mdi-flower',
color: 'deep-purple',
+ cost: {farm_petal: 5},
grow: 36 * MINUTES_PER_HOUR,
+ yield: 970,
rareDrop: [
- {name: 'farm_petal', type: 'currency', chance: 0.08, value: 1},
- {name: 'farm_bee', type: 'currency', chance: 0.01, value: 1}
+ {name: 'farm_petal', type: 'currency', chance: -0.3, value: 3},
+ {name: 'farm_bee', type: 'currency', chance: -0.33, value: 3}
],
tier: 19,
type: 'flower'
@@ -217,14 +239,78 @@ export default {
goldenRose: {
icon: 'mdi-flower',
color: 'amber',
- cost: 100,
+ cost: {farm_gold: 100},
grow: 168 * MINUTES_PER_HOUR,
+ yield: buildNum(64, 'K'),
rareDrop: [
- {name: 'farm_petal', type: 'currency', chance: 0.55, value: 10},
- {name: 'farm_goldenPetal', type: 'currency', chance: 0.225, value: 1},
- {name: 'farm_roseWater', type: 'consumable', chance: 0.1, value: 100}
+ {name: 'farm_petal', type: 'currency', chance: -0.1, value: 30},
+ {name: 'farm_goldenPetal', type: 'currency', chance: -0.4, value: 1, mult: 0.05},
+ {name: 'farm_roseWater', type: 'consumable', chance: -0.45, value: 100}
],
tier: 20,
type: 'flower'
},
+ sweetPotato: {
+ icon: 'mdi-circle',
+ color: 'beige',
+ cost: {farm_gold: 8},
+ grow: 11 * MINUTES_PER_HOUR + 30,
+ yield: 3300,
+ rareDrop: [
+ {name: 'farm_bug', type: 'currency', chance: -0.36, value: 8}
+ ],
+ tier: 20,
+ type: 'vegetable'
+ },
+ strawberry: {
+ icon: 'mdi-fruit-grapes',
+ color: 'red',
+ cost: {farm_butterfly: 1},
+ grow: 27 * MINUTES_PER_HOUR,
+ yield: 875,
+ rareDrop: [
+ {name: 'farm_ladybug', type: 'currency', chance: -0.4, value: 8},
+ {name: 'farm_bee', type: 'currency', chance: -0.45, value: 5}
+ ],
+ tier: 21,
+ type: 'berry'
+ },
+ sesame: {
+ icon: 'mdi-grain',
+ color: 'pale-orange',
+ cost: {farm_gold: 5, farm_seedHull: 25},
+ grow: 4 * MINUTES_PER_HOUR + 30,
+ yield: 1500,
+ rareDrop: [
+ {name: 'farm_smallSeed', type: 'currency', chance: -0.48, value: 3},
+ {name: 'farm_spider', type: 'currency', chance: -0.51, value: 1, mult: 0.5}
+ ],
+ tier: 22,
+ type: 'grain'
+ },
+ sunflower: {
+ icon: 'mdi-flower-outline',
+ color: 'brown',
+ cost: {farm_gold: 14},
+ grow: 28 * MINUTES_PER_HOUR,
+ yield: 8300,
+ rareDrop: [
+ {name: 'farm_smallSeed', type: 'currency', chance: -0.5, value: 15},
+ {name: 'farm_petal', type: 'currency', chance: -0.53, value: 4}
+ ],
+ tier: 23,
+ type: 'flower'
+ },
+ spinach: {
+ icon: 'mdi-flower-poppy',
+ color: 'green',
+ cost: {farm_gold: 3, farm_grass: 100},
+ grow: 5 * MINUTES_PER_HOUR + 45,
+ yield: 1425,
+ rareDrop: [
+ {name: 'farm_bug', type: 'currency', chance: -0.55, value: 3}
+ ],
+ tier: 24,
+ type: 'vegetable'
+ },
}
diff --git a/src/js/modules/farm/fertilizer.js b/src/js/modules/farm/fertilizer.js
index 28127ecf..7dd637df 100644
--- a/src/js/modules/farm/fertilizer.js
+++ b/src/js/modules/farm/fertilizer.js
@@ -1,104 +1,140 @@
export default {
+ // Unlocked from the beginning
basic: {
found: true,
type: 'all',
color: 'brown',
price: {farm_gold: 1},
- effect: {farmCropGain: 1.25, farmGrow: 1 / 1.25}
+ effect: {farmCropGain: 1.35}
},
flower: {
found: true,
type: 'flower',
color: 'pink',
price: {farm_gold: 3},
- effect: {farmGrow: 1 / 3}
+ effect: {farmCropGain: 1.5, farmGrow: 1 / 1.2}
},
speedGrow: {
found: true,
type: 'all',
color: 'blue',
price: {gem_sapphire: 1},
- effect: {farmGrow: 1 / 4}
+ effect: {farmGrow: 1 / 1.5}
},
richSoil: {
found: true,
type: 'all',
color: 'green',
price: {gem_sapphire: 1},
- effect: {farmCropGain: 1.5, farmGrow: 1 / 2}
+ effect: {farmCropGain: 2}
},
shiny: {
found: true,
type: 'all',
color: 'amber',
price: {gem_sapphire: 1},
- effect: {farmGoldChance: 2.5, farmRareDropChance: 1.35, farmGrow: 1 / 2}
+ effect: {farmGoldChance: 1.4, farmRareDropChance: 1.6}
},
juicy: {
found: true,
type: 'all',
color: 'lime',
- price: {farm_grass: 5},
- effect: {farmRareDropChance: 1.25}
+ price: {farm_grass: 16},
+ effect: {farmCropGain: 1.25, farmRareDropChance: 1.25}
},
+ dissolving: {
+ found: true,
+ type: 'all',
+ icon: 'mdi-test-tube',
+ color: 'cyan',
+ price: {farm_grass: 22},
+ effect: {farmExperience: 1.4, farmCropGain: 0, farmRareDropChance: 0, farmGoldChance: 0}
+ },
+
+ // Crop-specific
potatoWater: {
type: 'vegetable',
color: 'indigo',
- effect: {farmCropGain: 1.2}
+ effect: {farmCropGain: 1.65}
},
roseWater: {
type: 'flower',
color: 'red-pink',
- effect: {farmCropGain: 1.15, farmGoldChance: 1.4}
+ effect: {farmCropGain: 1.4, farmGoldChance: 1.3}
},
+
+ // Unlocked with upgrade
weedKiller: {
type: 'grain',
color: 'beige',
price: {farm_gold: 4},
- effect: {farmCropGain: 1.8, farmGrow: 1 / 1.75, farmRareDropChance: 1 / 1.25}
+ effect: {farmCropGain: 1.8, farmGrow: 1 / 1.2, farmRareDropChance: 1 / 1.5}
},
turboGrow: {
type: 'all',
color: 'red',
price: {gem_sapphire: 1},
- effect: {farmGrow: 1 / 10, farmCropGain: 0.5, farmGoldChance: 0.5, farmRareDropChance: 0.5, farmExperience: 0.5}
+ effect: {farmGrow: 1 / 2, farmCropGain: 1 / 1.15, farmGoldChance: 1 / 1.15, farmRareDropChance: 1 / 1.15, farmExperience: 1 / 1.75}
},
premium: {
type: 'all',
color: 'purple',
price: {gem_sapphire: 2},
- effect: {farmCropGain: 1.6, farmGrow: 1 / 3, farmGoldChance: 1.8, farmRareDropChance: 1.4}
+ effect: {farmCropGain: 1.75, farmGrow: 1 / 1.25, farmGoldChance: 1.4, farmRareDropChance: 1.4}
+ },
+
+ // Unlocked with second upgrade
+ analyzing: {
+ type: 'all',
+ color: 'blue',
+ price: {gem_sapphire: 5},
+ effect: {farmExperience: 1.35}
},
+ superJuicy: {
+ type: 'fruit',
+ color: 'orange-red',
+ price: {gem_sapphire: 3},
+ effect: {farmCropGain: 2.5, farmRareDropChance: 1.6}
+ },
+ pellets: {
+ type: 'vegetable',
+ icon: 'mdi-pill',
+ color: 'beige',
+ price: {farm_smallSeed: 20},
+ effect: {farmGoldChance: 1.25, farmRareDropChance: 1.25, farmExperience: 1.15}
+ },
+
+ // Event-exclusive
sunshine: {
type: 'all',
color: 'yellow',
- effect: {farmGrow: 1 / 2, farmGoldChance: 4, farmRareDropChance: 1.4}
+ effect: {farmGrow: 1 / 1.5, farmGoldChance: 2, farmRareDropChance: 1.4}
},
superFlower: {
type: 'flower',
color: 'orange-red',
- effect: {farmGrow: 1 / 2.5, farmCropGain: 2.25, farmGoldChance: 2}
+ effect: {farmGrow: 1 / 1.75, farmCropGain: 2.25, farmGoldChance: 1.5}
},
smellyMud: {
type: 'vegetable',
color: 'brown',
- effect: {farmGrow: 1 / 2, farmCropGain: 2.5, farmGoldChance: 1.5, farmRareDropChance: 1.25}
+ effect: {farmGrow: 1 / 1.5, farmCropGain: 2.5, farmGoldChance: 1.5, farmRareDropChance: 1.25}
},
tropicalWater: {
- type: 'fruit',
+ type: 'berry',
icon: 'mdi-flask-round-bottom',
color: 'cyan',
- effect: {farmGrow: 1 / 4, farmGoldChance: 2.5, farmRareDropChance: 1.25}
+ effect: {farmGrow: 1 / 2, farmGoldChance: 2, farmRareDropChance: 1.25}
},
fieldBlessing: {
type: 'grain',
icon: 'mdi-auto-fix',
color: 'pink-purple',
- effect: {farmGrow: 1 / 6, farmGoldChance: 5}
+ effect: {farmGrow: 1 / 2, farmGoldChance: 2.25}
},
cinnamonBag: {
type: 'all',
color: 'brown',
- effect: {farmGrow: 1 / 2, farmCropGain: 1.8, farmGoldChance: 2.5}
+ effect: {farmGrow: 1 / 1.5, farmCropGain: 1.8, farmGoldChance: 1.75}
},
}
diff --git a/src/js/modules/farm/gene.js b/src/js/modules/farm/gene.js
index 8de5de64..744d55e1 100644
--- a/src/js/modules/farm/gene.js
+++ b/src/js/modules/farm/gene.js
@@ -1,31 +1,41 @@
export default {
+ // Basics gene upgrade
+ basics: {
+ icon: 'mdi-sack',
+ effect: [],
+ upgrade: [{name: 'farmAllGain', type: 'mult', value: lvl => lvl * 0.03 + 1}]
+ },
+
// Level 1 genes
yield: {
icon: 'mdi-sack',
- effect: [{name: 'farmCropGain', type: 'mult', value: 1.4}],
- upgrade: [{name: 'farmCropGain', type: 'mult', value: lvl => Math.pow(1.1, lvl)}]
+ effect: [{name: 'farmCropGain', type: 'mult', value: 1.3}],
+ upgrade: [{name: 'farmCropGain', type: 'mult', value: lvl => lvl * 0.1 + 1}]
},
gold: {
icon: 'mdi-gold',
- effect: [{name: 'farmGoldChance', type: 'mult', value: 1.75}],
- upgrade: [{name: 'farmGoldChance', type: 'mult', value: lvl => Math.pow(1.12, lvl)}]
+ effect: [{name: 'farmGoldChance', type: 'mult', value: 1.4}],
+ upgrade: [{name: 'farmGoldChance', type: 'mult', value: lvl => lvl * 0.05 + 1}]
},
exp: {
icon: 'mdi-star',
- effect: [{name: 'farmExperience', type: 'mult', value: 1.3}],
+ effect: [{name: 'farmExperience', type: 'mult', value: 1.175}],
upgrade: [{name: 'farmExperience', type: 'base', value: lvl => lvl * 0.15}]
},
rareDrop: {
icon: 'mdi-dice-2',
effect: [{name: 'farmRareDropChance', type: 'mult', value: 1.25}],
- upgrade: [{name: 'farmRareDropChance', type: 'mult', value: lvl => Math.pow(1.08, lvl)}]
+ upgrade: [{name: 'farmRareDropChance', type: 'mult', value: lvl => lvl * 0.09 + 1}]
},
// Level 5 genes
grow: {
icon: 'mdi-timer',
effect: [{name: 'farmGrow', type: 'mult', value: 0.8}],
- upgrade: [{name: 'farmExperience', type: 'base', value: lvl => lvl * 0.12}]
+ upgrade: [
+ {name: 'farmGrow', type: 'mult', value: lvl => 1 / (lvl * 0.01 + 1)},
+ {name: 'farmExperience', type: 'base', value: lvl => lvl * 0.1}
+ ]
},
overgrow: {
icon: 'mdi-sprout',
@@ -36,13 +46,19 @@ export default {
icon: 'mdi-numeric-5-box-multiple',
effect: [
{name: 'farmGrow', type: 'mult', value: 5},
- {name: 'farmAllGain', type: 'mult', value: 4}
+ {name: 'farmAllGain', type: 'mult', value: 4},
+ {name: 'farmCropCost', type: 'mult', value: 4},
+ {name: 'farmFertilizerCost', type: 'mult', value: 4}
],
- upgrade: [{name: 'farmCropGain', type: 'mult', value: lvl => Math.pow(1.08, lvl)}]
+ upgrade: [
+ {name: 'farmCropGain', type: 'mult', value: lvl => lvl * 0.08 + 1},
+ {name: 'farmRareDropChance', type: 'mult', value: lvl => lvl * 0.04 + 1}
+ ],
+ lockOnField: true
},
grass: {
icon: 'mdi-grass',
- effect: [{name: 'farm_grass', type: 'addRareDrop', value: 8}],
+ effect: [{name: 'farm_grass', type: 'addRareDrop', value: 8, chance: 0.2}],
upgrade: [{name: 'farm_grass', type: 'addRareDropAmount', value: lvl => lvl}]
},
@@ -55,29 +71,41 @@ export default {
gnome: {
icon: 'mdi-human-child',
effect: [{name: 'farmGnomeBoost', type: 'text'}],
- upgrade: [{name: 'farmGoldChance', type: 'mult', value: lvl => Math.pow(1.09, lvl)}]
+ upgrade: [
+ {name: 'farmCropGain', type: 'mult', value: lvl => lvl * 0.06 + 1},
+ {name: 'farmExperience', type: 'base', value: lvl => lvl * 0.05}
+ ]
},
lonely: {
icon: 'mdi-circle-expand',
effect: [{name: 'farmLonelyGrow', type: 'text'}],
- upgrade: [{name: 'farmOvergrow', type: 'base', value: lvl => lvl * 0.12}]
+ upgrade: [
+ {name: 'farmGrow', type: 'mult', value: lvl => 1 / (lvl * 0.01 + 1)},
+ {name: 'farmOvergrow', type: 'base', value: lvl => lvl * 0.12}
+ ]
},
fertile: {
icon: 'mdi-sack-percent',
effect: [{name: 'farmFertileBoost', type: 'text'}],
- upgrade: [{name: 'farmAllGain', type: 'mult', value: lvl => lvl * 0.02 + 1}]
+ upgrade: [
+ {name: 'farmCropGain', type: 'mult', value: lvl => lvl * 0.03 + 1},
+ {name: 'farmOvergrow', type: 'base', value: lvl => lvl * 0.1}
+ ]
},
// Level 15 genes
mystery: {
icon: 'mdi-eye-circle-outline',
- effect: [{name: 'farm_mysteryStone', type: 'addRareDrop', value: 1}],
+ effect: [{name: 'farm_mysteryStone', type: 'addRareDrop', value: 1, chance: -0.1, mult: 0.01}],
upgrade: [{name: 'farmMystery', type: 'base', value: lvl => lvl}]
},
conversion: {
icon: 'mdi-swap-horizontal',
effect: [{name: 'farmYieldConversion', type: 'text'}],
- upgrade: [{name: 'farmCropGain', type: 'mult', value: lvl => Math.pow(1.07, lvl)}]
+ upgrade: [
+ {name: 'farmCropGain', type: 'mult', value: lvl => lvl * 0.06 + 1},
+ {name: 'farmExperience', type: 'base', value: lvl => lvl * 0.05}
+ ]
},
prestige: {
icon: 'mdi-shimmer',
@@ -89,4 +117,54 @@ export default {
effect: [{name: 'farmRareDropChance', type: 'base', value: 0.05}],
upgrade: [{name: 'farmRareDropChance', type: 'base', value: lvl => lvl * 0.001}]
},
+
+ // Level 20 genes
+ lucky: {
+ icon: 'mdi-horseshoe',
+ effect: [{name: 'farmLuckyHarvest', type: 'text'}],
+ upgrade: [{name: 'farmLuckyHarvestMult', type: 'base', value: lvl => lvl}]
+ },
+ finalize: {
+ icon: 'mdi-lock-alert',
+ effect: [
+ {name: 'farmCropGain', type: 'mult', value: 1.5},
+ {name: 'farmGoldChance', type: 'mult', value: 1.2},
+ {name: 'farmRareDropChance', type: 'mult', value: 1.2},
+ {name: 'farmExperience', type: 'mult', value: 0}
+ ],
+ upgrade: [{name: 'farmCropGain', type: 'mult', value: lvl => lvl * 0.12 + 1}]
+ },
+ selfless: {
+ icon: 'mdi-charity',
+ effect: [{name: 'farmSelfless', type: 'text'}],
+ upgrade: [{name: 'farmCropGain', type: 'mult', value: lvl => lvl * 0.05 + 1}]
+ },
+ unyielding: {
+ icon: 'mdi-content-duplicate',
+ effect: [{name: 'farmUnyielding', type: 'text'}],
+ upgrade: [
+ {name: 'farmGrow', type: 'mult', value: lvl => 1 / (lvl * 0.01 + 1)},
+ {name: 'farmExperience', type: 'base', value: lvl => lvl * 0.08}
+ ]
+ },
+
+ // Level 25 genes
+ teamwork: {
+ icon: 'mdi-handshake',
+ effect: [{name: 'farmTeamwork', type: 'text'}],
+ upgrade: [{name: 'farmCropGain', type: 'mult', value: lvl => lvl * 0.08 + 1}]
+ },
+ hunter: {
+ icon: 'mdi-bow-arrow',
+ effect: [{name: 'farmHunter', type: 'text'}],
+ upgrade: [{name: 'farmHuntChance', type: 'mult', value: lvl => Math.pow(1.15, lvl)}]
+ },
+ patient: {
+ icon: 'mdi-sleep',
+ effect: [{name: 'farmPatient', type: 'text'}],
+ upgrade: [
+ {name: 'farmGrow', type: 'mult', value: lvl => 1 / (lvl * 0.01 + 1)},
+ {name: 'farmAllGain', type: 'mult', value: lvl => lvl * 0.02 + 1}
+ ]
+ },
}
diff --git a/src/js/modules/farm/relic.js b/src/js/modules/farm/relic.js
index 90803b37..5512adba 100644
--- a/src/js/modules/farm/relic.js
+++ b/src/js/modules/farm/relic.js
@@ -3,7 +3,7 @@ export default {
{name: 'currencyFarmVegetableGain', type: 'mult', value: 1.4}
]},
goldenApple: {icon: 'mdi-food-apple', color: 'amber', effect: [
- {name: 'currencyFarmFruitGain', type: 'mult', value: 1.4}
+ {name: 'currencyFarmBerryGain', type: 'mult', value: 1.4}
]},
popcorn: {icon: 'mdi-popcorn', color: 'pale-yellow', effect: [
{name: 'currencyFarmGrainGain', type: 'mult', value: 1.4}
diff --git a/src/js/modules/farm/upgrade.js b/src/js/modules/farm/upgrade.js
index dd4182af..cb1e0d03 100644
--- a/src/js/modules/farm/upgrade.js
+++ b/src/js/modules/farm/upgrade.js
@@ -7,27 +7,32 @@ const requirementStat = 'farm_seedBox';
const requirementBase = () => store.state.upgrade.item[requirementStat].highestLevel;
export default {
- seedBox: {cap: 19, hideCap: true, price(lvl) {
+ seedBox: {cap: 24, hideCap: true, price(lvl) {
return [
{farm_vegetable: 70},
- {farm_fruit: 150},
+ {farm_berry: 150},
{farm_grain: 260},
{farm_flower: 800, farm_gold: 1},
{farm_vegetable: 4600},
- {farm_fruit: buildNum(50, 'K')},
+ {farm_berry: buildNum(50, 'K')},
{farm_grain: buildNum(335, 'K')},
{farm_flower: buildNum(2, 'M')},
{farm_vegetable: buildNum(17.5, 'M')},
- {farm_fruit: buildNum(120, 'M')},
+ {farm_berry: buildNum(120, 'M')},
{farm_grain: buildNum(900, 'M')},
{farm_flower: buildNum(7.2, 'B')},
{farm_vegetable: buildNum(54, 'B')},
- {farm_fruit: buildNum(370, 'B')},
+ {farm_berry: buildNum(370, 'B')},
{farm_grain: buildNum(2.2, 'T')},
{farm_flower: buildNum(35, 'T')},
{farm_vegetable: buildNum(875, 'T')},
- {farm_fruit: buildNum(3.1, 'Qa')},
- {farm_grain: buildNum(130, 'Qa')}
+ {farm_berry: buildNum(3.1, 'Qa')},
+ {farm_grain: buildNum(130, 'Qa')},
+ {farm_flower: buildNum(8.5, 'Qi')},
+ {farm_vegetable: buildNum(500, 'Qi')},
+ {farm_berry: buildNum(35, 'Sx')},
+ {farm_grain: buildNum(3, 'Sp')},
+ {farm_flower: buildNum(320, 'Sp')},
][lvl];
}, effect: [
{name: 'blueberry', type: 'farmSeed', value: lvl => lvl >= 1},
@@ -48,32 +53,41 @@ export default {
{name: 'cucumber', type: 'farmSeed', value: lvl => lvl >= 16},
{name: 'grapes', type: 'farmSeed', value: lvl => lvl >= 17},
{name: 'hops', type: 'farmSeed', value: lvl => lvl >= 18},
- {name: 'violet', type: 'farmSeed', value: lvl => lvl >= 19}
+ {name: 'violet', type: 'farmSeed', value: lvl => lvl >= 19},
+ {name: 'sweetPotato', type: 'farmSeed', value: lvl => lvl >= 20},
+ {name: 'strawberry', type: 'farmSeed', value: lvl => lvl >= 21},
+ {name: 'sesame', type: 'farmSeed', value: lvl => lvl >= 22},
+ {name: 'sunflower', type: 'farmSeed', value: lvl => lvl >= 23},
+ {name: 'spinach', type: 'farmSeed', value: lvl => lvl >= 24},
]},
fertility: {requirementBase, requirementStat, requirementValue: 1, price(lvl) {
- return {farm_vegetable: 50 * Math.pow(lvl * 0.005 + 1.3, lvl), farm_fruit: 50 * Math.pow(lvl * 0.005 + 1.3, lvl)};
+ return {farm_vegetable: 50 * Math.pow(lvl * 0.005 + 1.3, lvl), farm_berry: 50 * Math.pow(lvl * 0.005 + 1.3, lvl)};
}, effect: [
{name: 'farmCropGain', type: 'mult', value: lvl => Math.pow(1.1, lvl)}
]},
overgrowth: {cap: 9, requirementBase, requirementStat, requirementValue: 1, price(lvl) {
return fallbackArray([
- {farm_fruit: 200},
+ {farm_berry: 200},
{farm_grain: 850, farm_flower: 1300},
], {farm_flower: 240 * Math.pow(5 + lvl, lvl)}, lvl);
}, effect: [
{name: 'farmOvergrow', type: 'base', value: lvl => lvl >= 1 ? (lvl * 0.05 + 0.05) : null}
- ]},
+ ], onBuy() {
+ store.dispatch('farm/updateFieldCaches');
+ }},
expansion: {cap: 45, requirementBase, requirementStat, requirementValue: 2, price(lvl) {
return {farm_grain: 300 * Math.pow(lvl * 0.05 + 2, lvl)};
}, effect: [
{name: 'farmTiles', type: 'farmTile', value: lvl => lvl}
]},
gardenGnome: {cap: 5, hasDescription: true, requirementBase, requirementStat, requirementValue: 3, price(lvl) {
- return {farm_vegetable: 500 * Math.pow(96, lvl), farm_fruit: 500 * Math.pow(96, lvl), farm_flower: 1000 * Math.pow(128, lvl)};
+ return {farm_vegetable: 500 * Math.pow(96, lvl), farm_berry: 500 * Math.pow(96, lvl), farm_flower: 1000 * Math.pow(128, lvl)};
}, effect: [
{name: 'gardenGnome', type: 'farmBuilding', value: lvl => lvl},
{name: 'farmDisableEarlyGame', type: 'unlock', value: lvl => lvl >= 1}
- ]},
+ ], onBuy() {
+ store.dispatch('farm/applyEarlyGameBuff');
+ }},
learning: {cap: 1, hasDescription: true, requirementBase, requirementStat, requirementValue: 4, price() {
return {farm_gold: 1};
}, effect: [
@@ -91,7 +105,9 @@ export default {
}, effect: [
{name: 'currencyFarmGrainGain', type: 'mult', value: lvl => lvl * 0.15 + 1},
{name: 'farmOvergrow', type: 'base', value: lvl => lvl * 0.01}
- ]},
+ ], onBuy() {
+ store.dispatch('farm/updateFieldCaches');
+ }},
roastedSeeds: {cap: 5, requirementBase, requirementStat, requirementValue: 5, price(lvl) {
return {farm_seedHull: Math.round(Math.pow(1.8, lvl) * 4)};
}, effect: [
@@ -103,7 +119,7 @@ export default {
{name: 'currencyFarmGrassCap', type: 'base', value: lvl => lvl * 100}
]},
smallCrate: {cap: 7, capMult: true, requirementBase, requirementStat, requirementValue: 6, price(lvl) {
- return {farm_fruit: buildNum(24.5, 'K') * Math.pow(1.9, lvl)};
+ return {farm_berry: buildNum(24.5, 'K') * Math.pow(1.9, lvl)};
}, effect: [
{name: 'currencyFarmSeedHullCap', type: 'base', value: lvl => lvl * 10}
]},
@@ -123,6 +139,11 @@ export default {
{name: 'farmCropGain', type: 'mult', value: lvl => lvl * 0.1 + 1},
{name: 'currencyFarmPetalCap', type: 'base', value: lvl => lvl * 3}
]},
+ anthill: {requirementBase, requirementStat, requirementValue: 7, price(lvl) {
+ return {farm_grass: getSequence(3, lvl) * 50 + 200};
+ }, effect: [
+ {name: 'farmRareDropChance', type: 'base', value: lvl => lvl * 0.015}
+ ]},
bugPowder: {requirementBase, requirementStat, requirementValue: 8, price(lvl) {
return {farm_grain: buildNum(675, 'K') * Math.pow(1.75, lvl), farm_bug: Math.round(5 * lvl * Math.pow(1.1, Math.max(0, lvl - 10)) + 10)};
}, effect: [
@@ -143,8 +164,8 @@ export default {
perfume: {cap: 25, note: 'farm_13', requirementBase, requirementStat, requirementValue: 9, price(lvl) {
return {farm_bug: Math.round(5 * lvl * Math.pow(1.1, Math.max(0, lvl - 10)) + 10), farm_butterfly: Math.round(lvl * Math.pow(1.1, Math.max(0, lvl - 10)) + 2)};
}, effect: [
- {name: 'currencyFarmFruitGain', type: 'mult', value: lvl => lvl * 0.15 + 1},
- {name: 'farmRareDropChance', type: 'base', value: lvl => lvl * 0.002}
+ {name: 'currencyFarmBerryGain', type: 'mult', value: lvl => lvl * 0.15 + 1},
+ {name: 'farmRareDropChance', type: 'base', value: lvl => lvl * 0.01}
]},
mediumCrate: {cap: 8, capMult: true, requirementBase, requirementStat, requirementValue: 10, price(lvl) {
return {farm_vegetable: buildNum(90, 'M') * Math.pow(1.75, lvl), farm_grain: buildNum(54, 'M') * Math.pow(2.1, lvl)};
@@ -158,7 +179,7 @@ export default {
{name: 'farmCropGain', type: 'mult', value: lvl => Math.pow(1.12, lvl)}
]},
insectParadise: {cap: 6, capMult: true, requirementBase, requirementStat, requirementValue: 11, price(lvl) {
- return {farm_fruit: buildNum(750, 'M') * Math.pow(2.4, lvl), farm_petal: Math.round(Math.pow(1.75, lvl) * 11)};
+ return {farm_berry: buildNum(750, 'M') * Math.pow(2.4, lvl), farm_petal: Math.round(Math.pow(1.75, lvl) * 11)};
}, effect: [
{name: 'currencyFarmBugCap', type: 'base', value: lvl => lvl * 40},
{name: 'currencyFarmButterflyCap', type: 'base', value: lvl => lvl * 5},
@@ -175,7 +196,7 @@ export default {
{name: 'currencyFarmPetalCap', type: 'base', value: lvl => lvl * 15}
]},
fertileGround: {requirementBase, requirementStat, requirementValue: 12, price(lvl) {
- return {farm_fruit: buildNum(4, 'B') * Math.pow(2.25, lvl), farm_flower: buildNum(3.3, 'B') * Math.pow(2.25, lvl)};
+ return {farm_berry: buildNum(4, 'B') * Math.pow(2.25, lvl), farm_flower: buildNum(3.3, 'B') * Math.pow(2.25, lvl)};
}, effect: [
{name: 'currencyFarmVegetableGain', type: 'mult', value: lvl => lvl * 0.1 + 1}
]},
@@ -198,7 +219,7 @@ export default {
{name: 'farm_premium', type: 'findConsumable', value: lvl => lvl >= 1}
]},
bigCrate: {cap: 10, capMult: true, requirementBase, requirementStat, requirementValue: 14, price(lvl) {
- return {farm_fruit: buildNum(190, 'B') * Math.pow(1.85, lvl), farm_grain: buildNum(240, 'B') * Math.pow(1.85, lvl)};
+ return {farm_berry: buildNum(190, 'B') * Math.pow(1.85, lvl), farm_grain: buildNum(240, 'B') * Math.pow(1.85, lvl)};
}, effect: [
{name: 'currencyFarmSeedHullCap', type: 'base', value: lvl => lvl * 60},
{name: 'currencyFarmGrassCap', type: 'base', value: lvl => lvl * 80},
@@ -210,7 +231,7 @@ export default {
{name: 'currencyFarmSpiderCap', type: 'base', value: lvl => lvl * 4}
]},
studyInsects: {cap: 10, requirementBase, requirementStat, requirementValue: 15, price(lvl) {
- return {farm_fruit: buildNum(1.35, 'T') * Math.pow(2.65, lvl), farm_butterfly: Math.round(Math.pow(1.25, lvl) * 28)};
+ return {farm_berry: buildNum(1.35, 'T') * Math.pow(2.65, lvl), farm_butterfly: Math.round(Math.pow(1.25, lvl) * 28)};
}, effect: [
{name: 'farmExperience', type: 'mult', value: lvl => lvl * 0.1 + 1}
]},
@@ -220,9 +241,48 @@ export default {
{name: 'currencyFarmSpiderCap', type: 'base', value: lvl => lvl},
{name: 'currencyFarmBeeCap', type: 'base', value: lvl => lvl * 200}
]},
+ darkCorner: {cap: 10, requirementBase, requirementStat, requirementValue: 17, price(lvl) {
+ return {farm_vegetable: buildNum(175, 'T') * Math.pow(1.75, lvl), farm_grain: buildNum(300, 'T') * Math.pow(1.6, lvl), farm_bug: Math.round(Math.pow(1.24, lvl) * 230)};
+ }, effect: [
+ {name: 'currencyFarmSpiderCap', type: 'base', value: lvl => lvl * 2},
+ {name: 'farmRareDropChance', type: 'base', value: lvl => lvl * 0.01}
+ ]},
flag: {cap: 1, hasDescription: true, note: 'farm_20', requirementBase, requirementStat, requirementValue: 18, price() {
return {farm_spider: 50, farm_bee: 2500, farm_goldenPetal: 10};
}, effect: [
{name: 'flag', type: 'farmBuilding', value: lvl => lvl}
]},
+ wormBait: {requirementBase, requirementStat, requirementValue: 19, price(lvl) {
+ return {farm_grass: Math.round(Math.pow(1.22, lvl) * 1350), farm_petal: Math.round(Math.pow(1.16, lvl) * 175), farm_butterfly: Math.round(Math.pow(1.16, lvl) * 50)};
+ }, effect: [
+ {name: 'currencyFarmVegetableGain', type: 'mult', value: lvl => lvl * 0.05 + 1},
+ {name: 'currencyFarmBugCap', type: 'base', value: lvl => lvl * 20},
+ {name: 'currencyFarmLadybugCap', type: 'base', value: lvl => lvl * 35},
+ ]},
+ shinySoil: {requirementBase, requirementStat, requirementValue: 20, price(lvl) {
+ return {farm_bee: Math.round(Math.pow(1.16, lvl) * 4000), farm_goldenPetal: Math.round(lvl * 0.3 + 5)};
+ }, effect: [
+ {name: 'currencyFarmBerryGain', type: 'mult', value: lvl => lvl * 0.05 + 1},
+ {name: 'currencyFarmButterflyCap', type: 'base', value: lvl => lvl * 4},
+ ]},
+ bigFertilizerBag: {cap: 1, requirementBase, requirementStat, requirementValue: 21, price() {
+ return {farm_gold: 2000};
+ }, effect: [
+ {name: 'farm_analyzing', type: 'findConsumable', value: lvl => lvl >= 1},
+ {name: 'farm_superJuicy', type: 'findConsumable', value: lvl => lvl >= 1},
+ {name: 'farm_pellets', type: 'findConsumable', value: lvl => lvl >= 1}
+ ]},
+ openSesame: {requirementBase, requirementStat, requirementValue: 22, price(lvl) {
+ return {farm_flower: buildNum(870, 'Sx') * Math.pow(1.6, lvl), farm_smallSeed: Math.round(Math.pow(1.28, lvl) * 225)};
+ }, effect: [
+ {name: 'currencyFarmGrainGain', type: 'mult', value: lvl => lvl * 0.05 + 1},
+ {name: 'currencyFarmSeedHullCap', type: 'base', value: lvl => lvl * 50},
+ {name: 'currencyFarmSmallSeedCap', type: 'base', value: lvl => lvl * 150},
+ ]},
+ flowerPainting: {requirementBase, requirementStat, requirementValue: 23, price(lvl) {
+ return {farm_berry: buildNum(92, 'Sp') * Math.pow(1.6, lvl), farm_bee: Math.round(Math.pow(1.28, lvl) * 6000)};
+ }, effect: [
+ {name: 'currencyFarmFlowerGain', type: 'mult', value: lvl => lvl * 0.05 + 1},
+ {name: 'currencyFarmBeeCap', type: 'base', value: lvl => lvl * 150},
+ ]},
}
diff --git a/src/js/modules/farm/upgradePremium.js b/src/js/modules/farm/upgradePremium.js
index de3405b3..92ed1f09 100644
--- a/src/js/modules/farm/upgradePremium.js
+++ b/src/js/modules/farm/upgradePremium.js
@@ -7,12 +7,12 @@ export default {
}, effect: [
{name: 'currencyFarmVegetableGain', type: 'mult', value: lvl => getSequence(2, lvl) * 0.5 + 1}
]},
- biggerFruits: {type: 'premium', requirement() {
+ biggerBerries: {type: 'premium', requirement() {
return store.state.upgrade.item.farm_seedBox.level >= 1;
}, price(lvl) {
return {gem_ruby: [2, 3][lvl % 2] * Math.pow(2, Math.floor(lvl / 2)) * 80};
}, effect: [
- {name: 'currencyFarmFruitGain', type: 'mult', value: lvl => getSequence(2, lvl) * 0.5 + 1}
+ {name: 'currencyFarmBerryGain', type: 'mult', value: lvl => getSequence(2, lvl) * 0.5 + 1}
]},
biggerGrain: {type: 'premium', requirement() {
return store.state.upgrade.item.farm_seedBox.level >= 2;
diff --git a/src/js/modules/gallery.js b/src/js/modules/gallery.js
index cf0e84ed..2980da12 100644
--- a/src/js/modules/gallery.js
+++ b/src/js/modules/gallery.js
@@ -1,11 +1,13 @@
import store from "../../store"
import { buildArray } from "../utils/array";
import { capitalize } from "../utils/format";
-import { logBase } from "../utils/math";
+import { getSequence, logBase } from "../utils/math";
import achievement from "./gallery/achievement";
import idea from "./gallery/idea";
import relic from "./gallery/relic";
+import shape from "./gallery/shape";
import upgrade from "./gallery/upgrade";
+import upgradeShape from "./gallery/upgradeShape";
import upgradePremium from "./gallery/upgradePremium";
import upgradePrestige from "./gallery/upgradePrestige";
import bookGallery from "./school/bookGallery";
@@ -34,16 +36,14 @@ export default {
});
}
- const globalLevelGallery = Math.floor(logBase(store.state.stat.gallery_beauty.total, 5));
+ const globalLevelGallery = Math.floor(logBase(store.state.stat.gallery_beauty.total, 4));
if (globalLevelGallery > 0) {
store.dispatch('meta/globalLevelPart', {key: 'gallery_0', amount: globalLevelGallery});
}
- if (store.state.unlock.galleryConversion.use) {
- store.dispatch('currency/gain', {feature: 'gallery', name: 'converter', amount: seconds * store.getters['mult/get']('currencyGalleryConverterGain')});
- }
- if (store.state.unlock.galleryDrums.use) {
- store.dispatch('currency/gain', {feature: 'gallery', name: 'package', amount: seconds * store.getters['mult/get']('currencyGalleryPackageGain')});
+ store.dispatch('gallery/packageAndConverterTick', seconds);
+ if (store.state.unlock.galleryShape.use) {
+ store.dispatch('currency/gain', {feature: 'gallery', name: 'motivation', amount: seconds * store.getters['mult/get']('currencyGalleryMotivationGain')});
}
if (store.state.unlock.galleryInspiration.use) {
@@ -61,33 +61,71 @@ export default {
store.commit('gallery/updateKey', {key: 'inspirationAmount', value: newAmount});
}
}
+ if (store.state.unlock.galleryCanvas.use) {
+ let totalLevel = 0;
+ for (const [key, elem] of Object.entries(store.state.gallery.colorData)) {
+ if (elem.cacheSpace > 0) {
+ const speed = store.getters['mult/get']('galleryCanvasSpeed', getSequence(10, elem.cacheSpace) * 0.1, 1 + store.getters['currency/value'](`gallery_${ key }Drum`) * 0.1);
+ const oldProgress = elem.progress;
+ let progress = elem.progress;
+ let secondsLeft = seconds;
+ while (secondsLeft > 0) {
+ const difficulty = store.getters['gallery/canvasDifficulty'](key, Math.floor(progress));
+ const timeUsed = Math.min((Math.floor(progress + 1) - progress) * difficulty / speed, secondsLeft);
+ progress += timeUsed * speed / difficulty;
+ secondsLeft -= timeUsed;
+ }
+ store.commit('gallery/updateColorDataKey', {name: key, key: 'progress', value: progress});
+ if (Math.floor(progress) > Math.floor(oldProgress)) {
+ store.dispatch('gallery/applyCanvasLevel', {name: key, onLevel: true});
+ }
+ }
+ totalLevel += elem.progress;
+ }
+ store.commit('stat/increaseTo', {feature: 'gallery', name: 'canvasLevelTotal', value: totalLevel});
+ }
},
- unlock: ['galleryFeature', 'galleryConversion', 'galleryInspiration', 'galleryAuction', 'galleryDrums'],
+ unlock: ['galleryFeature', 'galleryConversion', 'galleryInspiration', 'galleryAuction', 'galleryDrums', 'galleryShape', 'galleryCanvas'],
stat: {
timeSpent: {display: 'time'},
- bestPrestige: {},
+ bestPrestige: {showInStatistics: true},
highestTierIdea: {},
- prestigeCount: {}
+ shapeComboHighest: {},
+ shapeComboTotal: {showInStatistics: true},
+ canvasLevelTotal: {showInStatistics: true},
+ hourglassHighest: {},
+ prestigeCount: {showInStatistics: true}
},
mult: {
- galleryInspirationBase: {baseValue: 300, display: 'time'},
- galleryInspirationIncrement: {baseValue: 1, min: 0, display: 'percent'},
- galleryInspirationStart: {}
+ galleryInspirationBase: {unlock: 'galleryInspiration', baseValue: 300, display: 'timeMs'},
+ galleryInspirationIncrement: {unlock: 'galleryInspiration', baseValue: 1, min: 0, display: 'percent'},
+ galleryInspirationStart: {unlock: 'galleryInspiration'},
+ galleryShapeGain: {unlock: 'galleryShape'},
+ gallerySpecialShapeChance: {unlock: 'galleryShape', baseValue: 0.005, display: 'percent'},
+ gallerySpecialShapeMult: {unlock: 'galleryShape', baseValue: 15, display: 'mult'},
+ galleryCanvasSize: {unlock: 'galleryCanvas', baseValue: 1, round: true},
+ galleryCanvasSpeed: {unlock: 'galleryCanvas', display: 'perSecond'}
},
currency: {
beauty: {color: 'deep-purple', icon: 'mdi-image-filter-vintage', gainMult: {baseValue: 1, display: 'perSecond'}, showGainMult: true, showGainTimer: true, timerIsEstimate: true},
- converter: {color: 'pale-green', icon: 'mdi-recycle', gainMult: {baseValue: 1, display: 'perSecond'}, showGainMult: true, showGainTimer: true, capMult: {baseValue: 1000}},
- inspiration: {color: 'yellow', icon: 'mdi-lightbulb-on'},
- package: {color: 'beige', icon: 'mdi-package-variant', overcapMult: 0.8, overcapScaling: 0.8, gainMult: {baseValue: 0.025, display: 'perSecond'}, showGainMult: true, showGainTimer: true, capMult: {baseValue: 5}},
- cash: {type: 'prestige', alwaysVisible: true, color: 'green', icon: 'mdi-cash', gainMult: {}}
+ converter: {multUnlock: 'galleryConversion', color: 'pale-green', icon: 'mdi-recycle', overcapMult: 0.75, overcapScaling: 0.95, gainMult: {baseValue: 0.2, display: 'perSecond'}, showGainMult: true, capMult: {baseValue: 1000}},
+ inspiration: {multUnlock: 'galleryInspiration', color: 'yellow', icon: 'mdi-lightbulb-on'},
+ package: {multUnlock: 'galleryDrums', color: 'beige', icon: 'mdi-package-variant', overcapMult: 0.8, overcapScaling: 0.8, gainMult: {baseValue: 0.0125, display: 'perSecond'}, showGainMult: true, showGainTimer: true, capMult: {baseValue: 10}},
+ motivation: {multUnlock: 'galleryShape', type: 'shape', color: 'pink-purple', icon: 'mdi-emoticon-excited', overcapMult: 0.5, gainMult: {baseValue: 0.2, display: 'perSecond'}, showGainMult: true, showGainTimer: true, capMult: {baseValue: 100}},
+ mysteryShape: {multUnlock: 'galleryShape', type: 'shape', color: 'pale-purple', icon: 'mdi-octahedron', overcapMult: 0, gainMult: {baseValue: 1}, capMult: {baseValue: 1337}},
+ cash: {multUnlock: 'galleryAuction', type: 'prestige', alwaysVisible: true, color: 'green', icon: 'mdi-cash', gainMult: {}}
},
note: buildArray(10).map(() => 'g'),
upgrade: {
...upgrade,
+ ...upgradeShape,
...upgradePrestige,
...upgradePremium,
...bookGallery
},
+ multGroup: [
+ {mult: 'galleryShapeGain', name: 'currencyGain', type: 'shape', blacklist: ['gallery_motivation', 'gallery_mysteryShape']}
+ ],
relic,
achievement,
init() {
@@ -106,6 +144,7 @@ export default {
[`currencyGallery${ capitalize(colorMult) }DrumCap`]: {type: 'bonus', value: val => val}
}, overcapMult: 0, capMult: {baseValue: 10, round: true}});
+ store.commit('gallery/initColorData', {name: elem});
store.commit('mult/init', {feature: 'gallery', name: `gallery${ capitalize(elem) }Conversion`, unlock: 'galleryFeature', baseValue: 1}, {root: true});
store.commit('mult/init', {feature: 'gallery', name: `gallery${ capitalize(elem) }DrumChance`, unlock: 'galleryDrums', display: 'percent', min: 0, max: 1}, {root: true});
});
@@ -117,9 +156,19 @@ export default {
for (const [key, elem] of Object.entries(idea)) {
store.commit('gallery/initIdea', {name: key, ...elem});
}
+ for (const [key, elem] of Object.entries(shape)) {
+ store.commit('gallery/initShape', {name: key, ...elem});
+ if (!elem.isSpecial) {
+ store.dispatch('currency/init', {feature: 'gallery', type: 'shape', multUnlock: 'galleryFeature', name: key, color: elem.color, icon: elem.icon, gainMult: {}, showGainMult: true});
+ }
+ }
+
+ store.commit('gallery/initShapeGrid');
},
saveGame() {
- let obj = {};
+ let obj = {
+ shapeGrid: store.state.gallery.shapeGrid
+ };
if (store.state.gallery.inspirationTime > 0) {
obj.inspirationTime = store.state.gallery.inspirationTime;
@@ -127,7 +176,13 @@ export default {
if (store.state.gallery.inspirationAmount > 0) {
obj.inspirationAmount = store.state.gallery.inspirationAmount;
}
- if (store.state.unlock.galleryInspiration.use) {
+ if (store.state.gallery.hourglassCombo > 0) {
+ obj.hourglassCombo = store.state.gallery.hourglassCombo;
+ }
+ if (store.state.gallery.canvasSpace.length > 0) {
+ obj.canvasSpace = store.state.gallery.canvasSpace;
+ }
+ if (store.state.unlock.galleryInspiration.see) {
let ideas = {};
for (const [key, elem] of Object.entries(store.state.gallery.idea)) {
if (elem.owned) {
@@ -136,16 +191,46 @@ export default {
}
obj.idea = ideas;
}
+ if (store.state.unlock.galleryCanvas.see) {
+ let colorData = {};
+ for (const [key, elem] of Object.entries(store.state.gallery.colorData)) {
+ if (elem.progress > 0) {
+ colorData[key] = elem.progress;
+ }
+ }
+ obj.colorData = colorData;
+ }
return obj;
},
loadGame(data) {
+ if (data.shapeGrid) {
+ store.commit('gallery/updateKey', {key: 'shapeGrid', value: data.shapeGrid});
+ }
if (data.inspirationTime) {
store.commit('gallery/updateKey', {key: 'inspirationTime', value: data.inspirationTime});
}
if (data.inspirationAmount) {
store.commit('gallery/updateKey', {key: 'inspirationAmount', value: data.inspirationAmount});
}
+ if (data.hourglassCombo) {
+ store.commit('gallery/updateKey', {key: 'hourglassCombo', value: data.hourglassCombo});
+ }
+ if (data.canvasSpace) {
+ store.commit('gallery/updateKey', {key: 'canvasSpace', value: data.canvasSpace});
+ let colors = {};
+ data.canvasSpace.forEach(elem => {
+ if (colors[elem] === undefined) {
+ colors[elem] = 0;
+ }
+ colors[elem]++;
+ });
+ for (const [key, elem] of Object.entries(colors)) {
+ if (store.state.gallery.colorData[key] !== undefined) {
+ store.commit('gallery/updateColorDataKey', {name: key, key: 'cacheSpace', value: elem});
+ }
+ }
+ }
if (data.idea !== undefined) {
for (const [key, elem] of Object.entries(data.idea)) {
if (store.state.gallery.idea[key] !== undefined) {
@@ -157,5 +242,17 @@ export default {
}
}
}
+ if (data.colorData !== undefined) {
+ for (const [key, elem] of Object.entries(data.colorData)) {
+ if (store.state.gallery.colorData[key] !== undefined) {
+ if (elem > 0) {
+ store.commit('gallery/updateColorDataKey', {name: key, key: 'progress', value: elem});
+ if (elem >= 1) {
+ store.dispatch('gallery/applyCanvasLevel', {name: key});
+ }
+ }
+ }
+ }
+ }
}
}
diff --git a/src/js/modules/gallery/achievement.js b/src/js/modules/gallery/achievement.js
index 5478124a..d9137763 100644
--- a/src/js/modules/gallery/achievement.js
+++ b/src/js/modules/gallery/achievement.js
@@ -1,8 +1,9 @@
import store from "../../../store";
import { buildNum } from "../../utils/format";
+import { getSequence } from "../../utils/math";
export default {
- beauty: {value: () => store.state.stat.gallery_beauty.total, milestones: lvl => Math.pow(buildNum(1, 'M'), lvl) * buildNum(1, 'T'), relic: {2: 'sackOfGold'}},
+ beauty: {value: () => store.state.stat.gallery_beauty.total, milestones: lvl => Math.pow(buildNum(1, 'M'), lvl) * buildNum(1, 'T'), relic: {2: 'sackOfGold', 6: 'imageAlbum'}},
converter: {value: () => store.state.stat.gallery_converter.total, milestones: lvl => Math.pow(20, lvl) * buildNum(200, 'K'), relic: {0: 'printer', 2: 'shredder'}},
colorVariety: {value: () => [
store.state.stat.gallery_red.total,
@@ -17,9 +18,13 @@ export default {
store.state.stat.gallery_teal.total,
store.state.stat["gallery_light-blue"].total,
store.state.stat.gallery_pink.total
- ].reduce((a, b) => a + (b > 0 ? 1 : 0), 0), milestones: lvl => lvl + 2, relic: {2: 'redBalloon', 3: 'orangeBalloon', 4: 'yellowBalloon'}},
- highestTierIdea: {value: () => store.state.stat.gallery_highestTierIdea.total, milestones: lvl => lvl + 2, relic: {0: 'lightbulb', 1: 'simpleCalculator'}},
- cash: {value: () => store.state.stat.gallery_cash.total, milestones: lvl => Math.pow(10, lvl) * 100, relic: {1: 'oldTV'}},
+ ].reduce((a, b) => a + (b > 0 ? 1 : 0), 0), milestones: lvl => lvl + 2, relic: {2: 'redBalloon', 3: 'orangeBalloon', 4: 'yellowBalloon', 5: 'greenBalloon', 6: 'blueBalloon', 7: 'purpleBalloon'}},
+ highestTierIdea: {value: () => store.state.stat.gallery_highestTierIdea.total, milestones: lvl => lvl + 2, relic: {0: 'lightbulb', 1: 'simpleCalculator', 3: 'strangeScroll'}},
+ cash: {value: () => store.state.stat.gallery_cash.total, milestones: lvl => Math.pow(100, lvl) * 100, relic: {1: 'oldTV', 5: 'printingPress'}},
packageMax: {value: () => store.state.stat.gallery_packageMax.total, milestones: lvl => Math.pow(3, lvl) * 100, relic: {0: 'worryingMail', 1: 'creditCard'}},
- redDrumMax: {value: () => store.state.stat.gallery_redDrumMax.total, milestones: lvl => lvl > 0 ? (Math.pow(2, lvl) * 25) : 20, relic: {2: 'redprint', 4: 'orangeprint'}},
+ redDrumMax: {value: () => store.state.stat.gallery_redDrumMax.total, milestones: lvl => lvl > 0 ? (Math.pow(2, lvl) * 25) : 20, relic: {2: 'redprint', 4: 'orangeprint', 6: 'yellowprint', 9: 'greenprint', 12: 'blueprint'}},
+ shapeComboTotal: {value: () => store.state.stat.gallery_shapeComboTotal.total, milestones: lvl => Math.round(Math.pow(lvl + 2, 2) * Math.pow(1.2, lvl) * 25), relic: {2: 'fishbowl', 4: 'smallBrush', 7: 'strangePills'}},
+ shapeComboHighest: {value: () => store.state.stat.gallery_shapeComboHighest.total, cap: 7, milestones: lvl => lvl * 5 + 10, relic: {2: 'pencil'}},
+ canvasLevelTotal: {value: () => store.state.stat.gallery_canvasLevelTotal.total, milestones: lvl => getSequence(2, lvl + 1) * 10, relic: {0: 'woodenHanger', 2: 'bedsheet'}},
+ hourglassHighest: {value: () => store.state.stat.gallery_hourglassHighest.total, secret: true, display: 'time', cap: 1, milestones: () => 86400},
}
diff --git a/src/js/modules/gallery/card.js b/src/js/modules/gallery/card.js
index 70e1bef4..eb62e1e7 100644
--- a/src/js/modules/gallery/card.js
+++ b/src/js/modules/gallery/card.js
@@ -1,7 +1,16 @@
import cardList from "./cardList";
export default {
- feature: {prefix: 'GA', reward: [{name: 'currencyGalleryBeautyGain', type: 'mult', value: lvl => lvl * 0.075 + 1}], unlock: 'galleryFeature'},
+ feature: {
+ prefix: 'GA',
+ reward: [{name: 'currencyGalleryBeautyGain', type: 'mult', value: lvl => lvl * 0.075 + 1}],
+ shinyReward: [{name: 'currencyGalleryCashGain', type: 'mult', value: lvl => lvl * 0.05 + 1}],
+ powerReward: [
+ {name: 'currencyGalleryBeautyGain', type: 'mult', value: lvl => Math.pow(1.1, lvl)},
+ {name: 'currencyGalleryCashGain', type: 'mult', value: lvl => Math.pow(1.05, lvl)},
+ ],
+ unlock: 'galleryFeature'
+ },
collection: {
artDisplay: {reward: [
{name: 'galleryCardCap', type: 'base', value: 1},
@@ -13,13 +22,13 @@ export default {
]},
},
pack: {
- newArtist: {unlock: 'galleryAuction', amount: 5, price: 55, content: {
+ newArtist: {unlock: 'galleryAuction', amount: 3, price: 55, content: {
'GA-0001': 1.2, 'GA-0002': 1, 'GA-0003': 0.8, 'GA-0004': 0.6,
'GA-0005': 3.2, 'GA-0006': 1.45, 'GA-0007': 2.5, 'GA-0008': 1.55, 'GA-0009': 1.8, 'GA-0010': 0.8, 'GA-0011': 0.66,
'GA-0012': 1.24, 'GA-0013': 1.5, 'GA-0014': 1.18,
'GA-0015': 1.4, 'GA-0016': 1.32, 'GA-0017': 1.12, 'GA-0018': 1.03,
}},
- inspiringCreations: {unlock: 'galleryAuction', amount: 3, price: 60, content: {
+ inspiringCreations: {unlock: 'galleryAuction', amount: 3, price: 120, content: {
'GA-0012': 1.24, 'GA-0013': 2.25, 'GA-0014': 1.18,
'GA-0015': 1.4, 'GA-0016': 1.32, 'GA-0017': 1.12, 'GA-0018': 1.03,
'GA-0019': 1.6, 'GA-0020': 0.77, 'GA-0021': 0.92, 'GA-0022': 0.85, 'GA-0023': 1.08,
diff --git a/src/js/modules/gallery/cardList.js b/src/js/modules/gallery/cardList.js
index beb1f761..1eda8390 100644
--- a/src/js/modules/gallery/cardList.js
+++ b/src/js/modules/gallery/cardList.js
@@ -1,6 +1,6 @@
export default [
- {id: 1, collection: 'organicDyes', reward: [
- {name: 'currencyGalleryRedGain', type: 'mult', value: 1.5}
+ {id: 1, collection: 'organicDyes', power: 2, reward: [
+ {name: 'currencyGalleryRedGain', type: 'mult', value: 1.25}
], color: 'red', icons: [
{"x": 0, "y": 0, "rotate": 135, "size": 1, "icon": "mdi-ladybug"},
{"x": 0.9, "y": -0.15, "rotate": 40, "size": 0.9, "icon": "mdi-ladybug"},
@@ -11,8 +11,8 @@ export default [
{"x": -0.8, "y": 0.9, "rotate": 170, "size": 0.95, "icon": "mdi-ladybug"},
{"x": -0.1, "y": 0.65, "rotate": -120, "size": 1, "icon": "mdi-ladybug"}
]},
- {id: 2, collection: 'organicDyes', reward: [
- {name: 'currencyGalleryOrangeGain', type: 'mult', value: 1.5}
+ {id: 2, collection: 'organicDyes', power: 2, reward: [
+ {name: 'currencyGalleryOrangeGain', type: 'mult', value: 1.25}
], color: 'orange', icons: [
{"x": -0.7, "y": -0.3, "rotate": 0, "size": 1.2, "icon": "mdi-bird"},
{"x": 0, "y": -0.55, "rotate": 0, "size": 1.2, "icon": "mdi-bird"},
@@ -22,15 +22,15 @@ export default [
{"x": 0.65, "y": 0.95, "rotate": 60, "size": 0.85, "icon": "mdi-feather"},
{"x": -0.4, "y": 0.9, "rotate": -135, "size": 0.85, "icon": "mdi-feather"}
]},
- {id: 3, collection: 'organicDyes', reward: [
- {name: 'currencyGalleryYellowGain', type: 'mult', value: 1.5}
+ {id: 3, collection: 'organicDyes', power: 2, reward: [
+ {name: 'currencyGalleryYellowGain', type: 'mult', value: 1.25}
], color: 'yellow', icons: [
{"x": 0, "y": 0.35, "rotate": 0, "size": 2, "icon": "mdi-cup"},
{"x": -0.75, "y": 0.5, "rotate": 0, "size": 1.25, "icon": "mdi-fruit-citrus"},
{"x": 0.5, "y": -0.5, "rotate": 0, "size": 2, "icon": "mdi-spoon-sugar"}
]},
- {id: 4, collection: 'organicDyes', reward: [
- {name: 'currencyGalleryGreenGain', type: 'mult', value: 1.5}
+ {id: 4, collection: 'organicDyes', power: 2, reward: [
+ {name: 'currencyGalleryGreenGain', type: 'mult', value: 1.25}
], color: 'green', icons: [
{"x": -0.55, "y": 0.5, "rotate": 0, "size": 2.75, "icon": "mdi-waves"},
{"x": 0.55, "y": 0.5, "rotate": 0, "size": 2.75, "icon": "mdi-waves"},
@@ -39,8 +39,8 @@ export default [
{"x": 0.7, "y": 0, "rotate": 0, "size": 1.1, "icon": "mdi-scent"}
]},
- {id: 5, collection: 'artDisplay', reward: [
- {name: 'currencyGalleryBeautyGain', type: 'mult', value: 1.5}
+ {id: 5, collection: 'artDisplay', power: 2, reward: [
+ {name: 'currencyGalleryBeautyGain', type: 'mult', value: 1.25}
], color: 'pale-purple', icons: [
{"x": -0.9, "y": -0.25, "rotate": 0, "size": 1.25, "icon": "mdi-image-filter-black-white"},
{"x": 0, "y": -0.25, "rotate": 0, "size": 1.35, "icon": "mdi-image-area"},
@@ -48,8 +48,7 @@ export default [
{"x": -0.55, "y": 0.7, "rotate": 0, "size": 1.75, "icon": "mdi-human-male-female-child"},
{"x": 0.7, "y": 0.75, "rotate": 0, "size": 1.5, "icon": "mdi-human-handsdown"}
]},
- {id: 6, collection: 'artDisplay', reward: [
- {name: 'currencyGalleryBeautyGain', type: 'mult', value: 1.25},
+ {id: 6, collection: 'artDisplay', power: 1, reward: [
{name: 'galleryColorGain', type: 'mult', value: 1.1}
], color: 'dark-grey', icons: [
{"x": 0, "y": 0, "rotate": 0, "size": 3, "icon": "mdi-artboard"},
@@ -57,7 +56,7 @@ export default [
{"x": 0, "y": 1.3, "rotate": 45, "size": 1, "icon": "mdi-pencil"},
{"x": -0.4, "y": 1.2, "rotate": 20, "size": 1, "icon": "mdi-pencil"}
]},
- {id: 7, collection: 'artDisplay', reward: [
+ {id: 7, collection: 'artDisplay', power: 1, reward: [
{name: 'galleryInspirationStart', type: 'base', value: 5}
], color: 'teal', icons: [
{"x": -0.9, "y": 0, "rotate": 135, "size": 1.5, "icon": "mdi-fountain-pen"},
@@ -66,24 +65,21 @@ export default [
{"x": 0.45, "y": 0, "rotate": 135, "size": 1.5, "icon": "mdi-pen"},
{"x": 0.9, "y": 0, "rotate": 135, "size": 1.5, "icon": "mdi-pencil"}
]},
- {id: 8, collection: 'artDisplay', reward: [
- {name: 'currencyGalleryBeautyGain', type: 'mult', value: 1.25},
+ {id: 8, collection: 'artDisplay', power: 2, reward: [
{name: 'galleryInspirationStart', type: 'base', value: 3}
], color: 'orange', icons: [
{"x": -0.25, "y": 0, "rotate": 0, "size": 2, "icon": "mdi-gradient-horizontal"},
{"x": 0.75, "y": 0.2, "rotate": 0, "size": 1.5, "icon": "mdi-spray"},
{"x": -0.6, "y": -0.35, "rotate": 0, "size": 2, "icon": "mdi-ruler-square"}
]},
- {id: 9, collection: 'artDisplay', reward: [
- {name: 'galleryColorGain', type: 'mult', value: 1.15}
- ], color: 'pale-pink', icons: [
+ {id: 9, collection: 'artDisplay', power: 3, color: 'pale-pink', icons: [
{"x": 0, "y": -0.35, "rotate": 0, "size": 2, "icon": "mdi-drawing-box"},
{"x": -0.5, "y": 0.9, "rotate": 0, "size": 1.5, "icon": "mdi-palette"},
{"x": 0.1, "y": 0.5, "rotate": 0, "size": 1, "icon": "mdi-brush"},
{"x": 0.9, "y": 0.7, "rotate": -90, "size": 1.5, "icon": "mdi-palette-swatch-variant"}
]},
- {id: 10, collection: 'artDisplay', reward: [
- {name: 'galleryInspirationIncrement', type: 'mult', value: 1 / 1.25}
+ {id: 10, collection: 'artDisplay', power: 2, reward: [
+ {name: 'galleryInspirationIncrement', type: 'mult', value: 1 / 1.1}
], color: 'light-blue', icons: [
{"x": -0.8, "y": -0.9, "rotate": 0, "size": 2, "icon": "mdi-format-line-style"},
{"x": 0, "y": -0.9, "rotate": 0, "size": 2, "icon": "mdi-format-line-style"},
@@ -92,16 +88,16 @@ export default [
{"x": -0.45, "y": 0.6, "rotate": -155, "size": 1, "icon": "mdi-brush-variant"},
{"x": -0.5, "y": 1, "rotate": 0, "size": 1.25, "icon": "mdi-pail"}
]},
- {id: 11, collection: 'artDisplay', reward: [
- {name: 'galleryInspirationIncrement', type: 'mult', value: 1 / 1.1},
- {name: 'galleryInspirationStart', type: 'base', value: 3}
+ {id: 11, collection: 'artDisplay', power: 2, reward: [
+ {name: 'galleryInspirationIncrement', type: 'mult', value: 1 / 1.05},
+ {name: 'galleryInspirationStart', type: 'base', value: 2}
], color: 'light-green', icons: [
{"x": 0, "y": -0.4, "rotate": 0, "size": 3, "icon": "mdi-image-area"},
{"x": 0.35, "y": 0.65, "rotate": -45, "size": 1.5, "icon": "mdi-tag-outline"},
{"x": 0.35, "y": 0.65, "rotate": 0, "size": 0.65, "icon": "mdi-gesture"},
{"x": 0.72, "y": 0.47, "rotate": 0, "size": 1, "icon": "mdi-fountain-pen"}
]},
- {id: 12, collection: 'artDisplay', reward: [
+ {id: 12, collection: 'artDisplay', power: 1, reward: [
{name: 'currencyGalleryCashGain', type: 'mult', value: 1.1},
{name: 'galleryInspirationStart', type: 'base', value: 3}
], color: 'red', icons: [
@@ -110,7 +106,7 @@ export default [
{"x": -0.45, "y": 0.95, "rotate": 0, "size": 1.5, "icon": "mdi-bucket"},
{"x": 0.65, "y": 0.3, "rotate": 90, "size": 1.2, "icon": "mdi-palette-swatch"}
]},
- {id: 13, collection: 'artDisplay', reward: [
+ {id: 13, collection: 'artDisplay', power: 2, reward: [
{name: 'currencyGalleryCashGain', type: 'mult', value: 1.2}
], color: 'skyblue', icons: [
{"x": 0, "y": -0.61, "rotate": 0, "size": 0.9, "icon": "mdi-shape"},
@@ -123,8 +119,8 @@ export default [
{"x": 0.4, "y": 0.13, "rotate": 0, "size": 0.8, "icon": "mdi-cash-register"},
{"x": -0.3, "y": 0.2, "rotate": 0, "size": 1, "icon": "mdi-human-male"}
]},
- {id: 14, collection: 'artDisplay', reward: [
- {name: 'currencyGalleryBeautyGain', type: 'mult', value: 1.35},
+ {id: 14, collection: 'artDisplay', power: 1, reward: [
+ {name: 'currencyGalleryBeautyGain', type: 'mult', value: 1.3},
{name: 'currencyGalleryCashGain', type: 'mult', value: 1.1}
], color: 'yellow', icons: [
{"x": -0.25, "y": 0, "rotate": 0, "size": 2, "icon": "mdi-image-outline"},
@@ -133,8 +129,8 @@ export default [
{"x": 0.8, "y": -0.5, "rotate": 0, "size": 1.5, "icon": "mdi-human-female"}
]},
- {id: 15, collection: 'deliveryService', reward: [
- {name: 'currencyGalleryConverterCap', type: 'mult', value: 2}
+ {id: 15, collection: 'deliveryService', power: 2, reward: [
+ {name: 'currencyGalleryConverterCap', type: 'mult', value: 1.3}
], color: 'pale-green', icons: [
{"x": -0.2, "y": 0, "rotate": 0, "size": 2, "icon": "mdi-delete-outline"},
{"x": -0.2, "y": 0.1, "rotate": 0, "size": 0.75, "icon": "mdi-recycle"},
@@ -142,15 +138,15 @@ export default [
{"x": 0.6, "y": -0.2, "rotate": 0, "size": 2.5, "icon": "mdi-human-greeting"},
{"x": -0.05, "y": -0.8, "rotate": 20, "size": 1, "icon": "mdi-food-takeout-box"}
]},
- {id: 16, collection: 'deliveryService', reward: [
- {name: 'currencyGalleryConverterGain', type: 'mult', value: 1.25}
+ {id: 16, collection: 'deliveryService', power: 2, reward: [
+ {name: 'currencyGalleryConverterGain', type: 'mult', value: 1.15}
], color: 'orange-red', icons: [
{"x": 0, "y": 0, "rotate": 0, "size": 3, "icon": "mdi-moped"},
{"x": 0, "y": -0.4, "rotate": 0, "size": 2, "icon": "mdi-walk"},
{"x": -0.4, "y": -0.55, "rotate": 60, "size": 1, "icon": "mdi-pizza"}
]},
- {id: 17, collection: 'deliveryService', reward: [
- {name: 'currencyGalleryPackageCap', type: 'mult', value: 1.75}
+ {id: 17, collection: 'deliveryService', power: 2, reward: [
+ {name: 'currencyGalleryPackageCap', type: 'mult', value: 1.25}
], color: 'brown', icons: [
{"x": 0.4, "y": 0, "rotate": 0, "size": 2.5, "icon": "mdi-truck-flatbed"},
{"x": -0.1, "y": -0.1, "rotate": 0, "size": 0.75, "icon": "mdi-package"},
@@ -161,15 +157,15 @@ export default [
{"x": -0.65, "y": 0.35, "rotate": 0, "size": 0.75, "icon": "mdi-package"},
{"x": -0.825, "y": 0.05, "rotate": 0, "size": 0.75, "icon": "mdi-package"}
]},
- {id: 18, collection: 'deliveryService', reward: [
- {name: 'currencyGalleryPackageGain', type: 'mult', value: 1.3}
+ {id: 18, collection: 'deliveryService', power: 2, reward: [
+ {name: 'currencyGalleryPackageGain', type: 'mult', value: 1.15}
], color: 'red', icons: [
{"x": -0.85, "y": 0, "rotate": 0, "size": 1.5, "icon": "mdi-bus-stop-covered"},
{"x": 0.3, "y": 0.1, "rotate": 0, "size": 2, "icon": "mdi-bus-school"},
{"x": 0.75, "y": -0.8, "rotate": 0, "size": 1, "icon": "mdi-town-hall"}
]},
- {id: 19, collection: 'deliveryService', reward: [
- {name: 'galleryColorDrumCap', type: 'base', value: 5}
+ {id: 19, collection: 'deliveryService', power: 3, reward: [
+ {name: 'galleryColorDrumCap', type: 'base', value: 3}
], color: 'dark-blue', icons: [
{"x": 0.65, "y": 0, "rotate": 0, "size": 2, "icon": "mdi-factory"},
{"x": -0.85, "y": 0.75, "rotate": 0, "size": 1, "icon": "mdi-barrel"},
@@ -179,9 +175,9 @@ export default [
{"x": -0.3, "y": -0.3, "rotate": 0, "size": 1, "icon": "mdi-forklift"},
{"x": -0.7, "y": -0.27, "rotate": 0, "size": 0.6, "icon": "mdi-walk"}
]},
- {id: 20, collection: 'deliveryService', reward: [
- {name: 'currencyGalleryConverterGain', type: 'mult', value: 1.15},
- {name: 'currencyGalleryPackageGain', type: 'mult', value: 1.2}
+ {id: 20, collection: 'deliveryService', power: 3, reward: [
+ {name: 'currencyGalleryConverterGain', type: 'mult', value: 1.1},
+ {name: 'currencyGalleryPackageGain', type: 'mult', value: 1.1}
], color: 'cyan', icons: [
{"x": 0.8, "y": 0.55, "rotate": 0, "size": 1.75, "icon": "mdi-ferry"},
{"x": -0.5, "y": 0.65, "rotate": 0, "size": 1, "icon": "mdi-shipping-pallet"},
@@ -191,7 +187,7 @@ export default [
{"x": -0.55, "y": 1.1, "rotate": 0, "size": 1.6, "icon": "mdi-rectangle"},
{"x": -0.05, "y": 1.1, "rotate": 0, "size": 1.6, "icon": "mdi-rectangle"}
]},
- {id: 21, collection: 'deliveryService', reward: [
+ {id: 21, collection: 'deliveryService', power: 3, reward: [
{name: 'currencyGalleryRedDrumCap', type: 'mult', value: 1.2}
], color: 'light-grey', icons: [
{"x": -0.95, "y": 0.05, "rotate": 0, "size": 1.2, "icon": "mdi-truck-cargo-container"},
@@ -206,9 +202,9 @@ export default [
{"x": 1.1, "y": -0.48, "rotate": 0, "size": 1, "icon": "mdi-traffic-light"},
{"x": 1.1, "y": 0, "rotate": 0, "size": 1.25, "icon": "mdi-sign-pole"}
]},
- {id: 22, collection: 'deliveryService', reward: [
- {name: 'galleryInspirationStart', type: 'base', value: 3},
- {name: 'galleryColorDrumCap', type: 'base', value: 3}
+ {id: 22, collection: 'deliveryService', power: 3, reward: [
+ {name: 'galleryInspirationStart', type: 'base', value: 2},
+ {name: 'galleryColorDrumCap', type: 'base', value: 2}
], color: 'light-blue', icons: [
{"x": 0, "y": -0.55, "rotate": 0, "size": 1.5, "icon": "mdi-quadcopter"},
{"x": 0, "y": 0.4, "rotate": 0, "size": 1.2, "icon": "mdi-parachute"},
@@ -216,8 +212,8 @@ export default [
{"x": -0.85, "y": 0, "rotate": 0, "size": 1, "icon": "mdi-cloud"},
{"x": 1, "y": -0.4, "rotate": 0, "size": 1, "icon": "mdi-clouds"}
]},
- {id: 23, collection: 'deliveryService', reward: [
- {name: 'galleryColorDrumCap', type: 'base', value: 3},
+ {id: 23, collection: 'deliveryService', power: 3, reward: [
+ {name: 'galleryColorDrumCap', type: 'base', value: 2},
{name: 'currencyGalleryCashGain', type: 'mult', value: 1.1}
], color: 'orange', icons: [
{"x": 0.3, "y": 0.05, "rotate": 0, "size": 1.75, "icon": "mdi-tow-truck"},
diff --git a/src/js/modules/gallery/idea.js b/src/js/modules/gallery/idea.js
index 1f52aa42..53a45b17 100644
--- a/src/js/modules/gallery/idea.js
+++ b/src/js/modules/gallery/idea.js
@@ -1,3 +1,5 @@
+import { getSequence } from "../../utils/math";
+
export default {
// Tier 1
makeItPretty: {tier: 1, owned: true, icon: 'mdi-image', color: 'deep-purple', effect: [
@@ -14,13 +16,18 @@ export default {
{name: 'currencyGalleryRedGain', type: 'mult', value: lvl => Math.pow(0.5, lvl / 2)},
]},
sortWaste: {tier: 1, icon: 'mdi-delete-variant', color: 'pale-light-green', effect: [
- {name: 'currencyGalleryConverterCap', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ {name: 'currencyGalleryConverterCap', type: 'mult', value: lvl => lvl * 0.5 + 1},
]},
advertise: {tier: 1, icon: 'mdi-cash', color: 'green', effect: [
{name: 'currencyGalleryCashGain', type: 'mult', value: lvl => lvl * 0.1 + 1},
]},
beImpatient: {tier: 1, icon: 'mdi-run-fast', color: 'light-blue', effect: [
- {name: 'currencyGalleryPackageGain', type: 'mult', value: lvl => lvl * 0.5 + 1},
+ {name: 'currencyGalleryPackageGain', type: 'mult', value: lvl => lvl * 0.1 + 1},
+ {name: 'currencyGalleryPackageCap', type: 'mult', value: lvl => lvl + 1},
+ ]},
+ beExcited: {tier: 1, icon: 'mdi-emoticon-excited', color: 'pink-purple', effect: [
+ {name: 'currencyGalleryMotivationGain', type: 'base', value: lvl => lvl * 0.02},
+ {name: 'currencyGalleryMotivationCap', type: 'base', value: lvl => lvl * 35},
]},
// Tier 2
@@ -35,18 +42,20 @@ export default {
{name: 'currencyGalleryYellowGain', type: 'mult', value: lvl => Math.pow(0.5, lvl / 2)},
]},
buildComposter: {tier: 2, icon: 'mdi-archive-sync', color: 'brown', effect: [
- {name: 'currencyGalleryConverterGain', type: 'mult', value: lvl => lvl * 0.3 + 1},
- {name: 'currencyGalleryConverterCap', type: 'mult', value: lvl => lvl * 0.3 + 1},
+ {name: 'currencyGalleryConverterGain', type: 'mult', value: lvl => getSequence(1, lvl) * 0.5 + 1},
+ {name: 'currencyGalleryConverterCap', type: 'mult', value: lvl => lvl * 0.1 + 1},
]},
- observeRainbow: {tier: 2, icon: 'mdi-looks', color: 'pink', effect: [
- {name: 'galleryColorGain', type: 'mult', value: lvl => lvl * 0.2 + 1},
+ observeRainbow: {tier: 2, icon: 'mdi-looks', color: 'babypink', effect: [
+ {name: 'galleryColorGain', type: 'mult', value: lvl => lvl * 0.1 + 1},
]},
buildRedReservoir: {tier: 2, icon: 'mdi-hoop-house', color: 'red', effect: [
- {name: 'currencyGalleryRedDrumCap', type: 'mult', value: lvl => lvl + 1},
- {name: 'galleryRedDrumChance', type: 'mult', value: lvl => Math.pow(2/3, lvl)},
+ {name: 'currencyGalleryRedDrumCap', type: 'mult', value: lvl => lvl * 0.25 + 1},
]},
orderMassiveSafe: {tier: 2, icon: 'mdi-safe-square', color: 'dark-grey', effect: [
- {name: 'galleryColorDrumCap', type: 'base', value: lvl => lvl * 3},
+ {name: 'galleryColorDrumCap', type: 'base', value: lvl => getSequence(3, lvl)},
+ ]},
+ buyPen: {tier: 2, icon: 'mdi-pen', color: 'indigo', effect: [
+ {name: 'galleryShapeGain', type: 'mult', value: lvl => lvl * 0.12 + 1},
]},
// Tier 3
@@ -64,10 +73,78 @@ export default {
{name: 'galleryColorDrumChance', type: 'mult', value: lvl => lvl * 0.4 + 1},
]},
buildOrangeReservoir: {tier: 3, icon: 'mdi-hoop-house', color: 'orange', effect: [
- {name: 'currencyGalleryOrangeDrumCap', type: 'mult', value: lvl => lvl + 1},
- {name: 'galleryOrangeDrumChance', type: 'mult', value: lvl => Math.pow(2/3, lvl)},
+ {name: 'currencyGalleryOrangeDrumCap', type: 'mult', value: lvl => lvl * 0.25 + 1},
]},
thinkHarder: {tier: 3, icon: 'mdi-head-lightbulb', color: 'amber', effect: [
{name: 'galleryInspirationStart', type: 'base', value: lvl => lvl * 2},
]},
+ paintFaster: {tier: 3, icon: 'mdi-brush', color: 'orange-red', effect: [
+ {name: 'galleryCanvasSpeed', type: 'mult', value: lvl => lvl * 0.15 + 1},
+ ]},
+ buyBrush: {tier: 3, icon: 'mdi-brush-variant', color: 'beige', effect: [
+ {name: 'gallerySpecialShapeChance', type: 'base', value: lvl => lvl * 0.002},
+ {name: 'gallerySpecialShapeMult', type: 'base', value: lvl => lvl * 1.5},
+ ]},
+
+ // Tier 4
+ harvestOranges: {tier: 4, icon: 'mdi-fruit-citrus', color: 'deep-orange', effect: [
+ {name: 'currencyGalleryDeep-orangeGain', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ {name: 'galleryDeep-orangeConversion', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ {name: 'currencyGalleryPurpleGain', type: 'mult', value: lvl => Math.pow(0.5, lvl / 2)},
+ ]},
+ pulverizeGold: {tier: 4, icon: 'mdi-shimmer', color: 'amber', effect: [
+ {name: 'currencyGalleryAmberGain', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ {name: 'galleryAmberConversion', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ {name: 'currencyGalleryDeep-orangeGain', type: 'mult', value: lvl => Math.pow(0.5, lvl / 2)},
+ ]},
+ buildYellowReservoir: {tier: 4, icon: 'mdi-hoop-house', color: 'yellow', effect: [
+ {name: 'currencyGalleryYellowDrumCap', type: 'mult', value: lvl => lvl * 0.25 + 1},
+ ]},
+ paintForFun: {tier: 4, icon: 'mdi-emoticon-happy', color: 'pink', effect: [
+ {name: 'currencyGalleryBeautyGain', type: 'mult', value: lvl => Math.pow(4, lvl)},
+ {name: 'currencyGalleryCashGain', type: 'mult', value: lvl => Math.pow(0.5, lvl)},
+ ]},
+ printNewspaper: {tier: 4, icon: 'mdi-newspaper', color: 'light-grey', effect: [
+ {name: 'currencyGalleryCashGain', type: 'mult', value: lvl => getSequence(2, lvl) * 0.25 + 1},
+ ]},
+ expandCanvas: {tier: 4, icon: 'mdi-artboard', color: 'wooden', effect: [
+ {name: 'galleryCanvasSize', type: 'base', value: lvl => lvl * 3},
+ ]},
+ hyperfocus: {tier: 4, icon: 'mdi-image-filter-center-focus-strong-outline', color: 'red-pink', effect: [
+ {name: 'currencyGalleryMotivationGain', type: 'base', value: lvl => lvl * 0.08},
+ {name: 'currencyGalleryCircleGain', type: 'mult', value: lvl => lvl * 0.24 + 1},
+ ]},
+
+ // Tier 5
+ cutGrass: {tier: 5, icon: 'mdi-grass', color: 'light-green', effect: [
+ {name: 'currencyGalleryLight-greenGain', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ {name: 'galleryLight-greenConversion', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ {name: 'currencyGalleryAmberGain', type: 'mult', value: lvl => Math.pow(0.5, lvl / 2)},
+ ]},
+ shapeClay: {tier: 5, icon: 'mdi-pot', color: 'teal', effect: [
+ {name: 'currencyGalleryTealGain', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ {name: 'galleryTealConversion', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ {name: 'currencyGalleryLight-greenGain', type: 'mult', value: lvl => Math.pow(0.5, lvl / 2)},
+ ]},
+ buildGreenReservoir: {tier: 5, icon: 'mdi-hoop-house', color: 'green', effect: [
+ {name: 'currencyGalleryGreenDrumCap', type: 'mult', value: lvl => lvl * 0.25 + 1},
+ ]},
+ beMysterious: {tier: 5, icon: 'mdi-wizard-hat', color: 'pale-purple', effect: [
+ {name: 'currencyGalleryMysteryShapeGain', type: 'base', value: lvl => (lvl % 2 === 0) ? (getSequence(1, lvl / 2) * 2) : Math.pow((lvl + 1) / 2, 2)},
+ ]},
+
+ // Tier 6
+ lookAtTheSky: {tier: 6, icon: 'mdi-clouds', color: 'light-blue', effect: [
+ {name: 'currencyGalleryLight-blueGain', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ {name: 'galleryLight-blueConversion', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ {name: 'currencyGalleryTealGain', type: 'mult', value: lvl => Math.pow(0.5, lvl / 2)},
+ ]},
+ chewBubblegum: {tier: 6, icon: 'mdi-dots-circle', color: 'pink', effect: [
+ {name: 'currencyGalleryPinkGain', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ {name: 'galleryPinkConversion', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ {name: 'currencyGalleryLight-blueGain', type: 'mult', value: lvl => Math.pow(0.5, lvl / 2)},
+ ]},
+ buildBlueReservoir: {tier: 6, icon: 'mdi-hoop-house', color: 'blue', effect: [
+ {name: 'currencyGalleryBlueDrumCap', type: 'mult', value: lvl => lvl * 0.25 + 1},
+ ]},
}
diff --git a/src/js/modules/gallery/relic.js b/src/js/modules/gallery/relic.js
index 70ae5a58..82ac5d06 100644
--- a/src/js/modules/gallery/relic.js
+++ b/src/js/modules/gallery/relic.js
@@ -48,4 +48,61 @@ export default {
{name: 'gallery_yellowPower', type: 'keepUpgrade', value: true},
{name: 'gallery_yellowConversion', type: 'keepUpgrade', value: true}
]},
+ fishbowl: {icon: 'mdi-fishbowl', color: 'pale-blue', effect: [
+ {name: 'galleryShapeGain', type: 'mult', value: 1.5},
+ {name: 'beExcited', type: 'galleryIdea', value: true}
+ ]},
+ pencil: {icon: 'mdi-lead-pencil', color: 'pale-red', effect: [
+ {name: 'galleryShapeGain', type: 'mult', value: 1.5},
+ {name: 'buyPen', type: 'galleryIdea', value: true}
+ ]},
+ smallBrush: {icon: 'mdi-brush', color: 'pale-pink', effect: [
+ {name: 'galleryShapeGain', type: 'mult', value: 1.5},
+ {name: 'buyBrush', type: 'galleryIdea', value: true}
+ ]},
+ strangePills: {icon: 'mdi-pill-multiple', color: 'pale-red', effect: [
+ {name: 'galleryShapeGain', type: 'mult', value: 1.5},
+ {name: 'hyperfocus', type: 'galleryIdea', value: true}
+ ]},
+ strangeScroll: {icon: 'mdi-script-text', color: 'dark-grey', effect: [
+ {name: 'beMysterious', type: 'galleryIdea', value: true}
+ ]},
+ printingPress: {icon: 'mdi-arrow-collapse-vertical', color: 'brown', effect: [
+ {name: 'currencyGalleryCashGain', type: 'mult', value: 1.5},
+ {name: 'printNewspaper', type: 'galleryIdea', value: true}
+ ]},
+ yellowprint: {icon: 'mdi-script-text', color: 'yellow', effect: [
+ {name: 'gallery_orangeLuck', type: 'keepUpgrade', value: true},
+ {name: 'buildYellowReservoir', type: 'galleryIdea', value: true}
+ ]},
+ greenBalloon: {icon: 'mdi-balloon', color: 'green', effect: [
+ {name: 'gallery_greenPower', type: 'keepUpgrade', value: true},
+ {name: 'gallery_greenConversion', type: 'keepUpgrade', value: true}
+ ]},
+ woodenHanger: {icon: 'mdi-hanger', color: 'wooden', effect: [
+ {name: 'paintFaster', type: 'galleryIdea', value: true}
+ ]},
+ bedsheet: {icon: 'mdi-bed-empty', color: 'pale-red', effect: [
+ {name: 'expandCanvas', type: 'galleryIdea', value: true}
+ ]},
+ imageAlbum: {icon: 'mdi-image-album', color: 'orange-red', effect: [
+ {name: 'gallery_paintDrumStorage', type: 'keepUpgrade', value: true},
+ {name: 'paintForFun', type: 'galleryIdea', value: true}
+ ]},
+ greenprint: {icon: 'mdi-script-text', color: 'green', effect: [
+ {name: 'gallery_yellowLuck', type: 'keepUpgrade', value: true},
+ {name: 'buildGreenReservoir', type: 'galleryIdea', value: true}
+ ]},
+ blueBalloon: {icon: 'mdi-balloon', color: 'blue', effect: [
+ {name: 'gallery_bluePower', type: 'keepUpgrade', value: true},
+ {name: 'gallery_blueConversion', type: 'keepUpgrade', value: true}
+ ]},
+ blueprint: {icon: 'mdi-script-text', color: 'blue', effect: [
+ {name: 'gallery_greenLuck', type: 'keepUpgrade', value: true},
+ {name: 'buildBlueReservoir', type: 'galleryIdea', value: true}
+ ]},
+ purpleBalloon: {icon: 'mdi-balloon', color: 'blue', effect: [
+ {name: 'gallery_purplePower', type: 'keepUpgrade', value: true},
+ {name: 'gallery_purpleConversion', type: 'keepUpgrade', value: true}
+ ]},
}
diff --git a/src/js/modules/gallery/shape.js b/src/js/modules/gallery/shape.js
new file mode 100644
index 00000000..6e299e67
--- /dev/null
+++ b/src/js/modules/gallery/shape.js
@@ -0,0 +1,21 @@
+export default {
+ // Shapes
+ circle: {unlocked: true, icon: 'mdi-circle', color: 'orange'},
+ rectangle: {icon: 'mdi-rectangle', color: 'indigo'},
+ triangle: {icon: 'mdi-triangle', color: 'light-green'},
+ star: {icon: 'mdi-star', color: 'amber'},
+ ellipse: {icon: 'mdi-ellipse', color: 'purple'},
+ heart: {icon: 'mdi-heart', color: 'red'},
+ square: {icon: 'mdi-square', color: 'light-blue'},
+ octagon: {icon: 'mdi-octagon', color: 'babypink'},
+ pentagon: {icon: 'mdi-pentagon', color: 'aqua'},
+ hexagon: {icon: 'mdi-hexagon', color: 'brown'},
+
+ // Special
+ bomb: {isSpecial: true, icon: 'mdi-bomb', color: 'pale-red'},
+ dice: {isSpecial: true, icon: 'mdi-dice-multiple', color: 'pale-pink'},
+ accelerator: {isSpecial: true, icon: 'mdi-rotate-orbit', color: 'pale-purple'},
+ sparkles: {isSpecial: true, icon: 'mdi-shimmer', color: 'pale-green'},
+ hourglass: {isSpecial: true, icon: 'mdi-timer-sand', color: 'pale-yellow'},
+ chest: {isSpecial: true, icon: 'mdi-treasure-chest', color: 'pale-blue'},
+}
diff --git a/src/js/modules/gallery/upgrade.js b/src/js/modules/gallery/upgrade.js
index d937cd9f..ebe120ed 100644
--- a/src/js/modules/gallery/upgrade.js
+++ b/src/js/modules/gallery/upgrade.js
@@ -31,9 +31,9 @@ export default {
filters: {note: 'gallery_4', requirement() {
return store.state.stat.gallery_red.total > 0;
}, price(lvl) {
- return {gallery_beauty: Math.pow(10, lvl) * buildNum(1, 'M')};
+ return {gallery_beauty: Math.pow(4.8, lvl) * buildNum(1, 'M')};
}, effect: [
- {name: 'currencyGalleryConverterGain', type: 'mult', value: lvl => Math.pow(1.25, lvl)}
+ {name: 'currencyGalleryConverterGain', type: 'mult', value: lvl => Math.pow(1.2, lvl)}
]},
orangePower: {cap: 15, capMult: true, requirement() {
@@ -48,7 +48,7 @@ export default {
}, price(lvl) {
return {gallery_orange: Math.pow(3 + 0.1 * lvl, lvl) * buildNum(1, 'M')};
}, effect: [
- {name: 'galleryRedDrumChance', type: 'base', value: lvl => lvl * 0.01}
+ {name: 'galleryRedDrumChance', type: 'base', value: lvl => lvl * 0.02}
]},
epiphany: {note: 'gallery_5', cap: 1, hasDescription: true, requirement() {
return store.state.stat.gallery_orange.total > 0;
@@ -60,9 +60,9 @@ export default {
trashCan: {note: 'gallery_6', requirement() {
return store.state.stat.gallery_orange.total > 0;
}, price(lvl) {
- return {gallery_beauty: Math.pow(1000, lvl) * buildNum(350, 'M')};
+ return {gallery_beauty: Math.pow(15, lvl) * buildNum(350, 'M')};
}, effect: [
- {name: 'currencyGalleryConverterCap', type: 'mult', value: lvl => Math.pow(2, lvl)}
+ {name: 'currencyGalleryConverterCap', type: 'mult', value: lvl => Math.pow(1.9, lvl)}
]},
orangeConversion: {cap: 10, requirement() {
return store.state.stat.gallery_orange.total > 0;
@@ -98,19 +98,19 @@ export default {
}, price(lvl) {
return {gallery_yellow: Math.pow(3 + 0.1 * lvl, lvl) * buildNum(1, 'M')};
}, effect: [
- {name: 'galleryOrangeDrumChance', type: 'base', value: lvl => lvl * 0.01}
+ {name: 'galleryOrangeDrumChance', type: 'base', value: lvl => lvl * 0.02}
]},
yellowConversion: {cap: 10, requirement() {
return store.state.stat.gallery_yellow.total > 0;
}, price(lvl) {
- return {gallery_beauty: Math.pow(15, lvl) * buildNum(60, 'T')};
+ return {gallery_beauty: Math.pow(15, lvl) * buildNum(12, 'T')};
}, effect: [
{name: 'galleryYellowConversion', type: 'mult', value: lvl => Math.pow(2, lvl)}
]},
paintDrumStorage: {note: 'gallery_9', cap: 1, hasDescription: true, requirement() {
return store.state.stat.gallery_yellow.total > 0;
}, price() {
- return {gallery_beauty: buildNum(1, 'Qa')};
+ return {gallery_beauty: buildNum(250, 'T')};
}, effect: [
{name: 'galleryDrums', type: 'unlock', value: lvl => lvl >= 1}
]},
@@ -127,19 +127,19 @@ export default {
}, price(lvl) {
return {gallery_green: Math.pow(3 + 0.1 * lvl, lvl) * buildNum(1, 'M')};
}, effect: [
- {name: 'galleryYellowDrumChance', type: 'base', value: lvl => lvl * 0.01}
+ {name: 'galleryYellowDrumChance', type: 'base', value: lvl => lvl * 0.02}
]},
greenConversion: {cap: 10, requirement() {
return store.state.stat.gallery_green.total > 0;
}, price(lvl) {
- return {gallery_beauty: Math.pow(20, lvl) * buildNum(33.5, 'Qi')};
+ return {gallery_beauty: Math.pow(20, lvl) * buildNum(1.35, 'Qi')};
}, effect: [
{name: 'galleryGreenConversion', type: 'mult', value: lvl => Math.pow(2, lvl)}
]},
redRage: {cap: 40, requirement() {
return store.state.stat.gallery_green.total > 0 && store.state.unlock.galleryDrums.see;
}, price(lvl) {
- return {gallery_red: Math.pow(2.75 + 0.1 * lvl, lvl) * buildNum(1, 'T')};
+ return {gallery_red: Math.pow(2.75 + 0.1 * lvl, lvl) * buildNum(100, 'T')};
}, effect: [
{name: 'currencyGalleryBeautyGain', type: 'mult', value: lvl => Math.pow(1.1, lvl)},
{name: 'currencyGalleryRedDrumCap', type: 'base', value: lvl => lvl * 2}
@@ -157,12 +157,12 @@ export default {
}, price(lvl) {
return {gallery_blue: Math.pow(3 + 0.1 * lvl, lvl) * buildNum(1, 'M')};
}, effect: [
- {name: 'galleryGreenDrumChance', type: 'base', value: lvl => lvl * 0.01}
+ {name: 'galleryGreenDrumChance', type: 'base', value: lvl => lvl * 0.02}
]},
blueConversion: {cap: 10, requirement() {
return store.state.stat.gallery_blue.total > 0;
}, price(lvl) {
- return {gallery_beauty: Math.pow(25, lvl) * buildNum(7, 'Sp')};
+ return {gallery_beauty: Math.pow(25, lvl) * buildNum(35, 'Sx')};
}, effect: [
{name: 'galleryBlueConversion', type: 'mult', value: lvl => Math.pow(2, lvl)}
]},
@@ -179,13 +179,159 @@ export default {
}, price(lvl) {
return {gallery_purple: Math.pow(3 + 0.1 * lvl, lvl) * buildNum(1, 'M')};
}, effect: [
- {name: 'galleryBlueDrumChance', type: 'base', value: lvl => lvl * 0.01}
+ {name: 'galleryBlueDrumChance', type: 'base', value: lvl => lvl * 0.02}
]},
purpleConversion: {cap: 10, requirement() {
return store.state.stat.gallery_purple.total > 0;
}, price(lvl) {
- return {gallery_beauty: Math.pow(30, lvl) * buildNum(940, 'D')};
+ return {gallery_beauty: Math.pow(30, lvl) * buildNum(9.4, 'N')};
}, effect: [
{name: 'galleryPurpleConversion', type: 'mult', value: lvl => Math.pow(2, lvl)}
]},
+
+ deepOrangePower: {cap: 15, capMult: true, requirement() {
+ return store.state.stat['gallery_deep-orange'].total > 0;
+ }, price(lvl) {
+ return {'gallery_deep-orange': Math.pow(2.5, lvl) * 4};
+ }, effect: [
+ {name: 'currencyGalleryPurpleGain', type: 'mult', value: lvl => splicedPowLinear(1.25, 0.1, 15, lvl)}
+ ]},
+ purpleLuck: {cap: 40, requirement() {
+ return store.state.stat['gallery_deep-orange'].total > 0 && store.state.unlock.galleryDrums.see;
+ }, price(lvl) {
+ return {'gallery_deep-orange': Math.pow(3 + 0.1 * lvl, lvl) * buildNum(3, 'M')};
+ }, effect: [
+ {name: 'galleryPurpleDrumChance', type: 'base', value: lvl => lvl * 0.02}
+ ]},
+ deepOrangeConversion: {cap: 10, requirement() {
+ return store.state.stat['gallery_deep-orange'].total > 0;
+ }, price(lvl) {
+ return {gallery_beauty: Math.pow(35, lvl) * buildNum(11, 'UD')};
+ }, effect: [
+ {name: 'galleryDeep-orangeConversion', type: 'mult', value: lvl => Math.pow(2, lvl)}
+ ]},
+ emptyCanvas: {cap: 1, hasDescription: true, requirement() {
+ return store.state.stat['gallery_deep-orange'].total > 0;
+ }, price() {
+ return {gallery_beauty: buildNum(40, 'UD'), 'gallery_deep-orange': 10};
+ }, effect: [
+ {name: 'galleryCanvas', type: 'unlock', value: lvl => lvl >= 1}
+ ]},
+ linen: {requirement() {
+ return store.state.unlock.galleryCanvas.use;
+ }, price(lvl) {
+ return {gallery_beauty: Math.pow(1000, lvl) * buildNum(1, 'DD')};
+ }, effect: [
+ {name: 'galleryCanvasSize', type: 'base', value: lvl => lvl}
+ ]},
+
+ amberPower: {cap: 15, capMult: true, requirement() {
+ return store.state.stat.gallery_amber.total > 0;
+ }, price(lvl) {
+ return {gallery_amber: Math.pow(2.5, lvl) * 8};
+ }, effect: [
+ {name: 'currencyGalleryDeep-orangeGain', type: 'mult', value: lvl => splicedPowLinear(1.25, 0.1, 15, lvl)}
+ ]},
+ deepOrangeLuck: {cap: 40, requirement() {
+ return store.state.stat.gallery_amber.total > 0 && store.state.unlock.galleryDrums.see;
+ }, price(lvl) {
+ return {gallery_amber: Math.pow(3 + 0.1 * lvl, lvl) * buildNum(9, 'M')};
+ }, effect: [
+ {name: 'galleryDeep-orangeDrumChance', type: 'base', value: lvl => lvl * 0.02}
+ ]},
+ amberConversion: {cap: 10, requirement() {
+ return store.state.stat.gallery_amber.total > 0;
+ }, price(lvl) {
+ return {gallery_beauty: Math.pow(50, lvl) * buildNum(555, 'QiD')};
+ }, effect: [
+ {name: 'galleryAmberConversion', type: 'mult', value: lvl => Math.pow(2, lvl)}
+ ]},
+
+ lightGreenPower: {cap: 15, capMult: true, requirement() {
+ return store.state.stat['gallery_light-green'].total > 0;
+ }, price(lvl) {
+ return {'gallery_light-green': Math.pow(2.5, lvl) * 16};
+ }, effect: [
+ {name: 'currencyGalleryAmberGain', type: 'mult', value: lvl => splicedPowLinear(1.25, 0.1, 15, lvl)}
+ ]},
+ amberLuck: {cap: 40, requirement() {
+ return store.state.stat['gallery_light-green'].total > 0 && store.state.unlock.galleryDrums.see;
+ }, price(lvl) {
+ return {'gallery_light-green': Math.pow(3 + 0.1 * lvl, lvl) * buildNum(27, 'M')};
+ }, effect: [
+ {name: 'galleryAmberDrumChance', type: 'base', value: lvl => lvl * 0.02}
+ ]},
+ lightGreenConversion: {cap: 10, requirement() {
+ return store.state.stat['gallery_light-green'].total > 0;
+ }, price(lvl) {
+ return {gallery_beauty: Math.pow(60, lvl) * buildNum(90, 'ND')};
+ }, effect: [
+ {name: 'galleryLight-greenConversion', type: 'mult', value: lvl => Math.pow(2, lvl)}
+ ]},
+
+ tealPower: {cap: 15, capMult: true, requirement() {
+ return store.state.stat.gallery_teal.total > 0;
+ }, price(lvl) {
+ return {gallery_teal: Math.pow(2.5, lvl) * 32};
+ }, effect: [
+ {name: 'currencyGalleryLight-greenGain', type: 'mult', value: lvl => splicedPowLinear(1.25, 0.1, 15, lvl)}
+ ]},
+ lightGreenLuck: {cap: 40, requirement() {
+ return store.state.stat.gallery_teal.total > 0 && store.state.unlock.galleryDrums.see;
+ }, price(lvl) {
+ return {gallery_teal: Math.pow(3 + 0.1 * lvl, lvl) * buildNum(81, 'M')};
+ }, effect: [
+ {name: 'galleryLight-greenDrumChance', type: 'base', value: lvl => lvl * 0.02}
+ ]},
+ tealConversion: {cap: 10, requirement() {
+ return store.state.stat.gallery_teal.total > 0;
+ }, price(lvl) {
+ return {gallery_beauty: Math.pow(80, lvl) * buildNum(750, 'DV')};
+ }, effect: [
+ {name: 'galleryTealConversion', type: 'mult', value: lvl => Math.pow(2, lvl)}
+ ]},
+
+ lightBluePower: {cap: 15, capMult: true, requirement() {
+ return store.state.stat['gallery_light-blue'].total > 0;
+ }, price(lvl) {
+ return {'gallery_light-blue': Math.pow(2.5, lvl) * 64};
+ }, effect: [
+ {name: 'currencyGalleryTealGain', type: 'mult', value: lvl => splicedPowLinear(1.25, 0.1, 15, lvl)}
+ ]},
+ tealLuck: {cap: 40, requirement() {
+ return store.state.stat['gallery_light-blue'].total > 0 && store.state.unlock.galleryDrums.see;
+ }, price(lvl) {
+ return {'gallery_light-blue': Math.pow(3 + 0.1 * lvl, lvl) * buildNum(243, 'M')};
+ }, effect: [
+ {name: 'galleryTealDrumChance', type: 'base', value: lvl => lvl * 0.02}
+ ]},
+ lightBlueConversion: {cap: 10, requirement() {
+ return store.state.stat['gallery_light-blue'].total > 0;
+ }, price(lvl) {
+ return {gallery_beauty: Math.pow(100, lvl) * buildNum(38, 'SxV')};
+ }, effect: [
+ {name: 'galleryLight-blueConversion', type: 'mult', value: lvl => Math.pow(2, lvl)}
+ ]},
+
+ pinkPower: {cap: 15, capMult: true, requirement() {
+ return store.state.stat.gallery_pink.total > 0;
+ }, price(lvl) {
+ return {gallery_pink: Math.pow(2.5, lvl) * 128};
+ }, effect: [
+ {name: 'currencyGalleryLight-blueGain', type: 'mult', value: lvl => splicedPowLinear(1.25, 0.1, 15, lvl)}
+ ]},
+ lightBlueLuck: {cap: 40, requirement() {
+ return store.state.stat.gallery_pink.total > 0 && store.state.unlock.galleryDrums.see;
+ }, price(lvl) {
+ return {gallery_pink: Math.pow(3 + 0.1 * lvl, lvl) * buildNum(729, 'M')};
+ }, effect: [
+ {name: 'galleryLight-blueDrumChance', type: 'base', value: lvl => lvl * 0.02}
+ ]},
+ pinkConversion: {cap: 10, requirement() {
+ return store.state.stat.gallery_pink.total > 0;
+ }, price(lvl) {
+ return {gallery_beauty: Math.pow(125, lvl) * buildNum(5, 'Tg')};
+ }, effect: [
+ {name: 'galleryPinkConversion', type: 'mult', value: lvl => Math.pow(2, lvl)}
+ ]},
}
diff --git a/src/js/modules/gallery/upgradePremium.js b/src/js/modules/gallery/upgradePremium.js
index 8c54fdc4..37cd2c61 100644
--- a/src/js/modules/gallery/upgradePremium.js
+++ b/src/js/modules/gallery/upgradePremium.js
@@ -22,6 +22,20 @@ export default {
}, effect: [
{name: 'currencyGalleryCashGain', type: 'mult', value: lvl => lvl * 0.25 + 1}
]},
+ prettyShapes: {type: 'premium', requirement() {
+ return store.state.unlock.galleryShape.see;
+ }, price(lvl) {
+ return {gem_ruby: [2, 3][lvl % 2] * Math.pow(2, Math.floor(lvl / 2)) * 225};
+ }, effect: [
+ {name: 'galleryShapeGain', type: 'mult', value: lvl => getSequence(2, lvl) * 0.5 + 1}
+ ]},
+ prettyCanvas: {type: 'premium', requirement() {
+ return store.state.unlock.galleryCanvas.see;
+ }, price(lvl) {
+ return {gem_ruby: [2, 3][lvl % 2] * Math.pow(2, Math.floor(lvl / 2)) * 320};
+ }, effect: [
+ {name: 'galleryCanvasSpeed', type: 'mult', value: lvl => getSequence(2, lvl) * 0.1 + 1}
+ ]},
prettyRed: {type: 'premium', cap: 1, requirement() {
return store.state.stat.gallery_redDrum.total > 0;
}, price(lvl) {
@@ -67,4 +81,31 @@ export default {
{name: 'galleryBlueDrumChance', type: 'mult', value: lvl => Math.pow(1.25, lvl)},
{name: 'currencyGalleryBlueDrumCap', type: 'mult', value: lvl => Math.pow(2, lvl)},
]},
+ prettyPurple: {type: 'premium', cap: 1, requirement() {
+ return store.state.stat.gallery_purpleDrum.total > 0;
+ }, price(lvl) {
+ return {gem_ruby: Math.pow(2, lvl) * 3900};
+ }, effect: [
+ {name: 'currencyGalleryPurpleGain', type: 'mult', value: lvl => Math.pow(4, lvl)},
+ {name: 'galleryPurpleDrumChance', type: 'mult', value: lvl => Math.pow(1.25, lvl)},
+ {name: 'currencyGalleryPurpleDrumCap', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ ]},
+ 'prettyDeep-orange': {type: 'premium', cap: 1, requirement() {
+ return store.state.stat['gallery_deep-orangeDrum'].total > 0;
+ }, price(lvl) {
+ return {gem_ruby: Math.pow(2, lvl) * 5200};
+ }, effect: [
+ {name: 'currencyGalleryDeep-orangeGain', type: 'mult', value: lvl => Math.pow(4, lvl)},
+ {name: 'galleryDeep-orangeDrumChance', type: 'mult', value: lvl => Math.pow(1.25, lvl)},
+ {name: 'currencyGalleryDeep-orangeDrumCap', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ ]},
+ prettyAmber: {type: 'premium', cap: 1, requirement() {
+ return store.state.stat.gallery_amberDrum.total > 0;
+ }, price(lvl) {
+ return {gem_ruby: Math.pow(2, lvl) * 6750};
+ }, effect: [
+ {name: 'currencyGalleryAmberGain', type: 'mult', value: lvl => Math.pow(4, lvl)},
+ {name: 'galleryAmberDrumChance', type: 'mult', value: lvl => Math.pow(1.25, lvl)},
+ {name: 'currencyGalleryAmberDrumCap', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ ]},
}
diff --git a/src/js/modules/gallery/upgradePrestige.js b/src/js/modules/gallery/upgradePrestige.js
index aedff9aa..6b3f6579 100644
--- a/src/js/modules/gallery/upgradePrestige.js
+++ b/src/js/modules/gallery/upgradePrestige.js
@@ -1,100 +1,125 @@
import store from "../../../store";
+import { fallbackArray } from "../../utils/array";
import { buildNum } from "../../utils/format";
+import { getSequence } from "../../utils/math";
export default {
artAcademy: {type: 'prestige', price(lvl) {
- return {gallery_cash: Math.pow(1.35, lvl) * 2};
+ return {gallery_cash: Math.pow(lvl * 0.01 + 1.65, lvl) * 2};
}, effect: [
- {name: 'currencyGalleryBeautyGain', type: 'mult', value: lvl => Math.pow(1.6, lvl)}
+ {name: 'currencyGalleryBeautyGain', type: 'mult', value: lvl => Math.pow(1.3, lvl)}
]},
- redCrayon: {type: 'prestige', cap: 10, requirement() {
+ redCrayon: {type: 'prestige', cap: 15, requirement() {
return store.state.stat.gallery_orange.total > 0;
}, price(lvl) {
- return {gallery_cash: Math.pow(lvl * 0.15 + 1.75, lvl) * 8};
+ return {gallery_cash: Math.pow(lvl * 0.02 + 1.5, lvl) * 8};
}, effect: [
{name: 'currencyGalleryRedGain', type: 'mult', value: lvl => Math.pow(1.5, lvl)}
]},
- rainbowJar: {type: 'prestige', cap: 5, price(lvl) {
- return {gallery_cash: Math.pow(10, lvl) * 10};
+ rainbowJar: {type: 'prestige', cap: 11, price(lvl) {
+ return {gallery_cash: fallbackArray([10, 100], Math.pow(1000, lvl - 1) * 10, lvl)};
}, effect: [
{name: 'carvePumpkins', type: 'galleryIdea', value: lvl => lvl >= 1},
{name: 'makeLemonade', type: 'galleryIdea', value: lvl => lvl >= 2},
{name: 'growATree', type: 'galleryIdea', value: lvl => lvl >= 3},
{name: 'drawOcean', type: 'galleryIdea', value: lvl => lvl >= 4},
{name: 'makeWine', type: 'galleryIdea', value: lvl => lvl >= 5},
+ {name: 'harvestOranges', type: 'galleryIdea', value: lvl => lvl >= 6},
+ {name: 'pulverizeGold', type: 'galleryIdea', value: lvl => lvl >= 7},
+ {name: 'cutGrass', type: 'galleryIdea', value: lvl => lvl >= 8},
+ {name: 'shapeClay', type: 'galleryIdea', value: lvl => lvl >= 9},
+ {name: 'lookAtTheSky', type: 'galleryIdea', value: lvl => lvl >= 10},
+ {name: 'chewBubblegum', type: 'galleryIdea', value: lvl => lvl >= 11},
]},
trashContainer: {type: 'prestige', cap: 8, price(lvl) {
return {gallery_cash: Math.pow(2, lvl) * 25};
}, effect: [
{name: 'currencyGalleryConverterCap', type: 'base', value: lvl => lvl * 500}
]},
- orangeCrayon: {type: 'prestige', cap: 10, requirement() {
+ orangeCrayon: {type: 'prestige', cap: 20, requirement() {
return store.state.stat.gallery_yellow.total > 0;
}, price(lvl) {
- return {gallery_cash: Math.pow(lvl * 0.15 + 1.75, lvl) * 30};
+ return {gallery_cash: Math.pow(lvl * 0.02 + 1.5, lvl) * 30};
}, effect: [
{name: 'currencyGalleryOrangeGain', type: 'mult', value: lvl => Math.pow(1.5, lvl)}
]},
- headstart: {type: 'prestige', requirement() {
+ shapes: {type: 'prestige', cap: 10, requirement() {
return store.state.stat.gallery_yellow.total > 0;
}, price(lvl) {
- return {gallery_cash: Math.pow(2, lvl) * 60};
+ return {gallery_cash: Math.pow(3 + lvl, lvl) * 150};
}, effect: [
- {name: 'galleryInspirationStart', type: 'base', value: lvl => lvl}
+ {name: 'galleryShape', type: 'unlock', value: lvl => lvl >= 1},
+ {name: 'rectangle', type: 'galleryShape', value: lvl => lvl >= 2},
+ {name: 'triangle', type: 'galleryShape', value: lvl => lvl >= 3},
+ {name: 'star', type: 'galleryShape', value: lvl => lvl >= 4},
+ {name: 'ellipse', type: 'galleryShape', value: lvl => lvl >= 5},
+ {name: 'heart', type: 'galleryShape', value: lvl => lvl >= 6},
+ {name: 'square', type: 'galleryShape', value: lvl => lvl >= 7},
+ {name: 'octagon', type: 'galleryShape', value: lvl => lvl >= 8},
+ {name: 'pentagon', type: 'galleryShape', value: lvl => lvl >= 9},
+ {name: 'hexagon', type: 'galleryShape', value: lvl => lvl >= 10},
]},
forklift: {type: 'prestige', cap: 9, requirement() {
return store.state.unlock.galleryDrums.see;
}, price(lvl) {
- return {gallery_cash: Math.pow(3, lvl) * 75};
+ return {gallery_cash: Math.pow(3, lvl) * 150};
}, effect: [
- {name: 'currencyGalleryPackageCap', type: 'base', value: lvl => lvl * 5}
+ {name: 'currencyGalleryPackageCap', type: 'base', value: lvl => lvl * 10}
]},
redCrate: {type: 'prestige', cap: 9, requirement() {
return store.state.unlock.galleryDrums.see;
}, price(lvl) {
- return {gallery_cash: Math.pow(2.15, lvl) * 180};
+ return {gallery_cash: Math.pow(2.5 + 0.2 * lvl, lvl) * 360};
}, effect: [
{name: 'currencyGalleryRedDrumCap', type: 'base', value: lvl => lvl * 10}
]},
- yellowCrayon: {type: 'prestige', cap: 10, requirement() {
+ yellowCrayon: {type: 'prestige', cap: 25, requirement() {
return store.state.stat.gallery_green.total > 0;
}, price(lvl) {
- return {gallery_cash: Math.pow(lvl * 0.15 + 1.75, lvl) * 325};
+ return {gallery_cash: Math.pow(lvl * 0.02 + 1.5, lvl) * 725};
}, effect: [
{name: 'currencyGalleryYellowGain', type: 'mult', value: lvl => Math.pow(1.5, lvl)}
]},
inspiringBooks: {type: 'prestige', requirement() {
return store.state.stat.gallery_green.total > 0;
}, price(lvl) {
- return {gallery_cash: Math.pow(2, lvl) * 600};
+ return {gallery_cash: Math.pow(2 + 0.25 * lvl, lvl) * 1400};
}, effect: [
+ {name: 'galleryInspirationBase', type: 'mult', value: lvl => Math.pow(0.8, lvl)},
{name: 'galleryInspirationIncrement', type: 'mult', value: lvl => Math.pow(0.95, lvl)}
]},
expressDelivery: {type: 'prestige', cap: 20, requirement() {
return store.state.stat.gallery_green.total > 0 && store.state.unlock.galleryDrums.see;
}, price(lvl) {
- return {gallery_cash: Math.pow(2.5 + 0.25 * lvl, lvl) * 700};
+ return {gallery_cash: Math.pow(2.5 + 0.25 * lvl, lvl) * 3000};
}, effect: [
{name: 'currencyGalleryPackageGain', type: 'mult', value: lvl => lvl * 0.2 + 1}
]},
orangeCrate: {type: 'prestige', cap: 9, requirement() {
return store.state.stat.gallery_green.total > 0 && store.state.unlock.galleryDrums.see;
}, price(lvl) {
- return {gallery_cash: Math.pow(2.15, lvl) * 4600};
+ return {gallery_cash: Math.pow(2.5 + 0.2 * lvl, lvl) * buildNum(13.5, 'K')};
}, effect: [
{name: 'currencyGalleryOrangeDrumCap', type: 'base', value: lvl => lvl * 10}
]},
- greenCrayon: {type: 'prestige', cap: 10, requirement() {
+ biggerShapes: {type: 'prestige', requirement() {
+ return store.state.stat.gallery_green.total > 0 && store.state.unlock.galleryShape.see;
+ }, price(lvl) {
+ return {gallery_cash: Math.pow(lvl * 0.05 + 1.75, lvl) * buildNum(35.5, 'K')};
+ }, effect: [
+ {name: 'galleryShapeGain', type: 'mult', value: lvl => Math.pow(1.45, lvl)}
+ ]},
+ greenCrayon: {type: 'prestige', cap: 30, requirement() {
return store.state.stat.gallery_blue.total > 0;
}, price(lvl) {
- return {gallery_cash: Math.pow(lvl * 0.15 + 1.75, lvl) * 9700};
+ return {gallery_cash: Math.pow(lvl * 0.02 + 1.5, lvl) * buildNum(110, 'K')};
}, effect: [
{name: 'currencyGalleryGreenGain', type: 'mult', value: lvl => Math.pow(1.5, lvl)}
]},
sortingSystem: {type: 'prestige', cap: 15, requirement() {
return store.state.stat.gallery_blue.total > 0;
}, price(lvl) {
- return {gallery_cash: Math.pow(2.2, lvl) * buildNum(15, 'K')};
+ return {gallery_cash: Math.pow(2.2, lvl) * buildNum(275, 'K')};
}, effect: [
{name: 'currencyGalleryConverterCap', type: 'mult', value: lvl => lvl * 0.2 + 1},
{name: 'currencyGalleryPackageCap', type: 'mult', value: lvl => lvl * 0.2 + 1}
@@ -102,45 +127,153 @@ export default {
redTruck: {type: 'prestige', cap: 5, requirement() {
return store.state.stat.gallery_blue.total > 0;
}, price(lvl) {
- return {gallery_cash: Math.pow(4 + 2 * lvl, lvl) * buildNum(28, 'K')};
+ return {gallery_cash: Math.pow(4 + 2 * lvl, lvl) * buildNum(880, 'K')};
}, effect: [
- {name: 'galleryRedDrumChance', type: 'mult', value: lvl => lvl * 0.2 + 1},
{name: 'currencyGalleryRedDrumCap', type: 'mult', value: lvl => lvl * 0.2 + 1}
]},
yellowCrate: {type: 'prestige', cap: 9, requirement() {
return store.state.stat.gallery_blue.total > 0 && store.state.unlock.galleryDrums.see;
}, price(lvl) {
- return {gallery_cash: Math.pow(2.15, lvl) * buildNum(40, 'K')};
+ return {gallery_cash: Math.pow(2.5 + 0.2 * lvl, lvl) * buildNum(2.4, 'M')};
}, effect: [
{name: 'currencyGalleryYellowDrumCap', type: 'base', value: lvl => lvl * 10}
]},
- blueCrayon: {type: 'prestige', cap: 10, requirement() {
+ blueCrayon: {type: 'prestige', cap: 35, requirement() {
return store.state.stat.gallery_purple.total > 0;
}, price(lvl) {
- return {gallery_cash: Math.pow(lvl * 0.15 + 1.75, lvl) * buildNum(65, 'K')};
+ return {gallery_cash: Math.pow(lvl * 0.02 + 1.5, lvl) * buildNum(130, 'M')};
}, effect: [
{name: 'currencyGalleryBlueGain', type: 'mult', value: lvl => Math.pow(1.5, lvl)}
]},
orangeTruck: {type: 'prestige', cap: 5, requirement() {
return store.state.stat.gallery_purple.total > 0;
}, price(lvl) {
- return {gallery_cash: Math.pow(4 + 2 * lvl, lvl) * buildNum(110, 'K')};
+ return {gallery_cash: Math.pow(4 + 2 * lvl, lvl) * buildNum(550, 'M')};
}, effect: [
- {name: 'galleryOrangeDrumChance', type: 'mult', value: lvl => lvl * 0.2 + 1},
{name: 'currencyGalleryOrangeDrumCap', type: 'mult', value: lvl => lvl * 0.2 + 1}
]},
greenCrate: {type: 'prestige', cap: 9, requirement() {
return store.state.stat.gallery_purple.total > 0 && store.state.unlock.galleryDrums.see;
}, price(lvl) {
- return {gallery_cash: Math.pow(2.15, lvl) * buildNum(280, 'K')};
+ return {gallery_cash: Math.pow(2.5 + 0.2 * lvl, lvl) * buildNum(2.3, 'B')};
}, effect: [
{name: 'currencyGalleryGreenDrumCap', type: 'base', value: lvl => lvl * 10}
]},
- purpleCrayon: {type: 'prestige', cap: 10, requirement() {
+ investment: {type: 'prestige', requirement() {
+ return store.state.stat.gallery_purple.total > 0;
+ }, price(lvl) {
+ return {gallery_cash: Math.pow(1.75 + 0.08 * lvl, lvl) * buildNum(12, 'B')};
+ }, effect: [
+ {name: 'currencyGalleryCashGain', type: 'mult', value: lvl => Math.pow(1.15, lvl)}
+ ]},
+ purpleCrayon: {type: 'prestige', cap: 40, requirement() {
return store.state.stat['gallery_deep-orange'].total > 0;
}, price(lvl) {
- return {gallery_cash: Math.pow(lvl * 0.15 + 1.75, lvl) * buildNum(720, 'K')};
+ return {gallery_cash: Math.pow(lvl * 0.02 + 1.5, lvl) * buildNum(140, 'B')};
}, effect: [
{name: 'currencyGalleryPurpleGain', type: 'mult', value: lvl => Math.pow(1.5, lvl)}
]},
+ yellowTruck: {type: 'prestige', cap: 5, requirement() {
+ return store.state.stat['gallery_deep-orange'].total > 0;
+ }, price(lvl) {
+ return {gallery_cash: Math.pow(4 + 2 * lvl, lvl) * buildNum(790, 'B')};
+ }, effect: [
+ {name: 'currencyGalleryYellowDrumCap', type: 'mult', value: lvl => lvl * 0.2 + 1}
+ ]},
+ blueCrate: {type: 'prestige', cap: 9, requirement() {
+ return store.state.stat['gallery_deep-orange'].total > 0 && store.state.unlock.galleryDrums.see;
+ }, price(lvl) {
+ return {gallery_cash: Math.pow(2.5 + 0.2 * lvl, lvl) * buildNum(3.75, 'T')};
+ }, effect: [
+ {name: 'currencyGalleryBlueDrumCap', type: 'base', value: lvl => lvl * 10}
+ ]},
+ artClass: {type: 'prestige', requirement() {
+ return store.state.unlock.galleryCanvas.see;
+ }, price(lvl) {
+ return {gallery_cash: Math.pow(1.5 + 0.1 * lvl, lvl) * buildNum(40, 'T')};
+ }, effect: [
+ {name: 'galleryCanvasSpeed', type: 'mult', value: lvl => Math.pow(1.15, lvl)}
+ ]},
+ preparation: {type: 'prestige', requirement() {
+ return store.state.unlock.galleryCanvas.see;
+ }, price(lvl) {
+ return {gallery_cash: Math.pow(2.5, getSequence(1, lvl)) * buildNum(500, 'T')};
+ }, effect: [
+ {name: 'galleryInspirationStart', type: 'base', value: lvl => lvl},
+ {name: 'galleryCanvasSize', type: 'base', value: lvl => lvl}
+ ]},
+ deepOrangeCrayon: {type: 'prestige', cap: 45, requirement() {
+ return store.state.stat.gallery_amber.total > 0;
+ }, price(lvl) {
+ return {gallery_cash: Math.pow(lvl * 0.02 + 1.5, lvl) * buildNum(6.25, 'Qa')};
+ }, effect: [
+ {name: 'currencyGalleryDeep-orangeGain', type: 'mult', value: lvl => Math.pow(1.5, lvl)}
+ ]},
+ greenTruck: {type: 'prestige', cap: 5, requirement() {
+ return store.state.stat.gallery_amber.total > 0;
+ }, price(lvl) {
+ return {gallery_cash: Math.pow(4 + 2 * lvl, lvl) * buildNum(70, 'Qa')};
+ }, effect: [
+ {name: 'currencyGalleryGreenDrumCap', type: 'mult', value: lvl => lvl * 0.1 + 1}
+ ]},
+ purpleCrate: {type: 'prestige', cap: 9, requirement() {
+ return store.state.stat.gallery_amber.total > 0 && store.state.unlock.galleryDrums.see;
+ }, price(lvl) {
+ return {gallery_cash: Math.pow(2.5 + 0.2 * lvl, lvl) * buildNum(420, 'Qa')};
+ }, effect: [
+ {name: 'currencyGalleryPurpleDrumCap', type: 'base', value: lvl => lvl * 10}
+ ]},
+ amberCrayon: {type: 'prestige', cap: 50, requirement() {
+ return store.state.stat['gallery_light-green'].total > 0;
+ }, price(lvl) {
+ return {gallery_cash: Math.pow(lvl * 0.02 + 1.5, lvl) * buildNum(2, 'Qi')};
+ }, effect: [
+ {name: 'currencyGalleryAmberGain', type: 'mult', value: lvl => Math.pow(1.5, lvl)}
+ ]},
+ truckConvoy: {type: 'prestige', requirement() {
+ return store.state.stat['gallery_light-green'].total > 0;
+ }, price(lvl) {
+ return {gallery_cash: Math.pow(1.2 + 0.1 * lvl, lvl) * buildNum(750, 'Qa')};
+ }, effect: [
+ {name: 'currencyGalleryRedDrumCap', type: 'mult', value: lvl => Math.min(lvl * 0.1 + 1, 3)},
+ {name: 'currencyGalleryOrangeDrumCap', type: 'mult', value: lvl => lvl > 5 ? Math.min((lvl - 5) * 0.1 + 1, 3) : null},
+ {name: 'currencyGalleryYellowDrumCap', type: 'mult', value: lvl => lvl > 10 ? Math.min((lvl - 10) * 0.1 + 1, 3) : null},
+ {name: 'currencyGalleryGreenDrumCap', type: 'mult', value: lvl => lvl > 15 ? Math.min((lvl - 15) * 0.1 + 1, 3) : null},
+ {name: 'currencyGalleryBlueDrumCap', type: 'mult', value: lvl => lvl > 20 ? Math.min((lvl - 20) * 0.1 + 1, 3) : null},
+ {name: 'currencyGalleryPurpleDrumCap', type: 'mult', value: lvl => lvl > 25 ? Math.min((lvl - 25) * 0.1 + 1, 3) : null},
+ {name: 'currencyGalleryDeep-orangeDrumCap', type: 'mult', value: lvl => lvl > 30 ? Math.min((lvl - 30) * 0.1 + 1, 3) : null},
+ {name: 'currencyGalleryAmberDrumCap', type: 'mult', value: lvl => lvl > 35 ? Math.min((lvl - 35) * 0.1 + 1, 3) : null},
+ {name: 'currencyGalleryLight-greenDrumCap', type: 'mult', value: lvl => lvl > 40 ? Math.min((lvl - 40) * 0.1 + 1, 3) : null},
+ {name: 'currencyGalleryTealDrumCap', type: 'mult', value: lvl => lvl > 45 ? Math.min((lvl - 45) * 0.1 + 1, 3) : null},
+ {name: 'currencyGalleryLight-blueDrumCap', type: 'mult', value: lvl => lvl > 50 ? Math.min((lvl - 50) * 0.1 + 1, 3) : null},
+ {name: 'currencyGalleryPinkDrumCap', type: 'mult', value: lvl => lvl > 55 ? Math.min((lvl - 55) * 0.1 + 1, 3) : null},
+ ]},
+ lightGreenCrayon: {type: 'prestige', cap: 55, requirement() {
+ return store.state.stat.gallery_teal.total > 0;
+ }, price(lvl) {
+ return {gallery_cash: Math.pow(lvl * 0.02 + 1.5, lvl) * buildNum(2, 'Sx')};
+ }, effect: [
+ {name: 'currencyGalleryLight-greenGain', type: 'mult', value: lvl => Math.pow(1.5, lvl)}
+ ]},
+ tealCrayon: {type: 'prestige', cap: 60, requirement() {
+ return store.state.stat['gallery_light-blue'].total > 0;
+ }, price(lvl) {
+ return {gallery_cash: Math.pow(lvl * 0.02 + 1.5, lvl) * buildNum(2, 'Sp')};
+ }, effect: [
+ {name: 'currencyGalleryTealGain', type: 'mult', value: lvl => Math.pow(1.5, lvl)}
+ ]},
+ lightBlueCrayon: {type: 'prestige', cap: 65, requirement() {
+ return store.state.stat.gallery_pink.total > 0;
+ }, price(lvl) {
+ return {gallery_cash: Math.pow(lvl * 0.02 + 1.5, lvl) * buildNum(2, 'O')};
+ }, effect: [
+ {name: 'currencyGalleryLight-blueGain', type: 'mult', value: lvl => Math.pow(1.5, lvl)}
+ ]},
+ pinkCrayon: {type: 'prestige', cap: 70, requirement() {
+ return store.state.stat.gallery_brown.total > 0;
+ }, price(lvl) {
+ return {gallery_cash: Math.pow(lvl * 0.02 + 1.5, lvl) * buildNum(2, 'N')};
+ }, effect: [
+ {name: 'currencyGalleryPinkGain', type: 'mult', value: lvl => Math.pow(1.5, lvl)}
+ ]},
}
diff --git a/src/js/modules/gallery/upgradeShape.js b/src/js/modules/gallery/upgradeShape.js
new file mode 100644
index 00000000..f60f374f
--- /dev/null
+++ b/src/js/modules/gallery/upgradeShape.js
@@ -0,0 +1,165 @@
+import store from "../../../store";
+import { fallbackArray } from "../../utils/array";
+import { buildNum } from "../../utils/format";
+import { getSequence } from "../../utils/math";
+
+export default {
+ bigCircle: {type: 'shape', price(lvl) {
+ return {gallery_circle: Math.pow(lvl * 0.01 + 1.35, lvl) * 100};
+ }, effect: [
+ {name: 'galleryShapeGain', type: 'mult', value: lvl => Math.pow(1.3, lvl)}
+ ]},
+ wellDrawnCircle: {type: 'shape', price(lvl) {
+ return {gallery_circle: Math.pow(lvl * 0.05 + 1.75, lvl) * 5000};
+ }, effect: [
+ {name: 'currencyGalleryRedGain', type: 'mult', value: lvl => getSequence(1, lvl + 4) * 0.01 + 1}
+ ]},
+ bigRectangle: {type: 'shape', requirement() {
+ return store.state.gallery.shape.rectangle.unlocked;
+ }, price(lvl) {
+ return {gallery_rectangle: Math.pow(lvl * 0.1 + 1.75, lvl) * 1000};
+ }, effect: [
+ {name: 'currencyGalleryMotivationCap', type: 'base', value: lvl => lvl * 3}
+ ]},
+ wellDrawnRectangle: {type: 'shape', requirement() {
+ return store.state.gallery.shape.rectangle.unlocked;
+ }, price(lvl) {
+ return {gallery_rectangle: Math.pow(lvl * 0.05 + 1.75, lvl) * 6500};
+ }, effect: [
+ {name: 'currencyGalleryConverterCap', type: 'base', value: lvl => lvl * 100}
+ ]},
+ creativity: {type: 'shape', requirement() {
+ return store.state.gallery.shape.triangle.unlocked;
+ }, price(lvl) {
+ return fallbackArray([
+ {gallery_triangle: buildNum(10, 'K'), gallery_circle: 4000},
+ {gallery_triangle: buildNum(100, 'K'), gallery_rectangle: buildNum(40, 'K')},
+ {gallery_triangle: buildNum(10, 'M'), gallery_star: buildNum(4, 'M')},
+ {gallery_triangle: buildNum(10, 'B'), gallery_ellipse: buildNum(3, 'B'), gallery_heart: buildNum(3, 'B')},
+ {gallery_triangle: buildNum(100, 'T'), gallery_square: buildNum(30, 'Sx'), gallery_octagon: buildNum(30, 'T')},
+ {gallery_triangle: buildNum(10, 'Qi'), gallery_pentagon: buildNum(300, 'Qa'), gallery_hexagon: buildNum(300, 'Qa')}
+ ], {gallery_triangle: Math.pow(10, getSequence(1, lvl)) * buildNum(10, 'K')}, lvl);
+ }, effect: [
+ {name: 'bomb', type: 'galleryShape', value: lvl => lvl >= 1},
+ {name: 'dice', type: 'galleryShape', value: lvl => lvl >= 2},
+ {name: 'accelerator', type: 'galleryShape', value: lvl => lvl >= 3},
+ {name: 'sparkles', type: 'galleryShape', value: lvl => lvl >= 4},
+ {name: 'hourglass', type: 'galleryShape', value: lvl => lvl >= 5},
+ {name: 'chest', type: 'galleryShape', value: lvl => lvl >= 6},
+ {name: 'currencyGalleryMotivationGain', type: 'base', value: lvl => lvl >= 7 ? ((lvl - 6) * 0.01) : null}
+ ]},
+ wellDrawnTriangle: {type: 'shape', requirement() {
+ return store.state.gallery.shape.triangle.unlocked;
+ }, price(lvl) {
+ return {gallery_triangle: Math.pow(lvl * 0.05 + 1.75, lvl) * 8500};
+ }, effect: [
+ {name: 'currencyGalleryCashGain', type: 'mult', value: lvl => lvl * 0.02 + 1}
+ ]},
+ luckyStar: {type: 'shape', requirement() {
+ return store.state.gallery.shape.star.unlocked;
+ }, price(lvl) {
+ return {gallery_star: Math.pow(lvl * 0.4 + 2.35, lvl) * buildNum(75, 'K')};
+ }, effect: [
+ {name: 'gallerySpecialShapeChance', type: 'base', value: lvl => lvl * 0.0008}
+ ]},
+ wellDrawnStar: {type: 'shape', requirement() {
+ return store.state.gallery.shape.star.unlocked;
+ }, price(lvl) {
+ return {gallery_star: Math.pow(lvl * 0.05 + 1.75, lvl) * buildNum(24, 'K')};
+ }, effect: [
+ {name: 'currencyGalleryRedDrumCap', type: 'base', value: lvl => lvl * 3}
+ ]},
+ bigEllipse: {type: 'shape', requirement() {
+ return store.state.gallery.shape.ellipse.unlocked;
+ }, price(lvl) {
+ return {gallery_ellipse: Math.pow(lvl * 0.4 + 2.35, lvl) * buildNum(400, 'K')};
+ }, effect: [
+ {name: 'gallerySpecialShapeMult', type: 'base', value: lvl => lvl * 0.25}
+ ]},
+ wellDrawnEllipse: {type: 'shape', requirement() {
+ return store.state.gallery.shape.ellipse.unlocked;
+ }, price(lvl) {
+ return {gallery_ellipse: Math.pow(lvl * 0.1 + 2.5, lvl) * buildNum(150, 'K')};
+ }, effect: [
+ {name: 'galleryColorDrumCap', type: 'base', value: lvl => lvl}
+ ]},
+ bigHeart: {type: 'shape', requirement() {
+ return store.state.gallery.shape.heart.unlocked;
+ }, price(lvl) {
+ return {gallery_heart: Math.pow(lvl + 8, lvl) * buildNum(2, 'M')};
+ }, effect: [
+ {name: 'galleryShapeGain', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ {name: 'currencyGalleryMotivationCap', type: 'base', value: lvl => lvl * 8}
+ ]},
+ wellDrawnHeart: {type: 'shape', requirement() {
+ return store.state.gallery.shape.heart.unlocked;
+ }, price(lvl) {
+ return {gallery_heart: Math.pow(lvl * 0.05 + 1.75, lvl) * buildNum(600, 'K')};
+ }, effect: [
+ {name: 'galleryColorGain', type: 'mult', value: lvl => lvl * 0.01 + 1}
+ ]},
+ bigSquare: {type: 'shape', requirement() {
+ return store.state.gallery.shape.square.unlocked;
+ }, price(lvl) {
+ return {gallery_square: Math.pow(lvl * 0.002 + 1.35, lvl) * buildNum(15, 'M')};
+ }, effect: [
+ {name: 'currencyGallerySquareGain', type: 'mult', value: lvl => Math.pow(1.3, lvl)}
+ ]},
+ wellDrawnSquare: {type: 'shape', requirement() {
+ return store.state.gallery.shape.square.unlocked;
+ }, price(lvl) {
+ return {gallery_square: Math.pow(lvl * 0.15 + 2.5, lvl) * buildNum(3.75, 'M')};
+ }, effect: [
+ {name: 'currencyGalleryOrangeDrumCap', type: 'base', value: lvl => lvl * 3},
+ {name: 'currencyGalleryYellowDrumCap', type: 'base', value: lvl => lvl * 2},
+ {name: 'currencyGalleryGreenDrumCap', type: 'base', value: lvl => lvl}
+ ]},
+ bigOctagon: {type: 'shape', requirement() {
+ return store.state.gallery.shape.octagon.unlocked;
+ }, price(lvl) {
+ return {gallery_octagon: Math.pow(lvl * 0.01 + 1.45, lvl) * buildNum(1, 'B')};
+ }, effect: [
+ {name: 'currencyGalleryCircleGain', type: 'mult', value: lvl => Math.pow(1.1, lvl)},
+ {name: 'currencyGalleryRectangleGain', type: 'mult', value: lvl => Math.pow(1.1, lvl)},
+ {name: 'currencyGalleryTriangleGain', type: 'mult', value: lvl => Math.pow(1.1, lvl)}
+ ]},
+ wellDrawnOctagon: {type: 'shape', requirement() {
+ return store.state.gallery.shape.octagon.unlocked;
+ }, price(lvl) {
+ return {gallery_octagon: Math.pow(lvl * 0.2 + 1.75, lvl) * buildNum(225, 'M')};
+ }, effect: [
+ {name: 'galleryInspirationBase', type: 'mult', value: lvl => 1 / (0.02 * lvl + 1)}
+ ]},
+ bigPentagon: {type: 'shape', requirement() {
+ return store.state.gallery.shape.pentagon.unlocked;
+ }, price(lvl) {
+ return {gallery_pentagon: Math.pow(lvl * 0.01 + 1.45, lvl) * buildNum(75, 'B')};
+ }, effect: [
+ {name: 'currencyGalleryStarGain', type: 'mult', value: lvl => Math.pow(1.1, lvl)},
+ {name: 'currencyGalleryEllipseGain', type: 'mult', value: lvl => Math.pow(1.1, lvl)},
+ {name: 'currencyGalleryHeartGain', type: 'mult', value: lvl => Math.pow(1.1, lvl)}
+ ]},
+ wellDrawnPentagon: {type: 'shape', requirement() {
+ return store.state.gallery.shape.pentagon.unlocked;
+ }, price(lvl) {
+ return {gallery_pentagon: Math.pow(lvl * 0.1 + 1.75, lvl) * buildNum(13.5, 'B')};
+ }, effect: [
+ {name: 'currencyGalleryPackageCap', type: 'base', value: lvl => lvl * 3}
+ ]},
+ bigHexagon: {type: 'shape', requirement() {
+ return store.state.gallery.shape.hexagon.unlocked;
+ }, price(lvl) {
+ return {gallery_hexagon: Math.pow(lvl * 0.01 + 1.45, lvl) * buildNum(11, 'T')};
+ }, effect: [
+ {name: 'currencyGalleryOctagonGain', type: 'mult', value: lvl => Math.pow(1.1, lvl)},
+ {name: 'currencyGalleryPentagonGain', type: 'mult', value: lvl => Math.pow(1.1, lvl)},
+ {name: 'currencyGalleryHexagonGain', type: 'mult', value: lvl => Math.pow(1.1, lvl)}
+ ]},
+ wellDrawnHexagon: {type: 'shape', requirement() {
+ return store.state.gallery.shape.hexagon.unlocked;
+ }, price(lvl) {
+ return {gallery_hexagon: Math.pow(lvl * 0.1 + 1.75, lvl) * buildNum(2, 'T')};
+ }, effect: [
+ {name: 'galleryCanvasSpeed', type: 'mult', value: lvl => lvl * 0.02 + 1}
+ ]},
+}
diff --git a/src/js/modules/gem/card.js b/src/js/modules/gem/card.js
index 49bd2b1b..e8e3d863 100644
--- a/src/js/modules/gem/card.js
+++ b/src/js/modules/gem/card.js
@@ -1,7 +1,12 @@
import cardList from "./cardList";
export default {
- feature: {prefix: 'GE', reward: [{name: 'currencyGemTopazCap', type: 'base', value: lvl => lvl * 20}], unlock: 'gemFeature'},
+ feature: {
+ prefix: 'GE',
+ reward: [{name: 'currencyGemTopazCap', type: 'base', value: lvl => lvl * 20}],
+ shinyReward: [{name: 'currencyGemTopazCap', type: 'base', value: lvl => lvl * 20}],
+ unlock: 'gemFeature'
+ },
collection: {
preciousJewelry: {reward: [
{name: 'currencyGemTopazCap', type: 'base', value: 160}
diff --git a/src/js/modules/general.js b/src/js/modules/general.js
index 2d2c2671..81445ea7 100644
--- a/src/js/modules/general.js
+++ b/src/js/modules/general.js
@@ -63,35 +63,35 @@ export default {
unlock: ['generalFeature', 'generalOrladeeSubfeature', 'generalOppenschroeSubfeature', 'generalBelluxSubfeature', 'generalOnocluaSubfeature', 'generalOmnisolixSubfeature'],
note: ['g', ...buildArray(31).map(() => 'grobodal'), ...buildArray(9).map(() => 'orladee')],
relic: {
- torch: {icon: 'mdi-torch', color: 'orange', effect: [
+ torch: {icon: 'mdi-torch', feature: ['general', 'mining', 'village'], color: 'orange', effect: [
{name: 'miningCardCap', type: 'base', value: 1},
{name: 'villageCardCap', type: 'base', value: 1}
]},
- purpleHeart: {icon: 'mdi-heart', color: 'purple', effect: [
+ purpleHeart: {icon: 'mdi-heart', feature: ['general', 'horde'], color: 'purple', effect: [
{name: 'hordeHealth', type: 'mult', value: 1.5},
{name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: 1.2}
]},
- rottenLeaf: {icon: 'mdi-leaf', color: 'brown', effect: [
+ rottenLeaf: {icon: 'mdi-leaf', feature: ['general', 'farm'], color: 'brown', effect: [
{name: 'farmCropGain', type: 'mult', value: 1.75},
{name: 'farmExperience', type: 'mult', value: 1.2},
{name: 'farmOvergrow', type: 'base', value: 0.1}
]},
- stonepiercer: {icon: 'mdi-screwdriver', color: 'cherry', effect: [
+ stonepiercer: {icon: 'mdi-screwdriver', feature: ['general', 'mining'], color: 'cherry', effect: [
{name: 'miningDamage', type: 'mult', value: 2.25}
]},
- consolationPrize: {icon: 'mdi-seal-variant', color: 'lighter-grey', effect: [
+ consolationPrize: {icon: 'mdi-seal-variant', feature: ['general', 'village', 'horde', 'farm'], color: 'lighter-grey', effect: [
{name: 'villageResourceGain', type: 'mult', value: 1.4},
{name: 'hordeItemMasteryGain', type: 'mult', value: 1.4},
{name: 'farmExperience', type: 'mult', value: 1.4}
]},
- prettyLamp: {icon: 'mdi-vanity-light', color: 'light-blue', effect: [
+ prettyLamp: {icon: 'mdi-vanity-light', feature: ['general', 'gallery'], color: 'light-blue', effect: [
{name: 'galleryInspirationStart', type: 'base', value: 3},
{name: 'thinkHarder', type: 'galleryIdea', value: true},
]},
- chessboard: {icon: 'mdi-checkerboard', color: 'grey', effect: [
+ chessboard: {icon: 'mdi-checkerboard', feature: ['general', 'horde'], color: 'grey', effect: [
{name: 'hordeChessItems', type: 'unlock', value: true},
]},
- iridiscentFlower: {icon: 'mdi-flower-pollen', color: 'pink', effect: [
+ iridiscentFlower: {icon: 'mdi-flower-pollen', feature: ['general', 'cryolab'], color: 'pink', effect: [
{name: 'cryolabMaxFeatures', type: 'base', value: 1},
]},
},
diff --git a/src/js/modules/horde.js b/src/js/modules/horde.js
index 95fe3ebf..781e5702 100644
--- a/src/js/modules/horde.js
+++ b/src/js/modules/horde.js
@@ -1,5 +1,5 @@
import store from "../../store"
-import { HORDE_ENEMY_RESPAWN_MAX, HORDE_ENEMY_RESPAWN_TIME, HORDE_INACTIVE_ITEM_COOLDOWN, HORDE_MONSTER_PART_MIN_ZONE, HORDE_RAMPAGE_ATTACK, HORDE_RAMPAGE_BOSS_TIME, HORDE_RAMPAGE_CRIT_CHANCE, HORDE_RAMPAGE_CRIT_DAMAGE, HORDE_RAMPAGE_ENEMY_TIME, HORDE_RAMPAGE_STUN_RESIST, SECONDS_PER_DAY } from "../constants";
+import { HORDE_DAMAGE_INCREASE_PER_STRENGTH, HORDE_ENEMY_RESPAWN_MAX, HORDE_ENEMY_RESPAWN_TIME, HORDE_INACTIVE_ITEM_COOLDOWN, HORDE_MONSTER_PART_MIN_ZONE, HORDE_RAMPAGE_ATTACK, HORDE_RAMPAGE_BOSS_TIME, HORDE_RAMPAGE_CRIT_CHANCE, HORDE_RAMPAGE_CRIT_DAMAGE, HORDE_RAMPAGE_ENEMY_TIME, HORDE_RAMPAGE_STUN_RESIST, HORDE_SHARD_CHANCE_REDUCTION, SECONDS_PER_DAY, SECONDS_PER_MINUTE } from "../constants";
import { buildArray } from "../utils/array";
import { buildNum } from "../utils/format";
import { chance, randomRound } from "../utils/random";
@@ -9,19 +9,42 @@ import equipment from "./horde/equipment";
import relic from "./horde/relic";
import sigil from "./horde/sigil";
import upgrade from "./horde/upgrade";
+import upgrade2 from "./horde/upgrade2";
import upgradePremium from "./horde/upgradePremium";
import upgradePrestige from "./horde/upgradePrestige";
import bookHorde from "./school/bookHorde";
import tower from "./horde/tower";
+import adventurer from "./horde/fighterClass/adventurer";
+import warzone from "./horde/area/warzone";
+import loveIsland from "./horde/area/loveIsland";
+import monkeyJungle from "./horde/area/monkeyJungle";
+import battlePass from "./horde/battlePass";
+import archer from "./horde/fighterClass/archer";
+import mage from "./horde/fighterClass/mage";
+import knight from "./horde/fighterClass/knight";
+import assassin from "./horde/fighterClass/assassin";
+import shaman from "./horde/fighterClass/shaman";
+import pirate from "./horde/fighterClass/pirate";
+import undead from "./horde/fighterClass/undead";
+import cultist from "./horde/fighterClass/cultist";
+import enemyType from "./horde/enemyType";
+import boss from "./horde/boss";
+import scholar from "./horde/fighterClass/scholar";
+import trinket from "./horde/trinket";
+import sigil_boss from "./horde/sigil_boss";
function playerDie() {
if (store.state.horde.player.revive) {
- store.commit('horde/updatePlayerKey', {key: 'health', value: store.getters['mult/get']('hordeHealth')});
+ store.commit('horde/updatePlayerKey', {key: 'health', value: store.state.horde.cachePlayerStats.health});
store.commit('horde/updatePlayerKey', {key: 'revive', value: store.state.horde.player.revive - 1});
+ return false;
} else {
store.commit('horde/updatePlayerKey', {key: 'health', value: 0});
store.commit('horde/updateKey', {key: 'combo', value: 0});
+ store.commit('horde/updateKey', {key: 'bossStage', value: 0});
store.commit('horde/updateKey', {key: 'bossFight', value: 0});
+ store.commit('horde/updateKey', {key: 'playerBuff', value: {}});
+ store.dispatch('horde/updatePlayerCache');
store.commit('horde/updateKey', {key: 'enemy', value: null});
@@ -35,6 +58,7 @@ function playerDie() {
store.commit('horde/updateKey', {key: 'towerFloor', value: 0});
store.dispatch('horde/resetStats');
}
+ return true;
}
}
@@ -49,6 +73,57 @@ function getDamage(amount, type, offender, defender) {
return amount * offender[type + 'Attack'] * defender[type + 'Taken'];
}
+function applyCritEffects(amount) {
+ const energyOnCrit = store.getters['tag/values']('hordeEnergyOnCrit')[0];
+ const healOnCrit = store.getters['tag/values']('hordeHealOnCrit')[0];
+ const restoreCooldownOnCrit = store.getters['tag/values']('hordeRestoreCooldownOnCrit')[0];
+ const bloodOnCrit = store.getters['tag/values']('hordeBloodOnCrit')[0];
+
+ if (energyOnCrit > 0 && store.state.horde.player.energy < store.state.horde.cachePlayerStats.energy) {
+ store.dispatch('horde/updateEnergy', Math.min(store.state.horde.player.energy + energyOnCrit * amount, store.state.horde.cachePlayerStats.energy));
+ }
+ if (healOnCrit > 0) {
+ store.commit('horde/updatePlayerKey', {key: 'health', value: Math.min(store.state.horde.cachePlayerStats.health, store.state.horde.player.health + store.state.horde.cachePlayerStats.health * store.state.horde.cachePlayerStats.healing * healOnCrit * amount)});
+ }
+ if (restoreCooldownOnCrit > 0) {
+ tickPlayerCooldowns(restoreCooldownOnCrit * amount);
+ }
+ if (bloodOnCrit > 0) {
+ store.dispatch('currency/gain', {feature: 'horde', name: 'blood', gainMult: true, amount: bloodOnCrit * amount * store.getters['horde/enemyBlood'](store.state.stat.horde_maxDifficulty.value, 0)});
+ }
+}
+
+function tickPlayerCooldowns(seconds) {
+ const hasteMult = store.state.horde.cachePlayerStats.haste * 0.01 + 1;
+ for (const [key, elem] of Object.entries(store.state.horde.items)) {
+ if (!(elem.equipped && elem.passive) && (elem.cooldownLeft > 0 || (elem.activeType === 'utility' && elem.equipped && !elem.passive))) {
+ const newCooldown = elem.cooldownLeft - seconds * (elem.activeType === 'combat' ? hasteMult : 1) * ((elem.equipped && !elem.passive) ? 1 : HORDE_INACTIVE_ITEM_COOLDOWN);
+ store.commit('horde/updateItemKey', {
+ name: key,
+ key: 'cooldownLeft',
+ value: elem.activeType === 'utility' ? newCooldown : Math.max(0, newCooldown)
+ });
+ }
+ }
+ for (const [key, elem] of Object.entries(store.state.horde.skillActive)) {
+ const split = key.split('_');
+ let type = null;
+ if (split[0] === 'skill') {
+ type = store.state.horde.fighterClass[store.state.horde.selectedClass].skills[split[1]].activeType;
+ } else if (split[0] === 'trinket') {
+ type = store.state.horde.trinket[split[1]].activeType;
+ }
+ if (elem > 0 || type === 'utility') {
+ const newCooldown = elem - seconds * (type === 'combat' ? hasteMult : 1);
+ store.commit('horde/updateSubkey', {
+ name: 'skillActive',
+ key,
+ value: type === 'utility' ? newCooldown : Math.max(0, newCooldown)
+ });
+ }
+ }
+}
+
const damageTypes = ['physic', 'magic', 'bio'];
const newSimulation = {
dead: 0,
@@ -59,6 +134,7 @@ const newSimulation = {
minibossDead: 0,
damage: 0,
bone: 0,
+ blood: 0,
monsterPartTime: 0,
complete: false
};
@@ -67,15 +143,40 @@ export default {
name: 'horde',
tickspeed: 1,
unlockNeeded: 'hordeFeature',
- tick(seconds, oldTime, newTime) {
+ forceTick(seconds, oldTime, newTime) {
+ // Get tower keys
+ if (store.state.unlock.hordeBrickTower.see) {
+ const dayDiff = Math.floor(newTime / (SECONDS_PER_DAY * 7)) - Math.floor(oldTime / (SECONDS_PER_DAY * 7));
+ if (dayDiff > 0) {
+ store.dispatch('currency/gain', {feature: 'horde', name: 'towerKey', amount: dayDiff}, {root: true});
+ }
+ }
+ },
+ tick(seconds) {
store.commit('stat/add', {feature: 'horde', name: 'timeSpent', value: seconds});
+ const subfeature = store.state.system.features.horde.currentSubfeature;
+
// Gain mystical shards
- const shardsMaxGain = store.getters['horde/maxMysticalShards'] - store.state.currency.horde_mysticalShard.value;
- if (shardsMaxGain > 0) {
- const gain = Math.min(randomRound(seconds * store.getters['mult/get']('hordeShardChance')), shardsMaxGain);
- if (gain > 0) {
- store.dispatch('currency/gain', {feature: 'horde', name: 'mysticalShard', amount: gain});
+ if (subfeature === 0) {
+ let secondsLeft = seconds;
+ let baseChance = store.getters['mult/get']('hordeShardChance');
+ let shards = 0;
+ while (secondsLeft > 0 && store.state.currency.horde_mysticalShard.value < store.state.currency.horde_mysticalShard.cap) {
+ if (baseChance * secondsLeft >= 1) {
+ // guaranteed shard
+ secondsLeft -= Math.ceil(1 / baseChance);
+ baseChance /= HORDE_SHARD_CHANCE_REDUCTION;
+ shards++;
+ } else {
+ if (chance(baseChance * secondsLeft)) {
+ shards++;
+ }
+ secondsLeft = 0;
+ }
+ }
+ if (shards > 0) {
+ store.dispatch('currency/gain', {feature: 'horde', name: 'mysticalShard', amount: shards});
}
}
@@ -84,71 +185,84 @@ export default {
store.dispatch('currency/gain', {feature: 'horde', name: 'corruptedFlesh', amount: store.getters['mult/get'](`currencyHordeCorruptedFleshGain`) * seconds});
}
- // Tick player cooldowns
- for (const [key, elem] of Object.entries(store.state.horde.items)) {
- if (elem.cooldownLeft > 0 || (elem.activeType === 'utility' && elem.equipped && !elem.passive)) {
- const newCooldown = elem.cooldownLeft - seconds * ((elem.equipped && !elem.passive) ? 1 : HORDE_INACTIVE_ITEM_COOLDOWN);
- store.commit('horde/updateItemKey', {
- name: key,
- key: 'cooldownLeft',
- value: elem.activeType === 'utility' ? newCooldown : Math.max(0, newCooldown)
- });
+ // Level up player
+ if (subfeature === 1) {
+ const oldProgress = store.state.horde.expLevel;
+ let progress = store.state.horde.expLevel;
+ let secondsLeft = seconds;
+ while (secondsLeft > 0) {
+ const difficulty = store.getters['horde/expDifficulty'](Math.floor(progress));
+ const timeUsed = Math.min((Math.floor(progress + 1) - progress) * difficulty, secondsLeft);
+ progress += timeUsed / difficulty;
+ secondsLeft -= timeUsed;
+ }
+ store.commit('horde/updateKey', {key: 'expLevel', value: progress});
+ const newLvl = Math.floor(progress);
+ if (newLvl > Math.floor(oldProgress)) {
+ store.commit('horde/updateKey', {key: 'skillPoints', value: (newLvl - Math.floor(oldProgress)) * store.getters['mult/get']('hordeSkillPointsPerLevel') + store.state.horde.skillPoints});
+ store.dispatch('horde/applyClassLevelEffects');
+
+ const classObj = store.state.horde.fighterClass[store.state.horde.selectedClass];
+ if (classObj.questsCompleted.level < classObj.quests.level.length && newLvl >= classObj.quests.level[classObj.questsCompleted.level]) {
+ store.commit('horde/updateClassQuestKey', {name: store.state.horde.selectedClass, key: 'level', value: classObj.quests.level.filter(el => newLvl >= el).length});
+ store.dispatch('horde/applyBattlePassEffects');
+ }
+ }
+
+ // Boss pass gain
+ if (store.state.horde.selectedClass === 'pirate') {
+ store.dispatch('currency/gain', {feature: 'horde', name: 'lockpick', amount: store.getters['mult/get'](`currencyHordeLockpickGain`) * seconds});
}
}
// Prepare combat stats
- const conversionTotal = store.getters['mult/get']('hordePhysicConversion') + store.getters['mult/get']('hordeMagicConversion') + store.getters['mult/get']('hordeBioConversion');
- const playerStats = {
- attack: store.getters['mult/get']('hordeAttack'),
- critChance: store.getters['mult/get']('hordeCritChance'),
- critMult: store.getters['mult/get']('hordeCritMult', 0, 1, 1),
- toxic: store.getters['mult/get']('hordeToxic'),
- firstStrike: store.getters['mult/get']('hordeFirstStrike'),
- spellblade: store.getters['mult/get']('hordeSpellblade'),
- cutting: store.getters['mult/get']('hordeCutting'),
- stunResist: store.getters['mult/get']('hordeStunResist'),
- shieldbreak: store.getters['mult/get']('hordeShieldbreak'),
-
- // Damage type specifics
- physicConversion: store.getters['mult/get']('hordePhysicConversion') / conversionTotal,
- magicConversion: store.getters['mult/get']('hordeMagicConversion') / conversionTotal,
- bioConversion: store.getters['mult/get']('hordeBioConversion') / conversionTotal,
- physicAttack: store.getters['mult/get']('hordePhysicAttack'),
- magicAttack: store.getters['mult/get']('hordeMagicAttack'),
- bioAttack: store.getters['mult/get']('hordeBioAttack'),
- physicTaken: store.getters['mult/get']('hordePhysicTaken'),
- magicTaken: store.getters['mult/get']('hordeMagicTaken'),
- bioTaken: store.getters['mult/get']('hordeBioTaken'),
- };
+ const playerStats = store.state.horde.cachePlayerStats;
let simulation = {...newSimulation};
+ let secondsLeft = seconds;
+ const attackAfterTime = store.getters['tag/values']('hordeAttackAfterTime')[0];
+ const strIntAfterTime = store.getters['tag/values']('hordeStrIntAfterTime')[0];
// Run combat
- while (seconds > 0) {
+ while (secondsLeft > 0) {
let respawn = store.state.horde.respawn;
let secondsSpent = 0;
- if (simulation.dead >= 2 && simulation.killed >= 100 && !simulation.complete) {
+ if ((simulation.dead >= 2 && simulation.killed >= 100 || simulation.dead >= 10) && !simulation.complete) {
// Combat simulation: gain resources based on average
const simTime = simulation.time + simulation.minibossTime + simulation.monsterPartTime;
- let cycles = Math.floor(seconds / simTime);
+ let cycles = Math.floor(secondsLeft / simTime) - 1;
- // Regular drops first
- store.dispatch('currency/gain', {feature: 'horde', name: 'bone', gainMult: true, amount: cycles * simulation.bone});
- store.dispatch('currency/gain', {feature: 'horde', name: 'monsterPart', gainMult: true, amount: cycles * simulation.monsterPartTime * store.getters['horde/currentMonsterPart']});
- store.commit('stat/add', {feature: 'horde', name: 'totalDamage', value: cycles * simulation.damage});
- store.dispatch('horde/findItems', cycles * simulation.killed);
+ if (cycles > 0) {
+ // Regular drops first
+ if (simulation.bone > 0) {
+ store.dispatch('currency/gain', {feature: 'horde', name: 'bone', gainMult: true, amount: cycles * simulation.bone});
+ }
+ if (subfeature === 0 && simulation.monsterPartTime > 0) {
+ store.dispatch('currency/gain', {feature: 'horde', name: 'monsterPart', gainMult: true, amount: cycles * simulation.monsterPartTime * store.getters['horde/currentMonsterPart']});
+ }
+ if (simulation.blood > 0) {
+ store.dispatch('currency/gain', {feature: 'horde', name: 'blood', gainMult: true, amount: cycles * simulation.blood});
+ }
+ store.commit('stat/add', {feature: 'horde', name: 'totalDamage', value: cycles * simulation.damage});
+ if (subfeature === 0) {
+ store.dispatch('horde/findItems', cycles * simulation.killed);
+
+ // Miniboss stuff after
+ secondsSpent = simTime * cycles;
+ const minibossTimer = secondsSpent / store.getters['mult/get']('hordeMinibossTime') + store.state.horde.minibossTimer;
+ const minibossesKilled = Math.floor(minibossTimer) - (store.state.horde.bossFight === 1 ? 1 : 0);
+ store.commit('horde/updateKey', {key: 'minibossTimer', value: Math.min(minibossTimer - minibossesKilled, 2)});
+ store.dispatch('horde/getMinibossReward', minibossesKilled);
+ }
- // Miniboss stuff after
- secondsSpent = simTime * cycles;
- const minibossTimer = secondsSpent / store.getters['mult/get']('hordeMinibossTime') + store.state.horde.minibossTimer;
- const minibossesKilled = Math.floor(minibossTimer) - (store.state.horde.bossFight === 1 ? 1 : 0);
- store.commit('horde/updateKey', {key: 'minibossTimer', value: Math.min(minibossTimer - minibossesKilled, 2)});
- store.dispatch('horde/getMinibossReward', minibossesKilled);
+ secondsLeft -= cycles * simTime;
+ tickPlayerCooldowns(cycles * simTime);
+ }
simulation.complete = true;
} else if (respawn > 0) {
// Wait for the player to respawn
- secondsSpent = Math.min(respawn, seconds);
+ secondsSpent = Math.min(respawn, secondsLeft);
let newRespawn = respawn - secondsSpent;
tickEnemyRespawn(secondsSpent);
@@ -182,11 +296,21 @@ export default {
// determine if the chosen attack can be used
let usedAttack = null;
+ let item = null;
if (store.state.horde.player.silence > 0) {
store.commit('horde/updatePlayerKey', {key: 'silence', value: Math.max(0, store.state.horde.player.silence - 1)});
} else if (store.state.horde.chosenActive) {
- const item = store.state.horde.items[store.state.horde.chosenActive];
- if ((!isStunned || item.usableInStun) && item.cooldownLeft <= 0) {
+ if (subfeature === 0) {
+ item = store.state.horde.items[store.state.horde.chosenActive];
+ } else if (subfeature === 1) {
+ const split = store.state.horde.chosenActive.split('_');
+ if (split[0] === 'skill') {
+ item = store.state.horde.fighterClass[store.state.horde.selectedClass].skills[split[1]];
+ } else if (split[0] === 'trinket') {
+ item = store.state.horde.trinket[split[1]];
+ }
+ }
+ if ((!isStunned || item.usableInStun) && (subfeature === 1 ? store.state.horde.skillActive[store.state.horde.chosenActive] : item.cooldownLeft) <= 0) {
usedAttack = store.state.horde.chosenActive;
}
}
@@ -196,55 +320,119 @@ export default {
}
if (!isStunned || usedAttack) {
// PLAYER ATTACK
-
- const baseDamage = playerStats.attack * Math.pow(playerStats.critMult, randomRound(playerStats.critChance));
const divisionShieldMult = enemyStats.divisionShield + 1;
let damage = 0;
let hitShield = false;
- if (usedAttack) {
- store.state.horde.items[usedAttack].active(store.state.horde.items[usedAttack].level).forEach(elem => {
- if (elem.type === 'heal') {
- store.commit('horde/updatePlayerKey', {key: 'health', value: Math.min(store.getters['mult/get']('hordeHealth'), store.state.horde.player.health + store.getters['mult/get']('hordeHealth') * elem.value)});
- } else if (elem.type === 'stun') {
- store.commit('horde/updateEnemyKey', {key: 'stun', value: store.state.horde.enemy.stun + elem.value});
- } else if (elem.type === 'silence') {
- store.commit('horde/updateEnemyKey', {key: 'silence', value: store.state.horde.enemy.silence + elem.value});
- } else if (elem.type === 'revive') {
- store.commit('horde/updatePlayerKey', {key: 'revive', value: Math.min(store.getters['mult/get']('hordeRevive'), store.state.horde.player.revive + elem.value)});
- } else if (elem.type === 'reviveAll') {
- store.commit('horde/updatePlayerKey', {key: 'revive', value: store.getters['mult/get']('hordeRevive')});
- } else if (elem.type === 'divisionShield') {
- store.commit('horde/updatePlayerKey', {key: 'divisionShield', value: store.state.horde.player.divisionShield + elem.value});
- } else if (elem.type === 'removeDivisionShield') {
- store.commit('horde/updateEnemyKey', {key: 'divisionShield', value: Math.ceil(store.state.horde.enemy.divisionShield * (1 - elem.value))});
- } else if (elem.type === 'removeAttack') {
- if (store.state.horde.fightRampage <= 0) {
- store.commit('horde/updateEnemyKey', {key: 'attack', value: Math.max(0, store.state.horde.enemy.attack * (1 - elem.value))});
+ if (usedAttack && item) {
+ const activeLevel = subfeature === 1 ? (
+ usedAttack.split('_')[0] === 'skill' ? (store.state.horde.skillLevel[usedAttack.split('_')[1]] ?? 0) : (store.state.horde.trinket[usedAttack.split('_')[1]].level)
+ ) : item.level;
+ const activeCost = item.activeCost !== undefined ? item.activeCost(activeLevel) : {};
+ if (
+ (activeCost.energy === undefined || playerStats.energy >= activeCost.energy) ||
+ (activeCost.mana === undefined || playerStats.mana >= activeCost.mana)
+ ) {
+ item.active(activeLevel).forEach(elem => {
+ let value = elem.value;
+ if (elem.str !== undefined) {
+ value += elem.str * playerStats.strength;
}
- } else if (elem.type === 'poison') {
- store.commit('horde/updateEnemyKey', {key: 'poison', value: getDamage(elem.value * playerStats.attack / divisionShieldMult, 'bio', playerStats, enemyStats) + store.state.horde.enemy.poison});
- hitShield = true;
- } else if (elem.type === 'antidote') {
- store.commit('horde/updatePlayerKey', {key: 'poison', value: store.state.horde.player.poison * (1 - elem.value)});
- } else if (elem.type === 'removeStun') {
- store.commit('horde/updatePlayerKey', {key: 'stun', value: 0});
- } else if (elem.type.substring(0, 6) === 'damage') {
- damage += getDamage(elem.value * playerStats.attack / divisionShieldMult, elem.type.substring(6).toLowerCase(), playerStats, enemyStats);
+ if (elem.int !== undefined) {
+ value += elem.int * playerStats.intelligence;
+ }
+ let critEffect = elem.canCrit ?? 0;
+ if (elem.type === 'heal') {
+ critEffect = Math.max(critEffect, store.getters['tag/values']('hordeActiveHealCrit')[0]);
+ } else if (elem.type.substring(0, 9) === 'maxdamage' || elem.type.substring(0, 6) === 'damage') {
+ critEffect = Math.max(critEffect, store.getters['tag/values']('hordeActiveDamageCrit')[0]);
+ }
+ if (critEffect > 0) {
+ const crits = randomRound(playerStats.critChance);
+ if (crits > 0) {
+ value *= Math.pow((playerStats.critMult - 1) * critEffect + 1, crits);
+ applyCritEffects(crits);
+ }
+ }
+ if (elem.type === 'heal') {
+ store.commit('horde/updatePlayerKey', {key: 'health', value: Math.min(playerStats.health, store.state.horde.player.health + playerStats.health * playerStats.healing * value)});
+ } else if (elem.type === 'refillEnergy') {
+ store.commit('horde/updatePlayerKey', {key: 'energy', value: Math.min(playerStats.energy, store.state.horde.player.energy + playerStats.energy * value)});
+ } else if (elem.type === 'refillMana') {
+ store.commit('horde/updatePlayerKey', {key: 'mana', value: Math.min(playerStats.mana, store.state.horde.player.mana + playerStats.mana * value)});
+ } else if (elem.type === 'stun') {
+ store.commit('horde/updateEnemyKey', {key: 'stun', value: store.state.horde.enemy.stun + Math.round(value)});
+ } else if (elem.type === 'silence') {
+ store.commit('horde/updateEnemyKey', {key: 'silence', value: store.state.horde.enemy.silence + Math.round(value)});
+ } else if (elem.type === 'revive') {
+ store.commit('horde/updatePlayerKey', {key: 'revive', value: Math.min(playerStats.revive, store.state.horde.player.revive + Math.round(value))});
+ } else if (elem.type === 'reviveAll') {
+ store.commit('horde/updatePlayerKey', {key: 'revive', value: playerStats.revive});
+ } else if (elem.type === 'divisionShield') {
+ store.commit('horde/updatePlayerKey', {key: 'divisionShield', value: store.state.horde.player.divisionShield + Math.round(value)});
+ } else if (elem.type === 'removeDivisionShield') {
+ store.commit('horde/updateEnemyKey', {key: 'divisionShield', value: Math.ceil(store.state.horde.enemy.divisionShield * (1 - value))});
+ } else if (elem.type === 'removeAttack') {
+ if (store.state.horde.fightRampage <= 0) {
+ store.commit('horde/updateEnemyKey', {key: 'attack', value: Math.max(0, store.state.horde.enemy.attack * (1 - value))});
+ }
+ } else if (elem.type === 'poison') {
+ const poisonDmg = Math.max(0, getDamage(value * playerStats.attack / divisionShieldMult, 'bio', playerStats, enemyStats) - enemyStats.defense * enemyStats.maxHealth);
+ if (poisonDmg > 0) {
+ store.commit('horde/updateEnemyKey', {key: 'poison', value: poisonDmg + store.state.horde.enemy.poison});
+ hitShield = true;
+ }
+ } else if (elem.type === 'antidote') {
+ store.commit('horde/updatePlayerKey', {key: 'poison', value: store.state.horde.player.poison * (1 - value)});
+ } else if (elem.type === 'removeStun') {
+ store.commit('horde/updatePlayerKey', {key: 'stun', value: 0});
+ } else if (elem.type === 'buff') {
+ store.dispatch('horde/addBuff', {name: `${ subfeature === 0 ? 'equipment_' : '' }${ usedAttack }`, time: Math.round(value), positive: true, effect: elem.effect});
+ } else if (elem.type.substring(0, 9) === 'maxdamage') {
+ const maxdamage = Math.max(0, enemyStats.maxHealth * (enemyHealth / enemyStats.maxHealth - playerStats.execute));
+ damage += getDamage(value * maxdamage / divisionShieldMult, elem.type.substring(9).toLowerCase(), playerStats, enemyStats);
+ } else if (elem.type.substring(0, 6) === 'damage') {
+ damage += getDamage(value * playerStats.attack / divisionShieldMult, elem.type.substring(6).toLowerCase(), playerStats, enemyStats);
+ }
+ });
+
+ damage = Math.max(0, damage - enemyStats.defense * enemyStats.maxHealth);
+ if (damage > 0) {
hitShield = true;
}
- });
- store.commit('horde/updateKey', {key: 'chosenActive', value: null});
+ if (activeCost.health !== undefined) {
+ store.commit('horde/updatePlayerKey', {key: 'health', value: store.state.horde.player.health * (1 - activeCost.health)});
+ }
+ if (activeCost.energy !== undefined) {
+ store.dispatch('horde/updateEnergy', store.state.horde.player.energy - activeCost.energy);
+ }
+ if (activeCost.mana !== undefined) {
+ store.dispatch('horde/updateMana', store.state.horde.player.mana - activeCost.mana);
+ }
+ if (activeCost.mysticalShard !== undefined) {
+ store.dispatch('currency/spend', {feature: 'horde', name: 'mysticalShard', amount: activeCost.mysticalShard});
+ store.dispatch('horde/checkPlayerHealth');
+ }
- const cooldown = Math.ceil(store.state.horde.items[usedAttack].cooldown(store.state.horde.items[usedAttack].level) / (store.state.horde.items[usedAttack].masteryLevel >= 4 ? 2 : 1));
- store.commit('horde/updateItemKey', {name: usedAttack, key: 'cooldownLeft', value: cooldown});
+ const cooldown = Math.ceil(item.cooldown(activeLevel) / ((subfeature === 0 && item.masteryLevel >= 4) ? 2 : 1));
+ if (subfeature === 0) {
+ store.commit('horde/updateItemKey', {name: usedAttack, key: 'cooldownLeft', value: cooldown});
+ } else if (subfeature === 1) {
+ store.commit('horde/updateSubkey', {name: 'skillActive', key: usedAttack, value: cooldown});
+ }
+
+ store.dispatch('horde/updateActiveTimer', 0);
- // Add stat for spellblade
- if (cooldown >= 10 || chance(cooldown * 0.1)) {
+ // Add stat for spellblade
store.commit('horde/updatePlayerKey', {key: 'spells', value: store.state.horde.player.spells + 1});
}
+ store.commit('horde/updateKey', {key: 'chosenActive', value: null});
} else {
+ // Perform basic attack
+ const crits = randomRound(playerStats.critChance);
+ const baseDamage = playerStats.attack * (HORDE_DAMAGE_INCREASE_PER_STRENGTH * playerStats.strength + 1) * Math.pow(playerStats.critMult, crits);
+
damageTypes.forEach(damagetype => {
const conversion = playerStats[damagetype + 'Conversion'];
if (conversion > 0) {
@@ -252,10 +440,12 @@ export default {
}
});
+ damage -= enemyStats.defense * enemyStats.maxHealth;
+
// Count damage stats (basic attacks only)
store.commit('stat/increaseTo', {feature: 'horde', name: 'maxDamage', value: damage});
store.commit('stat/add', {feature: 'horde', name: 'totalDamage', value: damage});
- if (simulation.dead) {
+ if (simulation.dead && damage > 0) {
simulation.damage += damage;
}
@@ -270,15 +460,24 @@ export default {
}
store.commit('horde/updatePlayerKey', {key: 'hits', value: store.state.horde.player.hits + 1});
- if (enemyHealth > damage && playerStats.cutting > 0 && enemyHealth < Infinity) {
- damage += getDamage((enemyHealth - damage) * playerStats.cutting / divisionShieldMult, 'bio', playerStats, enemyStats);
- }
+ damage = Math.max(0, damage);
- if (playerStats.toxic > 0) {
- store.commit('horde/updateEnemyKey', {key: 'poison', value: getDamage(baseDamage * playerStats.toxic / divisionShieldMult, 'bio', playerStats, enemyStats) + store.state.horde.enemy.poison});
+ if (damage > 0) {
+ if (enemyHealth > damage && playerStats.cutting > 0 && enemyHealth < Infinity) {
+ const maxdamage = Math.max(0, enemyStats.maxHealth * ((enemyHealth - damage) / enemyStats.maxHealth - playerStats.execute));
+ damage += getDamage(maxdamage * playerStats.cutting / divisionShieldMult, 'bio', playerStats, enemyStats);
+ }
+
+ if (playerStats.toxic > 0) {
+ store.commit('horde/updateEnemyKey', {key: 'poison', value: getDamage(baseDamage * playerStats.toxic / divisionShieldMult, 'bio', playerStats, enemyStats) + store.state.horde.enemy.poison});
+ }
+
+ hitShield = true;
}
- hitShield = true;
+ if (crits > 0) {
+ applyCritEffects(crits);
+ }
}
enemyHealth = Math.max(0, enemyHealth - damage);
@@ -286,15 +485,75 @@ export default {
store.commit('horde/updateEnemyKey', {key: 'divisionShield', value: Math.max(enemyStats.divisionShield - 1 - playerStats.shieldbreak, 0)});
}
}
+
+ // select autocast
+ if (store.state.horde.chosenActive === null && store.state.horde.autocast.length > 0) {
+ const sources = store.state.horde.autocast.map(name => {
+ if (subfeature === 0) {
+ const item = store.state.horde.items[name];
+ return {ready: item.cooldownLeft <= 0, type: item.activeType, effect: item.active(item.level), cost: item.activeCost(item.level), name};
+ } else if (subfeature === 1) {
+ const split = name.split('_');
+ if (split[0] === 'skill') {
+ const skill = store.state.horde.fighterClass[store.state.horde.selectedClass].skills[split[1]];
+ return {ready: store.state.horde.skillActive[name] <= 0, type: skill.activeType, effect: skill.active(skill.level), cost: skill.activeCost(skill.level), name};
+ } else if (split[0] === 'trinket') {
+ const trinket = store.state.horde.trinket[split[1]];
+ return {ready: store.state.horde.skillActive[name] <= 0, type: trinket.activeType, effect: trinket.active(trinket.level), cost: trinket.activeCost(trinket.level), name};
+ }
+ }
+ return {};
+ }).filter(elem => elem.ready && elem.type === 'combat' &&
+ (elem.cost.health === undefined || (store.state.horde.player.health >= elem.cost.health) && (store.state.horde.player.health / playerStats.health) >= 0.5) &&
+ (elem.cost.energy === undefined || (store.state.horde.player.energy >= elem.cost.energy) && (store.state.horde.player.energy / playerStats.energy) >= 0.5) &&
+ (elem.cost.mana === undefined || (store.state.horde.player.mana >= elem.cost.mana) && (store.state.horde.player.mana / playerStats.mana) >= 0.5) &&
+ (elem.cost.mysticalShard === undefined || (store.state.currency.horde_mysticalShard.value >= elem.cost.mysticalShard && store.state.currency.horde_mysticalShard.value >= store.state.currency.horde_mysticalShard.cap))
+ );
+ sources.forEach(elem => {
+ if (store.state.horde.chosenActive === null) {
+ let usePositive = false;
+ let useNegative = false;
+ elem.effect.forEach(el => {
+ let condition = null;
+ if (el.type === 'heal') {
+ condition = (store.state.horde.player.health / playerStats.health) <= (1 - el.value);
+ } else if (el.type === 'stun') {
+ condition = store.state.horde.enemy.stun <= 0;
+ } else if (el.type === 'silence') {
+ condition = store.state.horde.enemy.silence <= 0;
+ } else if (el.type === 'divisionShield') {
+ condition = store.state.horde.player.divisionShield <= 0;
+ } else if (el.type === 'antidote') {
+ condition = store.state.horde.player.poison > 0;
+ } else if (el.type === 'removeStun') {
+ condition = store.state.horde.player.stun > 0;
+ }
+
+ if (condition === true) {
+ usePositive = true;
+ } else if (condition === false) {
+ useNegative = true;
+ }
+ if (usePositive || !useNegative) {
+ store.commit('horde/updateKey', {key: 'chosenActive', value: elem.name});
+ }
+ });
+ }
+ });
+ }
}
- if (enemyHealth <= 0) {
+ if ((enemyHealth / enemyStats.maxHealth) <= playerStats.execute) {
if (enemyStats.revive) {
store.commit('horde/updateEnemyKey', {key: 'health', value: enemyStats.maxHealth});
store.commit('horde/updateEnemyKey', {key: 'revive', value: enemyStats.revive - 1});
} else {
if (simulation.dead) {
simulation.killed++;
- simulation.bone += store.getters['horde/currentBone'] * store.state.horde.enemy.loot;
+ if (subfeature === 0) {
+ simulation.bone += store.getters['horde/currentBone'] * store.state.horde.enemy.loot;
+ } else if (subfeature === 1) {
+ simulation.blood += store.getters['horde/currentBlood'] * store.state.horde.enemy.loot;
+ }
}
killEnemy = true;
}
@@ -320,19 +579,19 @@ export default {
let usePositive = false;
let useNegative = false;
let usableInStun = false;
- store.state.horde.sigil[key].active.effect(enemyStats.sigil[key], store.state.horde.bossFight).forEach(elem => {
+ store.state.horde.sigil[key].active.effect(enemyStats.sigil[key], store.state.horde.bossFight).forEach(el => {
let condition = null;
- if (elem.type === 'heal') {
- condition = (enemyStats.health / enemyStats.maxHealth) <= (1 - elem.value);
- } else if (elem.type === 'stun') {
+ if (el.type === 'heal') {
+ condition = (enemyStats.health / enemyStats.maxHealth) <= (1 - el.value);
+ } else if (el.type === 'stun') {
condition = store.state.horde.player.stun <= 0;
- } else if (elem.type === 'silence') {
+ } else if (el.type === 'silence') {
condition = store.state.horde.player.silence <= 0;
- } else if (elem.type === 'divisionShield') {
+ } else if (el.type === 'divisionShield') {
condition = enemyStats.divisionShield <= 0;
- } else if (elem.type === 'antidote') {
+ } else if (el.type === 'antidote') {
condition = enemyStats.poison > 0;
- } else if (elem.type === 'removeStun') {
+ } else if (el.type === 'removeStun') {
usableInStun = true;
condition = enemyStats.stun > 0;
}
@@ -379,12 +638,16 @@ export default {
enemyDamage += getDamage((playerHealth - enemyDamage) * enemyStats.cutting / divisionShieldMult, 'bio', enemyStats, playerStats);
}
- if (enemyStats.toxic > 0) {
- store.commit('horde/updatePlayerKey', {key: 'poison', value: getDamage(enemyBaseDamage * enemyStats.toxic / divisionShieldMult, 'bio', enemyStats, playerStats) + store.state.horde.player.poison});
- }
- store.commit('horde/updateEnemyKey', {key: 'hits', value: enemyStats.hits + 1});
+ enemyDamage = Math.max(0, enemyDamage - playerStats.defense * playerStats.health);
- hitShield = true;
+ if (enemyDamage > 0) {
+ if (enemyStats.toxic > 0) {
+ store.commit('horde/updatePlayerKey', {key: 'poison', value: getDamage(enemyBaseDamage * enemyStats.toxic / divisionShieldMult, 'bio', enemyStats, playerStats) + store.state.horde.player.poison});
+ }
+ store.commit('horde/updateEnemyKey', {key: 'hits', value: enemyStats.hits + 1});
+
+ hitShield = true;
+ }
} else {
// Perform an active attack
const active = store.state.horde.sigil[usedAttack].active;
@@ -397,18 +660,38 @@ export default {
store.commit('horde/updatePlayerKey', {key: 'silence', value: store.state.horde.player.silence + elem.value});
} else if (elem.type === 'divisionShield') {
store.commit('horde/updateEnemyKey', {key: 'divisionShield', value: store.state.horde.enemy.divisionShield + elem.value});
- } else if (elem.type === 'raiseAttack') {
- store.commit('horde/updateEnemyKey', {key: 'attack', value: store.state.horde.enemy.attack * (1 + elem.value)});
+ } else if (elem.type === 'removeDivisionShield') {
+ store.commit('horde/updatePlayerKey', {key: 'divisionShield', value: Math.ceil(store.state.horde.player.divisionShield * (1 - elem.value))});
+ } else if (elem.type === 'gainStat') {
+ const split = elem.stat.split('_');
+ if (split[1] === 'base') {
+ store.commit('horde/updateEnemyKey', {key: split[0], value: store.state.horde.enemy[split[0]] + elem.value});
+ } else if (split[1] === 'mult') {
+ store.commit('horde/updateEnemyKey', {key: split[0], value: store.state.horde.enemy[split[0]] * elem.value});
+ }
} else if (elem.type === 'poison') {
- store.commit('horde/updatePlayerKey', {key: 'poison', value: getDamage(elem.value * enemyStats.attack / divisionShieldMult, 'bio', enemyStats, playerStats) + store.state.horde.player.poison});
- hitShield = true;
+ const poisonDmg = Math.max(0, getDamage(elem.value * enemyStats.attack / divisionShieldMult, 'bio', enemyStats, playerStats) - playerStats.defense * playerStats.health);
+ if (poisonDmg > 0) {
+ store.commit('horde/updatePlayerKey', {key: 'poison', value: poisonDmg + store.state.horde.player.poison});
+ hitShield = true;
+ }
} else if (elem.type === 'antidote') {
store.commit('horde/updateEnemyKey', {key: 'poison', value: store.state.horde.enemy.poison * (1 - elem.value)});
} else if (elem.type === 'removeStun') {
store.commit('horde/updateEnemyKey', {key: 'stun', value: 0});
+ } else if (elem.type.substring(0, 9) === 'maxdamage') {
+ const maxdamage = Math.max(0, playerStats.health * (playerHealth / playerStats.health - enemyStats.execute));
+ enemyDamage += getDamage(elem.value * maxdamage / divisionShieldMult, elem.type.substring(9).toLowerCase(), enemyStats, playerStats);
+ enemyDamage = Math.max(0, enemyDamage - playerStats.defense * playerStats.health);
+ if (enemyDamage > 0) {
+ hitShield = true;
+ }
} else if (elem.type.substring(0, 6) === 'damage') {
enemyDamage += getDamage(elem.value * enemyStats.attack / divisionShieldMult, elem.type.substring(6).toLowerCase(), enemyStats, playerStats);
- hitShield = true;
+ enemyDamage = Math.max(0, enemyDamage - playerStats.defense * playerStats.health);
+ if (enemyDamage > 0) {
+ hitShield = true;
+ }
}
});
@@ -434,16 +717,17 @@ export default {
}
}
- if (playerHealth <= 0) {
- simulation.dead++;
- if (store.state.horde.bossFight === 1 && simulation.dead) {
- simulation.minibossDead++;
- }
- // Dying to a boss resets the simulation
- if (store.state.horde.bossFight === 2 && simulation.dead) {
- simulation = {...newSimulation};
+ if ((playerHealth / playerStats.health) <= enemyStats.execute) {
+ if (playerDie()) {
+ if (store.state.horde.bossFight === 1 && simulation.dead) {
+ simulation.minibossDead++;
+ }
+ // Dying to a boss resets the simulation
+ if (store.state.horde.bossFight === 2 && simulation.dead) {
+ simulation = {...newSimulation};
+ }
+ simulation.dead++;
}
- playerDie();
} else {
store.commit('horde/updatePlayerKey', {key: 'health', value: playerHealth});
}
@@ -452,6 +736,7 @@ export default {
tickEnemyRespawn(1);
if (killEnemy && store.state.horde.enemy) {
+ const wasBoss = store.state.horde.bossFight > 0;
if (store.state.horde.bossFight === 1 && simulation.dead) {
simulation.minibossKilled++;
}
@@ -460,6 +745,10 @@ export default {
simulation = {...newSimulation};
}
store.dispatch('horde/killEnemy');
+ if (subfeature === 1 && !wasBoss && store.state.horde.combo === 0) {
+ // Resetting enemy count counts as death for classes subfeature
+ simulation.dead++;
+ }
}
secondsSpent = 1;
@@ -467,6 +756,33 @@ export default {
// Apply rampage
store.commit('horde/updateKey', {key: 'fightTime', value: store.state.horde.fightTime + secondsSpent});
+ // Apply after x time effects
+ const fightMinutes = Math.floor(store.state.horde.fightTime / SECONDS_PER_MINUTE);
+ if (fightMinutes > 0) {
+ if (attackAfterTime > 0) {
+ store.dispatch('system/applyEffect', {
+ type: 'mult',
+ name: 'hordeAttack',
+ multKey: `hordeTime`,
+ value: attackAfterTime * fightMinutes + 1
+ });
+ }
+ if (strIntAfterTime > 0) {
+ store.dispatch('system/applyEffect', {
+ type: 'base',
+ name: 'hordeStrength',
+ multKey: `hordeTime`,
+ value: strIntAfterTime * fightMinutes
+ });
+ store.dispatch('system/applyEffect', {
+ type: 'base',
+ name: 'hordeIntelligence',
+ multKey: `hordeTime`,
+ value: strIntAfterTime * fightMinutes
+ });
+ }
+ }
+
const rampageTime = store.state.horde.bossFight > 0 ? HORDE_RAMPAGE_BOSS_TIME : HORDE_RAMPAGE_ENEMY_TIME;
const newRampage = Math.floor(store.state.horde.fightTime / rampageTime);
@@ -478,16 +794,18 @@ export default {
store.commit('horde/updateEnemyKey', {key: 'stunResist', value: enemyStats.stunResist + HORDE_RAMPAGE_STUN_RESIST * rampageDiff});
store.commit('horde/updateKey', {key: 'fightRampage', value: newRampage});
}
- } else if (store.state.horde.taunt && !store.state.horde.bossAvailable && store.state.horde.zone === store.state.stat.horde_maxZone.value) {
+ } else if (subfeature === 1 && store.state.horde.selectedArea === null) {
+ secondsLeft = 0;
+ } else if (subfeature === 0 && store.state.horde.taunt && !store.state.horde.bossAvailable && store.state.horde.zone === store.state.stat.horde_maxZone.value) {
store.dispatch('horde/updateEnemyStats');
} else {
- secondsSpent = Math.min(seconds, HORDE_ENEMY_RESPAWN_TIME - store.state.horde.enemyTimer);
+ secondsSpent = Math.max(Math.min(secondsLeft, HORDE_ENEMY_RESPAWN_TIME - store.state.horde.enemyTimer), 1);
tickEnemyRespawn(secondsSpent);
if (simulation.dead) {
simulation.time += secondsSpent;
}
- if (store.state.horde.zone >= HORDE_MONSTER_PART_MIN_ZONE && store.state.horde.combo > 0) {
+ if (subfeature === 0 && store.state.horde.zone >= HORDE_MONSTER_PART_MIN_ZONE && store.state.horde.combo > 0) {
store.dispatch('currency/gain', {feature: 'horde', name: 'monsterPart', gainMult: true, amount: secondsSpent * store.getters['horde/currentMonsterPart']});
if (simulation.dead) {
simulation.monsterPartTime += secondsSpent;
@@ -497,7 +815,44 @@ export default {
store.dispatch('horde/updateEnemyStats');
}
- seconds -= secondsSpent;
+ // Apply recovery
+ if (store.state.horde.player.health > 0) {
+ const passiveRecovery = store.getters['tag/values']('hordePassiveRecovery')[0] * playerStats.recovery * playerStats.healing;
+ const missingHealth = playerStats.health - store.state.horde.player.health;
+ if (passiveRecovery > 0 && missingHealth > 0) {
+ store.commit('horde/updatePlayerKey', {key: 'health', value: Math.min(playerStats.health, store.state.horde.player.health + missingHealth * passiveRecovery)});
+ }
+ }
+
+ // Tick player buffs
+ let newBuffs = {};
+ let refreshCache = false;
+ for (const [key, elem] of Object.entries(store.state.horde.playerBuff)) {
+ const newTime = elem.time - secondsSpent;
+ if (newTime > 0) {
+ newBuffs[key] = {...elem, time: newTime};
+ } else {
+ refreshCache = true;
+ }
+ }
+ store.commit('horde/updateKey', {key: 'playerBuff', value: newBuffs});
+ if (refreshCache) {
+ store.dispatch('horde/updatePlayerCache');
+ }
+
+ store.dispatch('horde/updateActiveTimer', store.state.horde.activeTimer + secondsSpent);
+
+ tickPlayerCooldowns(secondsSpent);
+
+ // Regen energy and mana
+ if (playerStats.energyRegen > 0 && store.state.horde.player.energy < playerStats.energy) {
+ store.dispatch('horde/updateEnergy', Math.min(store.state.horde.player.energy + playerStats.energyRegen * secondsSpent, playerStats.energy));
+ }
+ if (playerStats.manaRegen > 0 && store.state.horde.player.mana < playerStats.mana) {
+ store.dispatch('horde/updateMana', Math.min(store.state.horde.player.mana + playerStats.manaRegen * secondsSpent, playerStats.mana));
+ }
+
+ secondsLeft -= secondsSpent;
}
// Show heirloom notification after all combat happened
@@ -510,39 +865,35 @@ export default {
}
store.commit('horde/updateKey', {key: 'heirloomsFound', value: null});
}
-
- // Get tower keys
- if (store.state.unlock.hordeBrickTower.see) {
- const dayDiff = Math.floor(newTime / (SECONDS_PER_DAY * 7)) - Math.floor(oldTime / (SECONDS_PER_DAY * 7));
- if (dayDiff > 0) {
- store.dispatch('currency/gain', {feature: 'horde', name: 'towerKey', amount: dayDiff}, {root: true});
- }
- }
},
unlock: [
'hordeFeature', 'hordeItems', 'hordeDamageTypes', 'hordePrestige', 'hordeHeirlooms', 'hordeCorruptedFlesh', 'hordeItemMastery', 'hordeChessItems',
- 'hordeBrickTower', 'hordeFireTower', 'hordeIceTower',
+ 'hordeBrickTower', 'hordeFireTower', 'hordeIceTower', 'hordeDangerTower', 'hordeToxicTower',
...[
- 'RoyalArmor', 'RoyalStorage', 'RoyalButcher', 'RoyalCrypt',
+ 'RoyalArmor', 'RoyalStorage', 'RoyalButcher', 'RoyalCrypt', 'RoyalSecret',
].map(elem => 'hordeUpgrade' + elem),
+ 'hordeClassesSubfeature', 'hordeSacrifice', 'hordeEndOfContent'
],
stat: {
- maxZone: {value: 1},
- totalDamage: {},
- maxDamage: {},
+ maxZone: {value: 1, showInStatistics: true},
+ maxDifficulty: {showInStatistics: true},
+ totalDamage: {showInStatistics: true},
+ maxDamage: {showInStatistics: true},
timeSpent: {display: 'time'},
- bestPrestige: {},
- prestigeCount: {},
+ bestPrestige0: {showInStatistics: true},
+ bestPrestige1: {showInStatistics: true},
+ prestigeCount: {showInStatistics: true},
maxZoneSpeedrun: {value: 1},
maxItems: {},
+ maxCorruptionKill: {display: 'percent', showInStatistics: true},
maxMastery: {},
totalMastery: {},
unlucky: {},
},
mult: {
// Base combat stats
- hordeAttack: {baseValue: 5},
- hordeHealth: {baseValue: 500},
+ hordeAttack: {},
+ hordeHealth: {},
hordeRecovery: {display: 'percent', min: 0, max: 1},
hordeCritChance: {display: 'percent'},
hordeCritMult: {display: 'percent', baseValue: 0.5},
@@ -555,6 +906,9 @@ export default {
hordeStunResist: {round: true, min: 0},
hordeShieldbreak: {round: true, min: 0},
hordeEnemyActiveStart: {display: 'percent', min: 0, max: 1},
+ hordeDefense: {display: 'percent', min: 0},
+ hordeExecute: {display: 'percent', min: 0, max: 0.75},
+ hordeHealing: {display: 'percent', baseValue: 1, min: 0},
// Damage type specifics
hordePhysicConversion: {display: 'percent', baseValue: 1},
@@ -567,6 +921,7 @@ export default {
hordeMagicTaken: {display: 'percent', baseValue: 1},
hordeBioTaken: {display: 'percent', baseValue: 1},
+ // Utility stats
hordeMaxItems: {round: true, baseValue: 1},
hordeItemChance: {display: 'percent'},
hordeBossRequirement: {round: true, min: 1, max: 50},
@@ -578,7 +933,26 @@ export default {
hordeNostalgia: {baseValue: 25, round: true},
hordeCorruption: {display: 'percent', min: 0, roundNearZero: true},
hordeItemMasteryGain: {},
- hordeShardChance: {display: 'percent', baseValue: 0.0001},
+ hordeShardChance: {display: 'percent', baseValue: 0.001},
+ hordeTrinketGain: {},
+ hordeTrinketQuality: {min: 0},
+ hordeMaxSacrifice: {round: true, baseValue: 1},
+
+ // Classes stats
+ hordeEnergy: {round: true},
+ hordeEnergyRegen: {display: 'perSecond'},
+ hordeMana: {round: true},
+ hordeManaRegen: {display: 'perSecond'},
+ hordeHaste: {},
+ hordeStrength: {},
+ hordeIntelligence: {},
+ hordeExpBase: {display: 'time'},
+ hordeExpIncrement: {display: 'mult', min: 0},
+ hordeMaxTrinkets: {baseValue: 1, round: true},
+ hordeSkillPointsPerLevel: {baseValue: 10, round: true},
+ hordeAutocast: {round: true},
+
+ hordePrestigeIncome: {group: ['currencyHordeSoulCorruptedGain', 'currencyHordeSoulCorruptedCap', 'currencyHordeCourageGain']}
},
multGroup: [
{mult: 'hordeHeirloomEffect', name: 'multType', type: 'heirloomEffect'}
@@ -591,27 +965,54 @@ export default {
return store.getters['mult/get']('currencyHordeMonsterPartGain', store.getters['horde/currentMonsterPart'] * 0.8);
}, timerIsEstimate: true},
corruptedFlesh: {color: 'deep-purple', icon: 'mdi-food-steak', gainMult: {baseValue: 1, display: 'perSecond'}, showGainMult: true, showGainTimer: true},
- mysticalShard: {color: 'teal', icon: 'mdi-billiards-rack', currencyMult: {
- hordeAttack: {type: 'mult', value: val => Math.pow(1.1, val)},
- hordeHealth: {type: 'mult', value: val => Math.pow(1.1, val)},
- currencyHordeBoneGain: {type: 'mult', value: val => Math.pow(1.1, val)}
+ mysticalShard: {color: 'teal', icon: 'mdi-billiards-rack', overcapMult: 0, capMult: {baseValue: 0}, currencyMult: {
+ hordeAttack: {type: 'mult', value: val => Math.pow(1.02, val)},
+ hordeHealth: {type: 'mult', value: val => Math.pow(1.02, val)},
+ currencyHordeBoneGain: {type: 'mult', value: val => Math.pow(1.02, val)},
+ hordeShardChance: {type: 'mult', value: val => Math.pow(1 / HORDE_SHARD_CHANCE_REDUCTION, val)}
}},
soulCorrupted: {color: 'purple', icon: 'mdi-ghost', overcapMult: 0.75, overcapScaling: 0.85, gainMult: {}, capMult: {min: 200}, gainTimerFunction() {
return store.getters['mult/get']('currencyHordeSoulCorruptedGain') / store.getters['mult/get']('hordeMinibossTime');
}, timerIsEstimate: true},
soulEmpowered: {type: 'prestige', alwaysVisible: true, color: 'pink', icon: 'mdi-ghost'},
+ courage: {type: 'prestige', alwaysVisible: true, color: 'orange', icon: 'mdi-ghost', gainMult: {}},
crown: {type: 'prestige', color: 'amber', icon: 'mdi-crown-circle-outline'},
- towerKey: {type: 'prestige', color: 'light-grey', icon: 'mdi-key-variant'}
+ towerKey: {type: 'prestige', color: 'light-grey', icon: 'mdi-key-variant'},
+ blood: {color: 'red', icon: 'mdi-iv-bag', gainMult: {}, capMult: {baseValue: 7500}},
+ lockpick: {color: 'orange-red', icon: 'mdi-screwdriver', overcapMult: 0.9, overcapScaling: 0.75, gainMult: {}, showGainMult: true, showGainTimer: true, capMult: {baseValue: 7}},
},
upgrade: {
...upgrade,
+ ...upgrade2,
...upgradePrestige,
...upgradePremium,
...bookHorde
},
+ tag: {
+ hordeEnergyToStr: {params: ['number'], stacking: 'add'},
+ hordeEnergyToEnergyReg: {params: ['perSecond'], stacking: 'add'},
+ hordeEnergyOnCrit: {params: ['number'], stacking: 'add'},
+ hordeHealOnCrit: {params: ['percent'], stacking: 'add'},
+ hordeRestoreCooldownOnCrit: {params: ['time'], stacking: 'add'},
+ hordeBloodOnCrit: {params: ['percent'], stacking: 'add'},
+ hordeManaRest: {params: ['time', 'perSecond'], stacking: 'add'},
+ hordeManasteal: {params: ['number'], stacking: 'add'},
+ hordePassiveRecovery: {params: ['percent'], stacking: 'add'},
+ hordeActiveDamageCrit: {params: ['percent'], stacking: 'add'},
+ hordeActiveHealCrit: {params: ['percent'], stacking: 'add'},
+ hordeAttackAfterTime: {params: ['mult'], stacking: 'add'},
+ hordeStrIntAfterTime: {params: ['number'], stacking: 'add'},
+ },
relic,
achievement,
note: buildArray(31).map(() => 'g'),
+ consumable: {
+ manaPotion: {
+ icon: 'mdi-flask-round-bottom',
+ color: 'dark-blue',
+ price: {gem_sapphire: 35}
+ }
+ },
init() {
for (const [key, elem] of Object.entries(equipment)) {
store.commit('horde/initItem', {name: key, ...elem});
@@ -619,15 +1020,38 @@ export default {
for (const [key, elem] of Object.entries(heirloom)) {
store.dispatch('horde/initHeirloom', {name: key, ...elem});
}
- for (const [key, elem] of Object.entries(sigil)) {
+ for (const [key, elem] of Object.entries({...sigil, ...sigil_boss})) {
store.commit('horde/initSigil', {name: key, ...elem});
}
for (const [key, elem] of Object.entries(tower)) {
store.commit('horde/initTower', {name: key, ...elem});
}
+ for (const [key, elem] of Object.entries({adventurer, archer, mage, knight, assassin, shaman, pirate, undead, cultist, scholar})) {
+ if (elem.unlock) {
+ store.commit('unlock/init', elem.unlock);
+ }
+ store.commit('horde/initFighterClass', {name: key, ...elem});
+ }
+ for (const [key, elem] of Object.entries({warzone, monkeyJungle, loveIsland})) {
+ if (elem.unlock) {
+ store.commit('unlock/init', elem.unlock);
+ }
+ store.commit('horde/initArea', {name: key, ...elem});
+ }
+ for (const [key, elem] of Object.entries(trinket)) {
+ store.commit('horde/initTrinket', {name: key, ...elem});
+ }
+ for (const [key, elem] of Object.entries(enemyType)) {
+ store.commit('horde/initEnemyType', {name: key, ...elem});
+ }
+ for (const [key, elem] of Object.entries(boss)) {
+ store.commit('horde/initAreaBoss', {name: key, ...elem});
+ }
+ store.commit('horde/updateKey', {key: 'battlePassEffect', value: battlePass});
store.dispatch('horde/updatePlayerStats');
store.dispatch('horde/updateEnemyStats');
store.dispatch('mult/updateExternalCaches', 'hordeNostalgia');
+ store.dispatch('horde/updatePlayerCache');
},
saveGame() {
let obj = {
@@ -642,6 +1066,10 @@ export default {
enemyTimer: store.state.horde.enemyTimer
};
+ if (Object.keys(store.state.horde.playerBuff).length > 0) {
+ obj.playerBuff = store.state.horde.playerBuff;
+ }
+
if (store.state.horde.enemy) {
obj.enemy = {...store.state.horde.enemy};
}
@@ -710,6 +1138,34 @@ export default {
if (store.state.horde.taunt) {
obj.taunt = true;
}
+ if (store.state.horde.selectedClass !== null) {
+ obj.selectedClass = store.state.horde.selectedClass;
+ }
+ if (store.state.horde.selectedArea !== null) {
+ obj.selectedArea = store.state.horde.selectedArea;
+ }
+ if (store.state.horde.expLevel > 0) {
+ obj.expLevel = store.state.horde.expLevel;
+ }
+ if (store.state.horde.skillPoints > 0) {
+ obj.skillPoints = store.state.horde.skillPoints;
+ }
+ if (store.state.horde.activeTimer > 0) {
+ obj.activeTimer = store.state.horde.activeTimer;
+ }
+ if (store.state.horde.bossStage > 0) {
+ obj.bossStage = store.state.horde.bossStage;
+ }
+ if (store.state.horde.trinketDrop !== null) {
+ obj.trinketDrop = store.state.horde.trinketDrop;
+ }
+ if (store.state.horde.bossBonusDifficulty > 0) {
+ obj.bossBonusDifficulty = store.state.horde.bossBonusDifficulty;
+ }
+
+ if (store.state.horde.autocast.length > 0) {
+ obj.autocast = store.state.horde.autocast;
+ }
for (const [key, elem] of Object.entries(store.state.horde.tower)) {
if (elem.highest > 0) {
@@ -720,10 +1176,60 @@ export default {
}
}
+ for (const [key, elem] of Object.entries(store.state.horde.skillLevel)) {
+ if (elem > 0) {
+ if (obj.skillLevel === undefined) {
+ obj.skillLevel = {};
+ }
+ obj.skillLevel[key] = elem;
+ }
+ }
+
+ for (const [key, elem] of Object.entries(store.state.horde.fighterClass)) {
+ for (const [qkey, qelem] of Object.entries(elem.questsCompleted)) {
+ if (qelem > 0) {
+ if (obj.classQuest === undefined) {
+ obj.classQuest = {};
+ }
+ if (obj.classQuest[key] === undefined) {
+ obj.classQuest[key] = {};
+ }
+ obj.classQuest[key][qkey] = qelem;
+ }
+ }
+ }
+
+ for (const [key, elem] of Object.entries(store.state.horde.area)) {
+ for (const [qkey, qelem] of Object.entries(elem.zones)) {
+ if (qelem.unlocked && qelem.unlockedBy !== null) {
+ if (obj.areaUnlock === undefined) {
+ obj.areaUnlock = {};
+ }
+ if (obj.areaUnlock[key] === undefined) {
+ obj.areaUnlock[key] = [];
+ }
+ obj.areaUnlock[key].push(qkey);
+ }
+ }
+ }
+
+ for (const [key, elem] of Object.entries(store.state.horde.trinket)) {
+ if (elem.amount > 0) {
+ if (obj.trinket === undefined) {
+ obj.trinket = {};
+ }
+ obj.trinket[key] = {amount: elem.amount, equipped: elem.equipped, isActive: elem.isActive};
+ }
+ }
+
return obj;
},
loadGame(data) {
- ['zone', 'combo', 'respawn', 'maxRespawn', 'bossAvailable', 'bossFight', 'fightTime', 'fightRampage', 'enemyTimer', 'minibossTimer', 'nostalgiaLost', 'chosenActive', 'currentTower', 'towerFloor', 'taunt'].forEach(elem => {
+ [
+ 'zone', 'combo', 'respawn', 'maxRespawn', 'bossAvailable', 'bossFight', 'fightTime', 'fightRampage', 'enemyTimer',
+ 'playerBuff', 'minibossTimer', 'nostalgiaLost', 'chosenActive', 'currentTower', 'towerFloor', 'taunt',
+ 'selectedClass', 'selectedArea', 'expLevel', 'skillPoints', 'bossStage', 'trinketDrop', 'bossBonusDifficulty', 'autocast'
+ ].forEach(elem => {
if (data[elem] !== undefined) {
store.commit('horde/updateKey', {key: elem, value: data[elem]});
}
@@ -790,8 +1296,9 @@ export default {
}
if (data.itemStatMult) {
for (const [key, elem] of Object.entries(data.itemStatMult)) {
+ const split = key.split('_');
store.commit('horde/updateSubkey', {name: 'itemStatMult', key, value: elem});
- store.dispatch('system/applyEffect', {type: 'mult', name: key, multKey: `hordeItemPermanent`, value: elem + 1});
+ store.dispatch('system/applyEffect', {type: split[1], name: split[0], multKey: `hordeItemPermanent`, value: elem + (split[1] === 'mult' ? 1 : 0)});
}
}
if (data.tower) {
@@ -801,9 +1308,54 @@ export default {
}
}
}
+ if (data.skillLevel) {
+ for (const [key, elem] of Object.entries(data.skillLevel)) {
+ store.commit('horde/updateSubkey', {name: 'skillLevel', key, value: elem});
+ store.dispatch('horde/applySkillEffects', key);
+ }
+ }
+ if (data.classQuest) {
+ for (const [key, elem] of Object.entries(data.classQuest)) {
+ for (const [qkey, qelem] of Object.entries(elem)) {
+ store.commit('horde/updateClassQuestKey', {name: key, key: qkey, value: qelem});
+ }
+ }
+ }
+ if (data.areaUnlock) {
+ for (const [key, elem] of Object.entries(data.areaUnlock)) {
+ elem.forEach(zone => {
+ if (store.state.horde.area[key]?.zones[zone]) {
+ store.commit('horde/updateAreaZoneKey', {name: key, zone, key: 'unlocked', value: true});
+ }
+ });
+ }
+ }
+ if (data.activeTimer !== undefined) {
+ store.dispatch('horde/updateActiveTimer', data.activeTimer);
+ }
+ if (data.trinket) {
+ for (const [name, value] of Object.entries(data.trinket)) {
+ store.commit('horde/updateTrinketKey', {name, key: 'amount', value: value.amount});
+ store.commit('horde/updateTrinketKey', {name, key: 'level', value: store.state.horde.trinketAmountNeeded.filter(el => value.amount >= el).length});
+ store.commit('horde/updateTrinketKey', {name, key: 'equipped', value: value.equipped});
+ store.commit('horde/updateTrinketKey', {name, key: 'isActive', value: value.isActive});
+ if (value.isActive) {
+ store.dispatch('horde/applyTrinketEffects', name);
+ }
+ }
+ }
store.dispatch('horde/checkZoneUnlocks');
store.dispatch('mult/updateExternalCaches', 'hordeNostalgia');
store.dispatch('horde/updateNostalgia');
store.dispatch('horde/applyTowerEffects');
+ store.dispatch('horde/updatePlayerCache');
+ store.dispatch('horde/applyClassEffects');
+ store.dispatch('horde/applyClassLevelEffects');
+ store.dispatch('horde/applyBattlePassEffects');
+ store.dispatch('horde/updateSacrifice');
+ store.dispatch('horde/updateEnergy');
+ store.dispatch('horde/updateMana');
+ store.dispatch('horde/updateMaxDifficulty');
+ store.dispatch('horde/updateMysticalShardCap');
}
}
diff --git a/src/js/modules/horde/achievement.js b/src/js/modules/horde/achievement.js
index 229a4ac8..a965e020 100644
--- a/src/js/modules/horde/achievement.js
+++ b/src/js/modules/horde/achievement.js
@@ -1,14 +1,16 @@
import store from "../../../store";
import { buildNum } from "../../utils/format";
+import { getSequence } from "../../utils/math";
export default {
- maxZone: {value: () => store.state.stat.horde_maxZone.total, default: 1, milestones: lvl => lvl * 10 + 10, relic: {7: 'ultimateGuide', 11: 'crackedSafe'}},
- maxZoneSpeedrun: {value: () => store.state.stat.horde_maxZoneSpeedrun.total, default: 1, milestones: lvl => lvl * 5 + 10, relic: {8: 'dumbbell'}},
+ maxZone: {value: () => store.state.stat.horde_maxZone.total, default: 1, cap: 30, milestones: lvl => lvl * 10 + 10, relic: {7: 'ultimateGuide', 11: 'crackedSafe'}},
+ maxZoneSpeedrun: {value: () => store.state.stat.horde_maxZoneSpeedrun.total, default: 1, cap: 10, milestones: lvl => lvl * 5 + 10, relic: {8: 'dumbbell'}},
totalDamage: {value: () => store.state.stat.horde_totalDamage.total, milestones: lvl => Math.pow(lvl * 250 + 7500, lvl) * buildNum(10, 'K'), relic: {6: 'newBackpack'}},
maxDamage: {value: () => store.state.stat.horde_maxDamage.total, milestones: lvl => Math.pow(lvl * 250 + 7500, lvl) * 10, relic: {3: 'burningSkull'}},
- bone: {value: () => store.state.stat.horde_bone.total, milestones: lvl => Math.pow(buildNum(10, 'K'), lvl) * buildNum(1, 'M'), relic: {2: 'forgottenShield'}},
+ bone: {value: () => store.state.stat.horde_bone.total, milestones: lvl => Math.pow(2, getSequence(10, lvl) - 10) * buildNum(1, 'M'), relic: {2: 'forgottenShield'}},
monsterPart: {value: () => store.state.stat.horde_monsterPart.total, milestones: lvl => Math.pow(16, lvl) * 50, relic: {3: 'energyDrink', 5: 'bandage'}},
- soulCorrupted: {value: () => store.state.stat.horde_soulCorrupted.total, milestones: lvl => Math.pow(8, lvl) * 1000, relic: {4: 'luckyDice'}},
+ soulCorrupted: {value: () => store.state.stat.horde_soulCorrupted.total, milestones: lvl => Math.pow(7 + lvl, lvl) * 1000, relic: {4: 'luckyDice'}},
+ maxCorruptionKill: {value: () => store.state.stat.horde_maxCorruptionKill.total, display: 'percent', milestones: lvl => lvl + 1},
maxMastery: {value: () => store.state.stat.horde_maxMastery.total, milestones: lvl => lvl + 1},
totalMastery: {value: () => store.state.stat.horde_totalMastery.total, milestones: lvl => Math.round((lvl + 1) * 25 * (lvl * 0.2 + 1))},
unlucky: {value: () => store.state.stat.horde_unlucky.total, secret: true, display: 'boolean', cap: 1, milestones: () => 1},
diff --git a/src/js/modules/horde/area/loveIsland.js b/src/js/modules/horde/area/loveIsland.js
new file mode 100644
index 00000000..5fcab929
--- /dev/null
+++ b/src/js/modules/horde/area/loveIsland.js
@@ -0,0 +1,165 @@
+export default {
+ unlock: 'hordeAreaLoveIsland',
+ icon: 'mdi-heart-multiple',
+ color: 'babypink',
+ zones: {
+ sign_4: {
+ x: -3.25,
+ y: 5.5,
+ unlockedBy: null,
+ type: 'sign'
+ },
+ 1: {
+ x: -0.7,
+ y: 5,
+ unlockedBy: null,
+ type: 'regular',
+ difficulty: 78,
+ enemyType: ['seal', 'guineaPig']
+ },
+ 2: {
+ x: -3.5,
+ y: 2.5,
+ unlockedBy: '1',
+ type: 'regular',
+ difficulty: 81,
+ enemyType: ['seal', 'guineaPig', 'puppy']
+ },
+ 3: {
+ x: -6.25,
+ y: -0.25,
+ unlockedBy: '2',
+ type: 'regular',
+ difficulty: 84,
+ enemyType: ['guineaPig', 'puppy']
+ },
+ 4: {
+ x: -7,
+ y: -3.5,
+ unlockedBy: '3',
+ type: 'regular',
+ difficulty: 87,
+ enemyType: ['puppy', 'rabbit']
+ },
+ 5: {
+ x: -5.25,
+ y: -5.5,
+ unlockedBy: '4',
+ type: 'regular',
+ difficulty: 90,
+ enemyType: ['guineaPig', 'puppy', 'rabbit']
+ },
+ 6: {
+ x: -3,
+ y: -6,
+ unlockedBy: '5',
+ type: 'regular',
+ difficulty: 93,
+ enemyType: ['rabbit', 'kitten']
+ },
+ 7: {
+ x: -1,
+ y: -4.5,
+ unlockedBy: '6',
+ type: 'regular',
+ difficulty: 96,
+ enemyType: ['seal', 'rabbit', 'puppy', 'kitten']
+ },
+ 8: {
+ x: 0,
+ y: -2.5,
+ unlockedBy: '7',
+ type: 'regular',
+ difficulty: 99,
+ enemyType: ['puppy', 'kitten']
+ },
+ 9: {
+ x: 1,
+ y: -4.5,
+ unlockedBy: '8',
+ type: 'regular',
+ difficulty: 102,
+ enemyType: ['seal', 'guineaPig', 'kitten']
+ },
+ 10: {
+ x: 3,
+ y: -6,
+ unlockedBy: '9',
+ type: 'regular',
+ difficulty: 105,
+ enemyType: ['puppy', 'rabbit', 'kitten']
+ },
+ 11: {
+ x: 5.25,
+ y: -5.5,
+ unlockedBy: '10',
+ type: 'regular',
+ difficulty: 108,
+ enemyType: ['kitten', 'piglet']
+ },
+ 12: {
+ x: 7,
+ y: -3.5,
+ unlockedBy: '11',
+ type: 'regular',
+ difficulty: 111,
+ enemyType: ['piglet', 'guineaPig']
+ },
+ 13: {
+ x: 6.25,
+ y: -0.25,
+ unlockedBy: '12',
+ type: 'regular',
+ difficulty: 114,
+ enemyType: ['seal', 'panda']
+ },
+ 14: {
+ x: 3.5,
+ y: 2.5,
+ unlockedBy: '13',
+ type: 'regular',
+ difficulty: 117,
+ enemyType: ['piglet', 'panda', 'koala']
+ },
+ boss_1: {
+ x: 0,
+ y: 3.6,
+ unlockedBy: '14',
+ type: 'boss',
+ difficulty: 120,
+ boss: ['mina'],
+ reward: 'hordeEndOfContent'
+ },
+ endless: {
+ x: 0.7,
+ y: 5,
+ unlockedBy: '14',
+ type: 'endless',
+ difficulty: 120,
+ enemyType: ['seal', 'guineaPig', 'puppy', 'rabbit', 'kitten', 'piglet', 'panda', 'koala']
+ }
+ },
+ decoration: [
+ {x: 0, y: 3.75, rotate: 0, icon: 'mdi-seat', size: 2},
+ {x: -8.5, y: 1.2, rotate: 0, icon: 'mdi-home-variant', size: 3},
+ {x: -8.5, y: 1.9, rotate: -20, icon: 'mdi-dog', size: 0.75},
+ {x: -6, y: 2.2, rotate: 0, icon: 'mdi-dog-side', size: 1},
+ {x: -8, y: 3.2, rotate: -30, icon: 'mdi-bone', size: 0.6},
+ {x: -7.6, y: 3.5, rotate: 20, icon: 'mdi-bone', size: 0.5},
+ {x: -7.9, y: -1, rotate: 70, icon: 'mdi-tennis-ball', size: 0.4},
+ {x: 0.4, y: -6.3, rotate: 0, icon: 'mdi-inbox', size: 2},
+ {x: 0.4, y: -6.45, rotate: 0, icon: 'mdi-cat', size: 1},
+ {x: -7.5, y: -5.7, rotate: 0, icon: 'mdi-grass', size: 1.25},
+ {x: -7.4, y: -6.35, rotate: 15, icon: 'mdi-rabbit-variant', size: 0.7},
+ {x: -8.7, y: -4, rotate: 0, icon: 'mdi-rabbit', size: 0.8},
+ {x: -8, y: -3.83, rotate: 70, icon: 'mdi-carrot', size: 0.6},
+ {x: 6.6, y: -6.1, rotate: 0, icon: 'mdi-pig-variant', size: 0.6},
+ {x: 8.5, y: -6.4, rotate: 0, icon: 'mdi-pig-variant', size: 0.65},
+ {x: 7.7, y: -5.5, rotate: 0, icon: 'mdi-pig-variant', size: 0.8},
+ {x: 8.4, y: -5.33, rotate: 70, icon: 'mdi-carrot', size: 0.6},
+ {x: 7, y: 3.1, rotate: 0, icon: 'mdi-palm-tree', size: 2.5},
+ {x: 7.4, y: 2, rotate: 40, icon: 'mdi-koala', size: 1},
+ {x: 8.1, y: -1, rotate: 0, icon: 'mdi-panda', size: 1.2},
+ {x: 8.1, y: 0, rotate: 0, icon: 'mdi-package', size: 1.5},
+ ]
+}
diff --git a/src/js/modules/horde/area/monkeyJungle.js b/src/js/modules/horde/area/monkeyJungle.js
new file mode 100644
index 00000000..e913167a
--- /dev/null
+++ b/src/js/modules/horde/area/monkeyJungle.js
@@ -0,0 +1,281 @@
+export default {
+ unlock: 'hordeAreaMonkeyJungle',
+ icon: 'mdi-temple-hindu',
+ color: 'teal',
+ zones: {
+ 1: {
+ x: 8,
+ y: -2,
+ unlockedBy: null,
+ type: 'regular',
+ difficulty: 33,
+ enemyType: ['strongMonkey', 'monkeyWizard_1']
+ },
+ 2: {
+ x: 5,
+ y: -4,
+ unlockedBy: '1',
+ type: 'regular',
+ difficulty: 36,
+ enemyType: ['strongMonkey', 'monkeyWizard_1']
+ },
+ 3: {
+ x: 3,
+ y: -5.5,
+ unlockedBy: '2',
+ type: 'regular',
+ difficulty: 38,
+ enemyType: ['monkeyWizard_1', 'monkeyWizard_2', 'monkeyWizard_3', 'monkeyDefender']
+ },
+ 4: {
+ x: 2,
+ y: -3,
+ unlockedBy: '2',
+ type: 'regular',
+ difficulty: 39,
+ enemyAmount: 150,
+ enemyType: ['strongMonkey', 'angryMonkey', 'dartMonkey', 'monkeyMonk']
+ },
+ 5: {
+ x: 0,
+ y: -5,
+ unlockedBy: '3',
+ type: 'regular',
+ difficulty: 40,
+ enemyType: ['monkeyWizard_1', 'monkeyWizard_2', 'monkeyWizard_3', 'monkeyDefender']
+ },
+ 6: {
+ x: -2,
+ y: -3.5,
+ unlockedBy: ['4', '5'],
+ type: 'regular',
+ difficulty: 43,
+ enemyType: ['angryMonkey', 'monkeyWizard_2']
+ },
+ 7: {
+ x: -5,
+ y: -4,
+ unlockedBy: '6',
+ type: 'regular',
+ difficulty: 46,
+ enemyType: ['dartMonkey', 'monkeyWizard_3']
+ },
+ 8: {
+ x: -6,
+ y: -0.5,
+ unlockedBy: '7',
+ type: 'regular',
+ difficulty: 49,
+ enemyType: ['strongMonkey', 'angryMonkey', 'monkeyWizard_1', 'monkeyWizard_2']
+ },
+ 9: {
+ x: -8,
+ y: 1,
+ unlockedBy: '8',
+ type: 'regular',
+ difficulty: 51,
+ enemyAmount: 150,
+ enemyType: ['strongMonkey', 'angryMonkey', 'dartMonkey', 'monkeyMonk']
+ },
+ 10: {
+ x: -4,
+ y: -1.5,
+ unlockedBy: '8',
+ type: 'regular',
+ difficulty: 52,
+ enemyType: ['monkeyWizard_1', 'monkeyWizard_2', 'monkeyWizard_3', 'monkeyDefender']
+ },
+ 11: {
+ x: -7.5,
+ y: 4,
+ unlockedBy: '9',
+ type: 'regular',
+ difficulty: 56,
+ enemyAmount: 50,
+ enemyType: ['strongMonkey', 'angryMonkey', 'dartMonkey', 'monkeyMonk']
+ },
+ 12: {
+ x: -2.5,
+ y: 1,
+ unlockedBy: '10',
+ type: 'regular',
+ difficulty: 55,
+ enemyType: ['monkeyWizard_1', 'monkeyWizard_2', 'monkeyWizard_3', 'monkeyDefender']
+ },
+ 13: {
+ x: -4,
+ y: 3,
+ unlockedBy: ['11', '12'],
+ type: 'regular',
+ difficulty: 58,
+ enemyAmount: 150,
+ enemyType: ['angryMonkey', 'dartMonkey', 'monkeyWizard_2', 'monkeyWizard_3']
+ },
+ 14: {
+ x: -0.5,
+ y: 4,
+ unlockedBy: '13',
+ type: 'regular',
+ difficulty: 62,
+ enemyType: ['strongMonkey', 'dartMonkey', 'monkeyWizard_1', 'monkeyWizard_3']
+ },
+ 15: {
+ x: 2,
+ y: 6,
+ unlockedBy: '14',
+ type: 'regular',
+ difficulty: 64,
+ enemyType: ['strongMonkey', 'angryMonkey', 'dartMonkey', 'monkeyMonk']
+ },
+ 16: {
+ x: 3.5,
+ y: 1.5,
+ unlockedBy: '14',
+ type: 'regular',
+ difficulty: 66,
+ enemyType: ['monkeyWizard_1', 'monkeyWizard_2', 'monkeyWizard_3', 'monkeyDefender']
+ },
+ 17: {
+ x: 5,
+ y: 5,
+ unlockedBy: '15',
+ type: 'regular',
+ difficulty: 67,
+ enemyType: ['strongMonkey', 'angryMonkey', 'dartMonkey', 'monkeyMonk']
+ },
+ 18: {
+ x: 7.5,
+ y: 2,
+ unlockedBy: ['16', '17'],
+ type: 'regular',
+ difficulty: 69,
+ enemyType: ['angryMonkey', 'dartMonkey', 'monkeyWizard_2', 'monkeyWizard_3']
+ },
+ 19: {
+ x: 2.5,
+ y: -0.5,
+ unlockedBy: '18',
+ type: 'regular',
+ difficulty: 72,
+ enemyType: ['strongMonkey', 'angryMonkey', 'dartMonkey', 'monkeyWizard_1', 'monkeyWizard_2', 'monkeyWizard_3']
+ },
+ boss_1: {
+ x: -1,
+ y: -1.5,
+ unlockedBy: '19',
+ type: 'boss',
+ difficulty: 75,
+ boss: ['chriz1', 'chriz2'],
+ reward: 'hordeAreaLoveIsland'
+ },
+ endless: {
+ x: 4,
+ y: -2,
+ unlockedBy: '19',
+ type: 'endless',
+ difficulty: 75,
+ enemyType: ['strongMonkey', 'angryMonkey', 'dartMonkey', 'monkeyWizard_1', 'monkeyWizard_2', 'monkeyWizard_3']
+ }
+ },
+ decoration: [
+ {x: 8.2, y: -3.4, rotate: 0, icon: 'mdi-tent', size: 2},
+ {x: 9, y: -1.4, rotate: 0, icon: 'mdi-campfire', size: 1},
+ {x: 4.8, y: -6, rotate: 0, icon: 'mdi-palm-tree', size: 1.2},
+ {x: 5.6, y: -6.4, rotate: 0, icon: 'mdi-tree', size: 1},
+ {x: 7, y: -5.5, rotate: 0, icon: 'mdi-palm-tree', size: 1.8},
+ {x: 7.3, y: -6.25, rotate: 0, icon: 'mdi-koala', size: 0.5},
+ {x: 8.1, y: -6.6, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: 9.3, y: -6.2, rotate: 0, icon: 'mdi-palm-tree', size: 1.4},
+ {x: 8.9, y: -5.7, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: 5.8, y: -4.4, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: 1, y: -4, rotate: 0, icon: 'mdi-tree', size: 1},
+ {x: 2.2, y: -4.3, rotate: 0, icon: 'mdi-palm-tree', size: 1},
+ {x: 1.5, y: -6, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: 2.6, y: -6.3, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: -5, y: -6.1, rotate: 0, icon: 'mdi-palm-tree', size: 1.6},
+ {x: -3, y: -5.5, rotate: 0, icon: 'mdi-palm-tree', size: 2.5},
+ {x: -3.85, y: -5.55, rotate: 0, icon: 'mdi-spider-thread', size: 0.5},
+ {x: -1.25, y: -5.8, rotate: 0, icon: 'mdi-tree', size: 1.1},
+ {x: -9.5, y: -6.5, rotate: 0, icon: 'mdi-tree', size: 1},
+ {x: -7, y: -6, rotate: 0, icon: 'mdi-tree', size: 1.45},
+ {x: -4, y: -4.2, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: -7.2, y: -4.6, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: -8.5, y: -5, rotate: 0, icon: 'mdi-elephant', size: 1.1},
+ {x: -7.4, y: -3.5, rotate: 0, icon: 'mdi-elephant', size: 1.25},
+ {x: -9, y: -4.2, rotate: 0, icon: 'mdi-elephant', size: 0.8},
+ {x: -8.5, y: -3.2, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: -9.4, y: -2.4, rotate: 0, icon: 'mdi-palm-tree', size: 1.3},
+ {x: -9.7, y: -0.7, rotate: 0, icon: 'mdi-tree', size: 1.1},
+ {x: -7.8, y: -1.2, rotate: 0, icon: 'mdi-tree', size: 1.3},
+ {x: -6.1, y: -2.7, rotate: 0, icon: 'mdi-tree', size: 1.2},
+ {x: -6.35, y: -1, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: -8.9, y: 0.8, rotate: 0, icon: 'mdi-palm-tree', size: 1.5},
+ {x: -9.5, y: 2, rotate: 0, icon: 'mdi-palm-tree', size: 1},
+ {x: -8.7, y: 2.5, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: -8.3, y: 3.4, rotate: 0, icon: 'mdi-palm-tree', size: 1.2},
+ {x: -9.7, y: 3.7, rotate: 0, icon: 'mdi-tortoise', size: 0.5},
+ {x: -5.5, y: 1.5, rotate: 0, icon: 'mdi-volcano', size: 2},
+ {x: -6.7, y: 1, rotate: 0, icon: 'mdi-tree', size: 1},
+ {x: -6.6, y: 2.7, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: -4.4, y: -0.1, rotate: 0, icon: 'mdi-palm-tree', size: 1.2},
+ {x: -3.7, y: 1.3, rotate: 0, icon: 'mdi-palm-tree', size: 1},
+ {x: -4, y: -2.5, rotate: 0, icon: 'mdi-palm-tree', size: 1.35},
+ {x: -2.8, y: -2.8, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: -0.5, y: -1.8, rotate: 0, icon: 'mdi-palm-tree', size: 0.8},
+ {x: -1, y: -2.3, rotate: 0, icon: 'mdi-tree', size: 0.8},
+ {x: -1.5, y: -1.9, rotate: 0, icon: 'mdi-palm-tree', size: 0.8},
+ {x: -1.7, y: -1.2, rotate: 0, icon: 'mdi-palm-tree', size: 0.8},
+ {x: -1.2, y: -0.7, rotate: 0, icon: 'mdi-palm-tree', size: 0.8},
+ {x: -0.6, y: -0.9, rotate: 0, icon: 'mdi-grass', size: 0.5},
+ {x: 1.4, y: -2.1, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: 3.8, y: -0.9, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: 1.7, y: 1, rotate: 0, icon: 'mdi-palm-tree', size: 1.2},
+ {x: -1, y: 2.1, rotate: 0, icon: 'mdi-palm-tree', size: 1},
+ {x: -0.5, y: 2.6, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: 4, y: 2.8, rotate: 0, icon: 'mdi-palm-tree', size: 1.3},
+ {x: 1.2, y: 3.9, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: 2.75, y: 4.6, rotate: 0, icon: 'mdi-kangaroo', size: 0.75},
+ {x: 6.6, y: 0.8, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: 4.7, y: 6, rotate: 0, icon: 'mdi-palm-tree', size: 1.1},
+ {x: 8.6, y: 3.5, rotate: 0, icon: 'mdi-palm-tree', size: 1.6},
+ {x: 7.3, y: 4.2, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: 8.1, y: 6.3, rotate: 0, icon: 'mdi-snake', size: 0.5},
+ {x: 9.5, y: 5.6, rotate: 0, icon: 'mdi-grass', size: 0.6},
+ {x: -9.9, y: 6.25, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -9.9, y: 7, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -9.05, y: 6.25, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -9.05, y: 7, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -8.2, y: 6, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -8.2, y: 6.9, rotate: 0, icon: 'mdi-shark-fin', size: 1},
+ {x: -7.35, y: 6.25, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -7.35, y: 7, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -7.35, y: 5.75, rotate: 0, icon: 'mdi-wave', size: 1},
+ {x: -6.5, y: 6.25, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -6.5, y: 7, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -6.5, y: 5.75, rotate: 0, icon: 'mdi-wave', size: 1},
+ {x: -5.65, y: 6.25, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -5.65, y: 7, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -5.65, y: 5.75, rotate: 0, icon: 'mdi-wave', size: 1},
+ {x: -5.65, y: 5.5, rotate: 0, icon: 'mdi-wave', size: 1},
+ {x: -4.8, y: 6.25, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -4.8, y: 7, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -4.8, y: 5.75, rotate: 0, icon: 'mdi-wave', size: 1},
+ {x: -4.8, y: 5.5, rotate: 0, icon: 'mdi-wave', size: 1},
+ {x: -3.95, y: 6.25, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -3.95, y: 7, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -3.95, y: 5.75, rotate: 0, icon: 'mdi-wave', size: 1},
+ {x: -3.95, y: 5.5, rotate: 0, icon: 'mdi-wave', size: 1},
+ {x: -3.1, y: 6.25, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -3.1, y: 7, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -3.1, y: 5.75, rotate: 0, icon: 'mdi-wave', size: 1},
+ {x: -2.25, y: 6.25, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -2.25, y: 7, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -1.4, y: 7, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -1.4, y: 6.5, rotate: 0, icon: 'mdi-wave', size: 1},
+ {x: -0.55, y: 7.25, rotate: 0, icon: 'mdi-wave', size: 1},
+ {x: -9.2, y: 5.45, rotate: 0, icon: 'mdi-palm-tree', size: 1},
+ {x: -5, y: 4.85, rotate: 0, icon: 'mdi-palm-tree', size: 1.2},
+ {x: -3.2, y: 5.2, rotate: 0, icon: 'mdi-palm-tree', size: 1},
+ {x: -0.4, y: 6.6, rotate: 0, icon: 'mdi-palm-tree', size: 1.1},
+ ]
+}
diff --git a/src/js/modules/horde/area/warzone.js b/src/js/modules/horde/area/warzone.js
new file mode 100644
index 00000000..b0be5906
--- /dev/null
+++ b/src/js/modules/horde/area/warzone.js
@@ -0,0 +1,160 @@
+export default {
+ unlock: null,
+ icon: 'mdi-sign-caution',
+ color: 'orange',
+ zones: {
+ 1: {
+ x: -9.5,
+ y: 1.5,
+ unlockedBy: null,
+ type: 'regular',
+ difficulty: 0,
+ enemyType: ['soldier_1', 'officer_1']
+ },
+ 2: {
+ x: -8,
+ y: -1,
+ unlockedBy: '1',
+ type: 'regular',
+ difficulty: 3,
+ enemyType: ['soldier_1', 'officer_1']
+ },
+ 3: {
+ x: -5,
+ y: -2,
+ unlockedBy: '2',
+ type: 'regular',
+ difficulty: 6,
+ enemyType: ['soldier_1', 'soldier_2', 'soldier_3', 'officer_1', 'officer_2', 'officer_3']
+ },
+ 4: {
+ x: -3,
+ y: -4,
+ unlockedBy: '3',
+ type: 'regular',
+ difficulty: 9,
+ enemyType: ['soldier_1', 'soldier_2', 'soldier_3', 'officer_1', 'officer_2', 'officer_3']
+ },
+ sign_1: {
+ x: -4.25,
+ y: -5.25,
+ unlockedBy: '4',
+ type: 'sign'
+ },
+ 5: {
+ x: -1,
+ y: -5,
+ unlockedBy: '4',
+ type: 'regular',
+ difficulty: 12,
+ enemyType: ['soldier_1', 'soldier_2', 'soldier_3', 'hunter']
+ },
+ 6: {
+ x: 4,
+ y: -4.5,
+ unlockedBy: '5',
+ type: 'regular',
+ difficulty: 15,
+ enemyType: ['soldier_1', 'soldier_2', 'soldier_3', 'officer_1']
+ },
+ 7: {
+ x: 6,
+ y: -2,
+ unlockedBy: '6',
+ type: 'regular',
+ difficulty: 18,
+ enemyType: ['officer_1', 'officer_2', 'officer_3', 'sniper']
+ },
+ sign_2: {
+ x: 7.5,
+ y: -2.5,
+ unlockedBy: '7',
+ type: 'sign'
+ },
+ 8: {
+ x: 7,
+ y: 1.5,
+ unlockedBy: '7',
+ type: 'regular',
+ difficulty: 21,
+ enemyType: ['officer_1', 'officer_2', 'officer_3', 'soldier_1']
+ },
+ 9: {
+ x: 5.5,
+ y: 4,
+ unlockedBy: '8',
+ type: 'regular',
+ difficulty: 24,
+ enemyType: ['soldier_1', 'soldier_2', 'soldier_3', 'officer_1', 'officer_2', 'officer_3']
+ },
+ 10: {
+ x: 2,
+ y: 2,
+ unlockedBy: '9',
+ type: 'regular',
+ difficulty: 27,
+ enemyType: ['soldier_1', 'officer_1', 'hunter', 'sniper']
+ },
+ sign_3: {
+ x: 2.5,
+ y: 0.5,
+ unlockedBy: '10',
+ type: 'sign'
+ },
+ boss_1: {
+ x: 0,
+ y: 0,
+ unlockedBy: '10',
+ type: 'boss',
+ difficulty: 30,
+ boss: ['ohilio_guard1', 'ohilio_guard2', 'ohilio'],
+ reward: 'hordeAreaMonkeyJungle'
+ },
+ endless: {
+ x: -1,
+ y: 5,
+ unlockedBy: '10',
+ type: 'endless',
+ difficulty: 30,
+ enemyType: ['soldier_1', 'soldier_2', 'soldier_3', 'officer_1', 'officer_2', 'officer_3', 'hunter', 'sniper']
+ }
+ },
+ decoration: [
+ {x: 0, y: -0.5, rotate: 0, icon: 'mdi-tent', size: 3},
+ {x: -8, y: 5, rotate: 0, icon: 'mdi-forest', size: 3},
+ {x: -6.5, y: 3, rotate: 0, icon: 'mdi-forest', size: 2.25},
+ {x: 4, y: -2, rotate: 0, icon: 'mdi-pine-tree-variant', size: 1.9},
+ {x: -2, y: -5.5, rotate: 0, icon: 'mdi-truck-cargo-container', size: 1.2},
+ {x: -8, y: 1, rotate: 0, icon: 'mdi-flag-variant', size: 1.75},
+ {x: -6, y: -2.2, rotate: 160, icon: 'mdi-pistol', size: 0.75},
+ {x: -5, y: -2.5, rotate: 110, icon: 'mdi-magazine-pistol', size: 0.5},
+ {x: 1.5, y: -4.75, rotate: 0, icon: 'mdi-bridge', size: 1.5},
+ {x: 6.5, y: -2.6, rotate: 80, icon: 'mdi-magazine-rifle', size: 0.5},
+ {x: 6.5, y: 5, rotate: 0, icon: 'mdi-truck', size: 1.3},
+ {x: 5.55, y: 5.25, rotate: 270, icon: 'mdi-ammunition', size: 0.5},
+ {x: 5.6, y: 4.85, rotate: 0, icon: 'mdi-ammunition', size: 0.45},
+ {x: 5.1, y: 5.1, rotate: 20, icon: 'mdi-ammunition', size: 0.7},
+ {x: 1.9, y: -7.15, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: 1.65, y: -6.4, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: 1.5, y: -5.65, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: 1.5, y: -4, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: 1.3, y: -3.25, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: 0.9, y: -2.5, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: 0, y: -2.1, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -0.9, y: -2.3, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -1.8, y: -2.2, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -2.7, y: -1.8, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -3.2, y: -1.05, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -3.5, y: -0.4, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -3.6, y: 0.35, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -3.7, y: 1.1, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -3.4, y: 1.85, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -3.2, y: 2.6, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -3.5, y: 3.35, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -3.6, y: 4.1, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -4, y: 4.85, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -4.5, y: 5.6, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -4.8, y: 6.35, rotate: 0, icon: 'mdi-waves', size: 1},
+ {x: -4.9, y: 7.1, rotate: 0, icon: 'mdi-waves', size: 1},
+ ]
+}
diff --git a/src/js/modules/horde/battlePass.js b/src/js/modules/horde/battlePass.js
new file mode 100644
index 00000000..8daa3f29
--- /dev/null
+++ b/src/js/modules/horde/battlePass.js
@@ -0,0 +1,35 @@
+const newUpgrade = {icon: 'mdi-arrow-up-thin', color: 'light-blue', effect: [{name: 'hordeBattlePassUpgrade', type: 'text', value: true}]};
+const newPrestigeUpgrade = {icon: 'mdi-arrow-up-bold', color: 'orange', effect: [{name: 'hordeBattlePassPrestigeUpgrade', type: 'text', value: true}]};
+
+export default {
+ 1: newUpgrade,
+ 2: {icon: 'mdi-bow-arrow', color: 'light-green', effect: [{name: 'hordeClassArcher', type: 'unlock', value: true}]},
+ 3: newUpgrade,
+ 5: {icon: 'mdi-wizard-hat', color: 'deep-purple', effect: [{name: 'hordeClassMage', type: 'unlock', value: true}]},
+ 7: newPrestigeUpgrade,
+ 8: newUpgrade,
+ 10: newPrestigeUpgrade,
+ 12: newPrestigeUpgrade,
+ 14: newUpgrade,
+ 15: {icon: 'mdi-shield', color: 'blue-grey', effect: [{name: 'hordeClassKnight', type: 'unlock', value: true}]},
+ 16: newPrestigeUpgrade,
+ 18: newUpgrade,
+ 20: newPrestigeUpgrade,
+ 24: newUpgrade,
+ 25: {icon: 'mdi-cached', color: 'pink', effect: [{name: 'hordeAutocast', type: 'base', value: 1}]},
+ 27: newPrestigeUpgrade,
+ 30: {icon: 'mdi-necklace', color: 'cyan', effect: [{name: 'hordeHeirloomAmount', type: 'mult', value: 2}]},
+ 31: newUpgrade,
+ 33: newPrestigeUpgrade,
+ 35: {icon: 'mdi-pirate', color: 'orange', effect: [{name: 'hordeClassPirate', type: 'unlock', value: true}]},
+ 40: {icon: 'mdi-star', color: 'light-blue', effect: [{name: 'hordeSkillPointsPerLevel', type: 'base', value: 1}]},
+ 42: newUpgrade,
+ 45: newPrestigeUpgrade,
+ 50: {icon: 'mdi-treasure-chest', color: 'red', effect: [{name: 'hordeMaxTrinkets', type: 'base', value: 1}]},
+ 55: newUpgrade,
+ 60: {icon: 'mdi-billiards-rack', color: 'teal', effect: [{name: 'hordeShardChance', type: 'mult', value: 3}]},
+ 65: newPrestigeUpgrade,
+ 70: newUpgrade,
+ 75: {icon: 'mdi-treasure-chest', color: 'wooden', effect: [{name: 'hordeMaxItems', type: 'base', value: 1}]},
+ 80: {icon: 'mdi-star', color: 'light-blue', effect: [{name: 'hordeSkillPointsPerLevel', type: 'base', value: 1}]},
+}
diff --git a/src/js/modules/horde/boss.js b/src/js/modules/horde/boss.js
new file mode 100644
index 00000000..527398a7
--- /dev/null
+++ b/src/js/modules/horde/boss.js
@@ -0,0 +1,72 @@
+export default {
+ ohilio_guard1: {
+ attack: 0.15,
+ health: 150,
+ textShadow: '1px 1px 2px palevioletred, 0 0 25px lightpink, 0 0 5px pink',
+ sigil: {
+ shotgun_gun: 3,
+ war_bandage: 3,
+ },
+ stats: {}
+ },
+ ohilio_guard2: {
+ attack: 0.6125,
+ health: 45,
+ textShadow: '1px 1px 2px palevioletred, 0 0 25px lightpink, 0 0 5px pink',
+ sigil: {
+ rifle_gun: 3,
+ war_grenade: 2,
+ },
+ stats: {}
+ },
+ ohilio: {
+ attack: 0.01,
+ health: 0.01,
+ textShadow: '1px 1px 2px palevioletred, 0 0 25px lightpink, 0 0 5px pink',
+ sigil: {
+ ohilio_megagun: 1,
+ },
+ stats: {}
+ },
+ mina: {
+ attack: 0.5,
+ health: 87.5,
+ textShadow: '1px 1px 2px palevioletred, 0 0 25px lightpink, 0 0 5px pink',
+ sigil: {
+ mina_charm: 1,
+ },
+ stats: {
+ toxic_base: 0.03,
+ execute_base: 0.2
+ }
+ },
+ chriz1: {
+ attack: 0.375,
+ health: 42.5,
+ textShadow: '1px 1px 2px blue',
+ sigil: {
+ chriz_magicMissile: 1,
+ chriz_fireball: 1,
+ chriz_iceBlast: 1,
+ chriz_lightningStrike: 1,
+ chriz_heal: 1,
+ },
+ stats: {
+ magicConversion_base: 4,
+ physicTaken_mult: 0.01,
+ magicTaken_mult: 1.75,
+ }
+ },
+ chriz2: {
+ attack: 0.5,
+ health: 50,
+ textShadow: '1px 1px 2px red',
+ sigil: {},
+ stats: {
+ critChance_base: 0.35,
+ critMult_base: 3,
+ physicTaken_mult: 1.75,
+ magicTaken_mult: 0.01,
+ }
+ }
+}
diff --git a/src/js/modules/horde/card.js b/src/js/modules/horde/card.js
index 4cb9f520..161f0fc5 100644
--- a/src/js/modules/horde/card.js
+++ b/src/js/modules/horde/card.js
@@ -1,10 +1,22 @@
import cardList from "./cardList";
export default {
- feature: {prefix: 'HO', reward: [
- {name: 'hordeAttack', type: 'mult', value: lvl => lvl * 0.03 + 1},
- {name: 'hordeHealth', type: 'mult', value: lvl => lvl * 0.03 + 1}
- ], unlock: 'hordeFeature'},
+ feature: {
+ prefix: 'HO',
+ reward: [
+ {name: 'hordeAttack', type: 'mult', value: lvl => lvl * 0.03 + 1},
+ {name: 'hordeHealth', type: 'mult', value: lvl => lvl * 0.03 + 1}
+ ],
+ shinyReward: [
+ {name: 'hordePrestigeIncome', type: 'mult', value: lvl => lvl * 0.05 + 1},
+ ],
+ powerReward: [
+ {name: 'hordeAttack', type: 'mult', value: lvl => Math.pow(1.06, lvl)},
+ {name: 'hordeHealth', type: 'mult', value: lvl => Math.pow(1.06, lvl)},
+ {name: 'hordePrestigeIncome', type: 'mult', value: lvl => Math.pow(1.05, lvl)},
+ ],
+ unlock: 'hordeFeature'
+ },
collection: {
dangerousWeapons: {reward: [
{name: 'hordeAttack', type: 'mult', value: 1.35}
@@ -18,28 +30,28 @@ export default {
]},
},
pack: {
- rookieOnTheBattlefield: {unlock: 'hordeItems', amount: 5, price: 35, content: {
+ rookieOnTheBattlefield: {unlock: 'hordeItems', amount: 3, price: 20, content: {
'HO-0001': 2.6, 'HO-0002': 0.45, 'HO-0003': 1.25, 'HO-0004': 0.92, 'HO-0005': 1.55, 'HO-0006': 1.36,
'HO-0007': 0.6, 'HO-0008': 0.8, 'HO-0009': 0.88, 'HO-0010': 0.4, 'HO-0011': 0.48,
'HO-0012': 2.1, 'HO-0013': 1.6, 'HO-0014': 0.77,
}},
- spiritualSuccess: {unlock: 'hordePrestige', amount: 4, price: 50, content: {
+ spiritualSuccess: {unlock: 'hordePrestige', amount: 4, price: 65, content: {
'HO-0003': 1.25, 'HO-0004': 0.92, 'HO-0005': 1.55, 'HO-0006': 1.36,
'HO-0009': 0.88, 'HO-0010': 0.8, 'HO-0011': 0.96,
'HO-0012': 2.1, 'HO-0013': 1.6, 'HO-0014': 0.77, 'HO-0015': 1.2, 'HO-0016': 1.3, 'HO-0017': 1.8,
- 'HO-0018': 1.6, 'HO-0019': 0.75, 'HO-0020': 0.84, 'HO-0021': 1.05, 'HO-0022': 1.5, 'HO-0023': 0.2,
+ 'HO-0018': 1.6, 'HO-0019': 0.75, 'HO-0020': 0.84, 'HO-0021': 1.05, 'HO-0022': 1.5, 'HO-0023': 0.43,
'HO-0024': 0.7, 'HO-0026': 0.9,
}},
- oldMemories: {unlock: 'hordeHeirlooms', amount: 2, price: 30, content: {
+ oldMemories: {unlock: 'hordeHeirlooms', amount: 2, price: 50, content: {
'HO-0007': 1.2, 'HO-0010': 0.8, 'HO-0011': 0.96,
'HO-0019': 1.5, 'HO-0020': 1.68, 'HO-0021': 2.1, 'HO-0022': 3.75,
'HO-0024': 1.4, 'HO-0026': 1.8, 'HO-0027': 1.15, 'HO-0028': 2, 'HO-0030': 2.3,
}},
- taintedWorld: {unlock: 'hordeItemMastery', amount: 6, price: 115, content: {
- 'HO-0023': 0.5,
+ taintedWorld: {unlock: 'hordeItemMastery', amount: 6, price: 225, content: {
+ 'HO-0023': 0.72,
'HO-0024': 1.2, 'HO-0025': 1.3, 'HO-0026': 1.55, 'HO-0027': 1.15, 'HO-0028': 2, 'HO-0029': 1.1, 'HO-0030': 2.3,
'HO-0031': 3.5, 'HO-0032': 2.1, 'HO-0033': 0.9, 'HO-0034': 1.22, 'HO-0035': 1.58, 'HO-0036': 1.18,
- 'HO-0037': 1.4, 'HO-0038': 0.25, 'HO-0039': 0.77, 'HO-0040': 1.36, 'HO-0041': 0.09,
+ 'HO-0037': 1.4, 'HO-0038': 0.5, 'HO-0039': 0.77, 'HO-0040': 1.36, 'HO-0041': 0.22,
}},
},
card: cardList
diff --git a/src/js/modules/horde/cardList.js b/src/js/modules/horde/cardList.js
index ffe3cd70..d3886402 100644
--- a/src/js/modules/horde/cardList.js
+++ b/src/js/modules/horde/cardList.js
@@ -1,13 +1,10 @@
export default [
- {id: 1, collection: 'dangersInTheDark', reward: [
- {name: 'hordeAttack', type: 'mult', value: 1.2},
- {name: 'hordeHealth', type: 'mult', value: 1.2}
- ], color: 'green', icons: [
+ {id: 1, collection: 'dangersInTheDark', power: 3, color: 'green', icons: [
{"x": -0.1, "y": 0.1, "rotate": -20, "size": 2.5, "icon": "mdi-chart-bubble"},
{"x": 0.85, "y": 0.1, "rotate": 0, "size": 1.5, "icon": "mdi-snake"},
{"x": -0.85, "y": 0.05, "rotate": 0, "size": 2, "icon": "mdi-human-handsdown"}
]},
- {id: 2, collection: 'dangersInTheDark', reward: [
+ {id: 2, collection: 'dangersInTheDark', power: 2, reward: [
{name: 'hordeBossRequirement', type: 'base', value: -5}
], color: 'darker-grey', icons: [
{"x": 0, "y": 0.1, "rotate": 0, "size": 3, "icon": "mdi-ellipse-outline"},
@@ -16,9 +13,9 @@ export default [
{"x": 0.85, "y": -0.8, "rotate": 0, "size": 1, "icon": "mdi-grass"},
{"x": 0, "y": -1, "rotate": 0, "size": 0.9, "icon": "mdi-grass"}
]},
- {id: 3, collection: 'dangersInTheDark', reward: [
- {name: 'currencyHordeBoneGain', type: 'mult', value: 1.4},
- {name: 'currencyHordeBoneCap', type: 'mult', value: 2}
+ {id: 3, collection: 'dangersInTheDark', power: 1, reward: [
+ {name: 'currencyHordeBoneGain', type: 'mult', value: 1.2},
+ {name: 'currencyHordeBoneCap', type: 'mult', value: 1.35}
], color: 'orange-red', icons: [
{"x": 0, "y": 0.8, "rotate": 0, "size": 3, "icon": "mdi-image-filter-hdr"},
{"x": 0.15, "y": 0.55, "rotate": 0, "size": 1, "icon": "mdi-fountain"},
@@ -26,8 +23,7 @@ export default [
{"x": -0.6, "y": -0.15, "rotate": -140, "size": 0.95, "icon": "mdi-motion"},
{"x": -0.1, "y": -0.75, "rotate": -100, "size": 1.15, "icon": "mdi-motion"}
]},
- {id: 4, collection: 'dangersInTheDark', reward: [
- {name: 'currencyHordeMonsterPartGain', type: 'mult', value: 1.25},
+ {id: 4, collection: 'dangersInTheDark', power: 2, reward: [
{name: 'currencyHordeMonsterPartCap', type: 'base', value: 50}
], color: 'deep-purple', icons: [
{"x": 0, "y": 0, "rotate": 0, "size": 2, "icon": "mdi-human-handsdown"},
@@ -35,9 +31,8 @@ export default [
{"x": 0.55, "y": -0.3, "rotate": 0, "size": 1, "icon": "mdi-map-legend"},
{"x": -0.7, "y": 0.85, "rotate": 75, "size": 1.75, "icon": "mdi-chart-bubble"}
]},
- {id: 5, collection: 'dangersInTheDark', reward: [
- {name: 'hordeAttack', type: 'mult', value: 1.35},
- {name: 'currencyHordeBoneGain', type: 'mult', value: 1.35}
+ {id: 5, collection: 'dangersInTheDark', power: 2, reward: [
+ {name: 'currencyHordeBoneGain', type: 'mult', value: 1.25}
], color: 'cyan', icons: [
{"x": 0.6, "y": 0.2, "rotate": 0, "size": 2.5, "icon": "mdi-mirror-rectangle"},
{"x": 0.65, "y": 0.5, "rotate": 0, "size": 1, "icon": "mdi-human-greeting"},
@@ -45,8 +40,7 @@ export default [
{"x": -0.4, "y": 0.65, "rotate": 0, "size": 1.1, "icon": "mdi-human-handsdown"},
{"x": -0.3, "y": 0.05, "rotate": 15, "size": 0.75, "icon": "mdi-exclamation-thick"}
]},
- {id: 6, collection: 'dangersInTheDark', reward: [
- {name: 'hordeHealth', type: 'mult', value: 1.35},
+ {id: 6, collection: 'dangersInTheDark', power: 2, reward: [
{name: 'hordeDivisionShield', type: 'base', value: 4}
], color: 'red', icons: [
{"x": -0.95, "y": 0.8, "rotate": 0, "size": 1.5, "icon": "mdi-waves"},
@@ -59,17 +53,17 @@ export default [
{"x": -0.05, "y": 0.1, "rotate": -20, "size": 0.8, "icon": "mdi-fire"}
]},
- {id: 7, collection: 'maintainingSafety', reward: [
- {name: 'hordeMaxItems', type: 'base', value: 1}
+ {id: 7, collection: 'maintainingSafety', power: 2, reward: [
+ {name: 'hordeItemChance', type: 'mult', value: 1.6}
], color: 'pale-yellow', icons: [
{"x": 0, "y": 1, "rotate": 90, "size": 2, "icon": "mdi-rectangle"},
{"x": 0, "y": 0.35, "rotate": 0, "size": 1, "icon": "mdi-bag-personal"},
{"x": 0.55, "y": 0.75, "rotate": 0, "size": 1.6, "icon": "mdi-human-greeting"},
{"x": -0.9, "y": 0.75, "rotate": 0, "size": 1.55, "icon": "mdi-human-handsdown"}
]},
- {id: 8, collection: 'maintainingSafety', reward: [
- {name: 'currencyHordeBoneCap', type: 'mult', value: 2.5},
- {name: 'currencyHordeMonsterPartCap', type: 'base', value: 60}
+ {id: 8, collection: 'maintainingSafety', power: 2, reward: [
+ {name: 'currencyHordeBoneCap', type: 'mult', value: 1.2},
+ {name: 'currencyHordeMonsterPartCap', type: 'base', value: 30}
], color: 'cherry', icons: [
{"x": -0.1, "y": 0.55, "rotate": 0, "size": 1.25, "icon": "mdi-wall"},
{"x": 0.45, "y": 0.55, "rotate": 0, "size": 1.25, "icon": "mdi-wall"},
@@ -77,14 +71,14 @@ export default [
{"x": -0.5, "y": 0.2, "rotate": -15, "size": 0.8, "icon": "mdi-hammer"},
{"x": -0.85, "y": 0.45, "rotate": 0, "size": 1.6, "icon": "mdi-walk"}
]},
- {id: 9, collection: 'maintainingSafety', reward: [
- {name: 'hordeHealth', type: 'mult', value: 1.75}
+ {id: 9, collection: 'maintainingSafety', power: 2, reward: [
+ {name: 'hordeHealth', type: 'mult', value: 1.3}
], color: 'indigo', icons: [
{"x": -0.7, "y": 0, "rotate": 0, "size": 2.5, "icon": "mdi-home"},
{"x": 0.7, "y": 0, "rotate": 0, "size": 2.5, "icon": "mdi-home"},
{"x": 0.3, "y": -0.5, "rotate": 0, "size": 1, "icon": "mdi-cctv"}
]},
- {id: 10, collection: 'maintainingSafety', reward: [
+ {id: 10, collection: 'maintainingSafety', power: 2, reward: [
{name: 'hordeRevive', type: 'base', value: 1}
], color: 'green', icons: [
{"x": -0.75, "y": 0, "rotate": 20, "size": 0.75, "icon": "mdi-leaf"},
@@ -94,7 +88,7 @@ export default [
{"x": -0.3, "y": 0.7, "rotate": 0, "size": 2, "icon": "mdi-book-open-page-variant-outline"},
{"x": -0.55, "y": 0.7, "rotate": 0, "size": 0.6, "icon": "mdi-mushroom-off"}
]},
- {id: 11, collection: 'maintainingSafety', reward: [
+ {id: 11, collection: 'maintainingSafety', power: 2, reward: [
{name: 'hordeRespawn', type: 'base', value: -60}
], color: 'yellow', icons: [
{"x": 0, "y": 0.24, "rotate": 0, "size": 1.55, "icon": "mdi-fence-electric"},
@@ -105,8 +99,7 @@ export default [
{"x": 0.3, "y": -1, "rotate": 0, "size": 0.9, "icon": "mdi-dog-side"}
]},
- {id: 12, collection: 'dangerousWeapons', reward: [
- {name: 'hordeAttack', type: 'mult', value: 1.2},
+ {id: 12, collection: 'dangerousWeapons', power: 2, reward: [
{name: 'hordeCritChance', type: 'base', value: 0.05},
{name: 'hordeCritMult', type: 'base', value: 0.1}
], color: 'deep-orange', icons: [
@@ -118,7 +111,7 @@ export default [
{"x": 0.45, "y": 0.85, "rotate": 95, "size": 1.25, "icon": "mdi-bomb"},
{"x": 0.75, "y": 0.3, "rotate": 20, "size": 1.25, "icon": "mdi-bomb"}
]},
- {id: 13, collection: 'dangerousWeapons', reward: [
+ {id: 13, collection: 'dangerousWeapons', power: 1, reward: [
{name: 'hordeAttack', type: 'mult', value: 1.15},
{name: 'hordeCritMult', type: 'base', value: 0.35}
], color: 'purple', icons: [
@@ -126,8 +119,8 @@ export default [
{"x": 0, "y": 0.25, "rotate": 15, "size": 2.1, "icon": "mdi-firework"},
{"x": 0.1, "y": 0.7, "rotate": 0, "size": 1, "icon": "mdi-human-handsup"}
]},
- {id: 14, collection: 'dangerousWeapons', reward: [
- {name: 'hordeAttack', type: 'mult', value: 1.25},
+ {id: 14, collection: 'dangerousWeapons', power: 2, reward: [
+ {name: 'hordeAttack', type: 'mult', value: 1.05},
{name: 'hordeBossRequirement', type: 'base', value: -3}
], color: 'light-blue', icons: [
{"x": 0, "y": 0, "rotate": 15, "size": 2.75, "icon": "mdi-sword"},
@@ -135,17 +128,15 @@ export default [
{"x": -0.55, "y": 0.15, "rotate": -70, "size": 1, "icon": "mdi-rectangle"},
{"x": -0.68, "y": 0.48, "rotate": -160, "size": 0.6, "icon": "mdi-triangle"}
]},
- {id: 15, collection: 'dangerousWeapons', reward: [
- {name: 'hordeFirstStrike', type: 'base', value: 0.6},
- {name: 'hordeToxic', type: 'base', value: 0.06}
+ {id: 15, collection: 'dangerousWeapons', power: 3, reward: [
+ {name: 'hordeToxic', type: 'base', value: 0.01}
], color: 'green', icons: [
{"x": -0.85, "y": 0.45, "rotate": 0, "size": 1.25, "icon": "mdi-bottle-tonic-skull"},
{"x": 0.3, "y": 0, "rotate": 0, "size": 2.1, "icon": "mdi-bow-arrow"},
{"x": 0.8, "y": -0.1, "rotate": 0, "size": 0.65, "icon": "mdi-water"}
]},
- {id: 16, collection: 'dangerousWeapons', reward: [
- {name: 'hordeFirstStrike', type: 'base', value: 1.8},
- {name: 'hordeCritChance', type: 'base', value: 0.04}
+ {id: 16, collection: 'dangerousWeapons', power: 3, reward: [
+ {name: 'hordeFirstStrike', type: 'base', value: 0.8},
], color: 'pink', icons: [
{"x": 0, "y": 0, "rotate": 0, "size": 1.75, "icon": "mdi-rocket-launch"},
{"x": -0.5, "y": -0.5, "rotate": 0, "size": 1, "icon": "mdi-rocket-launch"},
@@ -153,8 +144,8 @@ export default [
{"x": -0.2, "y": -0.4, "rotate": 45, "size": 1.25, "icon": "mdi-minus-thick"},
{"x": 0.4, "y": 0.2, "rotate": 45, "size": 1, "icon": "mdi-minus-thick"}
]},
- {id: 17, collection: 'dangerousWeapons', reward: [
- {name: 'hordeAttack', type: 'mult', value: 1.45}
+ {id: 17, collection: 'dangerousWeapons', power: 2, reward: [
+ {name: 'hordeAttack', type: 'mult', value: 1.35}
], color: 'red', icons: [
{"x": 0, "y": 0.55, "rotate": 0, "size": 2.75, "icon": "mdi-human-handsup"},
{"x": -0.35, "y": -0.3, "rotate": 0, "size": 1.25, "icon": "mdi-axe-battle"},
@@ -162,16 +153,16 @@ export default [
{"x": 0.35, "y": -0.3, "rotate": 270, "size": 1.25, "icon": "mdi-axe-battle"},
{"x": 0.65, "y": 0, "rotate": 90, "size": 1.25, "icon": "mdi-axe-battle"}
]},
- {id: 18, collection: 'dangerousWeapons', reward: [
- {name: 'hordeCritChance', type: 'base', value: 0.08},
- {name: 'hordeItemChance', type: 'mult', value: 2}
+ {id: 18, collection: 'dangerousWeapons', power: 3, reward: [
+ {name: 'hordeCritChance', type: 'base', value: 0.1},
+ {name: 'hordeItemChance', type: 'mult', value: 1.25}
], color: 'pale-yellow', icons: [
{"x": 0, "y": 0.65, "rotate": 0, "size": 2, "icon": "mdi-book-open-variant"},
{"x": -0.2, "y": -0.3, "rotate": 20, "size": 1.65, "icon": "mdi-hand-front-left"},
{"x": 0.4, "y": -0.4, "rotate": -60, "size": 2, "icon": "mdi-pen"}
]},
- {id: 19, collection: 'dangerousWeapons', reward: [
- {name: 'hordeBossRequirement', type: 'base', value: -4},
+ {id: 19, collection: 'dangerousWeapons', power: 3, reward: [
+ {name: 'hordeBossRequirement', type: 'base', value: -2},
{name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: 1.12}
], color: 'brown', icons: [
{"x": -0.7, "y": 0, "rotate": 0, "size": 1, "icon": "mdi-bowl"},
@@ -184,17 +175,17 @@ export default [
{"x": 0.45, "y": 0.3, "rotate": 0, "size": 0.5, "icon": "mdi-circle"},
{"x": -0.7, "y": -0.2, "rotate": 0, "size": 1, "icon": "mdi-circle"}
]},
- {id: 20, collection: 'dangerousWeapons', reward: [
- {name: 'hordeItemChance', type: 'mult', value: 1.5},
+ {id: 20, collection: 'dangerousWeapons', power: 3, reward: [
+ {name: 'hordeItemChance', type: 'mult', value: 1.25},
{name: 'currencyHordeSoulCorruptedCap', type: 'mult', value: 1.15}
], color: 'pale-pink', icons: [
{"x": -0.15, "y": 0.2, "rotate": 0, "size": 2, "icon": "mdi-human"},
{"x": 0.4, "y": 0, "rotate": 0, "size": 1, "icon": "mdi-pistol"},
{"x": 0.42, "y": -0.2, "rotate": 45, "size": 1, "icon": "mdi-knife-military"}
]},
- {id: 21, collection: 'dangerousWeapons', reward: [
- {name: 'currencyHordeMonsterPartGain', type: 'mult', value: 1.2},
- {name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: 1.18}
+ {id: 21, collection: 'dangerousWeapons', power: 2, reward: [
+ {name: 'currencyHordeMonsterPartGain', type: 'mult', value: 1.3},
+ {name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: 1.2}
], color: 'amber', icons: [
{"x": 0.3, "y": -0.85, "rotate": 0, "size": 1.45, "icon": "mdi-white-balance-sunny"},
{"x": -0.3, "y": -0.25, "rotate": -45, "size": 2, "icon": "mdi-minus"},
@@ -202,16 +193,16 @@ export default [
{"x": -0.3, "y": 0.45, "rotate": 45, "size": 2, "icon": "mdi-minus"},
{"x": 0.2, "y": 0.55, "rotate": 10, "size": 1, "icon": "mdi-fire"}
]},
- {id: 22, collection: 'dangerousWeapons', reward: [
- {name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: 1.2},
- {name: 'currencyHordeSoulCorruptedCap', type: 'mult', value: 1.2}
+ {id: 22, collection: 'dangerousWeapons', power: 2, reward: [
+ {name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: 1.22},
+ {name: 'currencyHordeSoulCorruptedCap', type: 'mult', value: 1.22}
], color: 'cherry', icons: [
{"x": -0.85, "y": 0, "rotate": 0, "size": 1.5, "icon": "mdi-logout"},
{"x": 0, "y": 0, "rotate": 0, "size": 1.25, "icon": "mdi-saw-blade"},
{"x": 0.9, "y": 0, "rotate": 25, "size": 1.25, "icon": "mdi-saw-blade"}
]},
- {id: 23, collection: 'dangerousWeapons', reward: [
- {name: 'hordeToxic', type: 'base', value: 0.1}
+ {id: 23, collection: 'dangerousWeapons', power: 0, reward: [
+ {name: 'hordeToxic', type: 'base', value: 0.025}
], color: 'lime', icons: [
{"x": 0, "y": -0.2, "rotate": 0, "size": 2.5, "icon": "mdi-flask-empty"},
{"x": 0.05, "y": 0.45, "rotate": -90, "size": 1.25, "icon": "mdi-motion"},
@@ -219,8 +210,7 @@ export default [
{"x": 0.35, "y": 0.45, "rotate": -90, "size": 0.75, "icon": "mdi-motion"}
]},
- {id: 24, collection: 'supplyAndSupport', reward: [
- {name: 'currencyHordeBoneGain', type: 'mult', value: 1.5},
+ {id: 24, collection: 'supplyAndSupport', power: 3, reward: [
{name: 'hordePhysicTaken', type: 'mult', value: 1 / 1.25}
], color: 'wooden', icons: [
{"x": 0, "y": -0.2, "rotate": 0, "size": 3, "icon": "mdi-tree"},
@@ -228,9 +218,8 @@ export default [
{"x": -0.2, "y": 0.55, "rotate": 0, "size": 1.25, "icon": "mdi-hiking"},
{"x": -0.65, "y": 1.2, "rotate": -150, "size": 0.8, "icon": "mdi-arrow-projectile"}
]},
- {id: 25, collection: 'supplyAndSupport', reward: [
- {name: 'hordeItemChance', type: 'mult', value: 2},
- {name: 'hordeItemMasteryGain', type: 'mult', value: 1.5}
+ {id: 25, collection: 'supplyAndSupport', power: 5, reward: [
+ {name: 'hordeItemMasteryGain', type: 'mult', value: 1.2}
], color: 'green', icons: [
{"x": 0.1, "y": -0.15, "rotate": 0, "size": 1.25, "icon": "mdi-meditation"},
{"x": 0.85, "y": 0.15, "rotate": 0, "size": 1.95, "icon": "mdi-tree"},
@@ -240,9 +229,9 @@ export default [
{"x": -0.35, "y": 0.85, "rotate": 0, "size": 0.8, "icon": "mdi-grass"},
{"x": 0.4, "y": 0.75, "rotate": 0, "size": 0.75, "icon": "mdi-grass"}
]},
- {id: 26, collection: 'supplyAndSupport', reward: [
- {name: 'currencyHordeSoulCorruptedCap', type: 'mult', value: 1.12},
- {name: 'currencyHordeBoneCap', type: 'mult', value: 2.25}
+ {id: 26, collection: 'supplyAndSupport', power: 3, reward: [
+ {name: 'currencyHordeSoulCorruptedCap', type: 'mult', value: 1.1},
+ {name: 'currencyHordeBoneCap', type: 'mult', value: 1.15}
], color: 'light-grey', icons: [
{"x": 0, "y": 0, "rotate": 0, "size": 2, "icon": "mdi-human-handsdown"},
{"x": 0.4, "y": 0.1, "rotate": 80, "size": 1.75, "icon": "mdi-minus"},
@@ -251,23 +240,21 @@ export default [
{"x": 0.6, "y": -0.05, "rotate": 0, "size": 0.75, "icon": "mdi-exclamation-thick"},
{"x": -0.45, "y": 0.95, "rotate": 0, "size": 0.75, "icon": "mdi-mine"}
]},
- {id: 27, collection: 'supplyAndSupport', reward: [
- {name: 'hordeNostalgia', type: 'base', value: 50},
- {name: 'hordeRespawn', type: 'base', value: -30}
+ {id: 27, collection: 'supplyAndSupport', power: 4, reward: [
+ {name: 'hordeNostalgia', type: 'base', value: 20}
], color: 'dark-blue', icons: [
{"x": -0.65, "y": 0.25, "rotate": 0, "size": 1.55, "icon": "mdi-walk"},
{"x": -0.2, "y": 0.1, "rotate": -10, "size": 1, "icon": "mdi-shield"},
{"x": 0.6, "y": -0.15, "rotate": 160, "size": 1, "icon": "mdi-motion"}
]},
- {id: 28, collection: 'supplyAndSupport', reward: [
- {name: 'hordeHeirloomChance', type: 'base', value: 0.04},
- {name: 'hordeNostalgia', type: 'base', value: 50}
+ {id: 28, collection: 'supplyAndSupport', power: 4, reward: [
+ {name: 'hordeHeirloomChance', type: 'base', value: 0.03}
], color: 'yellow', icons: [
{"x": 0, "y": 0.25, "rotate": 180, "size": 5, "icon": "mdi-dome-light"},
{"x": -0.2, "y": 0.15, "rotate": 0, "size": 1.25, "icon": "mdi-human-handsdown"},
{"x": 0.3, "y": 0.2, "rotate": 0, "size": 1.15, "icon": "mdi-human-greeting"}
]},
- {id: 29, collection: 'supplyAndSupport', reward: [
+ {id: 29, collection: 'supplyAndSupport', power: 4, reward: [
{name: 'hordeCritMult', type: 'base', value: 0.25},
{name: 'hordeItemMasteryGain', type: 'mult', value: 1.3}
], color: 'pink-purple', icons: [
@@ -275,8 +262,8 @@ export default [
{"x": 0, "y": 0.12, "rotate": 20, "size": 1, "icon": "mdi-radar"},
{"x": 0.25, "y": -0.6, "rotate": 0, "size": 1.25, "icon": "mdi-antenna"}
]},
- {id: 30, collection: 'supplyAndSupport', reward: [
- {name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: 1.18},
+ {id: 30, collection: 'supplyAndSupport', power: 3, reward: [
+ {name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: 1.15},
{name: 'hordeHeirloomChance', type: 'base', value: 0.04}
], color: 'dark-grey', icons: [
{"x": -0.15, "y": 0.5, "rotate": 0, "size": 2.5, "icon": "mdi-human-handsdown"},
@@ -284,24 +271,24 @@ export default [
{"x": 0.5, "y": 0.55, "rotate": 15, "size": 1.2, "icon": "mdi-binoculars"}
]},
- {id: 31, collection: 'againstTheCorruption', reward: [
- {name: 'hordeCorruption', type: 'mult', value: 1 / 1.2}
+ {id: 31, collection: 'againstTheCorruption', power: 5, reward: [
+ {name: 'hordeCorruption', type: 'mult', value: 1 / 1.1}
], color: 'red', icons: [
{"x": 0, "y": 0.6, "rotate": 0, "size": 2.5, "icon": "mdi-sign-pole"},
{"x": 0, "y": -0.5, "rotate": -20, "size": 1.3, "icon": "mdi-liquid-spot"},
{"x": 0, "y": -0.5, "rotate": 0, "size": 2.5, "icon": "mdi-cancel"}
]},
- {id: 32, collection: 'againstTheCorruption', reward: [
- {name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: 1.15},
- {name: 'hordeCorruption', type: 'mult', value: 1 / 1.1}
+ {id: 32, collection: 'againstTheCorruption', power: 5, reward: [
+ {name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: 1.1},
+ {name: 'hordeCorruption', type: 'mult', value: 1 / 1.05}
], color: 'pale-green', icons: [
{"x": 0, "y": 0, "rotate": 0, "size": 2, "icon": "mdi-filter"},
{"x": 0, "y": -0.55, "rotate": -85, "size": 1.25, "icon": "mdi-liquid-spot"},
{"x": 0, "y": 0.7, "rotate": 0, "size": 1, "icon": "mdi-dots-vertical"}
]},
- {id: 33, collection: 'againstTheCorruption', reward: [
- {name: 'hordeItemChance', type: 'mult', value: 5},
- {name: 'hordeItemMasteryGain', type: 'mult', value: 3},
+ {id: 33, collection: 'againstTheCorruption', power: 5, reward: [
+ {name: 'hordeItemChance', type: 'mult', value: 2.5},
+ {name: 'hordeItemMasteryGain', type: 'mult', value: 1.75},
{name: 'hordeCorruption', type: 'mult', value: 1.15}
], color: 'skyblue', icons: [
{"x": -0.5, "y": 0.4, "rotate": 0, "size": 1.75, "icon": "mdi-washing-machine"},
@@ -310,10 +297,10 @@ export default [
{"x": -0.5, "y": -0.4, "rotate": 20, "size": 1, "icon": "mdi-liquid-spot"},
{"x": 0.5, "y": -0.2, "rotate": 0, "size": 1, "icon": "mdi-tray-full"}
]},
- {id: 34, collection: 'againstTheCorruption', reward: [
- {name: 'hordeAttack', type: 'mult', value: 1.5},
- {name: 'hordeCritChance', type: 'base', value: 0.2},
- {name: 'hordeCritMult', type: 'base', value: 0.6},
+ {id: 34, collection: 'againstTheCorruption', power: 5, reward: [
+ {name: 'hordeAttack', type: 'mult', value: 1.25},
+ {name: 'hordeCritChance', type: 'base', value: 0.15},
+ {name: 'hordeCritMult', type: 'base', value: 0.4},
{name: 'hordeCorruption', type: 'mult', value: 1.15}
], color: 'orange', icons: [
{"x": 0, "y": 0.5, "rotate": 30, "size": 1.5, "icon": "mdi-liquid-spot"},
@@ -322,9 +309,9 @@ export default [
{"x": -0.25, "y": -0.5, "rotate": -20, "size": 1.2, "icon": "mdi-fire"},
{"x": -0.6, "y": 0.25, "rotate": 30, "size": 1.95, "icon": "mdi-torch"}
]},
- {id: 35, collection: 'againstTheCorruption', reward: [
- {name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: 1.5},
- {name: 'currencyHordeSoulCorruptedCap', type: 'mult', value: 1.5},
+ {id: 35, collection: 'againstTheCorruption', power: 5, reward: [
+ {name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: 1.4},
+ {name: 'currencyHordeSoulCorruptedCap', type: 'mult', value: 1.4},
{name: 'hordeCorruption', type: 'mult', value: 1.15}
], color: 'pink', icons: [
{"x": -0.65, "y": 0.4, "rotate": 180, "size": 3, "icon": "mdi-alpha-t"},
@@ -332,10 +319,10 @@ export default [
{"x": 0.35, "y": 0.4, "rotate": 30, "size": 2, "icon": "mdi-minus"},
{"x": 0.65, "y": 0.55, "rotate": 0, "size": 1, "icon": "mdi-liquid-spot"}
]},
- {id: 36, collection: 'againstTheCorruption', reward: [
+ {id: 36, collection: 'againstTheCorruption', power: 5, reward: [
{name: 'hordeHealth', type: 'mult', value: 2},
{name: 'hordeDivisionShield', type: 'base', value: 10},
- {name: 'hordeRevive', type: 'base', value: 2},
+ {name: 'hordeRevive', type: 'base', value: 1},
{name: 'hordeCorruption', type: 'mult', value: 1.15}
], color: 'pale-purple', icons: [
{"x": 0, "y": -0.9, "rotate": 0, "size": 1.5, "icon": "mdi-arrow-collapse-down"},
@@ -343,8 +330,7 @@ export default [
{"x": -0.5, "y": 0.5, "rotate": 0, "size": 3, "icon": "mdi-minus"},
{"x": 0.5, "y": 0.5, "rotate": 0, "size": 3, "icon": "mdi-minus"}
]},
- {id: 37, collection: 'againstTheCorruption', reward: [
- {name: 'hordeMaxItems', type: 'base', value: 3},
+ {id: 37, collection: 'againstTheCorruption', power: 7, reward: [
{name: 'hordeCorruption', type: 'mult', value: 1.15}
], color: 'brown', icons: [
{"x": 0.25, "y": -0.6, "rotate": 0, "size": 1.75, "icon": "mdi-truck-cargo-container"},
@@ -353,7 +339,7 @@ export default [
{"x": 0.45, "y": 0.6, "rotate": 0, "size": 0.8, "icon": "mdi-sack"},
{"x": 0.85, "y": 0.6, "rotate": 0, "size": 0.8, "icon": "mdi-sack"}
]},
- {id: 38, collection: 'againstTheCorruption', reward: [
+ {id: 38, collection: 'againstTheCorruption', power: 0, reward: [
{name: 'hordeCorruption', type: 'mult', value: 2}
], color: 'purple', icons: [
{"x": -0.39, "y": 0, "rotate": 0, "size": 3, "icon": "mdi-pot-mix"},
@@ -362,9 +348,9 @@ export default [
{"x": -0.75, "y": -0.1, "rotate": -45, "size": 1, "icon": "mdi-feather"},
{"x": 0.8, "y": 0, "rotate": 0, "size": 2, "icon": "mdi-candle"}
]},
- {id: 39, collection: 'againstTheCorruption', reward: [
- {name: 'hordeFirstStrike', type: 'base', value: 12.5},
- {name: 'hordeBossRequirement', type: 'base', value: -10},
+ {id: 39, collection: 'againstTheCorruption', power: 5, reward: [
+ {name: 'hordeFirstStrike', type: 'base', value: 6.75},
+ {name: 'hordeBossRequirement', type: 'base', value: -25},
{name: 'hordeRespawn', type: 'mult', value: 0.2},
{name: 'hordeCorruption', type: 'mult', value: 1.15}
], color: 'cyan', icons: [
@@ -373,8 +359,8 @@ export default [
{"x": 0.85, "y": 0.55, "rotate": 25, "size": 1, "icon": "mdi-liquid-spot"},
{"x": 0.6, "y": 0.65, "rotate": 150, "size": 1, "icon": "mdi-liquid-spot"}
]},
- {id: 40, collection: 'againstTheCorruption', reward: [
- {name: 'hordeHeirloomChance', type: 'base', value: 0.15},
+ {id: 40, collection: 'againstTheCorruption', power: 5, reward: [
+ {name: 'hordeHeirloomChance', type: 'base', value: 0.1},
{name: 'hordeNostalgia', type: 'mult', value: 2},
{name: 'hordeCorruption', type: 'mult', value: 1.15}
], color: 'light-green', icons: [
@@ -385,10 +371,7 @@ export default [
{"x": 0.25, "y": 0.9, "rotate": -65, "size": 1, "icon": "mdi-liquid-spot"},
{"x": 0, "y": 0.9, "rotate": 20, "size": 1, "icon": "mdi-liquid-spot"}
]},
- {id: 41, collection: 'againstTheCorruption', reward: [
- {name: 'currencyHordeBoneGain', type: 'mult', value: 5},
- {name: 'currencyHordeMonsterPartGain', type: 'mult', value: 5},
- {name: 'currencyHordeCorruptedFleshGain', type: 'mult', value: 5},
+ {id: 41, collection: 'againstTheCorruption', power: 0, reward: [
{name: 'hordeCorruption', type: 'mult', value: 5}
], color: 'orange-red', icons: [
{"x": 0, "y": 0.2, "rotate": 0, "size": 3, "icon": "mdi-microwave"},
diff --git a/src/js/modules/horde/enemyType.js b/src/js/modules/horde/enemyType.js
new file mode 100644
index 00000000..114fb987
--- /dev/null
+++ b/src/js/modules/horde/enemyType.js
@@ -0,0 +1,213 @@
+export default {
+ // warzone
+ soldier_1: {
+ attack: 1.75,
+ health: 50,
+ sigil: {
+ rifle_gun: 1
+ }
+ },
+ soldier_2: {
+ attack: 1.75,
+ health: 45,
+ sigil: {
+ rifle_gun: 1,
+ war_grenade: 1
+ }
+ },
+ soldier_3: {
+ attack: 1.6,
+ health: 50,
+ sigil: {
+ rifle_gun: 1,
+ war_bandage: 1
+ }
+ },
+ officer_1: {
+ attack: 1,
+ health: 80,
+ sigil: {
+ pistol_gun: 1
+ }
+ },
+ officer_2: {
+ attack: 1,
+ health: 72.5,
+ sigil: {
+ pistol_gun: 1,
+ war_grenade: 1
+ }
+ },
+ officer_3: {
+ attack: 0.9,
+ health: 80,
+ sigil: {
+ pistol_gun: 1,
+ war_bandage: 1
+ }
+ },
+ hunter: {
+ attack: 1.2,
+ health: 55,
+ sigil: {
+ shotgun_gun: 1,
+ war_grenade: 2,
+ war_bandage: 2
+ }
+ },
+ sniper: {
+ attack: 1.5,
+ health: 40,
+ stats: {
+ critChance_base: 0.25,
+ critMult_base: 0.5
+ },
+ sigil: {
+ sniper_gun: 1
+ }
+ },
+
+ // monkey jungle
+ strongMonkey: {
+ attack: 2.5,
+ health: 40,
+ stats: {
+ physicTaken_mult: 1.25,
+ magicTaken_mult: 0.75,
+ },
+ sigil: {}
+ },
+ angryMonkey: {
+ attack: 1.7,
+ health: 35,
+ stats: {
+ physicTaken_mult: 1.25,
+ magicTaken_mult: 0.75,
+ critChance_base: 0.4,
+ critMult_base: 1.25,
+ },
+ sigil: {}
+ },
+ dartMonkey: {
+ attack: 1.8,
+ health: 45,
+ stats: {
+ physicTaken_mult: 1.25,
+ magicTaken_mult: 0.75,
+ },
+ sigil: {
+ monkey_dart: 1
+ }
+ },
+ monkeyWizard_1: {
+ attack: 1.75,
+ health: 50,
+ stats: {
+ physicTaken_mult: 0.75,
+ magicTaken_mult: 1.25,
+ },
+ sigil: {
+ monkey_fire: 1
+ }
+ },
+ monkeyWizard_2: {
+ attack: 1.75,
+ health: 50,
+ stats: {
+ physicTaken_mult: 0.75,
+ magicTaken_mult: 1.25,
+ },
+ sigil: {
+ monkey_ice: 1
+ }
+ },
+ monkeyWizard_3: {
+ attack: 1.75,
+ health: 50,
+ stats: {
+ physicTaken_mult: 0.75,
+ magicTaken_mult: 1.25,
+ },
+ sigil: {
+ monkey_lightning: 1
+ }
+ },
+ monkeyDefender: {
+ attack: 2,
+ health: 50,
+ stats: {
+ physicTaken_mult: 0.1,
+ magicTaken_mult: 1.5,
+ },
+ sigil: {}
+ },
+ monkeyMonk: {
+ attack: 2,
+ health: 50,
+ stats: {
+ physicTaken_mult: 1.5,
+ magicTaken_mult: 0.1,
+ },
+ sigil: {}
+ },
+
+ // love island
+ puppy: {
+ attack: 1.4,
+ health: 60,
+ sigil: {
+ cute_bark: 1,
+ cute_bite: 1,
+ }
+ },
+ kitten: {
+ attack: 2.8,
+ health: 30,
+ sigil: {
+ cute_claws: 1,
+ }
+ },
+ seal: {
+ attack: 1.6,
+ health: 60,
+ sigil: {
+ cute_ram: 1,
+ }
+ },
+ piglet: {
+ attack: 0.8,
+ health: 90,
+ sigil: {
+ cute_ram: 1,
+ cute_eatCarrot: 1,
+ }
+ },
+ panda: {
+ attack: 2.5,
+ health: 35,
+ sigil: {
+ cute_ram: 2,
+ }
+ },
+ koala: {
+ attack: 2.2,
+ health: 40,
+ sigil: {
+ cute_kick: 1,
+ cute_bite: 1,
+ }
+ },
+ rabbit: {
+ attack: 1.1,
+ health: 70,
+ sigil: {
+ cute_kick: 1,
+ cute_eatCarrot: 1,
+ }
+ },
+ guineaPig: {
+ attack: 1.6,
+ health: 70,
+ sigil: {}
+ },
+}
diff --git a/src/js/modules/horde/equipment.js b/src/js/modules/horde/equipment.js
index 2e46b1e9..393e2bec 100644
--- a/src/js/modules/horde/equipment.js
+++ b/src/js/modules/horde/equipment.js
@@ -1,5 +1,6 @@
-import { SECONDS_PER_DAY, SECONDS_PER_HOUR } from "../../constants";
+import { SECONDS_PER_DAY, SECONDS_PER_HOUR, SECONDS_PER_MINUTE } from "../../constants";
import { buildNum } from "../../utils/format";
+import { getSequence } from "../../utils/math";
export default {
dagger: {
@@ -13,13 +14,15 @@ export default {
{isPositive: true, type: 'base', name: 'hordeAttack', value: lvl * 4 + 6}
];
},
- active() {
+ active(lvl) {
return [
- {type: 'damagePhysic', value: 3.75}
+ {type: 'buff', value: 40, effect: [
+ {type: 'base', name: 'hordeAttack', value: lvl * 5 + 30}
+ ]}
];
},
activeType: 'combat',
- cooldown: () => 8,
+ cooldown: () => 300,
icon: 'mdi-knife-military',
activeIcon: 'mdi-knife-military',
activeColor: 'red'
@@ -37,7 +40,7 @@ export default {
},
active() {
return [
- {type: 'heal', value: 0.225}
+ {type: 'heal', value: 0.225, int: 0.01}
];
},
activeType: 'combat',
@@ -96,8 +99,9 @@ export default {
findZone: 8,
findChance: 1 / 4000,
price(lvl) {
- return Math.pow(8, lvl - 1) * 80;
+ return Math.pow(16, getSequence(1, lvl - 1)) * 80;
},
+ cap: 4,
stats(lvl) {
return [
{isPositive: true, type: 'base', name: 'hordeDivisionShield', value: lvl + 2}
@@ -129,7 +133,7 @@ export default {
},
active(lvl) {
return [
- {type: 'damagePhysic', value: 7 + lvl * 0.5}
+ {type: 'damagePhysic', value: 7.5, str: 0.1, canCrit: 0.1 * lvl}
];
},
activeType: 'combat',
@@ -151,8 +155,8 @@ export default {
},
active() {
return [
- {type: 'damageMagic', value: 4.5},
- {type: 'heal', value: 0.03}
+ {type: 'damageMagic', value: 4.5, int: 0.08},
+ {type: 'heal', value: 0.03, int: 0.002}
];
},
activeType: 'combat',
@@ -174,7 +178,7 @@ export default {
},
active() {
return [
- {type: 'permanentStat', stat: 'hordeItemChance', value: 0.25}
+ {type: 'permanentStat', stat: 'hordeItemChance_mult', value: 0.25}
];
},
activeType: 'utility',
@@ -221,8 +225,10 @@ export default {
},
active() {
return [
- {type: 'damageMagic', value: 13.5},
- {type: 'stun', value: 14}
+ {type: 'damageMagic', value: 13.5, int: 0.18},
+ {type: 'buff', value: 20, effect: [
+ {type: 'base', name: 'hordeCritChance', value: 0.5}
+ ]}
];
},
activeType: 'combat',
@@ -245,12 +251,14 @@ export default {
},
active() {
return [
- {type: 'heal', value: 0.015},
- {type: 'stun', value: 2}
+ {type: 'heal', value: 0.65, int: 0.02},
+ {type: 'buff', value: 210, effect: [
+ {type: 'base', name: 'hordeRecovery', value: 0.15}
+ ]}
];
},
activeType: 'combat',
- cooldown: () => 9,
+ cooldown: () => 1800,
icon: 'mdi-campfire',
activeIcon: 'mdi-campfire',
activeColor: 'orange-red'
@@ -271,11 +279,11 @@ export default {
masteryBoost: 0.25,
active() {
return [
- {type: 'removeAttack', value: 0.55}
+ {type: 'removeAttack', value: 0.4}
];
},
activeType: 'combat',
- cooldown: () => 720,
+ cooldown: () => 1200,
icon: 'mdi-snowflake',
activeIcon: 'mdi-snowflake',
activeColor: 'light-blue'
@@ -320,8 +328,9 @@ export default {
masteryBoost: 0.25,
active() {
return [
- {type: 'heal', value: 0.12},
- {type: 'stun', value: 10}
+ {type: 'buff', value: 5, effect: [
+ {type: 'mult', name: 'hordePhysicTaken', value: 0}
+ ]}
];
},
activeType: 'combat',
@@ -345,8 +354,8 @@ export default {
masteryBoost: 0.25,
active(lvl) {
return [
- {type: 'damageBio', value: 4.25 + lvl * 0.25},
- {type: 'poison', value: 0.2}
+ {type: 'damageBio', value: 4.25 + lvl * 0.25, int: 0.1},
+ {type: 'poison', value: 0.2, int: 0.01}
];
},
activeType: 'combat',
@@ -369,7 +378,7 @@ export default {
},
active() {
return [
- {type: 'damageMagic', value: 25}
+ {type: 'damageMagic', value: 25, int: 0.4}
];
},
activeType: 'combat',
@@ -392,7 +401,7 @@ export default {
},
active() {
return [
- {type: 'permanentStat', stat: 'hordeAttack', value: 0.1}
+ {type: 'permanentStat', stat: 'hordeAttack_mult', value: 0.1}
];
},
activeType: 'utility',
@@ -415,8 +424,7 @@ export default {
},
active(lvl) {
return [
- {type: 'removeAttack', value: 0.08},
- {type: 'stun', value: 5 + lvl}
+ {type: 'stun', value: 7 + lvl}
];
},
activeType: 'combat',
@@ -441,9 +449,9 @@ export default {
},
active() {
return [
- {type: 'removeAttack', value: 0.04},
+ {type: 'maxdamagePhysic', value: 0.05, str: 0.0004},
{type: 'divisionShield', value: 8},
- {type: 'stun', value: 7}
+ {type: 'stun', value: 3}
];
},
activeType: 'combat',
@@ -488,13 +496,13 @@ export default {
cap: 6,
stats() {
return [
- {isPositive: true, type: 'base', name: 'hordeToxic', value: 0.05},
+ {isPositive: true, type: 'base', name: 'hordeToxic', value: 0.02},
{isPositive: false, type: 'base', name: 'hordeBioConversion', value: 0.5}
];
},
active(lvl) {
return [
- {type: 'poison', value: lvl * 0.01 + 0.19}
+ {type: 'poison', value: lvl * 0.01 + 0.19, int: 0.01}
];
},
activeType: 'combat',
@@ -542,8 +550,8 @@ export default {
masteryBoost: 0.25,
active() {
return [
- {type: 'damageBio', value: 2.6},
- {type: 'poison', value: 0.1}
+ {type: 'damageBio', value: 2.6, int: 0.05},
+ {type: 'poison', value: 0.1, int: 0.005}
];
},
activeType: 'combat',
@@ -619,7 +627,7 @@ export default {
masteryBoost: 0.25,
active() {
return [
- {type: 'damagePhysic', value: 7.35}
+ {type: 'damagePhysic', value: 7.35, str: 0.12}
];
},
activeType: 'combat',
@@ -642,8 +650,8 @@ export default {
},
active() {
return [
- {type: 'damagePhysic', value: 0.8},
- {type: 'damageMagic', value: 3.4},
+ {type: 'damagePhysic', value: 0.8, str: 0.04},
+ {type: 'damageMagic', value: 3.4, int: 0.08},
];
},
activeType: 'combat',
@@ -668,7 +676,7 @@ export default {
},
active(lvl) {
return [
- {type: 'damagePhysic', value: lvl * 0.25 + 4.5},
+ {type: 'damagePhysic', value: lvl * 0.25 + 4.5, str: 0.1},
{type: 'stun', value: 3}
];
},
@@ -693,12 +701,12 @@ export default {
},
active(lvl) {
return [
- {type: 'damagePhysic', value: 1.5},
- {type: 'damageBio', value: lvl * 0.2 + 1.3}
+ {type: 'damagePhysic', value: lvl * 0.2 + 2.3, str: 0.04},
+ {type: 'maxdamageBio', value: 0.05, int: 0.0004}
];
},
activeType: 'combat',
- cooldown: () => 5,
+ cooldown: () => 15,
icon: 'mdi-content-cut',
activeIcon: 'mdi-content-cut',
activeColor: 'blue-grey'
@@ -744,7 +752,7 @@ export default {
masteryBoost: 0.25,
active(lvl) {
return [
- {type: 'heal', value: 0.01 * lvl + 0.44},
+ {type: 'heal', value: 0.01 * lvl + 0.44, int: 0.02},
{type: 'removeStun', value: null},
{type: 'stun', value: 20}
];
@@ -765,7 +773,7 @@ export default {
cap: 8,
stats() {
return [
- {isPositive: true, type: 'base', name: 'hordeToxic', value: 0.35},
+ {isPositive: true, type: 'base', name: 'hordeToxic', value: 0.125},
{isPositive: false, type: 'mult', name: 'hordeAttack', value: 0.25},
{isPositive: true, type: 'base', name: 'hordeBioAttack', value: 0.15}
];
@@ -773,11 +781,14 @@ export default {
masteryBoost: 0.25,
active(lvl) {
return [
- {type: 'heal', value: 0.05 + lvl * 0.0025}
+ {type: 'heal', value: 0.14 + lvl * 0.0075, int: 0.008},
+ {type: 'buff', value: 12, effect: [
+ {type: 'mult', name: 'hordeToxic', value: 2}
+ ]}
];
},
activeType: 'combat',
- cooldown: () => 16,
+ cooldown: () => 130,
icon: 'mdi-bird',
activeIcon: 'mdi-feather',
activeColor: 'skyblue'
@@ -823,7 +834,7 @@ export default {
},
active() {
return [
- {type: 'removeAttack', value: 0.7},
+ {type: 'removeAttack', value: 0.25},
{type: 'stun', value: 50}
];
},
@@ -848,7 +859,7 @@ export default {
active() {
return [
{type: 'removeAttack', value: 0.1},
- {type: 'heal', value: 0.15}
+ {type: 'heal', value: 0.15, int: 0.007}
];
},
activeType: 'combat',
@@ -875,7 +886,7 @@ export default {
masteryBoost: 0.25,
active() {
return [
- {type: 'damagePhysic', value: 6.66}
+ {type: 'damagePhysic', value: 6.66, str: 0.0666, int: 0.0666}
];
},
activeType: 'combat',
@@ -948,7 +959,16 @@ export default {
active() {
return [
{type: 'removeAttack', value: 0.8},
- {type: 'silence', value: 90}
+ {type: 'silence', value: 90},
+ {type: 'buff', value: 300, effect: [
+ {type: 'base', name: 'hordeCritChance', value: 0.75},
+ {type: 'base', name: 'hordeCritMult', value: 3},
+ {type: 'base', name: 'hordeSpellblade', value: 6.5},
+ {type: 'base', name: 'hordeCutting', value: 0.2},
+ {type: 'base', name: 'hordeShieldbreak', value: 15},
+ {type: 'base', name: 'hordeStunResist', value: 15},
+ {type: 'base', name: 'hordeRecovery', value: 0.25}
+ ]}
];
},
activeType: 'combat',
@@ -974,7 +994,7 @@ export default {
masteryBoost: 0.25,
active() {
return [
- {type: 'heal', value: 0.75},
+ {type: 'heal', value: 0.75, int: 0.03},
{type: 'revive', value: 1}
];
},
@@ -999,13 +1019,13 @@ export default {
},
active() {
return [
- {type: 'heal', value: 0.02},
- {type: 'removeAttack', value: 0.01},
+ {type: 'heal', value: 0.04, int: 0.002},
+ {type: 'removeAttack', value: 0.02},
{type: 'stun', value: 2}
];
},
activeType: 'combat',
- cooldown: () => 11,
+ cooldown: () => 22,
icon: 'mdi-shield-alert',
activeIcon: 'mdi-alert-octagram',
activeColor: 'wooden'
@@ -1019,14 +1039,14 @@ export default {
cap: 6,
stats() {
return [
- {isPositive: true, type: 'base', name: 'hordeToxic', value: 0.15},
+ {isPositive: true, type: 'base', name: 'hordeToxic', value: 0.05},
{isPositive: false, type: 'mult', name: 'hordeCorruption', value: 1.15}
];
},
masteryBoost: 0.25,
active(lvl) {
return [
- {type: 'poison', value: lvl * 0.04 + 0.16}
+ {type: 'poison', value: lvl * 0.04 + 0.16, int: 0.01}
];
},
activeType: 'combat',
@@ -1052,7 +1072,8 @@ export default {
masteryBoost: 0.25,
active(lvl) {
return [
- {type: 'damageBio', value: 9 + lvl * 0.3}
+ {type: 'maxdamageBio', value: 0.12, int: 0.001},
+ {type: 'damageBio', value: 5 + lvl * 0.3}
];
},
activeType: 'combat',
@@ -1078,11 +1099,14 @@ export default {
masteryBoost: 0.25,
active(lvl) {
return [
- {type: 'removeAttack', value: 0.07 + lvl * 0.01}
+ {type: 'buff', value: lvl * 2 + 14, effect: [
+ {type: 'mult', name: 'hordeAttack', value: 1.5},
+ {type: 'mult', name: 'hordeHealth', value: 1.5}
+ ]}
];
},
activeType: 'combat',
- cooldown: () => 28,
+ cooldown: () => 110,
icon: 'mdi-needle',
activeIcon: 'mdi-needle',
activeColor: 'cyan'
@@ -1104,11 +1128,13 @@ export default {
masteryBoost: 0.25,
active() {
return [
- {type: 'stun', value: 40}
+ {type: 'buff', value: 5, effect: [
+ {type: 'mult', name: 'hordeMagicTaken', value: 0}
+ ]}
];
},
activeType: 'combat',
- cooldown: lvl => 280 - lvl * 10,
+ cooldown: lvl => 90 - lvl * 6,
icon: 'mdi-glasses',
activeIcon: 'mdi-magnify',
activeColor: 'pale-blue'
@@ -1128,14 +1154,15 @@ export default {
];
},
masteryBoost: 0.25,
- active(lvl) {
+ active() {
return [
- {type: 'damageBio', value: 7.4 + lvl * 0.1},
- {type: 'poison', value: 0.45}
+ {type: 'buff', value: 5, effect: [
+ {type: 'mult', name: 'hordeBioTaken', value: 0}
+ ]}
];
},
activeType: 'combat',
- cooldown: () => 96,
+ cooldown: lvl => 90 - lvl * 6,
icon: 'mdi-microscope',
activeIcon: 'mdi-microscope',
activeColor: 'teal'
@@ -1155,7 +1182,7 @@ export default {
masteryBoost: 0.25,
active() {
return [
- {type: 'permanentStat', stat: 'hordeHealth', value: 0.15}
+ {type: 'permanentStat', stat: 'hordeHealth_mult', value: 0.15}
];
},
activeType: 'utility',
@@ -1180,11 +1207,12 @@ export default {
masteryBoost: 0.25,
active(lvl) {
return [
- {type: 'damageBio', value: 1.68 + lvl * 0.02}
+ {type: 'maxdamageBio', value: 0.08, str: 0.0007},
+ {type: 'damageBio', value: 1.68 + lvl * 0.02, int: 0.03}
];
},
activeType: 'combat',
- cooldown: () => 5,
+ cooldown: () => 30,
icon: 'mdi-box-cutter',
activeIcon: 'mdi-box-cutter',
activeColor: 'wooden'
@@ -1230,7 +1258,7 @@ export default {
masteryBoost: 0.25,
active() {
return [
- {type: 'permanentStat', stat: 'currencyHordeBoneGain', value: 0.18}
+ {type: 'permanentStat', stat: 'currencyHordeBoneGain_mult', value: 0.18}
];
},
activeType: 'utility',
@@ -1283,7 +1311,7 @@ export default {
masteryBoost: 0.25,
active() {
return [
- {type: 'heal', value: 0.1},
+ {type: 'heal', value: 0.1, int: 0.005},
{type: 'antidote', value: 1},
{type: 'removeStun', value: null}
];
@@ -1311,7 +1339,7 @@ export default {
masteryBoost: 0.25,
active() {
return [
- {type: 'permanentStat', stat: 'currencyHordeMonsterPartGain', value: 0.225}
+ {type: 'permanentStat', stat: 'currencyHordeMonsterPartGain_mult', value: 0.225}
];
},
activeType: 'utility',
@@ -1328,8 +1356,6 @@ export default {
},
stats(lvl) {
return [
- {isPositive: true, type: 'mult', name: 'hordePhysicTaken', value: 1 / 1.8},
- {isPositive: true, type: 'mult', name: 'hordeMagicTaken', value: 1 / 1.8},
{isPositive: true, type: 'base', name: 'hordeDivisionShield', value: lvl * 2 + 34},
{isPositive: true, type: 'base', name: 'hordeStunResist', value: 12},
{isPositive: false, type: 'mult', name: 'hordeCorruption', value: 1.15}
@@ -1338,7 +1364,7 @@ export default {
masteryBoost: 0.25,
active(lvl) {
return [
- {type: 'heal', value: 0.12},
+ {type: 'heal', value: 0.12, int: 0.006},
{type: 'divisionShield', value: lvl + 11}
];
},
@@ -1357,13 +1383,13 @@ export default {
stats(lvl) {
return [
{isPositive: true, type: 'base', name: 'hordeFirstStrike', value: lvl * 0.04 + 1.76},
- {isPositive: true, type: 'base', name: 'hordeSpellblade', value: lvl * 0.02 + 0.78},
+ {isPositive: true, type: 'base', name: 'hordeSpellblade', value: lvl * 0.01 + 0.49},
{isPositive: true, type: 'base', name: 'hordeDivisionShield', value: 2}
];
},
active() {
return [
- {type: 'damageMagic', value: 3.65},
+ {type: 'damageMagic', value: 3.65, int: 0.11},
{type: 'divisionShield', value: 2}
];
},
@@ -1382,7 +1408,7 @@ export default {
cap: 21,
stats() {
return [
- {isPositive: true, type: 'base', name: 'hordeToxic', value: 0.175},
+ {isPositive: true, type: 'base', name: 'hordeToxic', value: 0.1},
{isPositive: true, type: 'base', name: 'hordeCutting', value: 0.06},
{isPositive: false, type: 'mult', name: 'hordeRecovery', value: 0},
{isPositive: false, type: 'mult', name: 'hordeDivisionShield', value: 0},
@@ -1392,8 +1418,11 @@ export default {
masteryBoost: 0.25,
active(lvl) {
return [
- {type: 'poison', value: 24},
- {type: 'silence', value: lvl + 29}
+ {type: 'poison', value: 24, str: 0.25, int: 0.25},
+ {type: 'silence', value: lvl + 29},
+ {type: 'buff', value: 35, effect: [
+ {type: 'base', name: 'hordeCutting', value: 0.1}
+ ]}
];
},
activeType: 'combat',
@@ -1420,7 +1449,7 @@ export default {
masteryBoost: 0.25,
active() {
return [
- {type: 'damageMagic', value: 38}
+ {type: 'damageMagic', value: 38, int: 0.75}
];
},
activeType: 'combat',
@@ -1443,7 +1472,7 @@ export default {
},
active() {
return [
- {type: 'damageBio', value: 12.5},
+ {type: 'maxdamageBio', value: 0.125},
{type: 'heal', value: 0.125}
];
},
@@ -1468,7 +1497,7 @@ export default {
masteryBoost: 0.25,
active() {
return [
- {type: 'permanentStat', stat: 'currencyHordeSoulCorruptedGain', value: 0.03}
+ {type: 'permanentStat', stat: 'currencyHordeSoulCorruptedGain_mult', value: 0.03}
];
},
activeType: 'utility',
@@ -1477,36 +1506,91 @@ export default {
activeIcon: 'mdi-rhombus',
activeColor: 'light-blue'
},
- firework: {
+ hourglass: {
findZone: 177,
findChance: 1 / buildNum(40, 'B'),
price(lvl) {
- return Math.pow(2, lvl - 1) * buildNum(975, 'M');
+ return Math.pow(4, lvl - 1) * buildNum(975, 'M');
+ },
+ cap: 11,
+ stats() {
+ return [
+ {isPositive: true, type: 'base', name: 'hordeHaste', value: 15}
+ ];
+ },
+ active(lvl) {
+ return [
+ {type: 'buff', value: 45, effect: [
+ {type: 'base', name: 'hordeHaste', value: 50},
+ {type: 'base', name: 'hordeSpellblade', value: lvl * 0.05 + 1.45}
+ ]}
+ ];
+ },
+ activeType: 'combat',
+ cooldown: () => 20 * SECONDS_PER_MINUTE,
+ icon: 'mdi-timer-sand',
+ activeIcon: 'mdi-timer-sand-complete',
+ activeColor: 'pale-yellow'
+ },
+ glue: {
+ findZone: 184,
+ findChance: 1 / buildNum(80, 'B'),
+ price(lvl) {
+ return Math.pow(8, lvl - 1) * buildNum(1.75, 'B');
+ },
+ cap: 6,
+ stats() {
+ return [
+ {isPositive: true, type: 'mult', name: 'hordeAttack', value: 1.35},
+ {isPositive: false, type: 'base', name: 'hordeHaste', value: -30}
+ ];
+ },
+ masteryBoost: 0.25,
+ active(lvl) {
+ return [
+ {type: 'maxdamageBio', value: 0.3, int: 0.0025},
+ {type: 'damageMagic', value: lvl * 0.5 + 7, int: 0.1}
+ ];
+ },
+ activeType: 'combat',
+ cooldown: () => 40,
+ icon: 'mdi-bottle-tonic',
+ activeIcon: 'mdi-liquid-spot',
+ activeColor: 'pale-green'
+ },
+ firework: {
+ findZone: 191,
+ findChance: 1 / buildNum(160, 'B'),
+ price(lvl) {
+ return Math.pow(2, lvl - 1) * buildNum(3, 'B');
},
stats(lvl) {
return [
{isPositive: true, type: 'base', name: 'hordeAttack', value: lvl * 2 + 68},
{isPositive: true, type: 'base', name: 'hordeCritChance', value: 0.2},
- {isPositive: true, type: 'base', name: 'hordeToxic', value: 0.02}
+ {isPositive: true, type: 'base', name: 'hordeToxic', value: 0.01}
];
},
active() {
return [
- {type: 'damageBio', value: 18},
- {type: 'poison', value: 2.75}
+ {type: 'damageBio', value: 18, int: 0.35},
+ {type: 'poison', value: 2.75, int: 0.13},
+ {type: 'buff', value: 15, effect: [
+ {type: 'base', name: 'hordeCritMult', value: 5.75}
+ ]}
];
},
activeType: 'combat',
- cooldown: () => 220,
+ cooldown: () => 290,
icon: 'mdi-firework',
activeIcon: 'mdi-firework',
activeColor: 'pink-purple'
},
bowTie: {
- findZone: 184,
- findChance: 1 / buildNum(40, 'B'),
+ findZone: 198,
+ findChance: 1 / buildNum(320, 'B'),
price(lvl) {
- return Math.pow(2, lvl - 1) * buildNum(975, 'M');
+ return Math.pow(2, lvl - 1) * buildNum(5, 'B');
},
stats(lvl) {
return [
@@ -1518,7 +1602,7 @@ export default {
masteryBoost: 0.25,
active() {
return [
- {type: 'heal', value: 0.07},
+ {type: 'heal', value: 0.07, int: 0.003},
{type: 'divisionShield', value: 10}
];
},
@@ -1528,11 +1612,36 @@ export default {
activeIcon: 'mdi-bow-tie',
activeColor: 'beige'
},
+ forbiddenStopwatch: {
+ findZone: 205,
+ findChance: 1 / buildNum(640, 'B'),
+ price(lvl) {
+ return Math.pow(6, lvl - 1) * buildNum(8, 'B');
+ },
+ cap: 6,
+ stats() {
+ return [
+ {isPositive: true, type: 'base', name: 'hordeHaste', value: 70},
+ {isPositive: false, type: 'mult', name: 'hordeCorruption', value: 1.15}
+ ];
+ },
+ masteryBoost: 0.25,
+ active(lvl) {
+ return [
+ {type: 'stun', value: lvl + 34}
+ ];
+ },
+ activeType: 'combat',
+ cooldown: () => 360,
+ icon: 'mdi-timer',
+ activeIcon: 'mdi-timer',
+ activeColor: 'purple'
+ },
mysticalAccelerator: {
- findZone: 191,
- findChance: 1 / buildNum(80, 'B'),
+ findZone: 212,
+ findChance: 1 / buildNum(1.25, 'T'),
price(lvl) {
- return Math.pow(14, lvl - 1) * buildNum(1.75, 'B');
+ return Math.pow(14, lvl - 1) * buildNum(12.5, 'B');
},
cap: 5,
stats() {
@@ -1542,7 +1651,7 @@ export default {
},
active() {
return [
- {type: 'permanentStat', stat: 'hordeShardChance', value: 0.35}
+ {type: 'permanentStat', stat: 'hordeShardChance_mult', value: 0.35}
];
},
activeType: 'utility',
@@ -1552,10 +1661,10 @@ export default {
activeColor: 'teal'
},
blazingStaff: {
- findZone: 198,
- findChance: 1 / buildNum(160, 'B'),
+ findZone: 219,
+ findChance: 1 / buildNum(2.5, 'T'),
price(lvl) {
- return Math.pow(25, lvl - 1) * buildNum(3, 'B');
+ return Math.pow(25, lvl - 1) * buildNum(18, 'B');
},
cap: 4,
stats() {
@@ -1564,9 +1673,13 @@ export default {
{isPositive: false, type: 'mult', name: 'hordeHealth', value: 0.5}
];
},
+ masteryBoost: 0.25,
active(lvl) {
return [
- {type: 'damageMagic', value: lvl * 3 + 25}
+ {type: 'damageMagic', value: lvl * 3 + 25, str: 0.6},
+ {type: 'buff', value: 12, effect: [
+ {type: 'mult', name: 'hordeAttack', value: 1.4}
+ ]}
];
},
activeType: 'combat',
@@ -1575,6 +1688,297 @@ export default {
activeIcon: 'mdi-fire-alert',
activeColor: 'orange'
},
+ shield: {
+ findZone: 226,
+ findChance: 1 / buildNum(5, 'T'),
+ price(lvl) {
+ return Math.pow(25, lvl - 1) * buildNum(25, 'B');
+ },
+ cap: 4,
+ stats() {
+ return [
+ {isPositive: true, type: 'base', name: 'hordeDefense', value: 0.004}
+ ];
+ },
+ active() {
+ return [
+ {type: 'buff', value: 8, effect: [
+ {type: 'mult', name: 'hordePhysicTaken', value: 0.25},
+ {type: 'mult', name: 'hordeMagicTaken', value: 0.25},
+ {type: 'mult', name: 'hordeBioTaken', value: 0.25}
+ ]}
+ ];
+ },
+ activeType: 'combat',
+ cooldown: (lvl) => 90 - lvl * 5,
+ icon: 'mdi-shield',
+ activeIcon: 'mdi-shield-plus',
+ activeColor: 'pale-blue'
+ },
+ armor: {
+ findZone: 233,
+ findChance: 1 / buildNum(10, 'T'),
+ price(lvl) {
+ return Math.pow(2, lvl - 1) * buildNum(35, 'B');
+ },
+ stats(lvl) {
+ return [
+ {isPositive: true, type: 'base', name: 'hordeHealth', value: lvl * 400 + buildNum(10.8, 'K')},
+ {isPositive: true, type: 'base', name: 'hordeDefense', value: 0.0025}
+ ];
+ },
+ active() {
+ return [
+ {type: 'divisionShield', value: 20}
+ ];
+ },
+ activeType: 'combat',
+ cooldown: () => 55,
+ icon: 'mdi-tshirt-crew',
+ activeIcon: 'mdi-shield-half-full',
+ activeColor: 'indigo'
+ },
+ natureStone: {
+ findZone: 240,
+ findChance: 1 / buildNum(20, 'T'),
+ price(lvl) {
+ return Math.pow(20, lvl - 1) * buildNum(50, 'B');
+ },
+ cap: 5,
+ stats() {
+ return [
+ {isPositive: true, type: 'base', name: 'hordeRecovery', value: 0.01},
+ {isPositive: true, type: 'base', name: 'hordeHealing', value: 0.3}
+ ];
+ },
+ active(lvl) {
+ return [
+ {type: 'maxdamageBio', value: 0.15, int: 0.0012},
+ {type: 'heal', value: lvl * 0.04 + 0.3, int: 0.025}
+ ];
+ },
+ activeType: 'combat',
+ cooldown: () => 130,
+ icon: 'mdi-alpha-x-circle',
+ activeIcon: 'mdi-heart-circle',
+ activeColor: 'light-green'
+ },
+ evergrowingVine: {
+ findZone: 247,
+ findChance: 1 / buildNum(40, 'T'),
+ price(lvl) {
+ return Math.pow(100, lvl - 1) * buildNum(75, 'B');
+ },
+ cap: 3,
+ stats() {
+ return [
+ {isPositive: true, type: 'mult', name: 'hordeHealth', value: 1.5},
+ {isPositive: true, type: 'base', name: 'hordeRecovery', value: 0.2},
+ {isPositive: false, type: 'mult', name: 'hordeDefense', value: 0},
+ {isPositive: false, type: 'mult', name: 'hordeDivisionShield', value: 0},
+ {isPositive: true, type: 'tag', name: 'hordePassiveRecovery', value: [0.1]}
+ ];
+ },
+ masteryBoost: 0.25,
+ active(lvl) {
+ return [
+ {type: 'buff', value: lvl * 3 + 21, effect: [
+ {type: 'base', name: 'hordeHealing', value: 0.25}
+ ]}
+ ];
+ },
+ activeType: 'combat',
+ cooldown: () => 150,
+ icon: 'mdi-lasso',
+ activeIcon: 'mdi-heart-multiple',
+ activeColor: 'green'
+ },
+ energyDrink: {
+ findZone: 254,
+ findChance: 1 / buildNum(80, 'T'),
+ price(lvl) {
+ return Math.pow(100, lvl - 1) * buildNum(140, 'B');
+ },
+ cap: 3,
+ stats() {
+ return [
+ {isPositive: true, type: 'mult', name: 'hordeHaste', value: 1.5},
+ {isPositive: false, type: 'mult', name: 'hordeCritMult', value: 0.5}
+ ];
+ },
+ masteryBoost: 0.25,
+ active(lvl) {
+ return [
+ {type: 'buff', value: lvl + 7, effect: [
+ {type: 'base', name: 'hordeCritChance', value: 0.35},
+ {type: 'base', name: 'hordeCritMult', value: 0.8}
+ ]}
+ ];
+ },
+ activeType: 'combat',
+ cooldown: () => 48,
+ icon: 'mdi-beer',
+ activeIcon: 'mdi-lightning-bolt',
+ activeColor: 'amber'
+ },
+ dragonheart: {
+ findZone: 261,
+ findChance: 1 / buildNum(160, 'T'),
+ price(lvl) {
+ return Math.pow(2, lvl - 1) * buildNum(225, 'B');
+ },
+ cap: 21,
+ stats(lvl) {
+ return [
+ {isPositive: true, type: 'base', name: 'hordeRecovery', value: lvl * 0.001 + 0.039},
+ {isPositive: true, type: 'base', name: 'hordeDefense', value: 0.002}
+ ];
+ },
+ active() {
+ return [
+ {type: 'buff', value: 14, effect: [
+ {type: 'base', name: 'hordeDefense', value: 0.05}
+ ]}
+ ];
+ },
+ activeType: 'combat',
+ cooldown: () => 160,
+ icon: 'mdi-heart',
+ activeIcon: 'mdi-heart',
+ activeColor: 'pink-purple'
+ },
+ prism: {
+ findZone: 268,
+ findChance: 1 / buildNum(320, 'T'),
+ price(lvl) {
+ return Math.pow(12, lvl - 1) * buildNum(400, 'B');
+ },
+ cap: 8,
+ stats(lvl) {
+ return [
+ {isPositive: true, type: 'base', name: 'currencyHordeMysticalShardCap', value: lvl}
+ ];
+ },
+ active() {
+ return [
+ {type: 'maxdamageBio', value: 0.3, str: 0.002},
+ {type: 'damagePhysic', value: 15, str: 0.32},
+ {type: 'poison', value: 1.25, int: 0.06}
+ ];
+ },
+ activeCost: () => {
+ return {mysticalShard: 1};
+ },
+ activeType: 'combat',
+ cooldown: () => 330,
+ icon: 'mdi-mirror-variant',
+ activeIcon: 'mdi-mirror-variant',
+ activeColor: 'teal'
+ },
+ deathsword: {
+ findZone: 275,
+ findChance: 1 / buildNum(640, 'T'),
+ price(lvl) {
+ return Math.pow(25, lvl - 1) * buildNum(700, 'B');
+ },
+ cap: 5,
+ stats() {
+ return [
+ {isPositive: true, type: 'base', name: 'hordeExecute', value: 0.06}
+ ];
+ },
+ active() {
+ return [
+ {type: 'buff', value: 5, effect: [
+ {type: 'base', name: 'hordeCutting', value: 0.15}
+ ]}
+ ];
+ },
+ activeType: 'combat',
+ cooldown: (lvl) => 170 - 10 * lvl,
+ icon: 'mdi-sword',
+ activeIcon: 'mdi-skull',
+ activeColor: 'darker-grey'
+ },
+ needle: {
+ findZone: 282,
+ findChance: 1 / buildNum(1.25, 'Qa'),
+ price(lvl) {
+ return Math.pow(25, lvl - 1) * buildNum(1.2, 'T');
+ },
+ cap: 5,
+ stats() {
+ return [
+ {isPositive: true, type: 'base', name: 'hordeExecute', value: 0.04},
+ {isPositive: true, type: 'base', name: 'hordeCutting', value: 0.01}
+ ];
+ },
+ active() {
+ return [
+ {type: 'maxdamageBio', value: 0.45, str: 0.003}
+ ];
+ },
+ activeType: 'combat',
+ activeCost: () => {
+ return {health: 0.1};
+ },
+ cooldown: (lvl) => 275 - 15 * lvl,
+ icon: 'mdi-nail',
+ activeIcon: 'mdi-nail',
+ activeColor: 'pale-purple'
+ },
+ mine: {
+ findZone: 289,
+ findChance: 1 / buildNum(2.5, 'Qa'),
+ price(lvl) {
+ return Math.pow(8, lvl - 1) * buildNum(2, 'T');
+ },
+ cap: 9,
+ stats() {
+ return [
+ {isPositive: false, type: 'mult', name: 'hordeAttack', value: 1 / 1.25},
+ {isPositive: true, type: 'base', name: 'hordeCritChance', value: 0.5},
+ {isPositive: true, type: 'base', name: 'hordeHaste', value: 20},
+ {isPositive: true, type: 'tag', name: 'hordeActiveDamageCrit', value: [0.3]}
+ ];
+ },
+ masteryBoost: 0.25,
+ active(lvl) {
+ return [
+ {type: 'damagePhysic', value: lvl * 0.25 + 4.25, str: 0.13, canCrit: 1}
+ ];
+ },
+ activeType: 'combat',
+ cooldown: () => 42,
+ icon: 'mdi-mine',
+ activeIcon: 'mdi-mine',
+ activeColor: 'deep-orange'
+ },
+ maskOfJoy: {
+ findZone: 296,
+ findChance: 1 / buildNum(5, 'Qa'),
+ price(lvl) {
+ return Math.pow(25, lvl - 1) * buildNum(3.3, 'T');
+ },
+ cap: 5,
+ stats() {
+ return [
+ {isPositive: true, type: 'base', name: 'hordeCritChance', value: 0.15},
+ {isPositive: true, type: 'base', name: 'hordeHealing', value: 0.1},
+ {isPositive: true, type: 'tag', name: 'hordeActiveHealCrit', value: [0.1]}
+ ];
+ },
+ active() {
+ return [
+ {type: 'heal', value: 0.1, int: 0.005, canCrit: 0.4}
+ ];
+ },
+ activeType: 'combat',
+ cooldown: (lvl) => 275 - 15 * lvl,
+ icon: 'mdi-drama-masks',
+ activeIcon: 'mdi-drama-masks',
+ activeColor: 'pale-green'
+ },
pawn: {
findZone: 50,
@@ -1591,7 +1995,7 @@ export default {
},
active() {
return [
- {type: 'damagePhysic', value: 2.7}
+ {type: 'damagePhysic', value: 2.7, str: 0.08}
];
},
activeType: 'combat',
@@ -1615,7 +2019,7 @@ export default {
},
active() {
return [
- {type: 'damageMagic', value: 4.15},
+ {type: 'damageMagic', value: 4.15, int: 0.1},
{type: 'stun', value: 2}
];
},
@@ -1635,14 +2039,14 @@ export default {
stats(lvl) {
return [
{isPositive: true, type: 'base', name: 'hordeHealth', value: lvl * 500 + 7000},
- {isPositive: true, type: 'base', name: 'hordeToxic', value: 0.025},
+ {isPositive: true, type: 'base', name: 'hordeToxic', value: 0.01},
{isPositive: true, type: 'base', name: 'hordeCutting', value: 0.01}
];
},
active() {
return [
- {type: 'damageBio', value: 8.75},
- {type: 'poison', value: 0.2}
+ {type: 'maxdamageBio', value: 0.15, str: 0.0012},
+ {type: 'poison', value: 0.2, int: 0.01}
];
},
activeType: 'combat',
@@ -1688,7 +2092,7 @@ export default {
{isPositive: true, type: 'base', name: 'hordeAttack', value: lvl * 2 + 28},
{isPositive: true, type: 'base', name: 'hordeHealth', value: lvl * 200 + 2800},
{isPositive: true, type: 'base', name: 'hordeFirstStrike', value: 0.6},
- {isPositive: true, type: 'base', name: 'hordeToxic', value: 0.01},
+ {isPositive: true, type: 'base', name: 'hordeToxic', value: 0.005},
{isPositive: false, type: 'base', name: 'hordeMagicConversion', value: 0.4},
{isPositive: false, type: 'base', name: 'hordeBioConversion', value: 0.4}
];
diff --git a/src/js/modules/horde/fighterClass/adventurer.js b/src/js/modules/horde/fighterClass/adventurer.js
new file mode 100644
index 00000000..b8cab1b0
--- /dev/null
+++ b/src/js/modules/horde/fighterClass/adventurer.js
@@ -0,0 +1,217 @@
+import { SECONDS_PER_HOUR } from "../../../constants";
+import { getSequence } from "../../../utils/math";
+
+export default {
+ icon: 'mdi-bag-personal',
+ baseStats: {
+ attack: 5,
+ health: 500,
+ energy: 200,
+ energyRegen: 1,
+ mana: 120,
+ manaRegen: 0.01
+ },
+ exp: {
+ base: 600,
+ increment: 1.2
+ },
+ skills: {
+ energyConvert: {
+ type: 'passive',
+ color: 'amber',
+ icon: 'mdi-lightning-bolt',
+ max: 1,
+ effect: [
+ {name: 'hordeEnergyToStr', type: 'tag', value: lvl => [lvl * 0.02]},
+ {name: 'hordeEnergyToEnergyReg', type: 'tag', value: lvl => [lvl * 0.005]}
+ ]
+ },
+ stab: {
+ type: 'active',
+ color: 'red',
+ icon: 'mdi-knife',
+ max: 1,
+ cooldown: () => 8,
+ activeCost: () => {return {energy: 30};},
+ active() {
+ return [
+ {type: 'damagePhysic', value: 2, str: 0.1, int: 0.05}
+ ];
+ },
+ activeType: 'combat'
+ },
+ health: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeHealth', type: 'base', value: lvl => lvl * 70}
+ ]},
+ strength: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeStrength', type: 'base', value: lvl => lvl * 1.3}
+ ]},
+ energy: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeEnergy', type: 'base', value: lvl => lvl * 40}
+ ]},
+ brawl: {
+ type: 'active',
+ color: 'orange',
+ icon: 'mdi-arm-flex',
+ max: 5,
+ cost: 20,
+ cooldown: () => 60,
+ activeCost: () => {return {energy: 140};},
+ active(lvl) {
+ return [
+ {type: 'buff', value: 18, effect: [
+ {type: 'base', name: 'hordeStrength', value: 10 * lvl},
+ {type: 'mult', name: 'hordeAttack', value: 1.3}
+ ]}
+ ];
+ },
+ activeType: 'combat'
+ },
+ strength_2: {type: 'stat', max: 15, cost: 10, effect: [
+ {name: 'hordeStrength', type: 'base', value: lvl => lvl * 1.5}
+ ]},
+ spark: {
+ type: 'active',
+ color: 'light-blue',
+ icon: 'mdi-flare',
+ max: 5,
+ cost: 20,
+ cooldown: () => 6,
+ activeCost: () => {return {mana: 12};},
+ active() {
+ return [
+ {type: 'damageMagic', value: 2.5, int: 0.35}
+ ];
+ },
+ activeType: 'combat'
+ },
+ intelligence: {type: 'stat', max: 15, cost: 10, effect: [
+ {name: 'hordeIntelligence', type: 'base', value: lvl => lvl * 1.8}
+ ]},
+ smash: {
+ type: 'active',
+ color: 'brown',
+ icon: 'mdi-anvil',
+ max: 5,
+ cost: 20,
+ cooldown: () => 22,
+ activeCost: () => {return {energy: 60};},
+ active(lvl) {
+ return [
+ {type: 'damagePhysic', value: 2.75},
+ {type: 'stun', value: lvl + 5}
+ ];
+ },
+ activeType: 'combat'
+ },
+ haste: {type: 'stat', max: 15, cost: 10, effect: [
+ {name: 'hordeHaste', type: 'base', value: lvl => lvl * 4}
+ ]},
+ lootSearch: {
+ type: 'active',
+ color: 'light-green',
+ icon: 'mdi-sack',
+ max: 5,
+ cost: 20,
+ cooldown: () => 300,
+ activeCost: () => {return {};},
+ active(lvl) {
+ return [
+ {type: 'blood', value: 9 + lvl}
+ ];
+ },
+ activeType: 'utility'
+ },
+ damage: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeAttack', type: 'base', value: lvl => lvl * 0.15}
+ ]},
+ energy_2: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeEnergy', type: 'base', value: lvl => lvl * 40}
+ ]},
+ damage_2: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeAttack', type: 'base', value: lvl => lvl * 0.15}
+ ]},
+ health_2: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeHealth', type: 'base', value: lvl => lvl * 70}
+ ]},
+ recovery: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeHealth', type: 'base', value: lvl => lvl * 25},
+ {name: 'hordeRecovery', type: 'base', value: lvl => lvl * 0.008}
+ ]},
+ combatHeal: {
+ type: 'active',
+ color: 'green',
+ icon: 'mdi-medication',
+ max: 5,
+ cost: 20,
+ cooldown: () => 45,
+ activeCost: () => {return {mana: 55};},
+ active(lvl) {
+ return [
+ {type: 'heal', value: lvl * 0.05 + 0.125, int: 0.004}
+ ];
+ },
+ activeType: 'combat'
+ },
+ energy_3: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeEnergy', type: 'base', value: lvl => lvl * 40}
+ ]},
+ mana: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeMana', type: 'base', value: lvl => lvl * 20}
+ ]},
+ blood: {type: 'stat', max: 20, cost: 15, effect: [
+ {name: 'currencyHordeBloodGain', type: 'mult', value: lvl => getSequence(3, lvl) * 0.05 + 1},
+ {name: 'currencyHordeBloodCap', type: 'mult', value: lvl => getSequence(3, lvl) * 0.05 + 1}
+ ]},
+ courage: {type: 'stat', max: 20, cost: 15, effect: [
+ {name: 'currencyHordeCourageGain', type: 'mult', value: lvl => lvl * 0.05 + 1}
+ ]},
+ supercharge: {
+ type: 'active',
+ color: 'amber',
+ icon: 'mdi-lightning-bolt',
+ max: 5,
+ cost: 20,
+ cooldown: () => 22 * SECONDS_PER_HOUR,
+ activeCost: () => {return {};},
+ active(lvl) {
+ return [
+ {type: 'permanentStat', stat: 'hordeEnergy_base', value: lvl * 5 + 5}
+ ];
+ },
+ activeType: 'utility'
+ },
+ },
+ skillTree: [
+ {isInnate: true, level: 0, items: ['energyConvert', 'stab']},
+ {level: 1, items: ['health', 'strength', 'energy']},
+ {isChoice: true, level: 10, items: [['brawl', 'strength_2'], ['spark', 'intelligence'], ['smash', 'haste']]},
+ {level: 20, items: ['lootSearch', 'damage', 'energy_2']},
+ {level: 30, items: ['damage_2', 'health_2', 'recovery']},
+ {level: 40, items: ['combatHeal', 'energy_3', 'mana']},
+ {isChoice: true, level: 50, items: [['blood'], ['courage'], ['supercharge']]},
+ ],
+ quests: {
+ stat: [
+ {stat: 'hordeHealth', type: 'base', value: 1000},
+ {stat: 'hordeIntelligence', type: 'total', value: 20},
+ {stat: 'hordeStrength', type: 'total', value: 90},
+ ],
+ zone: [
+ {area: 'warzone', zone: '1'},
+ {area: 'warzone', zone: '3'},
+ {area: 'warzone', zone: '5'},
+ {area: 'warzone', zone: '10'},
+ {area: 'monkeyJungle', zone: '7'},
+ {area: 'monkeyJungle', zone: '14'},
+ {area: 'loveIsland', zone: '1'},
+ {area: 'loveIsland', zone: '8'},
+ ],
+ level: [7, 15, 25, 40, 60, 80, 100, 125, 150, 175, 200],
+ boss: [
+ {boss: 'ohilio', difficulty: 3},
+ {boss: 'chriz2', difficulty: 5},
+ {boss: 'mina', difficulty: 15},
+ ]
+ }
+}
diff --git a/src/js/modules/horde/fighterClass/archer.js b/src/js/modules/horde/fighterClass/archer.js
new file mode 100644
index 00000000..7b5609b7
--- /dev/null
+++ b/src/js/modules/horde/fighterClass/archer.js
@@ -0,0 +1,226 @@
+import { SECONDS_PER_HOUR } from "../../../constants";
+
+export default {
+ unlock: 'hordeClassArcher',
+ icon: 'mdi-bow-arrow',
+ baseStats: {
+ attack: 7,
+ health: 325,
+ energy: 150,
+ energyRegen: 1.25
+ },
+ exp: {
+ base: 720,
+ increment: 1.22
+ },
+ courageMult: 2,
+ skills: {
+ critMult: {type: 'stat', max: 1, effect: [
+ {name: 'hordeCritMult', type: 'base', value: lvl => lvl * 1.75}
+ ]},
+ energyOnCrit: {
+ type: 'passive',
+ color: 'amber',
+ icon: 'mdi-lightning-bolt',
+ max: 1,
+ effect: [
+ {name: 'hordeEnergyOnCrit', type: 'tag', value: lvl => [lvl * 10]}
+ ]
+ },
+ longshot: {
+ type: 'active',
+ color: 'skyblue',
+ icon: 'mdi-arrow-projectile',
+ max: 1,
+ cooldown: () => 30,
+ activeCost: () => {return {energy: 70};},
+ active() {
+ return [
+ {type: 'damagePhysic', value: 4.25, str: 0.65, canCrit: 0.75}
+ ];
+ },
+ activeType: 'combat'
+ },
+ eagleEye: {
+ type: 'active',
+ color: 'light-green',
+ icon: 'mdi-eye',
+ max: 5,
+ cost: 20,
+ cooldown: () => 45,
+ activeCost: () => {return {energy: 50};},
+ active(lvl) {
+ return [
+ {type: 'buff', value: 12, effect: [
+ {type: 'base', name: 'hordeCritChance', value: lvl * 0.05 + 0.05}
+ ]}
+ ];
+ },
+ activeType: 'combat'
+ },
+ strength: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeStrength', type: 'base', value: lvl => lvl * 1.3}
+ ]},
+ critMult_2: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeCritMult', type: 'base', value: lvl => lvl * 0.1}
+ ]},
+ fireArrows: {
+ type: 'active',
+ color: 'orange-red',
+ icon: 'mdi-fire',
+ max: 5,
+ cost: 20,
+ cooldown: () => 90,
+ activeCost: () => {return {energy: 110};},
+ active(lvl) {
+ return [
+ {type: 'buff', value: 30, effect: [
+ {type: 'mult', name: 'hordeAttack', value: lvl * 0.05 + 1.25},
+ {type: 'base', name: 'hordeMagicConversion', value: 1.75}
+ ]}
+ ];
+ },
+ activeType: 'combat'
+ },
+ poisonArrow: {
+ type: 'active',
+ color: 'lime',
+ icon: 'mdi-bottle-tonic-skull',
+ max: 5,
+ cost: 20,
+ cooldown: () => 16,
+ activeCost: () => {return {energy: 50};},
+ active(lvl) {
+ return [
+ {type: 'poison', value: lvl * 0.05 + 0.25, int: 0.01}
+ ];
+ },
+ activeType: 'combat'
+ },
+ critChance: {type: 'stat', max: 5, cost: 20, effect: [
+ {name: 'hordeCritChance', type: 'base', value: lvl => lvl * 0.03}
+ ]},
+ intelligence: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeIntelligence', type: 'base', value: lvl => lvl * 1.75}
+ ]},
+ healOnCrit: {
+ type: 'passive',
+ color: 'light-green',
+ icon: 'mdi-heart-plus',
+ max: 1,
+ cost: 50,
+ effect: [
+ {name: 'hordeHealOnCrit', type: 'tag', value: lvl => [lvl * 0.03]}
+ ]
+ },
+ health: {type: 'stat', max: 15, cost: 10, effect: [
+ {name: 'hordeHealth', type: 'base', value: lvl => lvl * 65}
+ ]},
+ reduceCooldownOnCrit: {
+ type: 'passive',
+ color: 'pale-orange',
+ icon: 'mdi-timer-sand-paused',
+ max: 1,
+ cost: 50,
+ effect: [
+ {name: 'hordeRestoreCooldownOnCrit', type: 'tag', value: lvl => [lvl]}
+ ]
+ },
+ haste: {type: 'stat', max: 15, cost: 10, effect: [
+ {name: 'hordeHaste', type: 'base', value: lvl => lvl * 4}
+ ]},
+ bloodOnCrit: {
+ type: 'passive',
+ color: 'cherry',
+ icon: 'mdi-diabetes',
+ max: 1,
+ cost: 50,
+ effect: [
+ {name: 'hordeBloodOnCrit', type: 'tag', value: lvl => [lvl * 0.15]}
+ ]
+ },
+ blood: {type: 'stat', max: 15, cost: 10, effect: [
+ {name: 'currencyHordeBloodCap', type: 'mult', value: lvl => lvl * 0.13 + 1}
+ ]},
+ critChance_2: {type: 'stat', max: 5, cost: 20, effect: [
+ {name: 'hordeCritChance', type: 'base', value: lvl => lvl * 0.03}
+ ]},
+ energy: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeEnergy', type: 'base', value: lvl => lvl * 30}
+ ]},
+ health_2: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeHealth', type: 'base', value: lvl => lvl * 60}
+ ]},
+ sharpArrow: {
+ type: 'active',
+ color: 'red',
+ icon: 'mdi-arrow-projectile-multiple',
+ max: 5,
+ cost: 20,
+ cooldown: () => 7,
+ activeCost: () => {return {energy: 25};},
+ active(lvl) {
+ return [
+ {type: 'damagePhysic', value: lvl * 0.4 + 1.2, str: 0.2},
+ {type: 'removeDivisionShield', value: 1}
+ ];
+ },
+ activeType: 'combat'
+ },
+ strength_2: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeStrength', type: 'base', value: lvl => lvl * 1.3}
+ ]},
+ sharpMind: {
+ type: 'active',
+ color: 'orange-red',
+ icon: 'mdi-motion',
+ max: 5,
+ cost: 20,
+ cooldown: () => 22 * SECONDS_PER_HOUR,
+ activeCost: () => {return {};},
+ active(lvl) {
+ return [
+ {type: 'permanentStat', stat: 'hordeCritMult_base', value: lvl * 0.02 + 0.02}
+ ];
+ },
+ activeType: 'utility'
+ },
+ critChance_3: {type: 'stat', max: 5, cost: 20, effect: [
+ {name: 'hordeCritChance', type: 'base', value: lvl => lvl * 0.03}
+ ]},
+ courage: {type: 'stat', max: 10, cost: 15, effect: [
+ {name: 'currencyHordeCourageGain', type: 'mult', value: lvl => lvl * 0.05 + 1}
+ ]},
+ },
+ skillTree: [
+ {isInnate: true, level: 0, items: ['critMult', 'energyOnCrit', 'longshot']},
+ {level: 1, items: ['eagleEye', 'strength', 'critMult_2']},
+ {level: 10, items: ['fireArrows', 'poisonArrow', 'critChance', 'intelligence']},
+ {isChoice: true, level: 20, items: [['healOnCrit', 'health'], ['reduceCooldownOnCrit', 'haste'], ['bloodOnCrit', 'blood']]},
+ {level: 30, items: ['critChance_2', 'energy', 'health_2']},
+ {level: 40, items: ['sharpArrow', 'sharpMind', 'strength_2']},
+ {level: 50, items: ['critChance_3', 'courage']},
+ ],
+ quests: {
+ stat: [
+ {stat: 'hordeIntelligence', type: 'total', value: 10},
+ {stat: 'hordeHaste', type: 'total', value: 80},
+ {stat: 'hordeCritChance', type: 'total', value: 0.5},
+ ],
+ zone: [
+ {area: 'warzone', zone: '4'},
+ {area: 'warzone', zone: '8'},
+ {area: 'monkeyJungle', zone: '5'},
+ {area: 'monkeyJungle', zone: '12'},
+ {area: 'monkeyJungle', zone: '16'},
+ {area: 'loveIsland', zone: '3'},
+ {area: 'loveIsland', zone: '11'},
+ ],
+ level: [10, 20, 35, 50, 70, 95, 120, 145, 170, 195],
+ boss: [
+ {boss: 'ohilio', difficulty: 7},
+ {boss: 'chriz2', difficulty: 10},
+ {boss: 'mina', difficulty: 10},
+ ]
+ }
+}
diff --git a/src/js/modules/horde/fighterClass/assassin.js b/src/js/modules/horde/fighterClass/assassin.js
new file mode 100644
index 00000000..1e5ef68e
--- /dev/null
+++ b/src/js/modules/horde/fighterClass/assassin.js
@@ -0,0 +1,23 @@
+export default {
+ unlock: 'hordeClassAssassin',
+ icon: 'mdi-robber',
+ baseStats: {
+ attack: 8.5,
+ health: 220,
+ mana: 90
+ },
+ exp: {
+ base: 2700,
+ increment: 1.5
+ },
+ skills: {},
+ skillTree: [
+ {isInnate: true, level: 0, items: []},
+ ],
+ quests: {
+ stat: [],
+ zone: [],
+ level: [],
+ boss: []
+ }
+}
diff --git a/src/js/modules/horde/fighterClass/cultist.js b/src/js/modules/horde/fighterClass/cultist.js
new file mode 100644
index 00000000..10127a02
--- /dev/null
+++ b/src/js/modules/horde/fighterClass/cultist.js
@@ -0,0 +1,22 @@
+export default {
+ unlock: 'hordeClassCultist',
+ icon: 'mdi-pentagram',
+ baseStats: {
+ attack: 3.3,
+ health: 700
+ },
+ exp: {
+ base: 12600,
+ increment: 1.875
+ },
+ skills: {},
+ skillTree: [
+ {isInnate: true, level: 0, items: []},
+ ],
+ quests: {
+ stat: [],
+ zone: [],
+ level: [],
+ boss: []
+ }
+}
diff --git a/src/js/modules/horde/fighterClass/knight.js b/src/js/modules/horde/fighterClass/knight.js
new file mode 100644
index 00000000..62553d7d
--- /dev/null
+++ b/src/js/modules/horde/fighterClass/knight.js
@@ -0,0 +1,251 @@
+import { SECONDS_PER_HOUR } from "../../../constants";
+import { buildNum } from "../../../utils/format";
+
+export default {
+ unlock: 'hordeClassKnight',
+ icon: 'mdi-shield',
+ baseStats: {
+ attack: 2.5,
+ health: 900,
+ energy: 160,
+ energyRegen: 1.5
+ },
+ exp: {
+ base: 1200,
+ increment: 1.3
+ },
+ courageMult: 12,
+ skills: {
+ damageRamp: {
+ type: 'passive',
+ color: 'red',
+ icon: 'mdi-chart-line',
+ max: 1,
+ effect: [
+ {name: 'hordeAttackAfterTime', type: 'tag', value: lvl => [lvl * 0.75]}
+ ]
+ },
+ revive: {
+ type: 'passive',
+ color: 'yellow',
+ icon: 'mdi-cross',
+ max: 1,
+ effect: [
+ {name: 'hordeRevive', type: 'base', value: lvl => lvl}
+ ]
+ },
+ heavyHit: {
+ type: 'active',
+ color: 'orange-red',
+ icon: 'mdi-sword',
+ max: 1,
+ cooldown: () => 70,
+ activeCost: () => {return {energy: 140};},
+ active() {
+ return [
+ {type: 'damagePhysic', value: 8, str: 0.6},
+ {type: 'damageMagic', value: 8, int: 0.75}
+ ];
+ },
+ activeType: 'combat'
+ },
+ shieldBash: {
+ type: 'active',
+ color: 'brown',
+ icon: 'mdi-shield',
+ max: 5,
+ cost: 20,
+ cooldown: () => 16,
+ activeCost: () => {return {energy: 100};},
+ active(lvl) {
+ return [
+ {type: 'damagePhysic', value: lvl * 0.25 + 2.25, str: 0.2},
+ {type: 'stun', value: lvl + 2}
+ ];
+ },
+ activeType: 'combat'
+ },
+ health: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeHealth', type: 'base', value: lvl => lvl * 120}
+ ]},
+ defense: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeDefense', type: 'base', value: lvl => lvl * 0.001}
+ ]},
+ haste: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeHaste', type: 'base', value: lvl => lvl * 3}
+ ]},
+ statRamp: {
+ type: 'passive',
+ color: 'pink-purple',
+ icon: 'mdi-chart-line',
+ max: 5,
+ cost: 40,
+ effect: [
+ {name: 'hordeStrIntAfterTime', type: 'tag', value: lvl => [lvl * 8]}
+ ]
+ },
+ defense_2: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeDefense', type: 'base', value: lvl => lvl * 0.0012}
+ ]},
+ toxic: {type: 'stat', max: 20, cost: 10, effect: [
+ {name: 'hordeToxic', type: 'base', value: lvl => lvl * 0.005}
+ ]},
+ magicTaken: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeMagicTaken', type: 'mult', value: lvl => Math.pow(1 / 1.09, lvl)}
+ ]},
+ cutting: {type: 'stat', max: 20, cost: 10, effect: [
+ {name: 'hordeCutting', type: 'base', value: lvl => lvl * 0.002}
+ ]},
+ physicTaken: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordePhysicTaken', type: 'mult', value: lvl => Math.pow(1 / 1.09, lvl)}
+ ]},
+ refuge: {
+ type: 'active',
+ color: 'green',
+ icon: 'mdi-medical-cotton-swab',
+ max: 5,
+ cost: 20,
+ cooldown: () => 50,
+ activeCost: () => {return {energy: 120};},
+ active(lvl) {
+ return [
+ {type: 'heal', value: lvl * 0.05 + 0.25, int: 0.006},
+ {type: 'buff', value: lvl * 2 + 8, effect: [
+ {type: 'mult', name: 'hordePhysicTaken', value: 1 / 1.4},
+ {type: 'mult', name: 'hordeMagicTaken', value: 1 / 1.4},
+ {type: 'mult', name: 'hordeBioTaken', value: 1 / 1.4}
+ ]}
+ ];
+ },
+ activeType: 'combat'
+ },
+ health_2: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeHealth', type: 'base', value: lvl => lvl * 120}
+ ]},
+ recovery: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeHealth', type: 'base', value: lvl => lvl * 35},
+ {name: 'hordeRecovery', type: 'base', value: lvl => lvl * 0.01}
+ ]},
+ physicTaken_2: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordePhysicTaken', type: 'mult', value: lvl => Math.pow(1 / 1.08, lvl)}
+ ]},
+ strength: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeStrength', type: 'base', value: lvl => lvl * 0.8}
+ ]},
+ consecrate: {
+ type: 'active',
+ color: 'amber',
+ icon: 'mdi-shimmer',
+ max: 5,
+ cost: 20,
+ cooldown: () => 28,
+ activeCost: () => {return {energy: 50};},
+ active(lvl) {
+ return [
+ {type: 'removeAttack', value: lvl * 0.02 + 0.06},
+ {type: 'stun', value: lvl + 4},
+ ];
+ },
+ activeType: 'combat'
+ },
+ energy: {type: 'stat', max: 15, cost: 10, effect: [
+ {name: 'hordeEnergy', type: 'base', value: lvl => lvl * 35}
+ ]},
+ blessing: {
+ type: 'active',
+ color: 'yellow',
+ icon: 'mdi-cross-outline',
+ max: 5,
+ cost: 20,
+ cooldown: lvl => 2700 - lvl * 300,
+ activeCost: () => {return {energy: 80};},
+ active(lvl) {
+ return [
+ {type: 'heal', value: lvl * 0.3 + 0.9, int: 0.02},
+ {type: 'revive', value: 1},
+ ];
+ },
+ activeType: 'combat'
+ },
+ revive_2: {
+ type: 'passive',
+ color: 'yellow',
+ icon: 'mdi-cross',
+ max: 3,
+ cost: 100,
+ effect: [
+ {name: 'hordeRevive', type: 'base', value: lvl => lvl}
+ ]
+ },
+ fortify: {
+ type: 'active',
+ color: 'pale-green',
+ icon: 'mdi-heart',
+ max: 5,
+ cost: 20,
+ cooldown: () => 22 * SECONDS_PER_HOUR,
+ activeCost: () => {return {};},
+ active(lvl) {
+ return [
+ {type: 'permanentStat', stat: 'hordeHealth_base', value: lvl * 30 + 30}
+ ];
+ },
+ activeType: 'utility'
+ },
+ bioTaken: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeBioTaken', type: 'mult', value: lvl => Math.pow(1 / 1.09, lvl)}
+ ]},
+ health_3: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeHealth', type: 'base', value: lvl => lvl * 120}
+ ]},
+ magicTaken_2: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeMagicTaken', type: 'mult', value: lvl => Math.pow(1 / 1.08, lvl)}
+ ]},
+ divisionShield: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeDivisionShield', type: 'base', value: lvl => lvl}
+ ]},
+ intelligence: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeIntelligence', type: 'base', value: lvl => lvl * 0.9}
+ ]},
+ recovery_2: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeHealth', type: 'base', value: lvl => lvl * 35},
+ {name: 'hordeRecovery', type: 'base', value: lvl => lvl * 0.01}
+ ]},
+ defense_3: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeDefense', type: 'base', value: lvl => lvl * 0.001}
+ ]},
+ courage: {type: 'stat', max: 10, cost: 15, effect: [
+ {name: 'currencyHordeCourageGain', type: 'mult', value: lvl => lvl * 0.05 + 1}
+ ]},
+ },
+ skillTree: [
+ {isInnate: true, level: 0, items: ['damageRamp', 'revive', 'heavyHit']},
+ {level: 1, items: ['shieldBash', 'health', 'defense', 'haste']},
+ {isChoice: true, level: 10, items: [['statRamp', 'defense_2'], ['toxic', 'physicTaken'], ['cutting', 'magicTaken']]},
+ {level: 20, items: ['refuge', 'health_2', 'recovery', 'physicTaken_2', 'strength']},
+ {isChoice: true, level: 30, items: [['consecrate', 'energy'], ['blessing', 'revive_2'], ['fortify', 'bioTaken']]},
+ {level: 40, items: ['health_3', 'magicTaken_2', 'divisionShield', 'intelligence']},
+ {level: 50, items: ['recovery_2', 'defense_3', 'courage']},
+ ],
+ quests: {
+ stat: [
+ {stat: 'hordeHealth', type: 'base', value: 3000},
+ {stat: 'hordeCutting', type: 'total', value: 0.04},
+ {stat: 'hordeHealth', type: 'base', value: buildNum(10, 'K')},
+ ],
+ zone: [
+ {area: 'warzone', zone: '9'},
+ {area: 'monkeyJungle', zone: '6'},
+ {area: 'monkeyJungle', zone: '13'},
+ {area: 'monkeyJungle', zone: '19'},
+ {area: 'loveIsland', zone: '6'},
+ {area: 'loveIsland', zone: '14'},
+ ],
+ level: [20, 35, 50, 70, 90, 115, 140, 165, 190],
+ boss: [
+ {boss: 'ohilio', difficulty: 20},
+ {boss: 'chriz2', difficulty: 15},
+ {boss: 'mina', difficulty: 2},
+ ]
+ }
+}
diff --git a/src/js/modules/horde/fighterClass/mage.js b/src/js/modules/horde/fighterClass/mage.js
new file mode 100644
index 00000000..60ca39f7
--- /dev/null
+++ b/src/js/modules/horde/fighterClass/mage.js
@@ -0,0 +1,337 @@
+import { SECONDS_PER_HOUR } from "../../../constants";
+
+export default {
+ unlock: 'hordeClassMage',
+ icon: 'mdi-wizard-hat',
+ baseStats: {
+ attack: 4,
+ health: 575,
+ mana: 400,
+ manaRegen: 0.1
+ },
+ exp: {
+ base: 840,
+ increment: 1.24
+ },
+ courageMult: 4,
+ skills: {
+ manaRest: {
+ type: 'passive',
+ color: 'blue',
+ icon: 'mdi-sleep',
+ max: 1,
+ effect: [
+ {name: 'hordeManaRest', type: 'tag', value: lvl => [15, lvl * 1.2]}
+ ]
+ },
+ autocast: {
+ type: 'passive',
+ color: 'pink',
+ icon: 'mdi-cached',
+ max: 3,
+ cost: 75,
+ effect: [
+ {name: 'hordeAutocast', type: 'base', value: lvl => lvl}
+ ]
+ },
+ magicMissile: {
+ type: 'active',
+ color: 'indigo',
+ icon: 'mdi-motion',
+ max: 1,
+ cooldown: () => 6,
+ activeCost: () => {return {mana: 10};},
+ active() {
+ return [
+ {type: 'damageMagic', value: 2.2, int: 0.16}
+ ];
+ },
+ activeType: 'combat'
+ },
+ fireball: {
+ type: 'active',
+ color: 'orange',
+ icon: 'mdi-fire-circle',
+ max: 5,
+ cost: 14,
+ cooldown: () => 13,
+ activeCost: () => {return {mana: 22};},
+ active(lvl) {
+ return [
+ {type: 'damageMagic', value: lvl * 0.1 + 3.3, int: 0.24, canCrit: lvl * 0.1 + 0.5}
+ ];
+ },
+ activeType: 'combat'
+ },
+ shockBlast: {
+ type: 'active',
+ color: 'yellow',
+ icon: 'mdi-flash',
+ max: 5,
+ cost: 14,
+ cooldown: () => 28,
+ activeCost: () => {return {mana: 30};},
+ active(lvl) {
+ return [
+ {type: 'damageMagic', value: lvl * 0.3 + 4.5, int: 0.3},
+ {type: 'silence', value: lvl * 2 + 4}
+ ];
+ },
+ activeType: 'combat'
+ },
+ heal: {
+ type: 'active',
+ color: 'green',
+ icon: 'mdi-medical-bag',
+ max: 5,
+ cost: 14,
+ cooldown: (lvl) => 55 - lvl * 5,
+ activeCost: () => {return {mana: 65};},
+ active() {
+ return [
+ {type: 'heal', value: 0.6, int: 0.01}
+ ];
+ },
+ activeType: 'combat'
+ },
+ mana: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeMana', type: 'base', value: lvl => lvl * 50}
+ ]},
+ intelligence: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeIntelligence', type: 'base', value: lvl => lvl * 1.4}
+ ]},
+ barrier: {
+ type: 'active',
+ color: 'light-grey',
+ icon: 'mdi-circle-outline',
+ max: 5,
+ cost: 16,
+ cooldown: () => 36,
+ activeCost: () => {return {mana: 40};},
+ active(lvl) {
+ return [
+ {type: 'divisionShield', value: lvl * 3 + 1}
+ ];
+ },
+ activeType: 'combat'
+ },
+ earthquake: {
+ type: 'active',
+ color: 'brown',
+ icon: 'mdi-landslide',
+ max: 5,
+ cost: 16,
+ cooldown: () => 30,
+ activeCost: () => {return {mana: 48};},
+ active(lvl) {
+ return [
+ {type: 'damageMagic', value: 3.75, int: 0.22},
+ {type: 'stun', value: lvl + 3}
+ ];
+ },
+ activeType: 'combat'
+ },
+ intelligence_2: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeIntelligence', type: 'base', value: lvl => lvl * 1.4}
+ ]},
+ haste: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeHaste', type: 'base', value: lvl => lvl * 3}
+ ]},
+ health: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeHealth', type: 'base', value: lvl => lvl * 70}
+ ]},
+ manasteal: {
+ type: 'passive',
+ color: 'teal',
+ icon: 'mdi-water-plus',
+ max: 3,
+ cost: 40,
+ effect: [
+ {name: 'hordeManasteal', type: 'tag', value: lvl => [lvl * 5]}
+ ]
+ },
+ waterBolt: {
+ type: 'active',
+ color: 'light-blue',
+ icon: 'mdi-waves',
+ max: 5,
+ cost: 18,
+ cooldown: () => 75,
+ activeCost: () => {return {mana: 130};},
+ active(lvl) {
+ return [
+ {type: 'damageMagic', value: lvl * 0.6 + 8, int: 0.36},
+ {type: 'heal', value: lvl * 0.025 + 0.075, int: 0.006}
+ ];
+ },
+ activeType: 'combat'
+ },
+ iceBlast: {
+ type: 'active',
+ color: 'cyan',
+ icon: 'mdi-snowflake-alert',
+ max: 5,
+ cost: 18,
+ cooldown: (lvl) => 38 - lvl * 4,
+ activeCost: () => {return {mana: 85};},
+ active(lvl) {
+ return [
+ {type: 'stun', value: lvl * 2 + 6},
+ {type: 'removeAttack', value: lvl * 0.02 + 0.1}
+ ];
+ },
+ activeType: 'combat'
+ },
+ mana_2: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeMana', type: 'base', value: lvl => lvl * 50}
+ ]},
+ haste_2: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeHaste', type: 'base', value: lvl => lvl * 3}
+ ]},
+ autocast_2: {
+ type: 'passive',
+ color: 'pink',
+ icon: 'mdi-cached',
+ max: 1,
+ cost: 50,
+ effect: [
+ {name: 'hordeAutocast', type: 'base', value: lvl => lvl}
+ ]
+ },
+ mana_3: {type: 'stat', max: 15, cost: 10, effect: [
+ {name: 'hordeMana', type: 'base', value: lvl => lvl * 40},
+ {name: 'hordeManaRegen', type: 'base', value: lvl => lvl * 0.08}
+ ]},
+ spellblade: {type: 'stat', max: 15, cost: 10, effect: [
+ {name: 'hordeSpellblade', type: 'base', value: lvl => lvl * 0.2}
+ ]},
+ focus: {
+ type: 'active',
+ color: 'purple',
+ icon: 'mdi-crystal-ball',
+ max: 5,
+ cost: 20,
+ cooldown: () => 180,
+ activeCost: () => {return {mana: 125};},
+ active(lvl) {
+ return [
+ {type: 'buff', value: 60, effect: [
+ {type: 'base', name: 'hordeIntelligence', value: 8 * lvl}
+ ]}
+ ];
+ },
+ activeType: 'combat'
+ },
+ smite: {
+ type: 'active',
+ color: 'red',
+ icon: 'mdi-nuke',
+ max: 5,
+ cost: 20,
+ cooldown: (lvl) => 95 - lvl * 5,
+ activeCost: () => {return {mana: 250};},
+ active(lvl) {
+ return [
+ {type: 'damageMagic', value: lvl * 4 + 18, int: 0.8}
+ ];
+ },
+ activeType: 'combat'
+ },
+ intelligence_3: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeIntelligence', type: 'base', value: lvl => lvl * 1.4}
+ ]},
+ health_2: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeHealth', type: 'base', value: lvl => lvl * 70}
+ ]},
+ autocast_3: {
+ type: 'passive',
+ color: 'pink',
+ icon: 'mdi-cached',
+ max: 1,
+ cost: 50,
+ effect: [
+ {name: 'hordeAutocast', type: 'base', value: lvl => lvl}
+ ]
+ },
+ conjure: {
+ type: 'active',
+ color: 'red-pink',
+ icon: 'mdi-sack',
+ max: 5,
+ cost: 20,
+ cooldown: () => 900,
+ activeCost: () => {return {};},
+ active(lvl) {
+ return [
+ {type: 'blood', value: lvl * 5 + 25}
+ ];
+ },
+ activeType: 'utility'
+ },
+ ascend: {
+ type: 'active',
+ color: 'amber',
+ icon: 'mdi-star-face',
+ max: 5,
+ cost: 20,
+ cooldown: (lvl) => 8100 - lvl * 900,
+ activeCost: () => {return {mana: 1000};},
+ active(lvl) {
+ return [
+ {type: 'buff', value: 150, effect: [
+ {type: 'mult', name: 'hordeAttack', value: lvl * 0.15 + 1.25},
+ {type: 'mult', name: 'hordeHealth', value: lvl * 0.15 + 1.25},
+ {type: 'base', name: 'hordeRecovery', value: lvl * 0.03 + 0.05},
+ {type: 'base', name: 'hordeManaRegen', value: lvl * 2 + 10},
+ ]}
+ ];
+ },
+ activeType: 'combat'
+ },
+ deepFocus: {
+ type: 'active',
+ color: 'blue',
+ icon: 'mdi-water',
+ max: 5,
+ cost: 20,
+ cooldown: () => 22 * SECONDS_PER_HOUR,
+ activeCost: () => {return {};},
+ active(lvl) {
+ return [
+ {type: 'permanentStat', stat: 'hordeMana_base', value: lvl * 10 + 10}
+ ];
+ },
+ activeType: 'utility'
+ },
+ },
+ skillTree: [
+ {isInnate: true, level: 0, items: ['manaRest', 'autocast', 'magicMissile']},
+ {level: 1, items: ['fireball', 'shockBlast', 'heal', 'mana', 'intelligence']},
+ {level: 10, items: ['barrier', 'earthquake', 'intelligence_2', 'haste', 'health']},
+ {level: 20, items: ['manasteal', 'waterBolt', 'iceBlast', 'mana_2', 'haste_2']},
+ {isChoice: true, level: 30, items: [['autocast_2'], ['mana_3'], ['spellblade']]},
+ {level: 40, items: ['focus', 'smite', 'intelligence_3', 'health_2']},
+ {isChoice: true, level: 50, items: [['autocast_3'], ['conjure'], ['ascend'], ['deepFocus']]},
+ ],
+ quests: {
+ stat: [
+ {stat: 'hordeMana', type: 'total', value: 1000},
+ {stat: 'hordeHaste', type: 'total', value: 60},
+ {stat: 'hordeMana', type: 'total', value: 2500},
+ ],
+ zone: [
+ {area: 'warzone', zone: '7'},
+ {area: 'monkeyJungle', zone: '4'},
+ {area: 'monkeyJungle', zone: '11'},
+ {area: 'monkeyJungle', zone: '17'},
+ {area: 'loveIsland', zone: '5'},
+ {area: 'loveIsland', zone: '13'},
+ ],
+ level: [15, 30, 45, 60, 85, 110, 135, 160, 185],
+ boss: [
+ {boss: 'ohilio', difficulty: 12},
+ {boss: 'chriz2', difficulty: 3},
+ {boss: 'mina', difficulty: 25},
+ ]
+ }
+}
diff --git a/src/js/modules/horde/fighterClass/pirate.js b/src/js/modules/horde/fighterClass/pirate.js
new file mode 100644
index 00000000..9b79a3aa
--- /dev/null
+++ b/src/js/modules/horde/fighterClass/pirate.js
@@ -0,0 +1,233 @@
+import { SECONDS_PER_HOUR } from "../../../constants";
+import { buildNum } from "../../../utils/format";
+import { getSequence } from "../../../utils/math";
+
+export default {
+ unlock: 'hordeClassPirate',
+ icon: 'mdi-pirate',
+ baseStats: {
+ attack: 3.3,
+ health: 285,
+ energy: 150,
+ energyRegen: 1,
+ mana: 100,
+ manaRegen: 0.01
+ },
+ exp: {
+ base: 1800,
+ increment: 1.4
+ },
+ courageMult: 35,
+ skills: {
+ challenge: {
+ type: 'passive',
+ color: 'orange-red',
+ icon: 'mdi-ticket',
+ max: 1,
+ effect: [
+ {name: 'currencyHordeLockpickGain', type: 'base', value: lvl => lvl / buildNum(100, 'K')}
+ ]
+ },
+ parrotAttack: {
+ type: 'active',
+ color: 'cyan',
+ icon: 'mdi-bird',
+ max: 1,
+ cooldown: () => 14,
+ activeCost: () => {return {energy: 50};},
+ active() {
+ return [
+ {type: 'maxdamageBio', value: 0.2, int: 0.001},
+ {type: 'damagePhysic', value: 2.6, str: 0.5}
+ ];
+ },
+ activeType: 'combat'
+ },
+ plunder: {
+ type: 'active',
+ color: 'light-green',
+ icon: 'mdi-sack',
+ max: 1,
+ cooldown: () => 60,
+ activeCost: () => {return {mana: 20};},
+ active() {
+ return [
+ {type: 'blood', value: 10}
+ ];
+ },
+ activeType: 'utility'
+ },
+ bottleOBrew: {
+ type: 'active',
+ color: 'pink',
+ icon: 'mdi-bottle-tonic',
+ max: 5,
+ cost: 20,
+ cooldown: () => 180,
+ activeCost: () => {return {mana: 55};},
+ active(lvl) {
+ return [
+ {type: 'buff', value: 30, effect: [
+ {type: 'mult', name: 'hordeAttack', value: lvl * 0.25 + 1.75},
+ {type: 'base', name: 'hordeCritChance', value: 0.4},
+ {type: 'base', name: 'hordeCritMult', value: 1.5},
+ {type: 'mult', name: 'hordePhysicTaken', value: 1 / (lvl * 0.25 + 1.75)},
+ {type: 'mult', name: 'hordeMagicTaken', value: 1 / (lvl * 0.25 + 1.75)},
+ {type: 'mult', name: 'hordeBioTaken', value: 1 / (lvl * 0.25 + 1.75)},
+ {type: 'base', name: 'hordeRecovery', value: 0.25},
+ {type: 'base', name: 'hordeDefense', value: 0.02},
+ ]}
+ ];
+ },
+ activeType: 'combat'
+ },
+ energy: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeEnergy', type: 'base', value: lvl => lvl * 40}
+ ]},
+ mana: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeMana', type: 'base', value: lvl => lvl * 25}
+ ]},
+ blood: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'currencyHordeBloodGain', type: 'mult', value: lvl => getSequence(3, lvl) * 0.08 + 1}
+ ]},
+ courage: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'currencyHordeCourageGain', type: 'mult', value: lvl => lvl * 0.08 + 1}
+ ]},
+ bombToss: {
+ type: 'active',
+ color: 'grey',
+ icon: 'mdi-bomb',
+ max: 5,
+ cost: 20,
+ cooldown: () => 22,
+ activeCost: () => {return {energy: 70};},
+ active(lvl) {
+ return [
+ {type: 'damageMagic', value: lvl + 6.5, int: 0.8}
+ ];
+ },
+ activeType: 'combat'
+ },
+ health: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeHealth', type: 'base', value: lvl => lvl * 40}
+ ]},
+ blood_2: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'currencyHordeBloodGain', type: 'mult', value: lvl => getSequence(3, lvl) * 0.08 + 1}
+ ]},
+ blood_3: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'currencyHordeBloodCap', type: 'mult', value: lvl => Math.pow(1.2, lvl) * (lvl * 0.1 + 1)}
+ ]},
+ lockpick: {type: 'stat', max: 4, cost: 15, effect: [
+ {name: 'currencyHordeLockpickGain', type: 'base', value: lvl => lvl / buildNum(2, 'M')}
+ ]},
+ blood_4: {type: 'stat', max: 20, cost: 10, effect: [
+ {name: 'currencyHordeBloodGain', type: 'mult', value: lvl => getSequence(3, lvl) * 0.05 + 1},
+ {name: 'currencyHordeBloodCap', type: 'mult', value: lvl => getSequence(3, lvl) * 0.05 + 1}
+ ]},
+ courage_2: {type: 'stat', max: 20, cost: 10, effect: [
+ {name: 'currencyHordeCourageGain', type: 'mult', value: lvl => lvl * 0.1 + 1}
+ ]},
+ trinket: {type: 'stat', max: 20, cost: 10, effect: [
+ {name: 'hordeTrinketGain', type: 'mult', value: lvl => lvl * 0.08 + 1}
+ ]},
+ invigoratingBottle: {
+ type: 'active',
+ color: 'amber',
+ icon: 'mdi-bottle-tonic',
+ max: 5,
+ cost: 20,
+ cooldown: (lvl) => 210 - 30 * lvl,
+ activeCost: (lvl) => {return {mana: 50 - 5 * lvl};},
+ active() {
+ return [
+ {type: 'refillEnergy', value: 1}
+ ];
+ },
+ activeType: 'combat'
+ },
+ damage: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeAttack', type: 'base', value: lvl => lvl * 0.1}
+ ]},
+ blood_5: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'currencyHordeBloodCap', type: 'mult', value: lvl => Math.pow(1.2, lvl) * (lvl * 0.1 + 1)}
+ ]},
+ courage_3: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'currencyHordeCourageGain', type: 'mult', value: lvl => lvl * 0.08 + 1}
+ ]},
+ lockpick_2: {type: 'stat', max: 4, cost: 15, effect: [
+ {name: 'currencyHordeLockpickGain', type: 'base', value: lvl => lvl / buildNum(2, 'M')}
+ ]},
+ treasureChest: {
+ type: 'active',
+ color: 'wooden',
+ icon: 'mdi-treasure-chest',
+ max: 5,
+ cost: 20,
+ cooldown: () => 22 * SECONDS_PER_HOUR,
+ activeCost: () => {return {};},
+ active(lvl) {
+ return [
+ {type: 'permanentStat', stat: 'currencyHordeBloodGain_mult', value: lvl * 0.07 + 0.07}
+ ];
+ },
+ activeType: 'utility'
+ },
+ blood_6: {type: 'stat', max: 15, cost: 10, effect: [
+ {name: 'currencyHordeBloodCap', type: 'mult', value: lvl => Math.pow(1.15, lvl) * (getSequence(3, lvl) * 0.1 + 1)}
+ ]},
+ bountyBoard: {
+ type: 'passive',
+ color: 'orange-red',
+ icon: 'mdi-screwdriver',
+ max: 1,
+ cost: 100,
+ effect: [
+ {name: 'currencyHordeLockpickGain', type: 'mult', value: lvl => lvl * 0.25 + 1},
+ {name: 'currencyHordeLockpickCap', type: 'base', value: lvl => lvl * 21},
+ ]
+ },
+ lockpick_3: {type: 'stat', max: 15, cost: 10, effect: [
+ {name: 'currencyHordeLockpickGain', type: 'base', value: lvl => lvl / buildNum(2.5, 'M')}
+ ]},
+ trinket_2: {type: 'stat', max: 25, cost: 10, effect: [
+ {name: 'hordeTrinketGain', type: 'mult', value: lvl => Math.pow(1.05, lvl) * (lvl * 0.08 + 1)},
+ {name: 'hordeTrinketQuality', type: 'base', value: lvl => lvl * -1},
+ ]},
+ haste: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'hordeHaste', type: 'base', value: lvl => lvl * 3}
+ ]},
+ blood_7: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'currencyHordeBloodGain', type: 'mult', value: lvl => getSequence(3, lvl) * 0.08 + 1}
+ ]},
+ blood_8: {type: 'stat', max: 10, cost: 10, effect: [
+ {name: 'currencyHordeBloodCap', type: 'mult', value: lvl => Math.pow(1.2, lvl) * (lvl * 0.1 + 1)}
+ ]},
+ },
+ skillTree: [
+ {isInnate: true, level: 0, items: ['challenge', 'parrotAttack', 'plunder']},
+ {level: 1, items: ['bottleOBrew', 'energy', 'mana', 'blood', 'courage']},
+ {level: 10, items: ['bombToss', 'health', 'blood_2', 'blood_3', 'lockpick']},
+ {isChoice: true, level: 20, items: [['blood_4'], ['courage_2'], ['trinket']]},
+ {level: 30, items: ['invigoratingBottle', 'damage', 'blood_5', 'courage_3', 'lockpick_2']},
+ {isChoice: true, level: 40, items: [['treasureChest', 'blood_6'], ['bountyBoard', 'lockpick_3'], ['trinket_2']]},
+ {level: 50, items: ['haste', 'blood_7', 'blood_8']},
+ ],
+ quests: {
+ stat: [
+ {stat: 'hordeHealth', type: 'base', value: 1200},
+ ],
+ zone: [
+ {area: 'monkeyJungle', zone: '2'},
+ {area: 'monkeyJungle', zone: '8'},
+ {area: 'monkeyJungle', zone: '18'},
+ {area: 'loveIsland', zone: '4'},
+ {area: 'loveIsland', zone: '10'},
+ ],
+ level: [25, 40, 55, 75, 95, 120, 150, 180],
+ boss: [
+ {boss: 'ohilio', difficulty: 30},
+ {boss: 'chriz2', difficulty: 20},
+ {boss: 'mina', difficulty: 5},
+ ]
+ }
+}
diff --git a/src/js/modules/horde/fighterClass/scholar.js b/src/js/modules/horde/fighterClass/scholar.js
new file mode 100644
index 00000000..2082f07e
--- /dev/null
+++ b/src/js/modules/horde/fighterClass/scholar.js
@@ -0,0 +1,22 @@
+export default {
+ unlock: 'hordeClassScholar',
+ icon: 'mdi-school',
+ baseStats: {
+ attack: 2,
+ health: 250
+ },
+ exp: {
+ base: 18000,
+ increment: 2.1
+ },
+ skills: {},
+ skillTree: [
+ {isInnate: true, level: 0, items: []},
+ ],
+ quests: {
+ stat: [],
+ zone: [],
+ level: [],
+ boss: []
+ }
+}
diff --git a/src/js/modules/horde/fighterClass/shaman.js b/src/js/modules/horde/fighterClass/shaman.js
new file mode 100644
index 00000000..3c6074da
--- /dev/null
+++ b/src/js/modules/horde/fighterClass/shaman.js
@@ -0,0 +1,23 @@
+export default {
+ unlock: 'hordeClassShaman',
+ icon: 'mdi-tree',
+ baseStats: {
+ attack: 4.4,
+ health: 575,
+ mana: 150
+ },
+ exp: {
+ base: 4200,
+ increment: 1.425
+ },
+ skills: {},
+ skillTree: [
+ {isInnate: true, level: 0, items: []},
+ ],
+ quests: {
+ stat: [],
+ zone: [],
+ level: [],
+ boss: []
+ }
+}
diff --git a/src/js/modules/horde/fighterClass/undead.js b/src/js/modules/horde/fighterClass/undead.js
new file mode 100644
index 00000000..86375a66
--- /dev/null
+++ b/src/js/modules/horde/fighterClass/undead.js
@@ -0,0 +1,22 @@
+export default {
+ unlock: 'hordeClassUndead',
+ icon: 'mdi-emoticon-dead',
+ baseStats: {
+ attack: 1.8,
+ health: 60
+ },
+ exp: {
+ base: 8400,
+ increment: 1.7
+ },
+ skills: {},
+ skillTree: [
+ {isInnate: true, level: 0, items: []},
+ ],
+ quests: {
+ stat: [],
+ zone: [],
+ level: [],
+ boss: []
+ }
+}
diff --git a/src/js/modules/horde/heirloom.js b/src/js/modules/horde/heirloom.js
index 8e930e99..ffc97b5c 100644
--- a/src/js/modules/horde/heirloom.js
+++ b/src/js/modules/horde/heirloom.js
@@ -34,15 +34,23 @@ export default {
// Tower-exclusive heirlooms
brick: {minZone: Infinity, color: 'cherry', icon: 'mdi-wall', effect: [
- {name: 'currencyHordeBoneGain', type: 'mult', value: lvl => lvl * 0.1 + 1},
- {name: 'hordeCritMult', type: 'base', value: lvl => Math.pow(lvl, 0.5) * 0.01}
+ {name: 'currencyHordeBoneGain', type: 'mult', value: lvl => lvl * 0.05 + 1},
+ {name: 'hordeCritMult', type: 'base', value: lvl => (Math.pow(lvl / 10 + 1, 0.4) - 1) * 0.01}
]},
heat: {minZone: Infinity, color: 'orange-red', icon: 'mdi-fire', effect: [
- {name: 'hordeAttack', type: 'mult', value: lvl => lvl * 0.1 + 1},
- {name: 'hordeCritChance', type: 'base', value: lvl => Math.log(lvl + 1) * 0.01}
+ {name: 'hordeAttack', type: 'mult', value: lvl => lvl * 0.05 + 1},
+ {name: 'hordeCritChance', type: 'base', value: lvl => Math.log(lvl / 10 + 1) * 0.008}
]},
ice: {minZone: Infinity, color: 'skyblue', icon: 'mdi-snowflake-variant', effect: [
- {name: 'hordeHealth', type: 'mult', value: lvl => lvl * 0.1 + 1},
- {name: 'hordeRecovery', type: 'base', value: lvl => Math.log(lvl + 1) * 0.003}
+ {name: 'hordeHealth', type: 'mult', value: lvl => lvl * 0.05 + 1},
+ {name: 'hordeRecovery', type: 'base', value: lvl => Math.log(lvl / 10 + 1) * 0.003}
+ ]},
+ crystal: {minZone: Infinity, color: 'indigo', icon: 'mdi-billiards-rack', effect: [
+ {name: 'hordeShardChance', type: 'mult', value: lvl => lvl * 0.001 + 1},
+ {name: 'currencyHordeMysticalShardCap', type: 'base', value: lvl => Math.floor(Math.log(lvl + 2))}
+ ]},
+ vitality: {minZone: Infinity, color: 'light-green', icon: 'mdi-heart-multiple', effect: [
+ {name: 'currencyHordeBoneCap', type: 'mult', value: lvl => lvl * 0.001 + 1},
+ {name: 'hordeHealing', type: 'mult', value: lvl => Math.log(lvl + 1) * 0.1 + 1}
]},
}
diff --git a/src/js/modules/horde/sigil.js b/src/js/modules/horde/sigil.js
index 6e6fadc6..d7654a79 100644
--- a/src/js/modules/horde/sigil.js
+++ b/src/js/modules/horde/sigil.js
@@ -286,14 +286,13 @@ export default {
color: 'lime',
stats: lvl => {
return {
- health: {type: 'mult', amount: Math.pow(1.1, lvl)},
- bioTaken: {type: 'mult', amount: Math.pow(0.8, lvl)},
+ bioTaken: {type: 'mult', amount: Math.pow(0.75, lvl)},
};
},
active: {
- effect(lvl) {
+ effect(lvl, boss) {
return [
- {type: 'heal', value: lvl * 0.025 + 0.075},
+ {type: 'heal', value: (lvl * 0.025 + 0.075) / bossTimeMult(boss)},
{type: 'antidote', value: 1}
];
},
@@ -311,7 +310,8 @@ export default {
cutting: {type: 'base', amount: 0.002 * lvl},
bioConversion: {type: 'base', amount: 1.5 * lvl},
};
- }
+ },
+ exclude: ['executing']
},
spitting: {
minZone: 56,
@@ -378,7 +378,7 @@ export default {
active: {
effect(lvl) {
return [
- {type: 'raiseAttack', value: lvl * 0.05 + 0.2}
+ {type: 'gainStat', stat: 'attack_mult', value: lvl * 0.05 + 1.2}
];
},
cooldown: () => 15,
@@ -432,7 +432,7 @@ export default {
effect(lvl) {
return [
{type: 'damagePhysic', value: lvl * 0.6 + 1.55},
- {type: 'raiseAttack', value: 0.03}
+ {type: 'gainStat', stat: 'attack_mult', value: 1.03}
];
},
cooldown: () => 4,
@@ -546,6 +546,29 @@ export default {
uses: (lvl, boss) => lvl * bossTimeMult(boss)
}
},
+ defense: {
+ minZone: 225,
+ icon: 'mdi-shield',
+ color: 'dark-blue',
+ stats: lvl => {
+ return {
+ health: {type: 'mult', amount: Math.pow(1.15, lvl)},
+ defense: {type: 'base', amount: lvl * 0.001},
+ };
+ }
+ },
+ executing: {
+ minZone: 275,
+ icon: 'mdi-skull',
+ color: 'pale-red',
+ stats: lvl => {
+ return {
+ attack: {type: 'mult', amount: Math.pow(1.15, lvl)},
+ execute: {type: 'base', amount: lvl * 0.05},
+ };
+ },
+ exclude: ['sharp']
+ },
// Tower-only sigils
berserk: {
diff --git a/src/js/modules/horde/sigil_boss.js b/src/js/modules/horde/sigil_boss.js
new file mode 100644
index 00000000..48f6e3fa
--- /dev/null
+++ b/src/js/modules/horde/sigil_boss.js
@@ -0,0 +1,371 @@
+import { buildNum } from "../../utils/format";
+
+export default {
+ // Regular enemy actives
+ pistol_gun: {
+ minZone: Infinity,
+ icon: 'mdi-pistol',
+ color: 'blue',
+ active: {
+ effect() {
+ return [
+ {type: 'damagePhysic', value: 3.35}
+ ];
+ },
+ cooldown: () => 4,
+ startCooldown: () => 4,
+ uses: lvl => lvl * 4
+ }
+ },
+ rifle_gun: {
+ minZone: Infinity,
+ icon: 'mdi-pistol',
+ color: 'orange',
+ active: {
+ effect() {
+ return [
+ {type: 'damagePhysic', value: 2},
+ {type: 'damageMagic', value: 0.75}
+ ];
+ },
+ cooldown: () => 2,
+ startCooldown: () => 2,
+ uses: lvl => lvl * 6
+ }
+ },
+ shotgun_gun: {
+ minZone: Infinity,
+ icon: 'mdi-pistol',
+ color: 'green',
+ active: {
+ effect() {
+ return [
+ {type: 'damagePhysic', value: 2.6},
+ {type: 'damageMagic', value: 2.6},
+ {type: 'damageBio', value: 2.6}
+ ];
+ },
+ cooldown: () => 13,
+ startCooldown: () => 13,
+ uses: lvl => lvl * 2
+ }
+ },
+ sniper_gun: {
+ minZone: Infinity,
+ icon: 'mdi-target',
+ color: 'purple',
+ active: {
+ effect() {
+ return [
+ {type: 'damagePhysic', value: 11.5, canCrit: 8}
+ ];
+ },
+ cooldown: () => 25,
+ startCooldown: () => 25,
+ uses: lvl => lvl * 1
+ }
+ },
+ war_grenade: {
+ minZone: Infinity,
+ icon: 'mdi-bomb',
+ color: 'pale-green',
+ active: {
+ effect() {
+ return [
+ {type: 'damageMagic', value: 2.75},
+ {type: 'stun', value: 2},
+ {type: 'silence', value: 8}
+ ];
+ },
+ cooldown: () => 12,
+ startCooldown: () => 6,
+ uses: lvl => lvl
+ }
+ },
+ war_bandage: {
+ minZone: Infinity,
+ icon: 'mdi-bandage',
+ color: 'pale-orange',
+ active: {
+ effect() {
+ return [
+ {type: 'heal', value: 0.4}
+ ];
+ },
+ cooldown: () => 8,
+ startCooldown: () => 4,
+ uses: lvl => lvl
+ }
+ },
+ monkey_dart: {
+ minZone: Infinity,
+ icon: 'mdi-arrow-projectile',
+ color: 'orange',
+ active: {
+ effect(lvl) {
+ return [
+ {type: 'damagePhysic', value: lvl * 0.5 + 2.25},
+ ];
+ },
+ cooldown: () => 5,
+ startCooldown: () => 3,
+ uses: () => null
+ }
+ },
+ monkey_fire: {
+ minZone: Infinity,
+ icon: 'mdi-fire',
+ color: 'orange',
+ active: {
+ effect() {
+ return [
+ {type: 'damageMagic', value: 4.5},
+ ];
+ },
+ cooldown: () => 8,
+ startCooldown: () => 4,
+ uses: lvl => lvl * 4
+ }
+ },
+ monkey_ice: {
+ minZone: Infinity,
+ icon: 'mdi-snowflake',
+ color: 'cyan',
+ active: {
+ effect() {
+ return [
+ {type: 'damageMagic', value: 6.75},
+ {type: 'stun', value: 3},
+ ];
+ },
+ cooldown: () => 14,
+ startCooldown: () => 7,
+ uses: lvl => lvl * 2
+ }
+ },
+ monkey_lightning: {
+ minZone: Infinity,
+ icon: 'mdi-flash',
+ color: 'yellow',
+ active: {
+ effect() {
+ return [
+ {type: 'damageMagic', value: 5.1},
+ {type: 'silence', value: 3},
+ ];
+ },
+ cooldown: () => 10,
+ startCooldown: () => 5,
+ uses: lvl => lvl * 3
+ }
+ },
+ cute_ram: {
+ minZone: Infinity,
+ icon: 'mdi-arrow-collapse-right',
+ color: 'red',
+ active: {
+ effect(lvl) {
+ return [
+ {type: 'damageBio', value: lvl + 3.5},
+ {type: 'stun', value: 3},
+ {type: 'gainStat', stat: 'bioAttack_mult', value: 1.2},
+ ];
+ },
+ cooldown: () => 12,
+ startCooldown: () => 8,
+ uses: lvl => lvl * 3
+ }
+ },
+ cute_eatCarrot: {
+ minZone: Infinity,
+ icon: 'mdi-carrot',
+ color: 'orange',
+ active: {
+ effect(lvl) {
+ return [
+ {type: 'heal', value: lvl * 0.05 + 0.4},
+ {type: 'gainStat', stat: 'attack_mult', value: 1.1},
+ ];
+ },
+ cooldown: () => 16,
+ startCooldown: () => 12,
+ uses: lvl => lvl * 2
+ }
+ },
+ cute_bark: {
+ minZone: Infinity,
+ icon: 'mdi-volume-high',
+ color: 'cyan',
+ active: {
+ effect() {
+ return [
+ {type: 'maxdamageBio', value: 0.06},
+ {type: 'removeDivisionShield', value: 1},
+ ];
+ },
+ cooldown: () => 11,
+ startCooldown: () => 6,
+ uses: lvl => lvl
+ }
+ },
+ cute_bite: {
+ minZone: Infinity,
+ icon: 'mdi-tooth',
+ color: 'brown',
+ active: {
+ effect(lvl) {
+ return [
+ {type: 'damageBio', value: lvl * 1.5 + 5},
+ ];
+ },
+ cooldown: () => 22,
+ startCooldown: () => 8,
+ uses: () => null
+ }
+ },
+ cute_kick: {
+ minZone: Infinity,
+ icon: 'mdi-seat-legroom-extra',
+ color: 'amber',
+ active: {
+ effect(lvl) {
+ return [
+ {type: 'damageBio', value: lvl * 0.3 + 2.5},
+ {type: 'silence', value: 2},
+ ];
+ },
+ cooldown: () => 6,
+ startCooldown: () => 0,
+ uses: lvl => lvl * 8
+ }
+ },
+ cute_claws: {
+ minZone: Infinity,
+ icon: 'mdi-nail',
+ color: 'light-green',
+ active: {
+ effect(lvl) {
+ return [
+ {type: 'maxdamageBio', value: 0.1},
+ {type: 'damageBio', value: lvl * 1.3 + 4.5},
+ ];
+ },
+ cooldown: () => 15,
+ startCooldown: () => 10,
+ uses: lvl => lvl * 3
+ }
+ },
+
+ // Boss actives
+ ohilio_megagun: {
+ minZone: Infinity,
+ icon: 'mdi-pistol',
+ color: 'orange-red',
+ active: {
+ effect() {
+ return [
+ {type: 'damagePhysic', value: buildNum(1, 'M')},
+ {type: 'damageMagic', value: buildNum(1, 'M')},
+ {type: 'damageBio', value: buildNum(1, 'M')}
+ ];
+ },
+ cooldown: () => 5,
+ startCooldown: () => 5,
+ uses: () => null
+ }
+ },
+ chriz_magicMissile: {
+ minZone: Infinity,
+ icon: 'mdi-motion',
+ color: 'indigo',
+ active: {
+ effect() {
+ return [
+ {type: 'damageMagic', value: 3},
+ ];
+ },
+ cooldown: () => 6,
+ startCooldown: () => 0,
+ uses: () => 25
+ }
+ },
+ chriz_fireball: {
+ minZone: Infinity,
+ icon: 'mdi-fire',
+ color: 'orange',
+ active: {
+ effect() {
+ return [
+ {type: 'damageMagic', value: 11.5},
+ ];
+ },
+ cooldown: () => 22,
+ startCooldown: () => 4,
+ uses: () => null
+ }
+ },
+ chriz_iceBlast: {
+ minZone: Infinity,
+ icon: 'mdi-snowflake',
+ color: 'cyan',
+ active: {
+ effect() {
+ return [
+ {type: 'damageMagic', value: 6},
+ {type: 'stun', value: 8},
+ ];
+ },
+ cooldown: () => 30,
+ startCooldown: () => 10,
+ uses: () => null
+ }
+ },
+ chriz_lightningStrike: {
+ minZone: Infinity,
+ icon: 'mdi-flash',
+ color: 'yellow',
+ active: {
+ effect() {
+ return [
+ {type: 'damageMagic', value: 7.25},
+ {type: 'silence', value: 5},
+ ];
+ },
+ cooldown: () => 15,
+ startCooldown: () => 15,
+ uses: () => null
+ }
+ },
+ chriz_heal: {
+ minZone: Infinity,
+ icon: 'mdi-medical-bag',
+ color: 'light-green',
+ active: {
+ effect() {
+ return [
+ {type: 'heal', value: 0.4},
+ ];
+ },
+ cooldown: () => 45,
+ startCooldown: () => 45,
+ uses: () => 3
+ }
+ },
+ mina_charm: {
+ minZone: Infinity,
+ icon: 'mdi-heart',
+ color: 'pink',
+ active: {
+ effect() {
+ return [
+ {type: 'silence', value: 5},
+ {type: 'gainStat', stat: 'bioAttack_mult', value: 1.6},
+ {type: 'gainStat', stat: 'execute_base', value: 0.05},
+ ];
+ },
+ cooldown: () => 30,
+ startCooldown: () => 15,
+ uses: () => null
+ }
+ },
+}
diff --git a/src/js/modules/horde/tower.js b/src/js/modules/horde/tower.js
index f4f1e83e..df4b5b4f 100644
--- a/src/js/modules/horde/tower.js
+++ b/src/js/modules/horde/tower.js
@@ -11,7 +11,9 @@ export default {
100: {type: 'mult', name: 'hordeHealth', value: 1.5},
150: {type: 'mult', name: 'currencyHordeMonsterPartCap', value: 1.35},
200: {type: 'base', name: 'hordeNostalgia', value: 50},
- 250: {type: 'unlock', name: 'hordeUpgradeRoyalButcher', value: true},
+ 300: {type: 'unlock', name: 'hordeUpgradeRoyalButcher', value: true},
+ 400: {type: 'base', name: 'hordeNostalgia', value: 50},
+ 500: {type: 'mult', name: 'currencyHordeBoneCap', value: 1.5},
},
},
fire: {
@@ -26,6 +28,8 @@ export default {
100: {type: 'base', name: 'hordeMaxItems', value: 1},
150: {type: 'mult', name: 'hordeAttack', value: 1.35},
200: {type: 'base', name: 'hordeCritMult', value: 0.2},
+ 300: {type: 'mult', name: 'currencyHordeBoneCap', value: 1.5},
+ 400: {type: 'mult', name: 'currencyHordeMonsterPartCap', value: 1.35},
},
},
ice: {
@@ -39,6 +43,37 @@ export default {
50: {type: 'mult', name: 'currencyHordeBoneGain', value: 1.5},
100: {type: 'unlock', name: 'hordeUpgradeRoyalCrypt', value: true},
150: {type: 'mult', name: 'currencyHordeSoulCorruptedGain', value: 1.2},
+ 200: {type: 'base', name: 'hordeMaxSacrifice', value: 1},
+ 300: {type: 'mult', name: 'hordeHealth', value: 1.5},
+ },
+ },
+ danger: {
+ unlock: 'hordeDangerTower',
+ sigils: ['executing', 'focus', 'nuke', 'precision', 'power'],
+ statBase: 245,
+ statScaling: 0.4,
+ crowns: 5,
+ heirlooms: ['crystal'],
+ reward: {
+ 50: {type: 'unlock', name: 'hordeUpgradeRoyalSecret', value: true},
+ 100: {type: 'mult', name: 'hordeAttack', value: 1.5},
+ 150: {type: 'base', name: 'currencyHordeMysticalShardCap', value: 5},
+ 200: {type: 'mult', name: 'hordeAttack', value: 1.5},
+ 300: {type: 'base', name: 'currencyHordeMysticalShardCap', value: 5},
+ },
+ },
+ toxic: {
+ unlock: 'hordeToxicTower',
+ sigils: ['toxic', 'foulBreath', 'drain', 'spitting', 'sharp'],
+ statBase: 290,
+ statScaling: 0.45,
+ crowns: 8,
+ heirlooms: ['vitality'],
+ reward: {
+ 50: {type: 'base', name: 'hordeMaxSacrifice', value: 1},
+ 100: {type: 'mult', name: 'hordeHealth', value: 1.5},
+ 150: {type: 'mult', name: 'hordeHealing', value: 1.2},
+ 200: {type: 'mult', name: 'hordeAttack', value: 1.5},
},
},
}
diff --git a/src/js/modules/horde/trinket.js b/src/js/modules/horde/trinket.js
new file mode 100644
index 00000000..eff43a8d
--- /dev/null
+++ b/src/js/modules/horde/trinket.js
@@ -0,0 +1,136 @@
+const needsEnergy = true;
+const needsMana = true;
+
+export default {
+ vitality: {color: 'green', icon: 'mdi-heart', effect: [
+ {name: 'hordeHealth', type: 'base', value: lvl => lvl * 70 + 30}
+ ]},
+ energy: {color: 'amber', icon: 'mdi-lightning-bolt', needsEnergy, effect: [
+ {name: 'hordeEnergy', type: 'base', value: lvl => lvl * 35 + 20}
+ ]},
+ magic: {color: 'blue', icon: 'mdi-water', needsMana, effect: [
+ {name: 'hordeMana', type: 'base', value: lvl => lvl * 25 + 15}
+ ]},
+ fists: {
+ color: 'orange-red',
+ icon: 'mdi-arm-flex',
+ needsEnergy,
+ cooldown: () => 15,
+ activeCost: () => {return {energy: 25};},
+ active(lvl) {
+ return [
+ {type: 'damagePhysic', value: lvl * 0.4 + 3.1, str: 0.15}
+ ];
+ },
+ activeType: 'combat'
+ },
+ sparks: {
+ color: 'light-blue',
+ icon: 'mdi-shimmer',
+ rarity: 10,
+ needsMana,
+ cooldown: () => 9,
+ activeCost: () => {return {mana: 5};},
+ active(lvl) {
+ return [
+ {type: 'damageMagic', value: lvl * 0.55 + 3.65, int: 0.2}
+ ];
+ },
+ activeType: 'combat'
+ },
+ haste: {color: 'pale-yellow', icon: 'mdi-timer-sand', rarity: 20, effect: [
+ {name: 'hordeHaste', type: 'base', value: lvl => lvl * 4 + 8}
+ ]},
+ precision: {color: 'orange', icon: 'mdi-bullseye', rarity: 30, effect: [
+ {name: 'hordeCritChance', type: 'base', value: lvl => lvl * 0.03 + 0.07}
+ ]},
+ wrath: {color: 'orange-red', icon: 'mdi-emoticon-angry', rarity: 40, effect: [
+ {name: 'hordeCritMult', type: 'base', value: lvl => lvl * 0.08 + 0.3}
+ ]},
+ strength: {color: 'red', icon: 'mdi-arm-flex', rarity: 50, effect: [
+ {name: 'hordeStrength', type: 'base', value: lvl => lvl * 3 + 5}
+ ]},
+ toxins: {
+ color: 'light-green',
+ icon: 'mdi-clouds',
+ rarity: 60,
+ cooldown: () => 135,
+ activeCost: () => {return {};},
+ active(lvl) {
+ return [
+ {type: 'maxdamageBio', value: lvl * 0.015 + 0.09},
+ {type: 'removeAttack', value: lvl * 0.005 + 0.05}
+ ];
+ },
+ activeType: 'combat'
+ },
+ wisdom: {color: 'indigo', icon: 'mdi-lightbulb-on', rarity: 70, effect: [
+ {name: 'hordeIntelligence', type: 'base', value: lvl => lvl * 3 + 5}
+ ]},
+ extraction: {color: 'red', icon: 'mdi-water', rarity: 80, effect: [
+ {name: 'currencyHordeBloodGain', type: 'mult', value: lvl => lvl * 0.04 + 1.16}
+ ]},
+ learning: {color: 'deep-purple', icon: 'mdi-school', rarity: 90, isTimeless: true, effect: [
+ {name: 'hordeSkillPointsPerLevel', type: 'base', value: () => 1}
+ ]},
+ preservation: {color: 'red', icon: 'mdi-iv-bag', rarity: 100, effect: [
+ {name: 'currencyHordeBloodCap', type: 'mult', value: lvl => lvl * 0.06 + 1.24}
+ ]},
+ energize: {
+ color: 'amber',
+ icon: 'mdi-battery',
+ rarity: 110,
+ isTimeless: true,
+ needsEnergy,
+ cooldown: () => 270,
+ activeCost: () => {return {};},
+ active() {
+ return [
+ {type: 'refillEnergy', value: 1}
+ ];
+ },
+ activeType: 'combat'
+ },
+ automation: {color: 'dark-grey', icon: 'mdi-cogs', rarity: 120, isTimeless: true, effect: [
+ {name: 'hordeAutocast', type: 'base', value: () => 1}
+ ]},
+ cure: {
+ color: 'teal',
+ icon: 'mdi-heart',
+ rarity: 130,
+ isTimeless: true,
+ cooldown: () => 45,
+ activeCost: () => {return {};},
+ active() {
+ return [
+ {type: 'heal', value: 0.05, int: 0.0005},
+ {type: 'removeStun', value: null}
+ ];
+ },
+ usableInStun: true,
+ activeType: 'combat'
+ },
+
+ // Boss-specific trinkets
+ duality: {color: 'purple', icon: 'mdi-call-split', rarity: 75, uniqueToBoss: 'chriz2', effect: [
+ {name: 'hordeStrength', type: 'base', value: lvl => lvl * 2 + 4},
+ {name: 'hordeIntelligence', type: 'base', value: lvl => lvl * 2 + 4}
+ ]},
+ love: {
+ color: 'babypink',
+ icon: 'mdi-heart-multiple',
+ rarity: 120,
+ uniqueToBoss: 'mina',
+ cooldown: () => 70,
+ activeCost: () => {return {};},
+ active(lvl) {
+ return [
+ {type: 'damageBio', value: lvl * 0.9 + 8.7},
+ {type: 'buff', value: lvl + 14, effect: [
+ {type: 'mult', name: 'hordeBioAttack', value: 1.35},
+ ]}
+ ];
+ },
+ activeType: 'combat'
+ },
+}
diff --git a/src/js/modules/horde/upgrade.js b/src/js/modules/horde/upgrade.js
index 751c8c2d..0c0f065e 100644
--- a/src/js/modules/horde/upgrade.js
+++ b/src/js/modules/horde/upgrade.js
@@ -154,6 +154,12 @@ export default {
{name: 'currencyHordeBoneGain', type: 'mult', value: lvl => Math.pow(4, lvl)},
{name: 'currencyHordeBoneCap', type: 'mult', value: lvl => Math.pow(1000, lvl)}
]},
+ combatLesson: {cap: 15, requirementBase, requirementStat, requirementValue: 120, price(lvl) {
+ return {horde_bone: Math.pow(lvl * 0.4 + 3.4, lvl) * buildNum(650, 'SpD')};
+ }, effect: [
+ {name: 'hordeAttack', type: 'mult', value: lvl => Math.pow(1.25, lvl)},
+ {name: 'hordeHealth', type: 'mult', value: lvl => Math.pow(1.22, lvl)}
+ ]},
carving: {cap: 5, capMult: true, requirementBase, requirementStat, requirementValue: 125, price(lvl) {
return {horde_bone: Math.pow(12, lvl) * buildNum(2, 'ND')};
}, effect: [
@@ -164,10 +170,38 @@ export default {
return {horde_mysticalShard: 25 * (lvl + 1)};
}, effect: [
{name: 'hordeMaxItems', type: 'base', value: lvl => lvl}
- ]},
- collector: {requirementBase, requirementStat, requirementValue: 175, price(lvl) {
- return {horde_mysticalShard: lvl * 8 + 45};
- }, effect: [
- {name: 'currencyHordeBoneGain', type: 'mult', value: lvl => Math.pow(1.75, lvl)}
- ]},
+ ], onBuy() {
+ store.dispatch('horde/checkPlayerHealth');
+ }},
+ unlimitedAnger: {cap: 20, requirementBase, requirementStat, requirementValue: 145, price(lvl) {
+ return {horde_bone: Math.pow(lvl * 0.1 + 4.7, lvl) * buildNum(4, 'QaV')};
+ }, effect: [
+ {name: 'hordeAttack', type: 'mult', value: lvl => Math.pow(1.2, lvl)}
+ ]},
+ strangePower: {requirementBase, requirementStat, requirementValue: 155, price(lvl) {
+ return {horde_mysticalShard: lvl * 4 + 28};
+ }, effect: [
+ {name: 'hordeAttack', type: 'mult', value: lvl => Math.pow(1.35, lvl)},
+ {name: 'hordeHealth', type: 'mult', value: lvl => Math.pow(1.35, lvl)}
+ ], onBuy() {
+ store.dispatch('horde/checkPlayerHealth');
+ }},
+ collector: {requirementBase, requirementStat, requirementValue: 165, price(lvl) {
+ return {horde_mysticalShard: lvl * 8 + 34};
+ }, effect: [
+ {name: 'currencyHordeBoneGain', type: 'mult', value: lvl => Math.pow(1.65, lvl)},
+ {name: 'currencyHordeBoneCap', type: 'mult', value: lvl => Math.pow(1.85, lvl)}
+ ], onBuy() {
+ store.dispatch('horde/checkPlayerHealth');
+ }},
+ prepareTheSacrifice: {persistent: true, alwaysActive: true, cap: 4, requirementBase, requirementStat, requirementValue: 175, price(lvl) {
+ return {horde_mysticalShard: lvl * 40 + 20};
+ }, effect: [
+ {name: 'horde_mysticalBag', type: 'keepUpgrade', value: lvl => lvl >= 1},
+ {name: 'horde_strangePower', type: 'keepUpgrade', value: lvl => lvl >= 2},
+ {name: 'horde_collector', type: 'keepUpgrade', value: lvl => lvl >= 3},
+ {name: 'hordeSacrifice', type: 'unlock', value: lvl => lvl >= 4},
+ ], onBuy() {
+ store.dispatch('horde/checkPlayerHealth');
+ }},
}
diff --git a/src/js/modules/horde/upgrade2.js b/src/js/modules/horde/upgrade2.js
new file mode 100644
index 00000000..c4dc395c
--- /dev/null
+++ b/src/js/modules/horde/upgrade2.js
@@ -0,0 +1,70 @@
+import store from "../../../store";
+import { buildNum } from "../../utils/format";
+import { getSequence } from "../../utils/math";
+
+const requirementBase = () => store.getters['horde/battlePassCurrentLevel'];
+
+export default {
+ transfusion: {subfeature: 1, cap: 50, price(lvl) {
+ return {horde_blood: Math.pow(1.3, lvl) * 300};
+ }, effect: [
+ {name: 'hordeAttack', type: 'mult', value: lvl => getSequence(5, lvl) * 0.02 + 1},
+ {name: 'hordeHealth', type: 'mult', value: lvl => getSequence(5, lvl) * 0.02 + 1}
+ ]},
+ darkAttack: {subfeature: 1, requirementBase, requirementValue: 1, price(lvl) {
+ return {horde_blood: Math.pow(lvl * 0.0025 + 1.325, lvl) * buildNum(24, 'K')};
+ }, effect: [
+ {name: 'hordeAttack', type: 'mult', value: lvl => Math.pow(1.18, lvl)}
+ ]},
+ darkHealth: {subfeature: 1, requirementBase, requirementValue: 3, price(lvl) {
+ return {horde_blood: Math.pow(lvl * 0.0025 + 1.325, lvl) * buildNum(110, 'K')};
+ }, effect: [
+ {name: 'hordeHealth', type: 'mult', value: lvl => Math.pow(1.19, lvl)}
+ ]},
+ harvest: {subfeature: 1, requirementBase, requirementValue: 8, price(lvl) {
+ return {horde_blood: Math.pow(lvl * 0.003 + 1.45, lvl) * buildNum(3, 'M')};
+ }, effect: [
+ {name: 'currencyHordeBloodGain', type: 'mult', value: lvl => Math.pow(1.11, lvl)}
+ ]},
+ protectiveShell: {subfeature: 1, cap: 20, requirementBase, requirementValue: 14, price(lvl) {
+ return {horde_blood: Math.pow(2.35, lvl) * buildNum(190, 'M')};
+ }, effect: [
+ {name: 'hordeAttack', type: 'mult', value: lvl => Math.pow(1.07, lvl)},
+ {name: 'hordeHealth', type: 'mult', value: lvl => Math.pow(1.14, lvl)}
+ ]},
+ bloodStorage: {subfeature: 1, cap: 20, requirementBase, requirementValue: 18, price(lvl) {
+ return {horde_blood: Math.pow(lvl * 0.04 + 1.9, lvl) * buildNum(2.2, 'B')};
+ }, effect: [
+ {name: 'hordeHealth', type: 'mult', value: lvl => Math.pow(1.1, lvl)},
+ {name: 'currencyHordeBloodCap', type: 'mult', value: lvl => Math.pow(1.175, lvl)}
+ ]},
+ darkMilestone: {subfeature: 1, requirementBase, requirementValue: 24, price(lvl) {
+ return {horde_blood: Math.pow(1000, lvl) * buildNum(1, 'T')};
+ }, effect: [
+ {name: 'hordeAttack', type: 'mult', value: lvl => Math.pow(3, lvl)},
+ {name: 'hordeHealth', type: 'mult', value: lvl => Math.pow(3, lvl)},
+ {name: 'currencyHordeBloodCap', type: 'mult', value: lvl => Math.pow(10, lvl)}
+ ]},
+ endlessAnger: {subfeature: 1, cap: 20, requirementBase, requirementValue: 31, price(lvl) {
+ return {horde_blood: Math.pow(2.8, lvl) * buildNum(25, 'Qi')};
+ }, effect: [
+ {name: 'hordeAttack', type: 'mult', value: lvl => Math.pow(1.33, lvl)}
+ ]},
+ fistFight: {subfeature: 1, cap: 30, requirementBase, requirementValue: 42, price(lvl) {
+ return {horde_blood: Math.pow(2.45, lvl) * buildNum(400, 'Sx')};
+ }, effect: [
+ {name: 'currencyHordeBloodGain', type: 'mult', value: lvl => Math.pow(1.1, lvl)},
+ {name: 'hordeAttack', type: 'mult', value: lvl => Math.pow(1.23, lvl)}
+ ]},
+ syringe: {subfeature: 1, cap: 30, requirementBase, requirementValue: 55, price(lvl) {
+ return {horde_blood: Math.pow(lvl * 0.02 + 1.7, lvl) * buildNum(65, 'Sp')};
+ }, effect: [
+ {name: 'currencyHordeBloodGain', type: 'mult', value: lvl => Math.pow(1.15, lvl)},
+ {name: 'currencyHordeBloodCap', type: 'mult', value: lvl => Math.pow(1.18, lvl)}
+ ]},
+ bloodRitual: {subfeature: 1, requirementBase, requirementValue: 70, price(lvl) {
+ return {horde_blood: Math.pow(10, lvl) * buildNum(1, 'O')};
+ }, effect: [
+ {name: 'hordeCorruption', type: 'bonus', value: lvl => -0.07 * lvl}
+ ]},
+}
diff --git a/src/js/modules/horde/upgradePrestige.js b/src/js/modules/horde/upgradePrestige.js
index 2b28801c..18eb90b7 100644
--- a/src/js/modules/horde/upgradePrestige.js
+++ b/src/js/modules/horde/upgradePrestige.js
@@ -4,6 +4,7 @@ import { getSequence } from "../../utils/math";
const requirementStat = 'horde_maxZone';
const requirementBase = () => store.state.stat[requirementStat].total;
+const requirementBase2 = () => store.getters['horde/battlePassCurrentLevel'];
export default {
wrath: {type: 'prestige', cap: 10, price(lvl) {
@@ -31,7 +32,7 @@ export default {
{name: 'currencyHordeMonsterPartGain', type: 'base', value: lvl => lvl * 0.05},
{name: 'currencyHordeMonsterPartCap', type: 'base', value: lvl => lvl * 30}
]},
- beginnerLuck: {type: 'prestige', requirementBase, requirementStat, requirementValue: 26, price(lvl) {
+ beginnerLuck: {type: 'prestige', cap: 120, requirementBase, requirementStat, requirementValue: 26, price(lvl) {
return {horde_soulEmpowered: Math.pow(1.9, lvl) * 375};
}, effect: [
{name: 'hordeItemChance', type: 'mult', value: lvl => lvl * 0.2 + 1},
@@ -46,16 +47,16 @@ export default {
advancedLuck: {type: 'prestige', requirementBase, requirementStat, requirementValue: 36, price(lvl) {
return {horde_soulEmpowered: Math.pow(1.9, lvl) * 4250};
}, effect: [
- {name: 'hordeHeirloomChance', type: 'mult', value: lvl => Math.min(lvl * 0.05 + 1, 3)},
+ {name: 'hordeHeirloomChance', type: 'base', value: lvl => Math.min(lvl * 0.0025, 0.1)},
{name: 'hordeNostalgia', type: 'base', value: lvl => lvl * 5}
]},
- boneTrader: {type: 'prestige', requirementBase, requirementStat, requirementValue: 41, price(lvl) {
+ boneTrader: {type: 'prestige', cap: 150, requirementBase, requirementStat, requirementValue: 41, price(lvl) {
return {horde_soulEmpowered: Math.pow(1.65, lvl) * buildNum(18.5, 'K')};
}, effect: [
{name: 'currencyHordeBoneGain', type: 'mult', value: lvl => Math.pow(1.3, lvl)},
{name: 'currencyHordeMonsterPartCap', type: 'mult', value: lvl => Math.pow(1.1, lvl)}
]},
- soulCage: {type: 'prestige', requirementBase, requirementStat, requirementValue: 46, price(lvl) {
+ soulCage: {type: 'prestige', cap: 80, requirementBase, requirementStat, requirementValue: 46, price(lvl) {
return {horde_soulEmpowered: Math.pow(2.35, lvl) * buildNum(65, 'K')};
}, effect: [
{name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: lvl => lvl * 0.05 + 1},
@@ -64,12 +65,12 @@ export default {
offenseBook: {type: 'prestige', cap: 50, requirementBase, requirementStat, requirementValue: 51, price(lvl) {
return {horde_soulEmpowered: Math.pow(1.3, lvl) * buildNum(350, 'K')};
}, effect: [
- {name: 'hordeAttack', type: 'mult', value: lvl => Math.pow(1.1, lvl) * (lvl * 0.15 + 1)}
+ {name: 'powerHeirloomEffect', type: 'mult', value: lvl => Math.pow(1.1, lvl) * (lvl * 0.15 + 1)}
]},
defenseBook: {type: 'prestige', cap: 50, requirementBase, requirementStat, requirementValue: 56, price(lvl) {
return {horde_soulEmpowered: Math.pow(1.3, lvl) * buildNum(1.25, 'M')};
}, effect: [
- {name: 'hordeHealth', type: 'mult', value: lvl => Math.pow(1.1, lvl) * (lvl * 0.15 + 1)}
+ {name: 'fortitudeHeirloomEffect', type: 'mult', value: lvl => Math.pow(1.1, lvl) * (lvl * 0.15 + 1)}
]},
ashCircle: {type: 'prestige', requirementBase, requirementStat, requirementValue: 61, price(lvl) {
return {horde_soulEmpowered: Math.pow(lvl * 0.02 + 1.25, lvl) * buildNum(9, 'M')};
@@ -93,7 +94,7 @@ export default {
{name: 'currencyHordeBoneCap', type: 'mult', value: lvl => Math.pow(1.2, lvl)},
{name: 'hordeHeirloomEffect', type: 'mult', value: lvl => lvl * 0.03 + 1}
]},
- mausoleum: {type: 'prestige', requirementBase, requirementStat, requirementValue: 91, price(lvl) {
+ mausoleum: {type: 'prestige', cap: 80, requirementBase, requirementStat, requirementValue: 91, price(lvl) {
return {horde_soulEmpowered: Math.pow(lvl * 0.005 + 1.4, lvl) * buildNum(2.4, 'T')};
}, effect: [
{name: 'currencyHordeBoneGain', type: 'mult', value: lvl => Math.pow(1.3, lvl)},
@@ -103,13 +104,28 @@ export default {
combatStudies: {type: 'prestige', requirementBase, requirementStat, requirementValue: 111, price(lvl) {
return {horde_soulEmpowered: Math.pow(1.45 + lvl * 0.025, lvl) * buildNum(85, 'Qa')};
}, effect: [
- {name: 'hordeItemMasteryGain', type: 'mult', value: lvl => Math.pow(1.2, lvl)}
+ {name: 'hordeItemMasteryGain', type: 'mult', value: lvl => Math.pow(1.1, lvl) * (lvl * 0.1 + 1)}
]},
boneChamber: {type: 'prestige', requirementBase, requirementStat, requirementValue: 131, price(lvl) {
return {horde_soulEmpowered: Math.pow(2.7 + lvl * 0.05, lvl) * buildNum(275, 'Qi')};
}, effect: [
{name: 'currencyHordeBoneCap', type: 'mult', value: lvl => Math.pow(2, lvl)}
]},
+ deepHatred: {type: 'prestige', cap: 30, requirementBase, requirementStat, requirementValue: 151, price(lvl) {
+ return {horde_soulEmpowered: Math.pow(lvl * 0.02 + 1.6, lvl) * buildNum(2.25, 'Sx')};
+ }, effect: [
+ {name: 'hordeAttack', type: 'mult', value: lvl => Math.pow(1.1, lvl) * (lvl * 0.18 + 1)}
+ ]},
+ spiritLure: {type: 'prestige', cap: 50, requirementBase, requirementStat, requirementValue: 181, price(lvl) {
+ return {horde_soulEmpowered: Math.pow(1.25, lvl) * buildNum(333, 'Sp')};
+ }, effect: [
+ {name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: lvl => lvl * 0.08 + 1}
+ ]},
+ mysticalCondenser: {type: 'prestige', requirementBase, requirementStat, requirementValue: 211, price(lvl) {
+ return {horde_soulEmpowered: Math.pow(lvl * 0.1 + 2, lvl) * buildNum(15, 'N')};
+ }, effect: [
+ {name: 'currencyHordeMysticalShardCap', type: 'base', value: lvl => lvl}
+ ]},
// Royal upgrades
royalSword: {type: 'prestige', requirementBase, requirementStat, requirementValue: 140, price(lvl) {
@@ -147,4 +163,80 @@ export default {
{name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: lvl => getSequence(5, lvl) * 0.01 + 1},
{name: 'currencyHordeSoulCorruptedCap', type: 'mult', value: lvl => getSequence(5, lvl) * 0.01 + 1}
]},
+ royalSecret: {type: 'prestige', requirement() {
+ return store.state.unlock.hordeUpgradeRoyalSecret.use;
+ }, price(lvl) {
+ return {horde_crown: Math.round(Math.pow(1.08, lvl) * (lvl + 1) * 222)};
+ }, effect: [
+ {name: 'currencyHordeMysticalShardCap', type: 'base', value: lvl => lvl}
+ ]},
+
+ precision: {type: 'prestige', requirement() {
+ return store.state.unlock.hordeClassesSubfeature.see;
+ }, price(lvl) {
+ return {horde_courage: Math.pow(lvl * 0.01 + 1.55, lvl) * 1000};
+ }, effect: [
+ {name: 'hordeAttack', type: 'mult', value: lvl => Math.pow(1.15, lvl)}
+ ]},
+ resolve: {type: 'prestige', requirement() {
+ return store.state.unlock.hordeClassesSubfeature.see;
+ }, price(lvl) {
+ return {horde_courage: Math.pow(lvl * 0.01 + 1.55, lvl) * 1250};
+ }, effect: [
+ {name: 'hordeHealth', type: 'mult', value: lvl => Math.pow(1.15, lvl)}
+ ]},
+ determination: {type: 'prestige', requirementBase: requirementBase2, requirementValue: 7, price(lvl) {
+ return {horde_courage: Math.pow(lvl * 0.02 + 2.35, lvl) * 6000};
+ }, effect: [
+ {name: 'currencyHordeSoulCorruptedGain', type: 'mult', value: lvl => Math.pow(1.08, lvl)},
+ {name: 'currencyHordeCourageGain', type: 'mult', value: lvl => Math.pow(1.08, lvl)}
+ ]},
+ education: {type: 'prestige', requirementBase: requirementBase2, requirementValue: 10, price(lvl) {
+ return {horde_courage: Math.pow(lvl * 0.01 + 1.6, lvl) * buildNum(11, 'K')};
+ }, effect: [
+ {name: 'hordeExpBase', type: 'mult', value: lvl => Math.pow(1 / 1.1, lvl)}
+ ]},
+ bloodChamber: {type: 'prestige', requirementBase: requirementBase2, requirementValue: 12, price(lvl) {
+ return {horde_courage: Math.pow(lvl * 0.05 + 2.5, lvl) * buildNum(16, 'K')};
+ }, effect: [
+ {name: 'currencyHordeBoneCap', type: 'mult', value: lvl => Math.pow(1.75, lvl)},
+ {name: 'currencyHordeBloodCap', type: 'mult', value: lvl => Math.pow(1.5, lvl)}
+ ]},
+ stoneSkin: {type: 'prestige', requirementBase: requirementBase2, requirementValue: 16, price(lvl) {
+ return {horde_courage: Math.pow(lvl + 5, lvl) * buildNum(70, 'K')};
+ }, effect: [
+ {name: 'hordeHealth', type: 'mult', value: lvl => Math.pow(1.5, lvl)},
+ {name: 'hordeHealing', type: 'mult', value: lvl => Math.pow(1 / 1.2, lvl)}
+ ]},
+ university: {type: 'prestige', requirementBase: requirementBase2, requirementValue: 20, price(lvl) {
+ return {horde_courage: Math.pow(lvl * 0.01 + 1.85, lvl) * buildNum(250, 'K')};
+ }, effect: [
+ {name: 'hordeExpIncrement', type: 'mult', value: lvl => Math.pow(1 / 1.1, lvl)}
+ ]},
+ discovery: {type: 'prestige', requirementBase: requirementBase2, requirementValue: 27, price(lvl) {
+ return {horde_courage: Math.pow(lvl * 0.25 + 4, lvl) * buildNum(5, 'M')};
+ }, effect: [
+ {name: 'hordeHeirloomAmount', type: 'base', value: lvl => lvl},
+ {name: 'hordeTrinketGain', type: 'mult', value: lvl => lvl * 0.1 + 1}
+ ]},
+ innerFocus: {type: 'prestige', requirementBase: requirementBase2, requirementValue: 33, price(lvl) {
+ return {horde_courage: Math.pow(lvl * 0.5 + 2, lvl) * buildNum(28, 'M')};
+ }, effect: [
+ {name: 'hordeHealing', type: 'mult', value: lvl => Math.pow(1.1, lvl)}
+ ]},
+ purge: {type: 'prestige', requirementBase: requirementBase2, requirementValue: 45, price(lvl) {
+ return {horde_courage: Math.pow(lvl * 0.015 + 1.25, lvl) * buildNum(150, 'B')};
+ }, effect: [
+ {name: 'hordeCorruption', type: 'base', value: lvl => lvl * -0.09}
+ ]},
+ chaosCrate: {type: 'prestige', cap: 10, requirementBase: requirementBase2, requirementValue: 65, price(lvl) {
+ return {horde_courage: Math.pow(10, lvl) * buildNum(1, 'Qa')};
+ }, effect: [
+ {name: 'hordeAttack', type: 'mult', value: lvl => Math.pow(1.35, lvl)},
+ {name: 'hordeItemChance', type: 'mult', value: lvl => lvl >= 1 ? (Math.floor((lvl + 4) / 5) * 0.5 + 1) : null},
+ {name: 'hordeHeirloomAmount', type: 'base', value: lvl => lvl >= 2 ? (Math.floor((lvl + 3) / 5) * 5) : null},
+ {name: 'hordeItemMasteryGain', type: 'mult', value: lvl => lvl >= 3 ? (Math.floor((lvl + 2) / 5) * 0.5 + 1) : null},
+ {name: 'currencyHordeMysticalShardCap', type: 'base', value: lvl => lvl >= 4 ? (Math.floor((lvl + 1) / 5) * 10) : null},
+ {name: 'hordeSkillPointsPerLevel', type: 'base', value: lvl => lvl >= 5 ? Math.floor(lvl / 5) : null},
+ ]},
}
diff --git a/src/js/modules/meta.js b/src/js/modules/meta.js
index 96d9123c..c6324432 100644
--- a/src/js/modules/meta.js
+++ b/src/js/modules/meta.js
@@ -18,6 +18,11 @@ import v1_3_5 from "./patchnote/v1_3_5";
import v1_4_0 from "./patchnote/v1_4_0";
import v1_3_6 from "./patchnote/v1_3_6";
import v1_4_1 from "./patchnote/v1_4_1";
+import v1_5_0 from "./patchnote/v1_5_0";
+import v1_4_2 from "./patchnote/v1_4_2";
+import v1_5_1 from "./patchnote/v1_5_1";
+import v1_5_2 from "./patchnote/v1_5_2";
+import v1_5_3 from "./patchnote/v1_5_3";
export default {
name: 'meta',
@@ -53,6 +58,11 @@ export default {
store.commit('system/initTheme', {name: key, ...elem});
}
for (const [key, elem] of Object.entries({
+ '1.5.3': v1_5_3,
+ '1.5.2': v1_5_2,
+ '1.5.1': v1_5_1,
+ '1.5.0': v1_5_0,
+ '1.4.2': v1_4_2,
'1.4.1': v1_4_1,
'1.4.0': v1_4_0,
'1.3.6': v1_3_6,
diff --git a/src/js/modules/migration/helper.js b/src/js/modules/migration/helper.js
index 12e0b279..bcfd0b60 100644
--- a/src/js/modules/migration/helper.js
+++ b/src/js/modules/migration/helper.js
@@ -1,4 +1,4 @@
-export { addCurrencyToSave, raiseUpgradeLevel, removeUpgrade, removeCurrency, refundCurrency, replaceTreasureEffect, removeRelic }
+export { addCurrencyToSave, raiseUpgradeLevel, lowerUpgradeLevel, removeUpgrade, removeCurrency, refundCurrency, replaceTreasureEffect, applyTreasureFilter, removeRelic }
function addCurrencyToSave(save, currency, amount) {
if (save.currency[currency] === undefined) {
@@ -32,6 +32,22 @@ function raiseUpgradeLevel(save, name, amount) {
return save;
}
+function lowerUpgradeLevel(save, name, max) {
+ if (save.upgrade[name] !== undefined) {
+ if (save.upgrade[name][1] > max) {
+ save.upgrade[name][1] = max;
+ }
+ if (save.upgrade[name][2] > max) {
+ save.upgrade[name][2] = max;
+ }
+ if (save.upgrade[name].length >= 4 && save.upgrade[name][3] > max) {
+ save.upgrade[name][3] = max;
+ }
+ }
+
+ return save;
+}
+
function removeUpgrade(save, name) {
if (save.upgrade[name] !== undefined) {
delete save.upgrade[name];
@@ -51,7 +67,7 @@ function removeCurrency(save, name) {
function refundCurrency(save, name) {
if (save.currency[name] !== undefined && save.stat[name] !== undefined) {
- save.currency[name] = save.stat[name].total;
+ save.currency[name] = save.stat[name][1];
}
return save;
}
@@ -70,6 +86,20 @@ function replaceTreasureEffect(save, oldName, newName) {
return save;
}
+function applyTreasureFilter(save, filter) {
+ if (save.treasure) {
+ if (save.treasure.newItem) {
+ save.treasure.newItem = filter(save.treasure.newItem);
+ }
+ save.treasure.items.forEach(treasure => {
+ if (treasure) {
+ treasure = filter(treasure);
+ }
+ });
+ }
+ return save;
+}
+
function removeRelic(save, name) {
if (save.relic) {
save.relic = save.relic.filter(elem => elem !== name);
diff --git a/src/js/modules/migration/v1_3_0.js b/src/js/modules/migration/v1_3_0.js
index 055c272d..f91e131d 100644
--- a/src/js/modules/migration/v1_3_0.js
+++ b/src/js/modules/migration/v1_3_0.js
@@ -1,5 +1,5 @@
import store from "../../../store";
-import { refundCurrency, removeCurrency, removeRelic, removeUpgrade, replaceTreasureEffect } from "./helper";
+import { removeCurrency, removeRelic, removeUpgrade, replaceTreasureEffect } from "./helper";
export default function(save) {
if (save.horde) {
@@ -54,7 +54,9 @@ export default function(save) {
});
save = removeCurrency(save, 'horde_bone');
- save = refundCurrency(save, 'horde_soulEmpowered');
+ if (save.currency.horde_soulEmpowered !== undefined && save.stat.horde_soulEmpowered !== undefined) {
+ save.currency.horde_soulEmpowered = save.stat.horde_soulEmpowered.total;
+ }
// Multiply all souls by 1000 to match the new increased gains
if (save.currency.horde_soulCorrupted !== undefined) {
diff --git a/src/js/modules/migration/v1_5_0.js b/src/js/modules/migration/v1_5_0.js
new file mode 100644
index 00000000..de0b40fc
--- /dev/null
+++ b/src/js/modules/migration/v1_5_0.js
@@ -0,0 +1,197 @@
+import { filterUnique } from "../../utils/array";
+import { applyTreasureFilter, lowerUpgradeLevel, refundCurrency, removeCurrency, removeUpgrade, replaceTreasureEffect } from "./helper";
+
+export default function(save) {
+ // Add anticheat variables
+ save.cheaterSelfMark = 0;
+ save.cheatDetected = {};
+
+ // Lower upgrade levels to new cap
+ save = lowerUpgradeLevel(save, 'mining_crystalRefinery', 50);
+ save = lowerUpgradeLevel(save, 'mining_crystalSalt', 50);
+ save = lowerUpgradeLevel(save, 'mining_crystalSmeltery', 100);
+ save = lowerUpgradeLevel(save, 'mining_crystalEnhancer', 25);
+ save = lowerUpgradeLevel(save, 'horde_beginnerLuck', 120);
+ save = lowerUpgradeLevel(save, 'horde_boneTrader', 150);
+ save = lowerUpgradeLevel(save, 'horde_soulCage', 80);
+ save = lowerUpgradeLevel(save, 'horde_mausoleum', 80);
+ save = lowerUpgradeLevel(save, 'farm_goldenTools', 5);
+
+ // Rename best prestige stats
+ if (save.stat.village_bestPrestige !== undefined) {
+ save.stat.village_bestPrestige0 = save.stat.village_bestPrestige;
+ delete save.stat.village_bestPrestige;
+ }
+ if (save.stat.horde_bestPrestige !== undefined) {
+ save.stat.horde_bestPrestige0 = save.stat.horde_bestPrestige;
+ delete save.stat.horde_bestPrestige;
+ }
+
+ // Respec tier 4 offerings
+ if (save.village && save.village.offering && (save.village.offering.knowledge !== undefined || save.village.offering.science !== undefined || save.village.offering.joy !== undefined)) {
+ let spent = 0;
+ ['plantFiber', 'wood', 'stone'].forEach(elem => {
+ if (save.village.offering[elem] !== undefined) {
+ spent += save.village.offering[elem].upgradeBought;
+ }
+ });
+ ['coin', 'metal', 'water'].forEach(elem => {
+ if (save.village.offering[elem] !== undefined) {
+ spent += save.village.offering[elem].upgradeBought * 3;
+ }
+ });
+ ['glass', 'hardwood', 'gem'].forEach(elem => {
+ if (save.village.offering[elem] !== undefined) {
+ spent += save.village.offering[elem].upgradeBought * 8;
+ }
+ });
+ save.currency.village_offering = save.stat.village_offering[1] - spent;
+ if (save.village.offering.knowledge !== undefined) {
+ save.village.offering.knowledge.upgradeBought = 0;
+ }
+ if (save.village.offering.science !== undefined) {
+ save.village.offering.science.upgradeBought = 0;
+ }
+ if (save.village.offering.joy !== undefined) {
+ save.village.offering.joy.upgradeBought = 0;
+ }
+ }
+
+ if (save.horde) {
+ // Convert enemy status
+ if (save.horde.enemy !== undefined) {
+ save.horde.enemy.defense = 0;
+ save.horde.enemy.execute = 0;
+ }
+
+ // Convert item stat multipliers
+ if (save.horde.itemStatMult !== undefined) {
+ let newObj = {};
+ for (const [key, elem] of Object.entries(save.horde.itemStatMult)) {
+ newObj[key + '_mult'] = elem;
+ }
+ save.horde.itemStatMult = newObj;
+ }
+
+ if (save.horde.items?.starShield) {
+ save.horde.items.starShield.level = 1;
+ }
+
+ // Unequip all equipment
+ if (save.horde.items) {
+ for (const [, elem] of Object.entries(save.horde.items)) {
+ if (elem.equipped) {
+ elem.equipped = false;
+ }
+ }
+ }
+ }
+
+ if (save.farm?.crop) {
+ for (const [, elem] of Object.entries(save.farm.crop)) {
+ if (elem.rareDrop) {
+ let newDrop = {};
+ elem.rareDrop.forEach(key => {
+ newDrop[key] = 0;
+ });
+ elem.rareDrop = newDrop;
+ }
+ }
+ }
+
+ // Rename fruit to berries
+ if (save.currency.farm_fruit !== undefined) {
+ save.currency.farm_berry = save.currency.farm_fruit;
+ }
+ if (save.stat.farm_fruit !== undefined) {
+ save.stat.farm_berry = save.stat.farm_fruit;
+ }
+ save = removeCurrency(save, 'farm_fruit');
+ save = replaceTreasureEffect(save, 'currencyFarmFruitGain', 'currencyFarmBerryGain');
+ if (save.upgrade.farm_biggerFruits !== undefined) {
+ save.upgrade.farm_biggerBerries = save.upgrade.farm_biggerFruits;
+ save = removeUpgrade(save, 'farm_biggerFruits');
+ }
+
+ // Remove excess gold
+ if (save.currency.farm_gold !== undefined && save.currency.farm_gold > 1000) {
+ save.currency.farm_gold = 1000;
+ }
+ if (save.stat.farm_gold !== undefined && save.stat.farm_gold[0] > 20759) {
+ save.stat.farm_gold = [20759, 20759];
+ }
+
+ // Remove excess mystery stones
+ if (save.currency.farm_mysteryStone !== undefined) {
+ const newAmount = Math.ceil(save.currency.farm_mysteryStone / 100);
+ save.currency.farm_mysteryStone = newAmount;
+ save.stat.farm_mysteryStone = [newAmount, newAmount];
+ }
+
+ // Give increased amount of event fertilizer
+ if (save.consumable) {
+ ['farm_sunshine', 'farm_superFlower', 'farm_smellyMud', 'farm_tropicalWater', 'farm_fieldBlessing', 'farm_cinnamonBag'].forEach(elem => {
+ if (save.consumable[elem] !== undefined && save.consumable[elem] > 0) {
+ save.consumable[elem] *= 4;
+ }
+ });
+ }
+
+ // Respec gallery prestige upgrades
+ [
+ 'artAcademy', 'redCrayon', 'rainbowJar', 'trashContainer', 'orangeCrayon',
+ 'headstart', 'forklift', 'redCrate', 'yellowCrayon', 'inspiringBooks',
+ 'expressDelivery', 'orangeCrate', 'greenCrayon', 'sortingSystem',
+ 'redTruck', 'yellowCrate', 'blueCrayon', 'orangeTruck', 'greenCrate',
+ 'purpleCrayon'
+ ].forEach(name => {
+ save = removeUpgrade(save, 'gallery_' + name);
+ });
+ save = refundCurrency(save, 'gallery_cash');
+
+ // Remove 1 tier from event treasure
+ save = applyTreasureFilter(save, treasure => {
+ if (treasure.type === 'empowered' && treasure.tier > 0) {
+ treasure.tier--;
+ }
+ return treasure;
+ });
+
+ // Update horde soul stats to prevent false positives from the anticheat
+ if (save.currency.horde_soulCorrupted !== undefined && save.stat.horde_soulCorrupted !== undefined && save.currency.horde_soulCorrupted > save.stat.horde_soulCorrupted[1]) {
+ save.stat.horde_soulCorrupted[1] = save.currency.horde_soulCorrupted;
+ }
+ if (save.currency.horde_soulEmpowered !== undefined && save.stat.horde_soulEmpowered !== undefined && save.currency.horde_soulEmpowered > save.stat.horde_soulEmpowered[1]) {
+ save.stat.horde_soulEmpowered[1] = save.currency.horde_soulEmpowered;
+ }
+
+ // Remove duplicate cards
+ if (save.card) {
+ for (const [key, elem] of Object.entries(save.card.feature)) {
+ save.card.feature[key].cardSelected = filterUnique(elem.cardSelected);
+ save.card.feature[key].cardEquipped = filterUnique(elem.cardEquipped);
+ }
+ }
+
+ // Award event highscores
+ if (save.stat.event_cindersToken !== undefined) {
+ save.stat.event_cindersHighscore = [0, save.stat.event_cindersToken[1]];
+ }
+ if (save.stat.event_bloomToken !== undefined) {
+ save.stat.event_bloomHighscore = [0, save.stat.event_bloomToken[1]];
+ }
+ if (save.stat.event_weatherChaosToken !== undefined) {
+ save.stat.event_weatherChaosHighscore = [0, save.stat.event_weatherChaosToken[1]];
+ }
+ if (save.stat.event_summerFestivalToken !== undefined) {
+ save.stat.event_summerFestivalHighscore = [0, Math.min(save.stat.event_summerFestivalToken[1], 492)];
+ }
+ if (save.stat.event_nightHuntToken !== undefined) {
+ save.stat.event_nightHuntHighscore = [0, save.stat.event_nightHuntToken[1]];
+ }
+ if (save.stat.event_snowdownToken !== undefined) {
+ save.stat.event_snowdownHighscore = [0, save.stat.event_snowdownToken[1]];
+ }
+
+ return save;
+}
diff --git a/src/js/modules/migration/v1_5_1.js b/src/js/modules/migration/v1_5_1.js
new file mode 100644
index 00000000..b8e943be
--- /dev/null
+++ b/src/js/modules/migration/v1_5_1.js
@@ -0,0 +1,24 @@
+export default function(save) {
+ // Use new school subject format
+ if (save.school) {
+ for (const [key, elem] of Object.entries(save.school)) {
+ save.school[key] = [elem.grade, elem.currentGrade, elem.progress];
+ }
+ }
+
+ // Use new smeltery format
+ if (save.mining && save.mining.smeltery) {
+ for (const [key, elem] of Object.entries(save.mining.smeltery)) {
+ save.mining.smeltery[key] = [elem.progress, elem.stored, elem.total];
+ }
+ }
+
+ // Use new offering format
+ if (save.village && save.village.offering) {
+ for (const [key, elem] of Object.entries(save.village.offering)) {
+ save.village.offering[key] = [elem.offeringBought, elem.upgradeBought];
+ }
+ }
+
+ return save;
+}
diff --git a/src/js/modules/migration/v1_5_3.js b/src/js/modules/migration/v1_5_3.js
new file mode 100644
index 00000000..100da33e
--- /dev/null
+++ b/src/js/modules/migration/v1_5_3.js
@@ -0,0 +1,73 @@
+import { deltaLinear } from "../../utils/math";
+import { replaceTreasureEffect } from "./helper";
+
+export default function(save) {
+ // Repeat offering respec for bugged savefiles
+ if (save.village && save.village.offering) {
+ let spent = 0;
+ let spentWithoutT4 = 0;
+ ['plantFiber', 'wood', 'stone'].forEach(elem => {
+ if (save.village.offering[elem] !== undefined) {
+ spent += save.village.offering[elem][1];
+ spentWithoutT4 += save.village.offering[elem][1];
+ }
+ });
+ ['coin', 'metal', 'water'].forEach(elem => {
+ if (save.village.offering[elem] !== undefined) {
+ spent += save.village.offering[elem][1] * 3;
+ spentWithoutT4 += save.village.offering[elem][1] * 3;
+ }
+ });
+ ['glass', 'hardwood', 'gem'].forEach(elem => {
+ if (save.village.offering[elem] !== undefined) {
+ spent += save.village.offering[elem][1] * 8;
+ spentWithoutT4 += save.village.offering[elem][1] * 8;
+ }
+ });
+ ['knowledge', 'science', 'joy'].forEach(elem => {
+ if (save.village.offering[elem] !== undefined) {
+ spent += deltaLinear(20, 1, save.village.offering[elem][1]);
+ }
+ });
+ let missing = save.stat.village_offering[1] - spent;
+ if (missing < 0) {
+ // Reset T4 offerings only if you do not have enough offerings to pay for them
+ if (save.village.offering.knowledge !== undefined) {
+ save.village.offering.knowledge[1] = 0;
+ }
+ if (save.village.offering.science !== undefined) {
+ save.village.offering.science[1] = 0;
+ }
+ if (save.village.offering.joy !== undefined) {
+ save.village.offering.joy[1] = 0;
+ }
+ missing = save.stat.village_offering[1] - spentWithoutT4;
+ }
+ save.currency.village_offering = missing;
+ }
+
+ // Fix event shops selling old treasure effect
+ if (save.event && save.event.shop_merchant) {
+ for (const [key, elem] of Object.entries(save.event.shop_merchant)) {
+ if (elem.data && elem.data.effect) {
+ const index = elem.data.effect.indexOf("currencyFarmFruitGain");
+ if (index !== -1) {
+ save.event.shop_merchant[key].data.effect[index] = "currencyFarmBerryGain";
+ }
+ }
+ }
+ }
+ if (save.event && save.event.shop_big) {
+ for (const [key, elem] of Object.entries(save.event.shop_big)) {
+ if (elem.data && elem.data.effect) {
+ const index = elem.data.effect.indexOf("currencyFarmFruitGain");
+ if (index !== -1) {
+ save.event.shop_big[key].data.effect[index] = "currencyFarmBerryGain";
+ }
+ }
+ }
+ }
+ save = replaceTreasureEffect(save, 'currencyFarmFruitGain', 'currencyFarmBerryGain');
+
+ return save;
+}
diff --git a/src/js/modules/mining.js b/src/js/modules/mining.js
index a4f89a6f..09e5a271 100644
--- a/src/js/modules/mining.js
+++ b/src/js/modules/mining.js
@@ -1,8 +1,10 @@
import store from "../../store"
-import { MINING_COAL_DEPTH, MINING_DWELLER_OVERCAP_MULT, MINING_DWELLER_OVERFLOW, MINING_GRANITE_DEPTH, MINING_NITER_DEPTH, MINING_OBSIDIAN_DEPTH, MINING_ORE_BREAK, MINING_RARE_DROP_BREAK, MINING_SALT_DEPTH, MINING_SCRAP_BREAK, MINING_SMOKE_BREAK, MINING_SULFUR_DEPTH } from "../constants";
+import { MINING_COAL_DEPTH, MINING_DEEPROCK_DEPTH, MINING_DWELLER_OVERCAP_MULT, MINING_DWELLER_OVERFLOW, MINING_GRANITE_DEPTH, MINING_NITER_DEPTH, MINING_OBSIDIAN_DEPTH, MINING_ORE_BREAK, MINING_RARE_DROP_BREAK, MINING_SALT_DEPTH, MINING_SCRAP_BREAK, MINING_SMOKE_BREAK, MINING_SULFUR_DEPTH } from "../constants";
import { buildArray } from "../utils/array";
import { buildNum } from "../utils/format";
+import { digitSum } from "../utils/math";
import achievement from "./mining/achievement";
+import beacon from "./mining/beacon";
import enhancement from "./mining/enhancement";
import ore from "./mining/ore";
import relic from "./mining/relic";
@@ -104,6 +106,9 @@ function awardLoot(breaks, loots, hits) {
if (gotLoot && depth >= MINING_OBSIDIAN_DEPTH && store.getters['mining/enhancementLevel'] <= 0) {
store.dispatch('currency/gain', {feature: 'mining', name: 'obsidian', amount: store.getters['mining/rareDropFinal']('obsidian') * (MINING_RARE_DROP_BREAK * breaks + loots)});
}
+ if (gotLoot && depth >= MINING_DEEPROCK_DEPTH && digitSum(depth) >= 14) {
+ store.dispatch('currency/gain', {feature: 'mining', name: 'deeprock', amount: store.getters['mining/rareDropFinal']('deeprock') * (MINING_RARE_DROP_BREAK * breaks + loots)});
+ }
}
if (breaks > 0) {
store.commit('mining/addBreaks', {depth: store.state.mining.depth, amount: breaks});
@@ -119,6 +124,10 @@ export default {
store.commit('stat/add', {feature: 'mining', name: 'timeSpent', value: seconds});
+ if (store.state.mining.beaconCooldown > 0) {
+ store.commit('mining/updateKey', {key: 'beaconCooldown', value: Math.max(store.state.mining.beaconCooldown - seconds, 0)});
+ }
+
// Smeltery
for (const [key, elem] of Object.entries(store.state.mining.smeltery)) {
if (elem.stored > 0) {
@@ -144,74 +153,82 @@ export default {
}
// Mining
- let secondsLeft = seconds;
- while (secondsLeft > 0) {
- const maxDepth = store.state.stat[`mining_maxDepth${subfeature}`].value;
+ if (store.getters['mining/currentDamage'] > 0) {
+ let secondsLeft = seconds;
+ while (secondsLeft > 0) {
+ const maxDepth = store.state.stat[`mining_maxDepth${subfeature}`].value;
- let breaks = 0;
- let loots = 0;
- let preHits = Math.min(secondsLeft, store.getters['mining/currentHitsNeeded']);
+ let breaks = 0;
+ let loots = 0;
+ let preHits = Math.min(secondsLeft, store.getters['mining/currentHitsNeeded']);
- if (store.state.mining.depth < maxDepth) {
- loots += preHits;
- }
- secondsLeft -= preHits;
+ if (store.state.mining.depth < maxDepth) {
+ loots += preHits;
+ }
+ secondsLeft -= preHits;
- store.commit('stat/increaseTo', {feature: 'mining', name: 'maxDamage', value: store.getters['mining/currentDamage']});
- store.commit('stat/add', {feature: 'mining', name: 'totalDamage', value: preHits * store.getters['mining/currentDamage']});
+ store.commit('stat/increaseTo', {feature: 'mining', name: 'maxDamage', value: store.getters['mining/currentDamage']});
+ store.commit('stat/add', {feature: 'mining', name: 'totalDamage', value: preHits * store.getters['mining/currentDamage']});
- let newDurability = store.state.mining.durability - preHits * store.getters['mining/currentDamage'];
+ let newDurability = store.state.mining.durability - preHits * store.getters['mining/currentDamage'];
- if (newDurability <= 0) {
- breaks++;
- let isLatest = maxDepth === store.state.mining.depth;
- if (isLatest) {
- // Get gasses for the first time
- for (const [key, elem] of Object.entries(store.getters['mining/currentGas'])) {
- store.dispatch('currency/gain', {feature: 'mining', name: key, amount: elem});
- }
+ if (newDurability <= 0) {
+ breaks++;
+ let isLatest = maxDepth === store.state.mining.depth;
+ if (isLatest) {
+ // Get gasses for the first time
+ for (const [key, elem] of Object.entries(store.getters['mining/currentGas'])) {
+ store.dispatch('currency/gain', {feature: 'mining', name: key, amount: elem});
+ }
- // also count the first break as loot
- loots++;
- store.commit('stat/increaseTo', {feature: 'mining', name: 'maxDepth' + subfeature, value: store.state.mining.depth + 1});
- store.dispatch('meta/globalLevelPart', {key: 'mining_' + subfeature, amount: store.state.stat[`mining_maxDepth${subfeature}`].total - 1});
+ // also count the first break as loot
+ loots++;
+ store.commit('stat/increaseTo', {feature: 'mining', name: 'maxDepth' + subfeature, value: store.state.mining.depth + 1});
+ store.dispatch('meta/globalLevelPart', {key: 'mining_' + subfeature, amount: store.state.stat[`mining_maxDepth${subfeature}`].total - 1});
- // Find notes based on depth
- if (subfeature === 0) {
- const note = notes[store.state.stat.mining_maxDepth0.total - 1];
- if (note !== undefined) {
- store.dispatch('note/find', note);
+ // Find notes based on depth
+ if (subfeature === 0) {
+ const note = notes[store.state.stat.mining_maxDepth0.total - 1];
+ if (note !== undefined) {
+ store.dispatch('note/find', note);
+ }
}
- }
- // Speedrun stat
- if (store.state.stat.mining_timeSpent.value <= 900 && subfeature === 0) {
- store.commit('stat/increaseTo', {feature: 'mining', name: 'maxDepthSpeedrun', value: store.state.mining.depth + 1});
- }
+ // Speedrun stat
+ if (store.state.stat.mining_timeSpent.value <= 900 && subfeature === 0) {
+ store.commit('stat/increaseTo', {feature: 'mining', name: 'maxDepthSpeedrun', value: store.state.mining.depth + 1});
+ }
- // Update dweller stat
- store.dispatch('mining/updateDwellerStat');
- }
- if (
- isLatest &&
- store.getters['mining/depthHitsNeeded'](store.state.mining.depth + 1) <= (store.state.system.settings.automation.items.progressMining.value ?? 0)
- ) {
- awardLoot(breaks, loots, preHits);
- store.commit('mining/updateKey', {key: 'depth', value: store.state.mining.depth + 1});
- newDurability = store.getters['mining/currentDurability'];
+ // Update dweller stat
+ store.dispatch('mining/updateDwellerStat');
+ }
+ if (
+ isLatest &&
+ store.getters['mining/depthHitsNeeded'](store.state.mining.depth + 1) <= (store.state.system.settings.automation.items.progressMining.value ?? 0)
+ ) {
+ awardLoot(breaks, loots, preHits);
+ store.commit('mining/updateKey', {key: 'depth', value: store.state.mining.depth + 1});
+ newDurability = store.getters['mining/currentDurability'];
+ store.dispatch('mining/applyBeaconEffects');
+ } else {
+ store.commit('stat/add', {feature: 'mining', name: 'totalDamage', value: secondsLeft * store.getters['mining/currentDamage']});
+ breaks += Math.floor(secondsLeft / store.getters['mining/hitsNeeded']);
+ loots += secondsLeft;
+ newDurability = store.getters['mining/currentDurability'] - store.getters['mining/currentDamage'] * (secondsLeft % store.getters['mining/hitsNeeded']);
+ awardLoot(breaks, loots, preHits + secondsLeft);
+ secondsLeft = 0;
+ }
} else {
- store.commit('stat/add', {feature: 'mining', name: 'totalDamage', value: secondsLeft * store.getters['mining/currentDamage']});
- breaks += Math.floor(secondsLeft / store.getters['mining/hitsNeeded']);
- loots += secondsLeft;
- newDurability = store.getters['mining/currentDurability'] - store.getters['mining/currentDamage'] * (secondsLeft % store.getters['mining/hitsNeeded']);
- awardLoot(breaks, loots, preHits + secondsLeft);
- secondsLeft = 0;
+ awardLoot(breaks, loots, preHits);
}
- } else {
- awardLoot(breaks, loots, preHits);
- }
- store.commit('mining/updateKey', {key: 'durability', value: newDurability});
+ store.commit('mining/updateKey', {key: 'durability', value: newDurability});
+ }
+ } else {
+ // Sulfur gain
+ if (store.state.mining.depth >= MINING_SULFUR_DEPTH && store.getters['mining/currentBreaks'] === 0) {
+ store.dispatch('currency/gain', {feature: 'mining', name: 'sulfur', amount: store.getters['mining/rareDropFinal']('sulfur') * seconds});
+ }
}
// Depth dweller
@@ -252,28 +269,29 @@ export default {
},
unlock: ['miningPickaxeCrafting', 'miningDepthDweller', 'miningSmeltery', 'miningEnhancement', 'miningResin', 'miningGasSubfeature', 'miningSmoke'],
stat: {
- maxDepth0: {value: 1},
- maxDepth1: {value: 1},
+ maxDepth0: {value: 1, showInStatistics: true},
+ maxDepth1: {value: 1, showInStatistics: true},
depthDweller0: {},
- depthDwellerCap0: {},
+ depthDwellerCap0: {showInStatistics: true},
depthDweller1: {},
- depthDwellerCap1: {},
- totalDamage: {},
- maxDamage: {},
- craftingCount: {},
+ depthDwellerCap1: {showInStatistics: true},
+ totalDamage: {showInStatistics: true},
+ maxDamage: {showInStatistics: true},
+ craftingCount: {showInStatistics: true},
craftingLuck: {value: 1},
craftingWasted: {},
dwellerCapHit: {},
timeSpent: {display: 'time'},
- bestPrestige0: {},
- bestPrestige1: {},
- prestigeCount: {},
+ bestPrestige0: {showInStatistics: true},
+ bestPrestige1: {showInStatistics: true},
+ prestigeCount: {showInStatistics: true},
maxDepthSpeedrun: {value: 1}
},
mult: {
miningDamage: {},
miningToughness: {},
miningOreGain: {},
+ miningOreCap: {},
miningRareEarthGain: {},
miningPickaxeCraftingSlots: {round: true, baseValue: 1},
miningPickaxePremiumCraftingSlots: {round: true},
@@ -292,10 +310,12 @@ export default {
miningSmelterySpeed: {baseValue: 1},
miningSmelteryTemperature: {display: 'temperature', baseValue: 100},
miningEnhancementBarsIncrement: {display: 'percent', baseValue: 0.75, min: 0},
- miningEnhancementFinalIncrement: {display: 'percent', baseValue: 3, min: 0}
+ miningEnhancementFinalIncrement: {display: 'percent', baseValue: 3, min: 0},
+ miningPrestigeIncome: {group: ['currencyMiningCrystalGreenGain', 'currencyMiningCrystalYellowGain']}
},
multGroup: [
{mult: 'miningOreGain', name: 'currencyGain', subtype: 'ore'},
+ {mult: 'miningOreCap', name: 'currencyCap', subtype: 'ore'},
{mult: 'miningRareEarthGain', name: 'currencyGain', subtype: 'rareEarth'}
],
currency: {
@@ -338,12 +358,23 @@ export default {
const oreGain = store.getters['mining/currentOre'];
return (hitsNeeded === Infinity || !oreGain.oreIridium) ? null : (((hitsNeeded + MINING_ORE_BREAK) * oreGain.oreIridium.amount) / hitsNeeded);
}, timerIsEstimate: true},
+ oreOsmium: {subtype: 'ore', color: 'pale-green', icon: 'mdi-chart-bubble', gainMult: {}, capMult: {baseValue: 1, round: true}, gainTimerFunction() {
+ const hitsNeeded = store.getters['mining/hitsNeeded'];
+ const oreGain = store.getters['mining/currentOre'];
+ return (hitsNeeded === Infinity || !oreGain.oreOsmium) ? null : (((hitsNeeded + MINING_ORE_BREAK) * oreGain.oreOsmium.amount) / hitsNeeded);
+ }, timerIsEstimate: true},
+ oreLead: {subtype: 'ore', color: 'pale-blue', icon: 'mdi-chart-bubble', gainMult: {}, capMult: {baseValue: 1, round: true}, gainTimerFunction() {
+ const hitsNeeded = store.getters['mining/hitsNeeded'];
+ const oreGain = store.getters['mining/currentOre'];
+ return (hitsNeeded === Infinity || !oreGain.oreLead) ? null : (((hitsNeeded + MINING_ORE_BREAK) * oreGain.oreLead.amount) / hitsNeeded);
+ }, timerIsEstimate: true},
barAluminium: {subtype: 'bar', color: 'blue-grey', icon: 'mdi-gold'},
barBronze: {subtype: 'bar', color: 'pale-orange', icon: 'mdi-gold'},
barSteel: {subtype: 'bar', color: 'grey', icon: 'mdi-gold'},
barTitanium: {subtype: 'bar', color: 'pale-green', icon: 'mdi-gold'},
barShiny: {subtype: 'bar', color: 'pale-blue', icon: 'mdi-gold'},
barIridium: {subtype: 'bar', color: 'pale-pink', icon: 'mdi-gold'},
+ barDarkIron: {subtype: 'bar', color: 'darker-grey', icon: 'mdi-gold'},
granite: {subtype: 'rareEarth', color: 'skyblue', icon: 'mdi-cube', gainMult: {}, gainTimerFunction() {
const hitsNeeded = store.getters['mining/hitsNeeded'];
const rareDropGain = store.getters['mining/rareDrops'];
@@ -364,15 +395,25 @@ export default {
const rareDropGain = store.getters['mining/rareDrops'];
return (hitsNeeded === Infinity || !rareDropGain.obsidian) ? null : (((hitsNeeded + MINING_RARE_DROP_BREAK) * rareDropGain.obsidian) / hitsNeeded);
}, timerIsEstimate: true},
+ deeprock: {subtype: 'rareEarth', color: 'darker-grey', icon: 'mdi-gamepad-circle', gainMult: {}, gainTimerFunction() {
+ const hitsNeeded = store.getters['mining/hitsNeeded'];
+ const rareDropGain = store.getters['mining/rareDrops'];
+ return (hitsNeeded === Infinity || !rareDropGain.deeprock) ? null : (((hitsNeeded + MINING_RARE_DROP_BREAK) * rareDropGain.deeprock) / hitsNeeded);
+ }, timerIsEstimate: true},
+ glowshard: {color: 'cyan', icon: 'mdi-lightbulb-fluorescent-tube', gainMult: {}, gainTimerFunction() {
+ const hitsNeeded = store.getters['mining/hitsNeeded'];
+ const rareDropGain = store.getters['mining/rareDrops'];
+ return (hitsNeeded === Infinity || !rareDropGain.glowshard) ? null : (((hitsNeeded + MINING_RARE_DROP_BREAK) * rareDropGain.glowshard) / hitsNeeded);
+ }, timerIsEstimate: true},
smoke: {color: 'grey', icon: 'mdi-smoke', gainMult: {}, capMult: {baseValue: 10}, overcapScaling: 0.25, gainTimerFunction() {
const hitsNeeded = store.getters['mining/hitsNeeded'];
return hitsNeeded === Infinity ? null : (((hitsNeeded + MINING_SMOKE_BREAK) * store.getters['mining/currentSmoke']) / hitsNeeded);
}, timerIsEstimate: true},
- ember: {type: 'prestige', color: 'orange-red', icon: 'mdi-fire', overcapMult: 0, gainMult: {}, capMult: {baseValue: 100}, currencyMult: {
+ ember: {type: 'prestige', color: 'orange-red', icon: 'mdi-fire', overcapMult: 0, gainMult: {display: 'percent'}, capMult: {baseValue: 100}, currencyMult: {
miningSmelterySpeed: {type: 'mult', value: val => val * 0.02 + 1}
}},
resin: {type: 'prestige', color: 'orange', icon: 'mdi-water', gainMult: {baseValue: 0.0001, display: 'perSecond'}, showGainMult: true, showGainTimer: true, capMult: {baseValue: 5}},
- crystalGreen: {type: 'prestige', alwaysVisible: true, color: 'light-green', icon: 'mdi-star-four-points', gainMult: {}},
+ crystalGreen: {type: 'prestige', alwaysVisible: true, color: 'light-green', icon: 'mdi-star-three-points', gainMult: {}},
helium: {type: 'prestige', color: 'pale-blue', icon: 'mdi-gas-cylinder', gainMult: {display: 'percent', baseValue: 0.01}, currencyMult: {
currencyMiningScrapCap: {type: 'mult', value: val => val * 0.01 + 1}
}},
@@ -415,6 +456,10 @@ export default {
for (const [key, elem] of Object.entries(enhancement)) {
store.commit('mining/initEnhancement', {name: key, ...elem});
}
+ for (const [key, elem] of Object.entries(beacon)) {
+ store.commit('mining/initBeacon', {name: key, ...elem});
+ store.commit('mult/init', {feature: 'mining', name: elem.ownedMult, round: true});
+ }
store.commit('mining/updateKey', {key: 'durability', value: store.getters['mining/currentDurability']});
},
@@ -444,7 +489,7 @@ export default {
let smelteryData = {};
for (const [key, elem] of Object.entries(store.state.mining.smeltery)) {
if (elem.total > 0) {
- smelteryData[key] = {progress: elem.progress, stored: elem.stored, total: elem.total};
+ smelteryData[key] = [elem.progress, elem.stored, elem.total];
}
}
if (Object.keys(smelteryData).length > 0) {
@@ -461,10 +506,17 @@ export default {
obj.enhancement = enhancementData;
}
+ if (Object.keys(store.state.mining.beaconPlaced).length > 0) {
+ obj.beaconPlaced = store.state.mining.beaconPlaced;
+ }
+ if (store.state.mining.beaconCooldown > 0) {
+ obj.beaconCooldown = store.state.mining.beaconCooldown;
+ }
+
return obj;
},
loadGame(data) {
- ['depth', 'durability', 'pickaxePower', 'breaks', 'ingredientList', 'enhancementBars', 'enhancementIngredient', 'resin'].forEach(elem => {
+ ['depth', 'durability', 'pickaxePower', 'breaks', 'ingredientList', 'enhancementBars', 'enhancementIngredient', 'resin', 'beaconPlaced', 'beaconCooldown'].forEach(elem => {
if (data[elem] !== undefined) {
store.commit('mining/updateKey', {key: elem, value: data[elem]});
}
@@ -472,9 +524,9 @@ export default {
if (data.smeltery !== undefined) {
for (const [key, elem] of Object.entries(data.smeltery)) {
if (store.state.mining.smeltery[key] !== undefined) {
- store.commit('mining/updateSmelteryKey', {name: key, key: 'progress', value: elem.progress});
- store.commit('mining/updateSmelteryKey', {name: key, key: 'stored', value: elem.stored});
- store.commit('mining/updateSmelteryKey', {name: key, key: 'total', value: elem.total});
+ store.commit('mining/updateSmelteryKey', {name: key, key: 'progress', value: elem[0]});
+ store.commit('mining/updateSmelteryKey', {name: key, key: 'stored', value: elem[1]});
+ store.commit('mining/updateSmelteryKey', {name: key, key: 'total', value: elem[2]});
}
}
}
@@ -486,5 +538,6 @@ export default {
}
}
}
+ store.dispatch('mining/applyBeaconEffects');
}
}
diff --git a/src/js/modules/mining/achievement.js b/src/js/modules/mining/achievement.js
index 7c30b208..195cfc89 100644
--- a/src/js/modules/mining/achievement.js
+++ b/src/js/modules/mining/achievement.js
@@ -4,7 +4,7 @@ import { buildNum } from "../../utils/format";
export default {
maxDepth0: {value: () => store.state.stat.mining_maxDepth0.total, default: 1, milestones: lvl => lvl * 25 + 25},
maxDepth1: {value: () => store.state.stat.mining_maxDepth1.total, default: 1, milestones: lvl => lvl * 10 + 10},
- maxDepthSpeedrun: {value: () => store.state.stat.mining_maxDepthSpeedrun.total, default: 1, milestones: lvl => lvl > 0 ? (lvl * 10 + 10) : 15, relic: {1: 'radar', 2: 'press', 3: 'cupboard', 5: 'bronzePickaxe', 9: 'washingMachine'}},
+ maxDepthSpeedrun: {value: () => store.state.stat.mining_maxDepthSpeedrun.total, default: 1, cap: 10, milestones: lvl => lvl > 0 ? (lvl * 10 + 10) : 15, relic: {1: 'radar', 2: 'press', 3: 'cupboard', 5: 'bronzePickaxe', 9: 'washingMachine'}},
totalDamage: {value: () => store.state.stat.mining_totalDamage.total, milestones: lvl => Math.pow(buildNum(200, 'K'), lvl) * buildNum(10, 'M'), relic: {6: 'openedGift'}},
maxDamage: {value: () => store.state.stat.mining_maxDamage.total, milestones: lvl => Math.pow(buildNum(200, 'K'), lvl) * buildNum(10, 'K'), relic: {3: 'bomb'}},
scrap: {value: () => store.state.stat.mining_scrap.total, milestones: lvl => Math.pow(8000, lvl) * buildNum(5, 'M'), relic: {3: 'jumprope', 4: 'oreShelf'}},
@@ -14,7 +14,10 @@ export default {
store.state.stat.mining_oreTin.total,
store.state.stat.mining_oreIron.total,
store.state.stat.mining_oreTitanium.total,
- store.state.stat.mining_orePlatinum.total
+ store.state.stat.mining_orePlatinum.total,
+ store.state.stat.mining_oreIridium.total,
+ store.state.stat.mining_oreOsmium.total,
+ store.state.stat.mining_oreLead.total,
].reduce((a, b) => a + b, 0), milestones: lvl => Math.pow(10, lvl) * 100, relic: {2: 'aluminiumBrick', 3: 'copperBrick', 4: 'aluminiumHeap', 5: 'copperPickaxe', 6: 'tinBucket'}},
oreVariety: {value: () => [
store.state.stat.mining_oreAluminium.total,
@@ -22,9 +25,12 @@ export default {
store.state.stat.mining_oreTin.total,
store.state.stat.mining_oreIron.total,
store.state.stat.mining_oreTitanium.total,
- store.state.stat.mining_orePlatinum.total
+ store.state.stat.mining_orePlatinum.total,
+ store.state.stat.mining_oreIridium.total,
+ store.state.stat.mining_oreOsmium.total,
+ store.state.stat.mining_oreLead.total,
].reduce((a, b) => a + (b > 0 ? 1 : 0), 0), milestones: lvl => lvl + 2, relic: {1: 'copperHeap', 2: 'catalyst', 3: 'magnet'}},
- depthDwellerCap0: {value: () => store.state.stat.mining_depthDwellerCap0.total, milestones: lvl => lvl * 10 + (lvl === 0 ? 5 : 0), relic: {0: 'hammer'}},
+ depthDwellerCap0: {value: () => store.state.stat.mining_depthDwellerCap0.total, cap: 30, milestones: lvl => lvl * 10 + (lvl === 0 ? 5 : 0), relic: {0: 'hammer'}},
depthDwellerCap1: {value: () => store.state.stat.mining_depthDwellerCap1.total, milestones: lvl => lvl * 10 + (lvl === 0 ? 5 : 0)},
coal: {value: () => store.state.stat.mining_coal.total, milestones: lvl => Math.pow(2.5, lvl) * 100, relic: {2: 'coalBrick'}},
resin: {value: () => store.state.stat.mining_resin.total, milestones: lvl => Math.pow(2, lvl) * 50, relic: {3: 'honeyPot'}},
diff --git a/src/js/modules/mining/beacon.js b/src/js/modules/mining/beacon.js
new file mode 100644
index 00000000..ac56d57e
--- /dev/null
+++ b/src/js/modules/mining/beacon.js
@@ -0,0 +1,32 @@
+export default {
+ piercing: {
+ color: 'purple',
+ ownedMult: 'miningBeaconPiercing',
+ effect: [
+ {name: 'miningToughness', type: 'mult', value: lvl => 1 / (lvl * 0.25 + 5)}
+ ]
+ },
+ rich: {
+ color: 'orange',
+ ownedMult: 'miningBeaconRich',
+ effect: [
+ {name: 'miningOreGain', type: 'mult', value: lvl => lvl * 0.05 + 2}
+ ]
+ },
+ wonder: {
+ color: 'blue',
+ ownedMult: 'miningBeaconWonder',
+ effect: [
+ {name: 'miningRareEarthGain', type: 'mult', value: lvl => lvl * 0.04 + 1.6}
+ ]
+ },
+ hope: {
+ color: 'green',
+ ownedMult: 'miningBeaconHope',
+ range: 5,
+ effect: [
+ {name: 'miningDamage', type: 'mult', value: lvl => lvl * 0.01 + 1.1},
+ {name: 'currencyMiningScrapGain', type: 'mult', value: lvl => lvl * 0.015 + 1.2}
+ ]
+ }
+}
diff --git a/src/js/modules/mining/card.js b/src/js/modules/mining/card.js
index d5690f4d..5aa6ae97 100644
--- a/src/js/modules/mining/card.js
+++ b/src/js/modules/mining/card.js
@@ -1,7 +1,16 @@
import cardList from "./cardList";
export default {
- feature: {prefix: 'MI', reward: [{name: 'miningDamage', type: 'mult', value: lvl => lvl * 0.05 + 1}], unlock: null},
+ feature: {
+ prefix: 'MI',
+ reward: [{name: 'miningDamage', type: 'mult', value: lvl => lvl * 0.05 + 1}],
+ shinyReward: [{name: 'miningPrestigeIncome', type: 'mult', value: lvl => lvl * 0.05 + 1}],
+ powerReward: [
+ {name: 'miningDamage', type: 'mult', value: lvl => Math.pow(1.08, lvl)},
+ {name: 'miningPrestigeIncome', type: 'mult', value: lvl => Math.pow(1.05, lvl)},
+ ],
+ unlock: null
+ },
collection: {
minersAndEquipment: {reward: [
{name: 'miningDamage', type: 'mult', value: 1.35}
@@ -20,25 +29,25 @@ export default {
]}
},
pack: {
- intoDarkness: {amount: 5, price: 25, content: {
+ intoDarkness: {amount: 3, price: 15, content: {
'MI-0001': 2.75, 'MI-0002': 0.3, 'MI-0003': 0.58, 'MI-0004': 1.1, 'MI-0005': 1.22, 'MI-0006': 0.9,
'MI-0007': 0.65, 'MI-0008': 1.11, 'MI-0009': 1.56, 'MI-0010': 0.28, 'MI-0011': 0.73, 'MI-0012': 0.86,
'MI-0013': 1.05, 'MI-0014': 1.45, 'MI-0015': 0.49, 'MI-0016': 0.55, 'MI-0017': 0.52, 'MI-0018': 1.16,
'MI-0023': 0.18, 'MI-0024': 0.05,
}},
- drillsAndDepths: {unlock: 'miningDepthDweller', amount: 5, price: 30, content: {
+ drillsAndDepths: {unlock: 'miningDepthDweller', amount: 4, price: 35, content: {
'MI-0001': 1.8, 'MI-0002': 0.4, 'MI-0003': 0.65, 'MI-0004': 1.1, 'MI-0005': 1.22, 'MI-0006': 0.9,
'MI-0013': 1.05, 'MI-0014': 1.45, 'MI-0015': 0.69, 'MI-0016': 0.55, 'MI-0017': 0.52, 'MI-0018': 1.16,
'MI-0019': 1.55, 'MI-0020': 2.3, 'MI-0021': 1.91, 'MI-0022': 2.12,
'MI-0023': 0.36, 'MI-0024': 0.12, 'MI-0025': 0.46, 'MI-0026': 0.62, 'MI-0027': 1.35,
}},
- hotStuff: {unlock: 'miningSmeltery', amount: 5, price: 40, content: {
+ hotStuff: {unlock: 'miningSmeltery', amount: 5, price: 70, content: {
'MI-0007': 1.3, 'MI-0008': 1.77, 'MI-0009': 1.56, 'MI-0010': 0.28, 'MI-0011': 0.58, 'MI-0012': 0.51,
'MI-0023': 0.72, 'MI-0024': 0.24, 'MI-0025': 0.46, 'MI-0026': 0.62, 'MI-0027': 1.35,
'MI-0028': 0.8, 'MI-0029': 0.66, 'MI-0030': 2.8, 'MI-0031': 1.35,
'MI-0032': 0.5,
}},
- dangerZone: {unlock: 'miningResin', amount: 4, price: 45, content: {
+ dangerZone: {unlock: 'miningResin', amount: 4, price: 105, content: {
'MI-0032': 1.6, 'MI-0033': 1.45, 'MI-0034': 1.35, 'MI-0035': 2.1, 'MI-0036': 1.95, 'MI-0037': 3.35, 'MI-0038': 2.1,
}}
},
diff --git a/src/js/modules/mining/cardList.js b/src/js/modules/mining/cardList.js
index 30900318..e55c2b38 100644
--- a/src/js/modules/mining/cardList.js
+++ b/src/js/modules/mining/cardList.js
@@ -1,47 +1,38 @@
export default [
- {id: 1, collection: 'minersAndEquipment', reward: [
- {name: 'miningDamage', type: 'mult', value: 1.1},
- {name: 'currencyMiningScrapGain', type: 'mult', value: 1.1},
- {name: 'miningOreGain', type: 'mult', value: 1.1}
- ], color: 'amber', icons: [
+ {id: 1, collection: 'minersAndEquipment', power: 3, color: 'amber', icons: [
{"x": 0, "y": -0.7, "rotate": 0, "size": 1.6, "icon": "mdi-hard-hat"},
{"x": -0.55, "y": 0.35, "rotate": -20, "size": 2.5, "icon": "mdi-torch"},
{"x": 0.45, "y": 0.35, "rotate": -30, "size": 2, "icon": "mdi-pickaxe"}
]},
- {id: 2, collection: 'minersAndEquipment', reward: [
- {name: 'miningPickaxeCraftingQuality', type: 'mult', value: 1.5},
- {name: 'miningPickaxeCraftingSlots', type: 'base', value: 1}
+ {id: 2, collection: 'minersAndEquipment', power: 2, reward: [
+ {name: 'miningPickaxeCraftingQuality', type: 'mult', value: 1.5}
], color: 'brown', icons: [
{"x": -0.3, "y": 0.05, "rotate": 0, "size": 1, "icon": "mdi-archive"},
{"x": -0.55, "y": 0.5, "rotate": 0, "size": 1, "icon": "mdi-archive"},
{"x": -0.05, "y": 0.5, "rotate": 0, "size": 1, "icon": "mdi-archive"},
{"x": 0.45, "y": 0.15, "rotate": 90, "size": 2.25, "icon": "mdi-pickaxe"}
]},
- {id: 3, collection: 'minersAndEquipment', reward: [
- {name: 'miningDamage', type: 'mult', value: 1.1},
- {name: 'miningPickaxeCraftingSlots', type: 'base', value: 2}
+ {id: 3, collection: 'minersAndEquipment', power: 2, reward: [
+ {name: 'miningPickaxeCraftingSlots', type: 'base', value: 1}
], color: 'pale-blue', icons: [
{"x": -0.25, "y": -0.35, "rotate": -50, "size": 1.75, "icon": "mdi-pickaxe"},
{"x": 0.2, "y": -0.1, "rotate": -20, "size": 1.75, "icon": "mdi-pickaxe"},
{"x": 0, "y": 0.25, "rotate": 0, "size": 2, "icon": "mdi-package"}
]},
- {id: 4, collection: 'minersAndEquipment', reward: [
- {name: 'miningDamage', type: 'mult', value: 1.2},
+ {id: 4, collection: 'minersAndEquipment', power: 2, reward: [
{name: 'miningToughness', type: 'mult', value: 0.8}
], color: 'orange-red', icons: [
{"x": -0.55, "y": 0, "rotate": 0, "size": 1.75, "icon": "mdi-bomb"},
{"x": 0.4, "y": 0.15, "rotate": -35, "size": 2.5, "icon": "mdi-torch"}
]},
- {id: 5, collection: 'minersAndEquipment', reward: [
- {name: 'miningDamage', type: 'mult', value: 1.12},
+ {id: 5, collection: 'minersAndEquipment', power: 2, reward: [
{name: 'currencyMiningScrapGain', type: 'mult', value: 1.2}
], color: 'pale-green', icons: [
{"x": 0, "y": 0, "rotate": 0, "size": 4, "icon": "mdi-elevator-down"},
{"x": -0.25, "y": 0.65, "rotate": 0, "size": 1, "icon": "mdi-account-hard-hat"},
{"x": 0.2, "y": 0.6, "rotate": 0, "size": 1.1, "icon": "mdi-account-hard-hat"}
]},
- {id: 6, collection: 'minersAndEquipment', reward: [
- {name: 'currencyMiningScrapGain', type: 'mult', value: 1.2},
+ {id: 6, collection: 'minersAndEquipment', power: 2, reward: [
{name: 'miningOreGain', type: 'mult', value: 1.2}
], color: 'orange', icons: [
{"x": 0, "y": 0, "rotate": 0, "size": 4, "icon": "mdi-cupboard"},
@@ -49,16 +40,16 @@ export default [
{"x": 0.25, "y": -0.6, "rotate": 0, "size": 0.8, "icon": "mdi-hard-hat"},
{"x": -0.1, "y": -0.1, "rotate": 0, "size": 0.8, "icon": "mdi-hard-hat"}
]},
- {id: 7, collection: 'minersAndEquipment', reward: [
- {name: 'miningToughness', type: 'mult', value: 1 / 1.7}
+ {id: 7, collection: 'minersAndEquipment', power: 1, reward: [
+ {name: 'miningToughness', type: 'mult', value: 1 / 1.5}
], color: 'red', icons: [
{"x": -0.35, "y": 0.1, "rotate": -95, "size": 1.5, "icon": "mdi-bomb"},
{"x": 0.35, "y": 0, "rotate": 30, "size": 1.5, "icon": "mdi-bomb"},
{"x": -0.05, "y": -0.45, "rotate": -15, "size": 1.5, "icon": "mdi-bomb"},
{"x": 0, "y": 0.9, "rotate": 0, "size": 2, "icon": "mdi-sign-caution"}
]},
- {id: 8, collection: 'minersAndEquipment', reward: [
- {name: 'miningDamage', type: 'mult', value: 1.3}
+ {id: 8, collection: 'minersAndEquipment', power: 2, reward: [
+ {name: 'miningDamage', type: 'mult', value: 1.15}
], color: 'purple', icons: [
{"x": 0.85, "y": 0.5, "rotate": 0, "size": 2, "icon": "mdi-human-greeting"},
{"x": 0.25, "y": -0.2, "rotate": -90, "size": 1.25, "icon": "mdi-pickaxe"},
@@ -66,40 +57,40 @@ export default [
{"x": 0, "y": 0.9, "rotate": 220, "size": 1.8, "icon": "mdi-chart-bubble"},
{"x": -0.35, "y": 0.3, "rotate": 0, "size": 1.6, "icon": "mdi-chart-bubble"}
]},
- {id: 9, collection: 'minersAndEquipment', reward: [
- {name: 'currencyMiningScrapGain', type: 'mult', value: 1.4}
+ {id: 9, collection: 'minersAndEquipment', power: 1, reward: [
+ {name: 'currencyMiningScrapGain', type: 'mult', value: 1.35}
], color: 'teal', icons: [
{"x": 0.6, "y": 0.3, "rotate": -10, "size": 2, "icon": "mdi-pickaxe"},
{"x": -0.6, "y": 0.35, "rotate": 100, "size": 2, "icon": "mdi-shovel"},
{"x": 0, "y": -0.5, "rotate": 0, "size": 1.5, "icon": "mdi-help"},
{"x": 0.8, "y": -0.8, "rotate": 80, "size": 1.1, "icon": "mdi-chart-bubble"}
]},
- {id: 10, collection: 'minersAndEquipment', reward: [
- {name: 'miningOreQuality', type: 'mult', value: 2}
+ {id: 10, collection: 'minersAndEquipment', power: 2, reward: [
+ {name: 'miningOreQuality', type: 'mult', value: 1.75}
], color: 'pink', icons: [
{"x": -0.4, "y": 0.4, "rotate": 0, "size": 3, "icon": "mdi-cupboard"},
{"x": -0.3, "y": -0.55, "rotate": 25, "size": 1.4, "icon": "mdi-pickaxe"},
{"x": 0.7, "y": 0.65, "rotate": 0, "size": 2, "icon": "mdi-human-greeting"}
]},
- {id: 11, collection: 'minersAndEquipment', reward: [
+ {id: 11, collection: 'minersAndEquipment', power: 1, reward: [
{name: 'miningDamage', type: 'mult', value: 1.1},
- {name: 'currencyMiningOreAluminiumGain', type: 'mult', value: 1.5}
+ {name: 'currencyMiningOreAluminiumGain', type: 'mult', value: 1.6}
], color: 'pale-red', icons: [
{"x": 0, "y": 0.5, "rotate": 0, "size": 3, "icon": "mdi-human-handsup"},
{"x": -0.4, "y": -0.45, "rotate": -30, "size": 1.5, "icon": "mdi-pickaxe"},
{"x": 0.35, "y": -0.55, "rotate": -60, "size": 1.5, "icon": "mdi-pickaxe"}
]},
- {id: 12, collection: 'minersAndEquipment', reward: [
- {name: 'currencyMiningScrapGain', type: 'mult', value: 1.1},
- {name: 'currencyMiningOreCopperGain', type: 'mult', value: 1.5}
+ {id: 12, collection: 'minersAndEquipment', power: 1, reward: [
+ {name: 'currencyMiningScrapGain', type: 'mult', value: 1.15},
+ {name: 'currencyMiningOreCopperGain', type: 'mult', value: 1.6}
], color: 'light-blue', icons: [
{"x": 0.4, "y": 0.5, "rotate": 0, "size": 2.5, "icon": "mdi-walk"},
{"x": -0.8, "y": 1, "rotate": -125, "size": 0.8, "icon": "mdi-hard-hat"},
{"x": 0.5, "y": -1, "rotate": 90, "size": 1, "icon": "mdi-motion"}
]},
- {id: 13, collection: 'scrapLogistics', reward: [
- {name: 'currencyMiningScrapCap', type: 'mult', value: 2}
+ {id: 13, collection: 'scrapLogistics', power: 2, reward: [
+ {name: 'currencyMiningScrapCap', type: 'mult', value: 1.4}
], color: 'beige', icons: [
{"x": -1, "y": 0.65, "rotate": 0, "size": 1, "icon": "mdi-archive"},
{"x": -0.5, "y": 0.65, "rotate": 0, "size": 1, "icon": "mdi-archive"},
@@ -113,17 +104,16 @@ export default [
{"x": 1, "y": 0.65, "rotate": 0, "size": 1, "icon": "mdi-dots-triangle"},
{"x": 0.1, "y": -0.1, "rotate": 0, "size": 1, "icon": "mdi-dots-horizontal"}
]},
- {id: 14, collection: 'scrapLogistics', reward: [
- {name: 'currencyMiningScrapGain', type: 'mult', value: 1.2},
- {name: 'currencyMiningScrapCap', type: 'mult', value: 1.5}
+ {id: 14, collection: 'scrapLogistics', power: 2, reward: [
+ {name: 'currencyMiningScrapGain', type: 'mult', value: 1.12},
+ {name: 'currencyMiningScrapCap', type: 'mult', value: 1.25}
], color: 'wooden', icons: [
{"x": 0, "y": 0.4, "rotate": 0, "size": 2.5, "icon": "mdi-package"},
{"x": 0, "y": -0.4, "rotate": 0, "size": 1.75, "icon": "mdi-dots-triangle"},
{"x": 0.7, "y": 0.8, "rotate": 0, "size": 1.75, "icon": "mdi-circle-small"},
{"x": -0.85, "y": 0.8, "rotate": 0, "size": 1.75, "icon": "mdi-circle-small"}
]},
- {id: 15, collection: 'scrapLogistics', reward: [
- {name: 'miningOreGain', type: 'mult', value: 1.15},
+ {id: 15, collection: 'scrapLogistics', power: 2, reward: [
{name: 'currencyMiningOreAluminiumCap', type: 'base', value: 80},
{name: 'currencyMiningOreCopperCap', type: 'base', value: 24}
], color: 'green', icons: [
@@ -133,16 +123,16 @@ export default [
{"x": 0.3, "y": 0.65, "rotate": 0, "size": 0.6, "icon": "mdi-package"},
{"x": 0.3, "y": 0.45, "rotate": 0, "size": 0.5, "icon": "mdi-dots-triangle"}
]},
- {id: 16, collection: 'scrapLogistics', reward: [
- {name: 'currencyMiningScrapGain', type: 'mult', value: 1.1},
+ {id: 16, collection: 'scrapLogistics', power: 1, reward: [
+ {name: 'currencyMiningScrapGain', type: 'mult', value: 1.14},
{name: 'currencyMiningOreAluminiumCap', type: 'mult', value: 2}
], color: 'pale-orange', icons: [
{"x": 0.4, "y": 0, "rotate": 0, "size": 3, "icon": "mdi-excavator"},
{"x": 0, "y": -0.1, "rotate": 0, "size": 1.75, "icon": "mdi-circle-small"},
{"x": -0.8, "y": 0.4, "rotate": 0, "size": 1.75, "icon": "mdi-dots-triangle"}
]},
- {id: 17, collection: 'scrapLogistics', reward: [
- {name: 'currencyMiningScrapCap', type: 'mult', value: 1.2},
+ {id: 17, collection: 'scrapLogistics', power: 1, reward: [
+ {name: 'currencyMiningScrapCap', type: 'mult', value: 1.3},
{name: 'currencyMiningOreCopperCap', type: 'mult', value: 2}
], color: 'lime', icons: [
{"x": 0.5, "y": 0.5, "rotate": 0, "size": 2.5, "icon": "mdi-truck-flatbed"},
@@ -150,9 +140,9 @@ export default [
{"x": -1, "y": 0.65, "rotate": 0, "size": 1.5, "icon": "mdi-dots-triangle"},
{"x": -0.6, "y": 0.65, "rotate": -70, "size": 1.25, "icon": "mdi-shovel"}
]},
- {id: 18, collection: 'scrapLogistics', reward: [
+ {id: 18, collection: 'scrapLogistics', power: 2, reward: [
{name: 'miningDamage', type: 'mult', value: 1.1},
- {name: 'currencyMiningScrapCap', type: 'mult', value: 1.75}
+ {name: 'currencyMiningScrapCap', type: 'mult', value: 1.2}
], color: 'skyblue', icons: [
{"x": 0.6, "y": 0.35, "rotate": 0, "size": 2, "icon": "mdi-human-handsdown"},
{"x": -0.7, "y": 0.5, "rotate": 0, "size": 1.6, "icon": "mdi-package"},
@@ -160,24 +150,24 @@ export default [
{"x": 0.15, "y": 0.4, "rotate": -10, "size": 1, "icon": "mdi-clipboard-text"},
{"x": 1, "y": 0.35, "rotate": -20, "size": 0.8, "icon": "mdi-pencil"}
]},
- {id: 19, collection: 'scrapLogistics', reward: [
- {name: 'miningDepthDwellerSpeed', type: 'mult', value: 1.75}
+ {id: 19, collection: 'scrapLogistics', power: 3, reward: [
+ {name: 'miningDepthDwellerSpeed', type: 'mult', value: 1.4}
], color: 'yellow', icons: [
{"x": 0.5, "y": -0.1, "rotate": 0, "size": 2.5, "icon": "mdi-factory"},
{"x": -0.6, "y": 0.75, "rotate": 0, "size": 1.75, "icon": "mdi-truck-flatbed"},
{"x": -1, "y": 0.65, "rotate": 0, "size": 0.6, "icon": "mdi-archive"},
{"x": -0.7, "y": 0.65, "rotate": 0, "size": 0.6, "icon": "mdi-archive"}
]},
- {id: 20, collection: 'scrapLogistics', reward: [
- {name: 'currencyMiningCrystalGreenGain', type: 'mult', value: 1.2}
+ {id: 20, collection: 'scrapLogistics', power: 3, reward: [
+ {name: 'currencyMiningCrystalGreenGain', type: 'mult', value: 1.15}
], color: 'grey', icons: [
{"x": 0, "y": -1, "rotate": 0, "size": 1.5, "icon": "mdi-arrow-collapse-down"},
{"x": 0, "y": 0.8, "rotate": 0, "size": 2, "icon": "mdi-square"},
{"x": 0, "y": 0, "rotate": 0, "size": 1.5, "icon": "mdi-dots-triangle"}
]},
- {id: 21, collection: 'scrapLogistics', reward: [
+ {id: 21, collection: 'scrapLogistics', power: 2, reward: [
{name: 'miningDepthDwellerSpeed', type: 'mult', value: 1.5},
- {name: 'currencyMiningCrystalGreenGain', type: 'mult', value: 1.1}
+ {name: 'currencyMiningCrystalGreenGain', type: 'mult', value: 1.2}
], color: 'red', icons: [
{"x": 0, "y": 0, "rotate": 90, "size": 1.5, "icon": "mdi-dots-hexagon"},
{"x": 0, "y": -0.9, "rotate": 180, "size": 1.25, "icon": "mdi-magnet-on"},
@@ -185,32 +175,31 @@ export default [
{"x": -0.65, "y": 0, "rotate": 0, "size": 1.5, "icon": "mdi-dots-horizontal"},
{"x": 0.65, "y": 0, "rotate": 0, "size": 1.5, "icon": "mdi-dots-horizontal"}
]},
- {id: 22, collection: 'scrapLogistics', reward: [
- {name: 'miningDamage', type: 'mult', value: 1.1},
- {name: 'currencyMiningCrystalGreenGain', type: 'mult', value: 1.15}
+ {id: 22, collection: 'scrapLogistics', power: 3, reward: [
+ {name: 'miningDamage', type: 'mult', value: 1.12}
], color: 'indigo', icons: [
{"x": -0.5, "y": 0.1, "rotate": 0, "size": 2, "icon": "mdi-robot-industrial"},
{"x": 0.7, "y": 0.25, "rotate": -20, "size": 1.5, "icon": "mdi-robot"},
{"x": 0, "y": -0.2, "rotate": 0, "size": 1.5, "icon": "mdi-circle-small"}
]},
- {id: 23, collection: 'caveLocations', reward: [
- {name: 'miningPickaxeCraftingQuality', type: 'mult', value: 1.75}
+ {id: 23, collection: 'caveLocations', power: 3, reward: [
+ {name: 'miningPickaxeCraftingQuality', type: 'mult', value: 1.25}
], color: 'light-blue', icons: [
{"x": -0.15, "y": 0.2, "rotate": 90, "size": 1.8, "icon": "mdi-chart-bubble"},
{"x": 0.15, "y": 0.3, "rotate": 225, "size": 2, "icon": "mdi-chart-bubble"},
{"x": -0.1, "y": -0.3, "rotate": 80, "size": 1.25, "icon": "mdi-pickaxe"}
]},
- {id: 24, collection: 'caveLocations', reward: [
- {name: 'miningPickaxeCraftingSlots', type: 'base', value: 4}
+ {id: 24, collection: 'caveLocations', power: 3, reward: [
+ {name: 'miningPickaxeCraftingSlots', type: 'base', value: 1}
], color: 'pale-green', icons: [
{"x": 0, "y": 0, "rotate": 0, "size": 2.75, "icon": "mdi-tunnel"},
{"x": -0.7, "y": 0.9, "rotate": 0, "size": 1, "icon": "mdi-grass"},
{"x": -1, "y": 0, "rotate": 0, "size": 0.75, "icon": "mdi-torch"},
{"x": 1, "y": 0, "rotate": 0, "size": 0.75, "icon": "mdi-torch"}
]},
- {id: 25, collection: 'caveLocations', reward: [
- {name: 'miningDepthDwellerSpeed', type: 'mult', value: 1.25},
+ {id: 25, collection: 'caveLocations', power: 2, reward: [
+ {name: 'miningDepthDwellerSpeed', type: 'mult', value: 1.1},
{name: 'currencyMiningOreTinCap', type: 'mult', value: 2}
], color: 'red', icons: [
{"x": -0.65, "y": 0.5, "rotate": 0, "size": 1.6, "icon": "mdi-chart-bubble"},
@@ -220,9 +209,9 @@ export default [
{"x": 0.1, "y": -0.6, "rotate": 240, "size": 2.4, "icon": "mdi-chart-bubble"},
{"x": 0, "y": 1, "rotate": 0, "size": 1.25, "icon": "mdi-bomb"}
]},
- {id: 26, collection: 'caveLocations', reward: [
+ {id: 26, collection: 'caveLocations', power: 2, reward: [
{name: 'miningPickaxeCraftingSlots', type: 'base', value: 1},
- {name: 'currencyMiningOreTinGain', type: 'mult', value: 1.5}
+ {name: 'currencyMiningOreTinGain', type: 'mult', value: 1.6}
], color: 'yellow', icons: [
{"x": -0.25, "y": -0.35, "rotate": 0, "size": 3, "icon": "mdi-minus"},
{"x": 0.25, "y": -0.35, "rotate": 0, "size": 3, "icon": "mdi-minus"},
@@ -231,8 +220,8 @@ export default [
{"x": -0.4, "y": 0.1, "rotate": 15, "size": 1, "icon": "mdi-torch"},
{"x": 0.1, "y": -0.7, "rotate": 70, "size": 1.65, "icon": "mdi-chart-bubble"}
]},
- {id: 27, collection: 'caveLocations', reward: [
- {name: 'miningDamage', type: 'mult', value: 1.25},
+ {id: 27, collection: 'caveLocations', power: 2, reward: [
+ {name: 'miningDamage', type: 'mult', value: 1.2},
{name: 'currencyMiningScrapGain', type: 'mult', value: 1.1}
], color: 'light-green', icons: [
{"x": 0, "y": 0, "rotate": 225, "size": 2.25, "icon": "mdi-chart-bubble"},
@@ -242,8 +231,8 @@ export default [
{"x": 0.85, "y": -0.6, "rotate": 0, "size": 1, "icon": "mdi-grass"},
{"x": 0.15, "y": -0.85, "rotate": 0, "size": 0.9, "icon": "mdi-grass"}
]},
- {id: 28, collection: 'caveLocations', reward: [
- {name: 'currencyMiningCrystalGreenGain', type: 'mult', value: 1.08},
+ {id: 28, collection: 'caveLocations', power: 3, reward: [
+ {name: 'currencyMiningCrystalGreenGain', type: 'mult', value: 1.05},
{name: 'currencyMiningOreIronCap', type: 'mult', value: 2}
], color: 'dark-grey', icons: [
{"x": -0.5, "y": 0.85, "rotate": 5, "size": 2, "icon": "mdi-torch"},
@@ -254,9 +243,9 @@ export default [
{"x": -0.2, "y": 0, "rotate": 5, "size": 1, "icon": "mdi-bat"},
{"x": 0.5, "y": 0.65, "rotate": 45, "size": 1.4, "icon": "mdi-bat"}
]},
- {id: 29, collection: 'caveLocations', reward: [
+ {id: 29, collection: 'caveLocations', power: 3, reward: [
{name: 'miningSmelterySpeed', type: 'mult', value: 1.15},
- {name: 'currencyMiningOreIronGain', type: 'mult', value: 1.5}
+ {name: 'currencyMiningOreIronGain', type: 'mult', value: 1.6}
], color: 'light-grey', icons: [
{"x": -0.65, "y": 0.9, "rotate": -20, "size": 2, "icon": "mdi-chart-bubble"},
{"x": 0.9, "y": -0.95, "rotate": 20, "size": 1.5, "icon": "mdi-spider-web"},
@@ -265,7 +254,7 @@ export default [
{"x": 0.1, "y": -0.1, "rotate": 0, "size": 1, "icon": "mdi-spider-thread"},
{"x": 0.1, "y": -0.5, "rotate": 90, "size": 1, "icon": "mdi-minus"}
]},
- {id: 30, collection: 'caveLocations', reward: [
+ {id: 30, collection: 'caveLocations', power: 3, reward: [
{name: 'miningOreGain', type: 'mult', value: 1.4}
], color: 'cyan', icons: [
{"x": 0.4, "y": 0.6, "rotate": 30, "size": 2, "icon": "mdi-chart-bubble"},
@@ -273,10 +262,7 @@ export default [
{"x": -0.6, "y": 0.75, "rotate": 75, "size": 2.4, "icon": "mdi-chart-bubble"},
{"x": -0.3, "y": 0.35, "rotate": 10, "size": 0.75, "icon": "mdi-flare"}
]},
- {id: 31, collection: 'caveLocations', reward: [
- {name: 'miningSmelterySpeed', type: 'mult', value: 1.3},
- {name: 'miningOreGain', type: 'mult', value: 1.25}
- ], color: 'dark-blue', icons: [
+ {id: 31, collection: 'caveLocations', power: 5, color: 'dark-blue', icons: [
{"x": 0, "y": 0.25, "rotate": 0, "size": 3, "icon": "mdi-ellipse-outline"},
{"x": 0, "y": 0.25, "rotate": 0, "size": 1.5, "icon": "mdi-waves"},
{"x": -0.9, "y": 0.9, "rotate": -20, "size": 1.5, "icon": "mdi-chart-bubble"},
@@ -284,15 +270,15 @@ export default [
{"x": 0.9, "y": -0.45, "rotate": -135, "size": 1, "icon": "mdi-chart-bubble"}
]},
- {id: 32, collection: 'dangersInTheDark', reward: [
- {name: 'miningSmelterySpeed', type: 'mult', value: 1.6}
+ {id: 32, collection: 'dangersInTheDark', power: 4, reward: [
+ {name: 'miningSmelterySpeed', type: 'mult', value: 1.35}
], color: 'orange', icons: [
{"x": -0.45, "y": 0.6, "rotate": -125, "size": 1.8, "icon": "mdi-liquid-spot"},
{"x": 0.45, "y": 0.6, "rotate": 70, "size": 2, "icon": "mdi-liquid-spot"},
{"x": 0, "y": 0.6, "rotate": 0, "size": 2.2, "icon": "mdi-liquid-spot"},
{"x": 0, "y": -0.5, "rotate": 0, "size": 3, "icon": "mdi-fire"}
]},
- {id: 33, collection: 'dangersInTheDark', reward: [
+ {id: 33, collection: 'dangersInTheDark', power: 4, reward: [
{name: 'miningResinMax', type: 'base', value: 1},
{name: 'currencyMiningOreTitaniumCap', type: 'mult', value: 2}
], color: 'cherry', icons: [
@@ -303,23 +289,23 @@ export default [
{"x": -0.55, "y": 1, "rotate": 0, "size": 0.65, "icon": "mdi-bone"},
{"x": -0.25, "y": 0.6, "rotate": -30, "size": 0.65, "icon": "mdi-bone"}
]},
- {id: 34, collection: 'dangersInTheDark', reward: [
- {name: 'miningSmelterySpeed', type: 'mult', value: 1.2},
- {name: 'currencyMiningOreTitaniumGain', type: 'mult', value: 1.5}
+ {id: 34, collection: 'dangersInTheDark', power: 4, reward: [
+ {name: 'miningSmelterySpeed', type: 'mult', value: 1.1},
+ {name: 'currencyMiningOreTitaniumGain', type: 'mult', value: 1.6}
], color: 'pale-purple', icons: [
{"x": -0.25, "y": 0, "rotate": -135, "size": 2, "icon": "mdi-chart-bubble"},
{"x": 0.4, "y": 0.7, "rotate": 75, "size": 2.25, "icon": "mdi-chart-bubble"},
{"x": -0.5, "y": 0.7, "rotate": 0, "size": 1.5, "icon": "mdi-spider"}
]},
- {id: 35, collection: 'dangersInTheDark', reward: [
- {name: 'miningResinMax', type: 'base', value: 3}
+ {id: 35, collection: 'dangersInTheDark', power: 5, reward: [
+ {name: 'miningResinMax', type: 'base', value: 1}
], color: 'brown', icons: [
{"x": -1, "y": 0.75, "rotate": 0, "size": 1.5, "icon": "mdi-square"},
{"x": 1, "y": 0.75, "rotate": 0, "size": 1.5, "icon": "mdi-square"},
{"x": 0, "y": 0.3, "rotate": 0, "size": 2.5, "icon": "mdi-bridge"},
{"x": 0, "y": 0.1, "rotate": 0, "size": 1.25, "icon": "mdi-circle"}
]},
- {id: 36, collection: 'dangersInTheDark', reward: [
+ {id: 36, collection: 'dangersInTheDark', power: 4, reward: [
{name: 'miningDamage', type: 'mult', value: 1.25},
{name: 'miningResinMax', type: 'base', value: 1}
], color: 'blue-grey', icons: [
@@ -330,17 +316,17 @@ export default [
{"x": -0.2, "y": -0.65, "rotate": 90, "size": 1.15, "icon": "mdi-motion"},
{"x": -0.55, "y": 0.75, "rotate": 90, "size": 1.2, "icon": "mdi-motion"}
]},
- {id: 37, collection: 'dangersInTheDark', reward: [
- {name: 'currencyMiningEmberGain', type: 'mult', value: 2}
+ {id: 37, collection: 'dangersInTheDark', power: 5, reward: [
+ {name: 'currencyMiningEmberGain', type: 'mult', value: 1.25}
], color: 'light-green', icons: [
{"x": 0, "y": 1, "rotate": 90, "size": 3, "icon": "mdi-human-cane"},
{"x": -0.6, "y": -0.3, "rotate": 0, "size": 1.2, "icon": "mdi-cloud"},
{"x": 0.4, "y": -0.75, "rotate": 0, "size": 1.4, "icon": "mdi-cloud"},
{"x": 0.7, "y": 0, "rotate": 0, "size": 1.6, "icon": "mdi-cloud"}
]},
- {id: 38, collection: 'dangersInTheDark', reward: [
+ {id: 38, collection: 'dangersInTheDark', power: 4, reward: [
{name: 'miningSmelterySpeed', type: 'mult', value: 1.25},
- {name: 'currencyMiningEmberGain', type: 'base', value: 5},
+ {name: 'currencyMiningEmberGain', type: 'base', value: 0.1},
{name: 'miningResinMax', type: 'base', value: 1}
], color: 'pale-pink', icons: [
{"x": -0.85, "y": 0.8, "rotate": 90, "size": 3, "icon": "mdi-rectangle"},
diff --git a/src/js/modules/mining/enhancement.js b/src/js/modules/mining/enhancement.js
index e9e507d8..15a9d5e5 100644
--- a/src/js/modules/mining/enhancement.js
+++ b/src/js/modules/mining/enhancement.js
@@ -21,7 +21,7 @@ export default {
},
barTitanium: {
effect: [
- {name: 'currencyMiningScrapGain', type: 'mult', value: lvl => getSequence(2, lvl)}
+ {name: 'currencyMiningScrapGain', type: 'mult', value: lvl => getSequence(2, lvl) + 1}
]
},
barShiny: {
@@ -34,5 +34,10 @@ export default {
effect: [
{name: 'currencyMiningEmberGain', type: 'mult', value: lvl => lvl + 1}
]
+ },
+ barDarkIron: {
+ effect: [
+ {name: 'currencyMiningScrapCap', type: 'mult', value: lvl => getSequence(2, lvl) * 0.5 + 1}
+ ]
}
}
diff --git a/src/js/modules/mining/ore.js b/src/js/modules/mining/ore.js
index 76e69b91..b7e19560 100644
--- a/src/js/modules/mining/ore.js
+++ b/src/js/modules/mining/ore.js
@@ -63,5 +63,23 @@ export default {
modulo: 17,
baseAmount: 0.00000128,
amountMult: 1.05
+ },
+ oreOsmium: {
+ power: buildNum(1.75, 'M'),
+ impurity: 6,
+ minDepth: 350,
+ maxDepth: 525,
+ modulo: 23,
+ baseAmount: 0.000000256,
+ amountMult: 1.05
+ },
+ oreLead: {
+ power: buildNum(12.5, 'M'),
+ impurity: 7.5,
+ minDepth: 450,
+ maxDepth: 650,
+ modulo: 29,
+ baseAmount: 0.0000000512,
+ amountMult: 1.05
}
}
diff --git a/src/js/modules/mining/smeltery.js b/src/js/modules/mining/smeltery.js
index bb6d8ccd..2aef02de 100644
--- a/src/js/modules/mining/smeltery.js
+++ b/src/js/modules/mining/smeltery.js
@@ -57,5 +57,16 @@ export default {
output: 'mining_barIridium',
timeNeeded: 365 * SECONDS_PER_DAY,
minTemperature: 1750
- }
+ },
+ darkIron: {
+ price: {
+ mining_oreIron: {base: buildNum(10, 'M'), increment: buildNum(500, 'K')},
+ mining_oreOsmium: {base: 1000, increment: 50},
+ mining_deeprock: {base: buildNum(100, 'M'), increment: buildNum(25, 'M')},
+ mining_neon: {base: buildNum(10, 'K'), increment: 2500}
+ },
+ output: 'mining_barDarkIron',
+ timeNeeded: 5000 * SECONDS_PER_DAY,
+ minTemperature: 2500
+ },
}
diff --git a/src/js/modules/mining/upgrade.js b/src/js/modules/mining/upgrade.js
index f1928437..865407ba 100644
--- a/src/js/modules/mining/upgrade.js
+++ b/src/js/modules/mining/upgrade.js
@@ -44,8 +44,8 @@ export default {
}, effect: [
{name: 'miningPickaxeCraftingPower', type: 'mult', value: lvl => Math.pow(1.2, lvl)}
]},
- oreSlots: {cap: 8, hideCap: true, requirementBase, requirementStat, requirementValue: 25, requirement(lvl) {
- return store.state.stat.mining_maxDepth0.total >= [25, 25, 30, 50, 80, 120, 175, 260][lvl];
+ oreSlots: {cap: 10, hideCap: true, requirementBase, requirementStat, requirementValue: 25, requirement(lvl) {
+ return store.state.stat.mining_maxDepth0.total >= [25, 25, 30, 50, 80, 120, 175, 260, 350, 450][lvl];
}, price(lvl) {
return [
{mining_oreAluminium: 10},
@@ -55,13 +55,15 @@ export default {
{mining_oreIron: 12},
{mining_oreTitanium: 10},
{mining_orePlatinum: 8},
- {mining_oreIridium: 6}
+ {mining_oreIridium: 6},
+ {mining_oreOsmium: 5},
+ {mining_oreLead: 4}
][lvl];
}, effect: [
{name: 'miningPickaxeCraftingSlots', type: 'base', value: lvl => lvl}
]},
- compressor: {cap: 7, hasDescription: true, hideCap: true, requirementBase, requirementStat, requirementValue: 25, requirement(lvl) {
- return store.state.stat.mining_maxDepth0.total >= [25, 35, 60, 95, 140, 200, 280][lvl];
+ compressor: {cap: 9, hasDescription: true, hideCap: true, requirementBase, requirementStat, requirementValue: 25, requirement(lvl) {
+ return store.state.stat.mining_maxDepth0.total >= [25, 35, 60, 95, 140, 200, 280, 375, 480][lvl];
}, price(lvl) {
return [
{mining_oreAluminium: 20},
@@ -70,7 +72,9 @@ export default {
{mining_oreAluminium: buildNum(30, 'K')},
{mining_oreAluminium: buildNum(750, 'K')},
{mining_oreAluminium: buildNum(1, 'B')},
- {mining_oreAluminium: buildNum(100, 'T')}
+ {mining_oreAluminium: buildNum(100, 'T')},
+ {mining_oreAluminium: buildNum(100, 'Qi')},
+ {mining_oreAluminium: buildNum(1, 'O')}
][lvl];
}, effect: [
{name: 'miningCompressAluminium', type: 'unlock', value: lvl => lvl >= 1},
@@ -79,7 +83,9 @@ export default {
{name: 'miningCompressIron', type: 'unlock', value: lvl => lvl >= 4},
{name: 'miningCompressTitanium', type: 'unlock', value: lvl => lvl >= 5},
{name: 'miningCompressPlatinum', type: 'unlock', value: lvl => lvl >= 6},
- {name: 'miningCompressIridium', type: 'unlock', value: lvl => lvl >= 7}
+ {name: 'miningCompressIridium', type: 'unlock', value: lvl => lvl >= 7},
+ {name: 'miningCompressOsmium', type: 'unlock', value: lvl => lvl >= 8},
+ {name: 'miningCompressLead', type: 'unlock', value: lvl => lvl >= 9}
]},
copperCache: {cap: 8, requirementBase, requirementStat, requirementValue: 30, price(lvl) {
return {mining_oreCopper: Math.round(lvl + 3)};
@@ -256,7 +262,7 @@ export default {
emberForge: {hasDescription: true, requirementBase, requirementStat, requirementValue: 125, price(lvl) {
return {mining_coal: lvl * 3 + 80};
}, effect: [
- {name: 'currencyMiningEmberGain', type: 'base', value: lvl => lvl}
+ {name: 'currencyMiningEmberGain', type: 'base', value: lvl => lvl * 0.03}
]},
titaniumCache: {cap: 5, requirementBase, requirementStat, requirementValue: 130, price(lvl) {
return {mining_scrap: Math.pow(7, lvl) * buildNum(80, 'Sx'), mining_oreTitanium: Math.pow(2, lvl) * 4, mining_sulfur: Math.pow(2.2, lvl) * buildNum(45, 'K'), mining_barSteel: 3};
@@ -266,7 +272,7 @@ export default {
{name: 'currencyMiningOreIronCap', type: 'base', value: lvl => lvl * 4},
{name: 'currencyMiningOreTitaniumCap', type: 'base', value: lvl => lvl * 2}
]},
- giantForge: {persistent: true, requirementBase, requirementStat, requirementValue: 132, price(lvl) {
+ giantForge: {persistent: true, alwaysActive: true, requirementBase, requirementStat, requirementValue: 132, price(lvl) {
return {mining_coal: Math.round(Math.pow(1.25, lvl) * 1200)};
}, effect: [
{name: 'currencyMiningEmberCap', type: 'base', value: lvl => lvl * 50}
@@ -282,7 +288,7 @@ export default {
return {mining_niter: Math.round(Math.pow(1.05, lvl) * (lvl * 200 + 1000))};
}, effect: [
{name: 'miningDamage', type: 'mult', value: lvl => lvl * 0.1 + 1},
- {name: 'miningEnhancementBarsIncrement', type: 'mult', value: lvl => Math.pow(1 / 1.03, lvl)}
+ {name: 'miningEnhancementBarsIncrement', type: 'mult', value: lvl => 1 / (lvl * 0.03 + 1)}
]},
metalDetector: {cap: 12, capMult: true, requirementBase, requirementStat, requirementValue: 140, price(lvl) {
return {mining_scrap: Math.pow(3.5, lvl) * buildNum(15, 'Sp'), mining_barSteel: lvl + 11};
@@ -294,7 +300,7 @@ export default {
recycling: {persistent: true, requirementBase, requirementStat, requirementValue: 145, price(lvl) {
return {mining_ember: Math.round(Math.pow(1.15, lvl) * 50)};
}, effect: [
- {name: 'currencyMiningScrapGain', type: 'mult', value: lvl => Math.pow(1.35, lvl)}
+ {name: 'currencyMiningScrapGain', type: 'mult', value: lvl => Math.pow(1.1, lvl) * (lvl * 0.25 + 1)}
]},
stickyJar: {cap: 1, hasDescription: true, persistent: true, note: 'mining_30', requirementBase, requirementStat, requirementValue: 150, price() {
return {mining_scrap: buildNum(4, 'O')};
@@ -364,14 +370,62 @@ export default {
{name: 'currencyMiningOreIridiumCap', type: 'mult', value: lvl => lvl + 1}
]},
iridiumTreetap: {persistent: true, requirementBase, requirementStat, requirementValue: 280, price(lvl) {
- return {mining_barIridium: Math.round(Math.pow(1.3, lvl) * (lvl + 2))};
+ return {mining_deeprock: Math.pow(lvl + 1, 2) * buildNum(500, 'M'), mining_barIridium: Math.round(Math.pow(1.3, lvl) * (lvl + 2))};
}, effect: [
{name: 'currencyMiningResinCap', type: 'base', value: lvl => lvl * 10},
{name: 'miningResinMax', type: 'base', value: lvl => lvl}
]},
- iridiumBombs: {cap: 7, requirementBase, requirementStat, requirementValue: 300, price(lvl) {
+ deepCuts: {requirementBase, requirementStat, requirementValue: 290, price(lvl) {
+ return {mining_deeprock: Math.pow(lvl * 0.01 + 1.5, lvl) * buildNum(2.5, 'B')};
+ }, effect: [
+ {name: 'miningToughness', type: 'mult', value: lvl => Math.pow(1 / 1.25, lvl)}
+ ]},
+ iridiumBombs: {cap: 7, requirementBase, requirementStat, requirementValue: 310, price(lvl) {
return {mining_barBronze: Math.round(Math.pow(1.4, lvl) * buildNum(30, 'K')), mining_barIridium: lvl * 8 + 6};
}, effect: [
{name: 'miningDamage', type: 'mult', value: lvl => Math.pow(1.23, lvl)}
]},
+ oreBag: {requirementBase, cap: 12, requirementStat, requirementValue: 330, price(lvl) {
+ return {mining_deeprock: Math.pow(1.65, lvl) * buildNum(800, 'B'), mining_sulfur: Math.pow(1.9, lvl) * buildNum(450, 'T')};
+ }, effect: [
+ {name: 'currencyMiningOreTinCap', type: 'base', value: lvl => lvl * 12},
+ {name: 'currencyMiningOreIronCap', type: 'base', value: lvl => lvl * 10},
+ {name: 'currencyMiningOreTitaniumCap', type: 'base', value: lvl => lvl * 4},
+ {name: 'currencyMiningOrePlatinumCap', type: 'base', value: lvl => lvl * 4},
+ ]},
+ osmiumExpansion: {requirementBase, cap: 9, requirementStat, requirementValue: 350, price(lvl) {
+ return {mining_barShiny: Math.round(Math.pow(1.44, lvl) * (lvl + 3) * 25), mining_barIridium: Math.round(Math.pow(1.22, lvl) * (lvl + 3) * 8)};
+ }, effect: [
+ {name: 'currencyMiningScrapCap', type: 'mult', value: lvl => Math.pow(1.4, lvl)},
+ {name: 'currencyMiningOreOsmiumCap', type: 'base', value: lvl => lvl * 4},
+ ]},
+ osmiumCache: {cap: 7, requirementBase, requirementStat, requirementValue: 355, price(lvl) {
+ return {mining_scrap: Math.pow(6.75, lvl) * buildNum(900, 'SxD'), mining_deeprock: Math.pow(2.1, lvl) * buildNum(42, 'T')};
+ }, effect: [
+ {name: 'currencyMiningOreOsmiumCap', type: 'base', value: lvl => lvl * 2},
+ {name: 'currencyMiningOreOsmiumCap', type: 'mult', value: lvl => lvl + 1}
+ ]},
+ darkBombs: {cap: 10, requirementBase, requirementStat, requirementValue: 375, price(lvl) {
+ return {mining_barTitanium: Math.round(Math.pow(1.2, lvl) * 360), mining_barDarkIron: lvl * 6 + 2};
+ }, effect: [
+ {name: 'miningDamage', type: 'mult', value: lvl => Math.pow(1.55, lvl)},
+ {name: 'currencyMiningScrapCap', type: 'mult', value: lvl => Math.pow(1.75, lvl)},
+ ]},
+ colossalScrapStorage: {cap: 1, requirementBase, requirementStat, requirementValue: 400, price() {
+ return {mining_scrap: buildNum(1, 'V')};
+ }, effect: [
+ {name: 'currencyMiningScrapCap', type: 'mult', value: lvl => Math.pow(buildNum(1, 'M'), lvl)}
+ ]},
+ stoneDissolver: {cap: 50, requirementBase, requirementStat, requirementValue: 425, price(lvl) {
+ return {mining_scrap: Math.pow(lvl * 0.02 + 1.8, lvl) * buildNum(1, 'UV')};
+ }, effect: [
+ {name: 'miningDamage', type: 'mult', value: lvl => Math.pow(1.15, lvl)},
+ {name: 'miningToughness', type: 'mult', value: lvl => Math.pow(1 / 1.3, lvl)},
+ ]},
+ leadExpansion: {requirementBase, cap: 5, requirementStat, requirementValue: 450, price(lvl) {
+ return {mining_barDarkIron: Math.round(Math.pow(1.4, lvl) * (lvl + 3) * 4)};
+ }, effect: [
+ {name: 'miningOreCap', type: 'mult', value: lvl => lvl * 0.2 + 1},
+ {name: 'currencyMiningOreLeadCap', type: 'base', value: lvl => lvl * 7},
+ ]},
}
diff --git a/src/js/modules/mining/upgrade2.js b/src/js/modules/mining/upgrade2.js
index db76339c..f1f63a40 100644
--- a/src/js/modules/mining/upgrade2.js
+++ b/src/js/modules/mining/upgrade2.js
@@ -6,14 +6,14 @@ const requirementBase = () => store.state.stat[requirementStat].total;
export default {
fumes: {subfeature: 1, price(lvl) {
- return {mining_scrap: Math.ceil(Math.pow(lvl * 0.012 + 1.24, lvl) * buildNum(7.5, 'M'))};
+ return {mining_scrap: Math.ceil(Math.pow(lvl * 0.012 + 1.24, lvl) * buildNum(750, 'K'))};
}, effect: [
{name: 'miningDamage', type: 'mult', value: lvl => Math.pow(1.12, lvl) * Math.pow(lvl * 0.2 + 1, 2)}
]},
giantCrate: {subfeature: 1, requirementBase, requirementStat, requirementValue: 5, price(lvl) {
- return {mining_scrap: Math.ceil(Math.pow(lvl * 2 + 10, lvl) * buildNum(25, 'M'))};
+ return {mining_scrap: Math.ceil(Math.pow(lvl * 2 + 8, lvl) * buildNum(2.5, 'M'))};
}, effect: [
- {name: 'currencyMiningScrapCap', type: 'mult', value: lvl => Math.pow(8, lvl)}
+ {name: 'currencyMiningScrapCap', type: 'mult', value: lvl => Math.pow(7, lvl)}
]},
morePressure: {subfeature: 1, requirementBase, requirementStat, requirementValue: 10, price(lvl) {
return {mining_scrap: Math.ceil(Math.pow(lvl * 0.025 + 1.75, lvl) * buildNum(400, 'M'))};
@@ -53,8 +53,8 @@ export default {
vent: {subfeature: 1, cap: 20, requirementBase, requirementStat, requirementValue: 40, price(lvl) {
return {mining_scrap: Math.ceil(Math.pow(1.65, lvl) * buildNum(40, 'T'))};
}, effect: [
- {name: 'miningDamage', type: 'mult', value: lvl => Math.pow(1.09, lvl)},
- {name: 'currencyMiningScrapGain', type: 'mult', value: lvl => Math.pow(1.12, lvl)}
+ {name: 'miningDamage', type: 'mult', value: lvl => Math.pow(1.05, lvl)},
+ {name: 'currencyMiningScrapGain', type: 'mult', value: lvl => Math.pow(1.3, lvl)}
]},
harvester: {subfeature: 1, requirementBase, requirementStat, requirementValue: 50, price(lvl) {
return {mining_neon: Math.round(Math.pow(1.35, lvl) * 50)};
diff --git a/src/js/modules/mining/upgradePremium.js b/src/js/modules/mining/upgradePremium.js
index f24aaa20..90814ee7 100644
--- a/src/js/modules/mining/upgradePremium.js
+++ b/src/js/modules/mining/upgradePremium.js
@@ -106,6 +106,22 @@ export default {
{name: 'currencyMiningOreIridiumGain', type: 'mult', value: lvl => Math.pow(2, lvl)},
{name: 'currencyMiningOreIridiumCap', type: 'mult', value: lvl => lvl * 0.25 + 1}
]},
+ moreOsmium: {type: 'premium', cap: 1, requirement() {
+ return store.state.stat.mining_maxDepth0.total >= 350;
+ }, price(lvl) {
+ return {gem_ruby: Math.pow(2, lvl) * 3500};
+ }, effect: [
+ {name: 'currencyMiningOreOsmiumGain', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ {name: 'currencyMiningOreOsmiumCap', type: 'mult', value: lvl => lvl * 0.25 + 1}
+ ]},
+ moreLead: {type: 'premium', cap: 1, requirement() {
+ return store.state.stat.mining_maxDepth0.total >= 450;
+ }, price(lvl) {
+ return {gem_ruby: Math.pow(2, lvl) * 5000};
+ }, effect: [
+ {name: 'currencyMiningOreLeadGain', type: 'mult', value: lvl => Math.pow(2, lvl)},
+ {name: 'currencyMiningOreLeadCap', type: 'mult', value: lvl => lvl * 0.25 + 1}
+ ]},
moreHelium: {type: 'premium', cap: 5, requirement() {
return store.state.unlock.miningGasSubfeature.see;
}, price(lvl) {
diff --git a/src/js/modules/mining/upgradePrestige.js b/src/js/modules/mining/upgradePrestige.js
index 585baa52..673ffc5d 100644
--- a/src/js/modules/mining/upgradePrestige.js
+++ b/src/js/modules/mining/upgradePrestige.js
@@ -75,11 +75,27 @@ export default {
}, effect: [
{name: 'currencyMiningOreIridiumCap', type: 'mult', value: lvl => lvl * 0.25 + 1}
]},
+ crystalOsmiumStorage: {type: 'prestige', cap: 16, requirement() {
+ return store.state.stat.mining_maxDepth0.total >= 350;
+ }, price(lvl) {
+ return {mining_crystalGreen: Math.pow(1.4, lvl) * buildNum(2.6, 'T')};
+ }, effect: [
+ {name: 'currencyMiningOreOsmiumCap', type: 'mult', value: lvl => lvl * 0.25 + 1}
+ ]},
+ crystalLeadStorage: {type: 'prestige', cap: 16, requirement() {
+ return store.state.stat.mining_maxDepth0.total >= 450;
+ }, price(lvl) {
+ return {mining_crystalGreen: Math.pow(1.4, lvl) * buildNum(2.6, 'T')};
+ }, effect: [
+ {name: 'currencyMiningOreLeadCap', type: 'mult', value: lvl => lvl * 0.25 + 1}
+ ]},
crystalDrill: {type: 'prestige', cap: 90, requirementBase: requirementBase0, requirementStat: requirementStat0, requirementValue: 5, price(lvl) {
return {mining_crystalGreen: Math.pow(lvl * 0.01 + 1.5, lvl) * 30};
}, effect: [
{name: 'miningDepthDwellerMax', type: 'mult', value: lvl => lvl * 0.1 + 1}
- ]},
+ ], onBuy() {
+ store.dispatch('mining/updateDwellerStat');
+ }},
crystalDetector: {type: 'prestige', requirementBase: requirementBase0, requirementStat: requirementStat0, requirementValue: 10, price(lvl) {
return {mining_crystalGreen: Math.pow(1.4, lvl) * 40};
}, effect: [
@@ -103,14 +119,14 @@ export default {
}, effect: [
{name: 'miningToughness', type: 'mult', value: lvl => Math.pow(1 / 1.2, lvl)}
]},
- crystalRefinery: {type: 'prestige', requirementBase: requirementBase0, requirementStat: requirementStat0, requirementValue: 25, price(lvl) {
+ crystalRefinery: {type: 'prestige', cap: 50, requirementBase: requirementBase0, requirementStat: requirementStat0, requirementValue: 25, price(lvl) {
return {mining_crystalGreen: Math.pow(1.4, lvl) * 650};
}, effect: [
{name: 'miningOreGain', type: 'mult', value: lvl => Math.pow(1.05, lvl) * (lvl * 0.1 + 1)},
{name: 'miningRareEarthGain', type: 'mult', value: lvl => Math.pow(1.05, lvl)},
{name: 'miningOreQuality', type: 'mult', value: lvl => lvl * 0.05 + 1}
]},
- crystalSmeltery: {type: 'prestige', requirementBase: requirementBase0, requirementStat: requirementStat0, requirementValue: 30, price(lvl) {
+ crystalSmeltery: {type: 'prestige', cap: 100, requirementBase: requirementBase0, requirementStat: requirementStat0, requirementValue: 30, price(lvl) {
return {mining_crystalGreen: Math.pow(1.4, lvl) * 3300};
}, effect: [
{name: 'miningSmelteryTemperature', type: 'base', value: lvl => 10 * lvl},
@@ -127,7 +143,7 @@ export default {
}, effect: [
{name: 'currencyMiningResinGain', type: 'mult', value: lvl => lvl * 0.1 + 1}
]},
- crystalSalt: {type: 'prestige', requirementBase: requirementBase0, requirementStat: requirementStat0, requirementValue: 50, price(lvl) {
+ crystalSalt: {type: 'prestige', cap: 50, requirementBase: requirementBase0, requirementStat: requirementStat0, requirementValue: 50, price(lvl) {
return {mining_crystalGreen: Math.pow(1.4, lvl) * buildNum(1.1, 'M')};
}, effect: [
{name: 'currencyMiningSaltGain', type: 'mult', value: lvl => Math.pow(1.1, lvl) * (lvl * 0.2 + 1)}
@@ -152,8 +168,8 @@ export default {
}, effect: [
{name: 'currencyMiningScrapCap', type: 'mult', value: lvl => Math.pow(1.5, lvl) * (lvl * 0.5 + 1)}
]},
- crystalExpansion: {type: 'prestige', cap: 7, requirementBase: requirementBase0, requirementStat: requirementStat0, requirementValue: 150, price(lvl) {
- return {mining_crystalGreen: Math.pow(10, lvl) * buildNum(25, 'T')};
+ crystalExpansion: {type: 'prestige', cap: 9, requirementBase: requirementBase0, requirementStat: requirementStat0, requirementValue: 150, price(lvl) {
+ return {mining_crystalGreen: Math.pow(10, lvl) * Math.pow(1000, Math.max(0, lvl - 6)) * buildNum(25, 'T')};
}, effect: [
{name: 'currencyMiningOreAluminiumCap', type: 'mult', value: lvl => lvl >= 1 ? 1000 : null},
{name: 'currencyMiningOreCopperCap', type: 'mult', value: lvl => lvl >= 2 ? 1000 : null},
@@ -161,7 +177,38 @@ export default {
{name: 'currencyMiningOreIronCap', type: 'mult', value: lvl => lvl >= 4 ? 1000 : null},
{name: 'currencyMiningOreTitaniumCap', type: 'mult', value: lvl => lvl >= 5 ? 1000 : null},
{name: 'currencyMiningOrePlatinumCap', type: 'mult', value: lvl => lvl >= 6 ? 1000 : null},
- {name: 'currencyMiningOreAluminiumCap', type: 'mult', value: lvl => lvl >= 7 ? 1000 : null}
+ {name: 'currencyMiningOreIridiumCap', type: 'mult', value: lvl => lvl >= 7 ? 1000 : null},
+ {name: 'currencyMiningOreOsmiumCap', type: 'mult', value: lvl => lvl >= 8 ? 1000 : null},
+ {name: 'currencyMiningOreLeadCap', type: 'mult', value: lvl => lvl >= 9 ? 1000 : null}
+ ]},
+ crystalTnt: {cap: 25, type: 'prestige', requirementBase: requirementBase0, requirementStat: requirementStat0, requirementValue: 175, price(lvl) {
+ return {mining_crystalGreen: Math.pow(10, lvl) * buildNum(6, 'Qa')};
+ }, effect: [
+ {name: 'miningToughness', type: 'mult', value: lvl => Math.pow(0.5, lvl)}
+ ]},
+ crystalBeacon: {type: 'prestige', cap: 4, requirementBase: requirementBase0, requirementStat: requirementStat0, requirementValue: 200, price(lvl) {
+ return {mining_crystalGreen: Math.pow(buildNum(1, 'M'), lvl) * buildNum(1, 'Sx')};
+ }, effect: [
+ {name: 'miningBeaconPiercing', type: 'base', value: lvl => lvl >= 1 ? 1 : null},
+ {name: 'miningBeaconRich', type: 'base', value: lvl => lvl >= 2 ? 1 : null},
+ {name: 'miningBeaconWonder', type: 'base', value: lvl => lvl >= 3 ? 1 : null},
+ {name: 'miningBeaconHope', type: 'base', value: lvl => lvl >= 4 ? 1 : null},
+ ]},
+ crystalNiter: {type: 'prestige', requirementBase: requirementBase0, requirementStat: requirementStat0, requirementValue: 225, price(lvl) {
+ return {mining_crystalGreen: Math.pow(lvl * 0.02 + 1.4, lvl) * buildNum(3, 'Sx')};
+ }, effect: [
+ {name: 'currencyMiningNiterGain', type: 'mult', value: lvl => lvl * 0.05 + 1}
+ ]},
+ crystalBunker: {type: 'prestige', cap: 20, requirementBase: requirementBase0, requirementStat: requirementStat0, requirementValue: 250, price(lvl) {
+ return {mining_crystalGreen: Math.pow(4.5, lvl) * buildNum(65, 'Sx')};
+ }, effect: [
+ {name: 'currencyMiningScrapCap', type: 'mult', value: lvl => Math.pow(1.2, lvl) * (lvl * 0.4 + 1)},
+ {name: 'miningOreCap', type: 'mult', value: lvl => lvl * 0.2 + 1},
+ ]},
+ crystalOreBag: {type: 'prestige', cap: 40, requirementBase: requirementBase0, requirementStat: requirementStat0, requirementValue: 300, price(lvl) {
+ return {mining_crystalGreen: Math.pow(1.2, lvl) * buildNum(1, 'Sp')};
+ }, effect: [
+ {name: 'miningOreCap', type: 'base', value: lvl => lvl}
]},
crystalSpikes: {type: 'prestige', requirement() {
diff --git a/src/js/modules/patchnote/v1_0_0.js b/src/js/modules/patchnote/v1_0_0.js
index cd4f2fb8..b4c29b1e 100644
--- a/src/js/modules/patchnote/v1_0_0.js
+++ b/src/js/modules/patchnote/v1_0_0.js
@@ -91,5 +91,11 @@ export default {
text: 'addedFeature',
}
],
+ mining_1: [
+ {
+ type: 'new',
+ text: 'addedSubfeature'
+ }
+ ],
}
}
diff --git a/src/js/modules/patchnote/v1_4_2.js b/src/js/modules/patchnote/v1_4_2.js
new file mode 100644
index 00000000..c5975831
--- /dev/null
+++ b/src/js/modules/patchnote/v1_4_2.js
@@ -0,0 +1,30 @@
+export default {
+ day: '2024-06-09',
+ content: {
+ card: [
+ {
+ type: 'balance',
+ text: '299_2'
+ }
+ ],
+ farm: [
+ {
+ unlock: 'farmCropExp',
+ type: 'balance',
+ text: '299_4'
+ },
+ ],
+ event: [
+ {
+ unlock: 'weatherChaosEvent',
+ type: 'bugfix',
+ text: '299_1'
+ },
+ {
+ unlock: 'weatherChaosEvent',
+ type: 'balance',
+ text: '299_3'
+ }
+ ]
+ }
+}
diff --git a/src/js/modules/patchnote/v1_5_0.js b/src/js/modules/patchnote/v1_5_0.js
new file mode 100644
index 00000000..94691c2a
--- /dev/null
+++ b/src/js/modules/patchnote/v1_5_0.js
@@ -0,0 +1,673 @@
+export default {
+ day: '2024-09-27',
+ content: {
+ meta: [
+ {
+ type: 'new',
+ text: '300'
+ },
+ {
+ type: 'new',
+ text: '311'
+ },
+ {
+ type: 'new',
+ text: '312'
+ },
+ {
+ type: 'bugfix',
+ text: '310'
+ },
+ {
+ type: 'accessibility',
+ text: '313'
+ },
+ {
+ type: 'anticheat',
+ text: '317'
+ },
+ {
+ type: 'anticheat',
+ text: '318'
+ },
+ {
+ unlock: 'gemFeature',
+ type: 'appearance',
+ text: '356'
+ },
+ {
+ unlock: 'miningDepthDweller',
+ type: 'clarity',
+ text: '377'
+ }
+ ],
+ mining: [
+ {
+ type: 'new',
+ text: 'addedUpgrade',
+ params: [8]
+ },
+ {
+ unlock: 'miningDepthDweller',
+ type: 'new',
+ text: 'addedPrestigeUpgrade',
+ params: [7]
+ },
+ {
+ unlock: 'gemFeature',
+ type: 'new',
+ text: 'addedGemUpgrade',
+ params: [2]
+ },
+ {
+ unlock: 'miningPickaxeCrafting',
+ type: 'new',
+ text: 'addedOre',
+ params: [2]
+ },
+ {
+ unlock: 'miningDepthDweller',
+ type: 'new',
+ text: 'addedRareEarth',
+ params: [1]
+ },
+ {
+ unlock: 'miningDepthDweller',
+ type: 'balance',
+ text: '352'
+ },
+ {
+ unlock: 'miningEnhancement',
+ type: 'change',
+ text: '309'
+ },
+ {
+ unlock: 'miningGasSubfeature',
+ type: 'qol',
+ text: '348'
+ }
+ ],
+ gem: [
+ {
+ type: 'new',
+ text: '357'
+ },
+ {
+ unlock: 'cardFeature',
+ type: 'new',
+ text: '358'
+ },
+ {
+ unlock: 'eventFeature',
+ type: 'new',
+ text: '359'
+ },
+ {
+ unlock: 'treasureFeature',
+ type: 'new',
+ text: '360'
+ }
+ ],
+ village: [
+ {
+ unlock: 'villageLoot',
+ type: 'balance',
+ text: '355'
+ },
+ {
+ unlock: 'villageOffering4',
+ type: 'balance',
+ text: '362'
+ }
+ ],
+ achievement: [
+ {
+ type: 'balance',
+ text: '328'
+ },
+ {
+ type: 'balance',
+ text: '329'
+ },
+ {
+ type: 'balance',
+ text: '347'
+ }
+ ],
+ school: [
+ {
+ type: 'balance',
+ text: '361'
+ }
+ ],
+ card: [
+ {
+ type: 'context',
+ text: '319'
+ },
+ {
+ type: 'new',
+ text: '314'
+ },
+ {
+ type: 'new',
+ text: '320'
+ },
+ {
+ type: 'change',
+ text: '321'
+ },
+ {
+ type: 'balance',
+ text: '322'
+ },
+ {
+ type: 'balance',
+ text: '323'
+ }
+ ],
+ horde: [
+ {
+ type: 'new',
+ text: 'addedAchievement',
+ params: [1]
+ },
+ {
+ type: 'new',
+ text: 'addedUpgrade',
+ params: [4]
+ },
+ {
+ unlock: 'hordePrestige',
+ type: 'new',
+ text: 'addedPrestigeUpgrade',
+ params: [4]
+ },
+ {
+ unlock: 'hordeItems',
+ type: 'new',
+ text: 'addedHordeItem',
+ params: [14]
+ },
+ {
+ unlock: 'hordeBrickTower',
+ type: 'new',
+ text: 'addedTower',
+ params: [2]
+ },
+ {
+ unlock: 'hordeHeirlooms',
+ type: 'new',
+ text: 'addedHordeHeirloom',
+ params: [2]
+ },
+ {
+ unlock: 'hordePrestige',
+ type: 'new',
+ text: 'addedHordeSigil',
+ params: [2]
+ },
+ {
+ unlock: 'hordePrestige',
+ type: 'balance',
+ text: '352'
+ },
+ {
+ unlock: 'hordeItemMastery',
+ type: 'bugfix',
+ text: '308'
+ },
+ {
+ unlock: 'hordeItemMastery',
+ type: 'bugfix',
+ text: '315'
+ },
+ {
+ unlock: 'hordeBrickTower',
+ type: 'qol',
+ text: '342'
+ },
+ {
+ unlock: 'hordeBrickTower',
+ type: 'balance',
+ text: '343'
+ },
+ {
+ unlock: 'hordeBrickTower',
+ type: 'balance',
+ text: '344',
+ balance: 'nerf',
+ before: 'x1.1',
+ after: 'x1.02'
+ },
+ {
+ unlock: 'hordeItems',
+ type: 'change',
+ text: '345'
+ },
+ {
+ unlock: 'hordeItems',
+ type: 'balance',
+ text: '346'
+ },
+ {
+ unlock: 'hordeDamageTypes',
+ type: 'balance',
+ text: '369'
+ },
+ {
+ unlock: 'hordeCorruptedFlesh',
+ type: 'new',
+ text: '370'
+ },
+ {
+ unlock: 'hordeBrickTower',
+ type: 'new',
+ text: '371'
+ },
+ {
+ unlock: 'hordeBrickTower',
+ type: 'change',
+ text: '376'
+ },
+ {
+ unlock: 'hordeBrickTower',
+ type: 'balance',
+ text: '378',
+ balance: 'nerf',
+ before: '100%',
+ after: '50%'
+ },
+ {
+ unlock: 'hordeHeirlooms',
+ type: 'balance',
+ text: '382',
+ balance: 'change',
+ before: '+0.05x',
+ after: '+0.25%'
+ },
+ {
+ unlock: 'hordeItems',
+ type: 'balance',
+ text: '387'
+ }
+ ],
+ farm: [
+ {
+ type: 'qol',
+ text: '380'
+ },
+ {
+ type: 'qol',
+ text: '381'
+ },
+ {
+ type: 'change',
+ text: '325'
+ },
+ {
+ type: 'change',
+ text: '334'
+ },
+ {
+ type: 'qol',
+ text: '335'
+ },
+ {
+ unlock: 'farmLuxuryCardPack',
+ type: 'balance',
+ text: '336',
+ balance: 'buff',
+ before: '5',
+ after: '25'
+ },
+ {
+ unlock: 'farmDisableEarlyGame',
+ type: 'new',
+ text: 'addedRareDrop',
+ params: [1]
+ },
+ {
+ unlock: 'farmCropExp',
+ type: 'new',
+ text: 'addedGene',
+ params: [7]
+ },
+ {
+ type: 'new',
+ text: 'addedCrop',
+ params: [5]
+ },
+ {
+ unlock: 'farmFertilizer',
+ type: 'new',
+ text: 'addedFertilizer',
+ params: [4]
+ },
+ {
+ type: 'new',
+ text: 'addedUpgrade',
+ params: [7]
+ },
+ {
+ unlock: 'farmDisableEarlyGame',
+ type: 'clarity',
+ text: '324'
+ },
+ {
+ unlock: 'farmCropExp',
+ type: 'context',
+ text: '301'
+ },
+ {
+ unlock: 'farmCropExp',
+ type: 'new',
+ text: '302'
+ },
+ {
+ unlock: 'farmCropExp',
+ type: 'balance',
+ text: '337'
+ },
+ {
+ unlock: 'farmCropExp',
+ type: 'new',
+ text: '338'
+ },
+ {
+ unlock: 'farmCropExp',
+ type: 'balance',
+ text: '339'
+ },
+ {
+ unlock: 'farmFertilizer',
+ type: 'balance',
+ text: '340'
+ },
+ {
+ unlock: 'farmDisableEarlyGame',
+ type: 'balance',
+ text: '379'
+ },
+ {
+ unlock: 'farmCropExp',
+ type: 'balance',
+ text: '341'
+ },
+ {
+ unlock: 'farmFertilizer',
+ type: 'balance',
+ text: '365',
+ balance: 'nerf',
+ before: '10%',
+ after: '4%'
+ },
+ {
+ unlock: 'farmFertilizer',
+ type: 'balance',
+ text: '366'
+ },
+ {
+ unlock: 'farmFertilizer',
+ type: 'balance',
+ text: '367'
+ },
+ {
+ unlock: 'farmFertilizer',
+ type: 'balance',
+ text: '368',
+ balance: 'nerf',
+ before: '20%',
+ after: '5%'
+ },
+ {
+ unlock: 'farmAdvancedCardPack',
+ type: 'balance',
+ text: '383',
+ balance: 'nerf',
+ before: '+0.02%',
+ after: '+0.01%'
+ },
+ {
+ unlock: 'farmAdvancedCardPack',
+ type: 'balance',
+ text: '372',
+ balance: 'change',
+ before: '+1%',
+ after: '+0.015x'
+ },
+ {
+ unlock: 'farmCropExp',
+ type: 'balance',
+ text: '373'
+ },
+ {
+ unlock: 'farmDisableEarlyGame',
+ type: 'balance',
+ text: '374'
+ }
+ ],
+ event: [
+ {
+ unlock: 'farmFertilizer',
+ type: 'balance',
+ text: '333',
+ balance: 'buff',
+ before: '5',
+ after: '20'
+ },
+ {
+ unlock: 'nightHuntEvent',
+ type: 'change',
+ text: '384',
+ },
+ {
+ unlock: 'nightHuntEvent',
+ type: 'new',
+ text: '385',
+ },
+ {
+ unlock: 'nightHuntEvent',
+ type: 'new',
+ text: '386',
+ },
+ ],
+ treasure: [
+ {
+ unlock: 'eventFeature',
+ type: 'balance',
+ text: '263',
+ balance: 'nerf',
+ before: '125%',
+ after: '100%'
+ },
+ {
+ unlock: 'eventFeature',
+ type: 'balance',
+ text: '331'
+ },
+ {
+ unlock: 'eventFeature',
+ type: 'balance',
+ text: '332',
+ balance: 'buff',
+ before: '16',
+ after: '32'
+ },
+ {
+ unlock: 'miningSmoke',
+ type: 'new',
+ text: '353'
+ },
+ {
+ type: 'qol',
+ text: '354'
+ }
+ ],
+ gallery: [
+ {
+ type: 'appearance',
+ text: '304'
+ },
+ {
+ type: 'new',
+ text: 'addedAchievement',
+ params: [4]
+ },
+ {
+ type: 'new',
+ text: 'addedGalleryIdea',
+ params: [18]
+ },
+ {
+ type: 'new',
+ text: 'addedRelic',
+ params: [15]
+ },
+ {
+ type: 'new',
+ text: 'addedUpgrade',
+ params: [40]
+ },
+ {
+ type: 'new',
+ text: 'addedPrestigeUpgrade',
+ params: [16]
+ },
+ {
+ type: 'new',
+ text: 'addedGemUpgrade',
+ params: [5]
+ },
+ {
+ unlock: 'galleryCanvas',
+ type: 'new',
+ text: '327'
+ },
+ {
+ unlock: 'galleryInspiration',
+ type: 'clarity',
+ text: '306'
+ },
+ {
+ type: 'context',
+ text: '303'
+ },
+ {
+ unlock: 'galleryConversion',
+ type: 'change',
+ text: '305'
+ },
+ {
+ unlock: 'galleryConversion',
+ type: 'new',
+ text: '326'
+ },
+ {
+ unlock: 'galleryShape',
+ type: 'new',
+ text: '307'
+ },
+ {
+ unlock: 'galleryAuction',
+ type: 'balance',
+ text: '316'
+ },
+ {
+ unlock: 'galleryAuction',
+ type: 'balance',
+ text: '363'
+ },
+ {
+ unlock: 'galleryInspiration',
+ type: 'balance',
+ text: '364'
+ },
+ {
+ unlock: 'galleryDrums',
+ type: 'balance',
+ text: '375'
+ }
+ ],
+ cryolab: [
+ {
+ type: 'balance',
+ text: '330',
+ balance: 'nerf',
+ before: '100%',
+ after: '40%'
+ },
+ ],
+ mining_1: [
+ {
+ type: 'balance',
+ text: '349',
+ balance: 'nerf',
+ before: '2',
+ after: '0.1'
+ },
+ {
+ type: 'balance',
+ text: '350',
+ balance: 'buff',
+ before: '25M',
+ after: '2.5M'
+ },
+ {
+ type: 'balance',
+ text: '351',
+ balance: 'nerf',
+ before: 'x8',
+ after: 'x7'
+ }
+ ],
+ village_1: [
+ {
+ type: 'new',
+ text: 'addedSubfeature'
+ },
+ {
+ type: 'new',
+ text: 'addedVillageRecipe',
+ params: [30]
+ },
+ {
+ type: 'new',
+ text: 'addedUpgrade',
+ params: [12]
+ },
+ {
+ type: 'new',
+ text: 'addedPrestigeUpgrade',
+ params: [10]
+ }
+ ],
+ horde_1: [
+ {
+ type: 'new',
+ text: 'addedSubfeature'
+ },
+ {
+ type: 'new',
+ text: 'addedUpgrade',
+ params: [11]
+ },
+ {
+ type: 'new',
+ text: 'addedPrestigeUpgrade',
+ params: [11]
+ },
+ {
+ type: 'new',
+ text: 'addedHordeClass',
+ params: [5]
+ },
+ {
+ unlock: 'hordeAreaMonkeyJungle',
+ type: 'new',
+ text: 'addedTrinket',
+ params: [19]
+ }
+ ],
+ }
+}
diff --git a/src/js/modules/patchnote/v1_5_1.js b/src/js/modules/patchnote/v1_5_1.js
new file mode 100644
index 00000000..905734bd
--- /dev/null
+++ b/src/js/modules/patchnote/v1_5_1.js
@@ -0,0 +1,50 @@
+export default {
+ day: '2024-09-28',
+ content: {
+ card: [
+ {
+ type: 'bugfix',
+ text: '392'
+ },
+ ],
+ horde: [
+ {
+ unlock: 'hordeItems',
+ type: 'bugfix',
+ text: '388'
+ },
+ ],
+ farm: [
+ {
+ type: 'bugfix',
+ text: '389'
+ },
+ ],
+ gallery: [
+ {
+ unlock: 'galleryConversion',
+ type: 'balance',
+ text: '390',
+ balance: 'nerf',
+ before: '4x',
+ after: '16x'
+ },
+ {
+ unlock: 'galleryConversion',
+ type: 'new',
+ text: '391'
+ },
+ {
+ unlock: 'galleryConversion',
+ type: 'clarity',
+ text: '394'
+ },
+ ],
+ horde_1: [
+ {
+ type: 'bugfix',
+ text: '393'
+ },
+ ],
+ }
+}
diff --git a/src/js/modules/patchnote/v1_5_2.js b/src/js/modules/patchnote/v1_5_2.js
new file mode 100644
index 00000000..a596d7b2
--- /dev/null
+++ b/src/js/modules/patchnote/v1_5_2.js
@@ -0,0 +1,15 @@
+export default {
+ day: '2024-09-29',
+ content: {
+ gallery: [
+ {
+ unlock: 'galleryConversion',
+ type: 'balance',
+ text: '395',
+ balance: 'buff',
+ before: '1.5x',
+ after: '1.9x'
+ },
+ ],
+ }
+}
diff --git a/src/js/modules/patchnote/v1_5_3.js b/src/js/modules/patchnote/v1_5_3.js
new file mode 100644
index 00000000..e14addf9
--- /dev/null
+++ b/src/js/modules/patchnote/v1_5_3.js
@@ -0,0 +1,24 @@
+export default {
+ day: '2024-09-29',
+ content: {
+ village: [
+ {
+ unlock: 'villageOffering1',
+ type: 'bugfix',
+ text: '396'
+ }
+ ],
+ event: [
+ {
+ type: 'bugfix',
+ text: '397'
+ }
+ ],
+ village_1: [
+ {
+ type: 'bugfix',
+ text: '398'
+ }
+ ]
+ }
+}
diff --git a/src/js/modules/relic.js b/src/js/modules/relic.js
index 98e36f13..58b3f9aa 100644
--- a/src/js/modules/relic.js
+++ b/src/js/modules/relic.js
@@ -1,8 +1,15 @@
+import store from "../../store";
import { buildArray } from "../utils/array";
+import glyph from "./relic/glyph";
export default {
name: 'relic',
unlockNeeded: 'relicFeature',
- unlock: ['relicFeature'],
- note: buildArray(1).map(() => 'g')
+ unlock: ['relicFeature', 'relicMuseum'],
+ note: buildArray(1).map(() => 'g'),
+ init() {
+ for (const [key, elem] of Object.entries(glyph)) {
+ store.commit('relic/initGlyph', {name: key, ...elem});
+ }
+ }
}
diff --git a/src/js/modules/relic/glyph.js b/src/js/modules/relic/glyph.js
new file mode 100644
index 00000000..6171880f
--- /dev/null
+++ b/src/js/modules/relic/glyph.js
@@ -0,0 +1,79 @@
+export default {
+ // mining
+ dust: {icon: 'mdi-weather-dust', color: 'brown', effect: [
+ {name: 'currencyMiningScrapGain', type: 'mult', value: lvl => Math.pow(1.2, lvl)},
+ {name: 'currencyMiningScrapCap', type: 'mult', value: lvl => Math.pow(1.15, lvl)}
+ ]},
+ clay: {icon: 'mdi-ellipse', color: 'pale-orange', effect: [
+ {name: 'miningOreGain', type: 'mult', value: lvl => Math.pow(1.12, lvl)},
+ {name: 'miningRareEarthGain', type: 'mult', value: lvl => Math.pow(1.16, lvl)}
+ ]},
+ fire: {icon: 'mdi-fire', color: 'orange-red', effect: [
+ {name: 'miningSmelterySpeed', type: 'mult', value: lvl => Math.pow(1.1, lvl)},
+ {name: 'currencyMiningEmberCap', type: 'base', value: lvl => lvl * 30}
+ ]},
+
+ // village
+ wood: {icon: 'mdi-tree', color: 'wooden', effect: [
+ {name: 'villageWorker', type: 'base', value: lvl => lvl * 12},
+ {name: 'villageArtisan', type: 'base', value: lvl => lvl}
+ ]},
+ flow: {icon: 'mdi-waterfall', color: 'light-blue', effect: [
+ {name: 'villageMaterialGain', type: 'mult', value: lvl => Math.pow(1.1, lvl)}
+ ]},
+ stone: {icon: 'mdi-chart-bubble', color: 'dark-grey', effect: [
+ {name: 'villageMaterialCap', type: 'mult', value: lvl => Math.pow(1.09, lvl)}
+ ]},
+
+ // horde
+ spike: {icon: 'mdi-nail', color: 'pale-red', effect: [
+ {name: 'hordeAttack', type: 'mult', value: lvl => Math.pow(1.12, lvl)},
+ {name: 'hordeHealth', type: 'mult', value: lvl => Math.pow(1.12, lvl)}
+ ]},
+ dream: {icon: 'mdi-sleep', color: 'pale-light-blue', effect: [
+ {name: 'hordeNostalgia', type: 'base', value: lvl => lvl * 15},
+ {name: 'hordeHeirloomAmount', type: 'base', value: lvl => lvl}
+ ]},
+ clover: {icon: 'mdi-clover', color: 'light-green', effect: [
+ {name: 'hordeItemChance', type: 'mult', value: lvl => Math.pow(1.1, lvl)},
+ {name: 'hordeItemMasteryGain', type: 'mult', value: lvl => Math.pow(1.18, lvl)}
+ ]},
+
+ // farm
+ rain: {icon: 'mdi-weather-pouring', color: 'dark-blue', effect: [
+ {name: 'currencyFarmVegetableGain', type: 'mult', value: lvl => Math.pow(1.15, lvl)},
+ {name: 'currencyFarmGrassCap', type: 'base', value: lvl => lvl * 100}
+ ]},
+ sun: {icon: 'mdi-white-balance-sunny', color: 'yellow', effect: [
+ {name: 'currencyFarmBerryGain', type: 'mult', value: lvl => Math.pow(1.15, lvl)},
+ {name: 'farmGoldChance', type: 'mult', value: lvl => lvl * 0.03 + 1}
+ ]},
+ cloud: {icon: 'mdi-clouds', color: 'blue-grey', effect: [
+ {name: 'currencyFarmGrainGain', type: 'mult', value: lvl => Math.pow(1.15, lvl)},
+ {name: 'currencyFarmFlowerGain', type: 'mult', value: lvl => Math.pow(1.15, lvl)}
+ ]},
+
+ // gallery
+ blossom: {icon: 'mdi-image-filter-vintage', color: 'purple', effect: [
+ {name: 'currencyGalleryBeautyGain', type: 'mult', value: lvl => Math.pow(1.35, lvl)},
+ {name: 'currencyGalleryConverterGain', type: 'mult', value: lvl => Math.pow(1.06, lvl)}
+ ]},
+ leaf: {icon: 'mdi-leaf', color: 'pale-green', effect: [
+ {name: 'galleryShapeGain', type: 'mult', value: lvl => Math.pow(1.15, lvl)},
+ {name: 'currencyGalleryMotivationCap', type: 'base', value: lvl => lvl * 5}
+ ]},
+ paper: {icon: 'mdi-note', color: 'pale-yellow', effect: [
+ {name: 'galleryInspirationStart', type: 'base', value: lvl => lvl},
+ {name: 'galleryCanvasSize', type: 'base', value: lvl => lvl}
+ ]},
+
+ // other
+ book: {icon: 'mdi-book', color: 'beige', effect: [
+ {name: 'currencySchoolBookGain', type: 'base', value: lvl => lvl * 5},
+ {name: 'currencySchoolGoldenDustCap', type: 'base', value: lvl => lvl * 2500}
+ ]},
+ coin: {icon: 'mdi-circle-multiple', color: 'amber', effect: [
+ {name: 'currencyTreasureFragmentGain', type: 'mult', value: lvl => lvl * 0.05 + 1},
+ {name: 'treasureSlots', type: 'base', value: lvl => lvl}
+ ]},
+}
diff --git a/src/js/modules/school.js b/src/js/modules/school.js
index 8d912df9..19012552 100644
--- a/src/js/modules/school.js
+++ b/src/js/modules/school.js
@@ -43,7 +43,7 @@ export default {
let obj = {};
for (const [key, elem] of Object.entries(store.state.school)) {
if (elem.grade > 0 || elem.progress > 0) {
- obj[key] = {grade: elem.grade, currentGrade: elem.currentGrade, progress: elem.progress};
+ obj[key] = [elem.grade, elem.currentGrade, elem.progress];
}
}
return obj;
@@ -51,9 +51,9 @@ export default {
loadGame(data) {
for (const [key, elem] of Object.entries(data)) {
if (store.state.school[key] !== undefined) {
- store.commit('school/updateKey', {name: key, key: 'grade', value: elem.grade});
- store.commit('school/updateKey', {name: key, key: 'currentGrade', value: elem.currentGrade});
- store.commit('school/updateKey', {name: key, key: 'progress', value: elem.progress});
+ store.commit('school/updateKey', {name: key, key: 'grade', value: elem[0]});
+ store.commit('school/updateKey', {name: key, key: 'currentGrade', value: elem[1]});
+ store.commit('school/updateKey', {name: key, key: 'progress', value: elem[2]});
}
}
}
diff --git a/src/js/modules/treasure.js b/src/js/modules/treasure.js
index 3da683e8..76f19b8a 100644
--- a/src/js/modules/treasure.js
+++ b/src/js/modules/treasure.js
@@ -40,9 +40,9 @@ const treasureTypes = {
icon: 'mdi-call-split'
},
empowered: {
- destroyPrice: 16,
+ destroyPrice: 32,
slots: [
- {type: 'regular', power: 1.25}
+ {type: 'regular', power: 1}
],
icon: 'mdi-star-circle'
},
diff --git a/src/js/modules/treasure/effect.js b/src/js/modules/treasure/effect.js
index 5cb8c4f5..9b715a57 100644
--- a/src/js/modules/treasure/effect.js
+++ b/src/js/modules/treasure/effect.js
@@ -1,36 +1,38 @@
export default {
// Mining effects
- miningDamage: {feature: 'mining', value: 0.25},
- currencyMiningScrapGain: {feature: 'mining', value: 0.3},
- miningOreGain: {feature: 'mining', value: 0.2},
- miningSmelterySpeed: {feature: 'mining', unlock: 'miningSmeltery', value: 0.2},
- currencyMiningCrystalGreenGain: {feature: 'mining', type: 'special', unique: true, value: 0.1},
- currencyMiningCrystalYellowGain: {feature: 'mining', unlock: 'miningGasSubfeature', type: 'special', unique: true, value: 0.05},
+ miningDamage: {feature: 'mining', icon: 'mdi-bomb', value: 0.25},
+ currencyMiningScrapGain: {feature: 'mining', icon: 'mdi-dots-triangle', value: 0.3},
+ miningOreGain: {feature: 'mining', icon: 'mdi-chart-bubble', value: 0.2},
+ miningSmelterySpeed: {feature: 'mining', unlock: 'miningSmeltery', icon: 'mdi-fire', value: 0.2},
+ currencyMiningSmokeGain: {feature: 'mining', unlock: 'miningSmoke', icon: 'mdi-smoke', value: 0.04},
+ currencyMiningCrystalGreenGain: {feature: 'mining', type: 'special', icon: 'mdi-star-three-points', unique: true, value: 0.1},
+ currencyMiningCrystalYellowGain: {feature: 'mining', unlock: 'miningGasSubfeature', type: 'special', icon: 'mdi-star-four-points', unique: true, value: 0.05},
// Village effects
- queueSpeedVillageBuilding: {feature: 'village', value: 0.3},
- villageMaterialGain: {feature: 'village', value: 0.1},
- currencyVillageCoinGain: {feature: 'village', value: 0.25},
- villageMentalGain: {feature: 'village', value: 0.1},
- currencyVillageFaithGain: {feature: 'village', type: 'special', unique: true, value: 0.1},
+ queueSpeedVillageBuilding: {feature: 'village', icon: 'mdi-hammer', value: 0.3},
+ villageMaterialGain: {feature: 'village', icon: 'mdi-tree', value: 0.1},
+ currencyVillageCoinGain: {feature: 'village', icon: 'mdi-circle-multiple', value: 0.25},
+ villageMentalGain: {feature: 'village', icon: 'mdi-brain', value: 0.1},
+ currencyVillageFaithGain: {feature: 'village', type: 'special', icon: 'mdi-hands-pray', unique: true, value: 0.1},
+ currencyVillageSharesGain: {feature: 'village', unlock: 'villageCraftingSubfeature', type: 'special', icon: 'mdi-certificate', unique: true, value: 0.05},
// Horde effects
- hordeAttack: {feature: 'horde', value: 0.2},
- currencyHordeBoneGain: {feature: 'horde', value: 0.3},
- currencyHordeMonsterPartGain: {feature: 'horde', value: 0.15},
- hordeItemMasteryGain: {feature: 'horde', unlock: 'hordeItemMastery', value: 0.1},
- currencyHordeSoulCorruptedGain: {feature: 'horde', type: 'special', unique: true, value: 0.1},
+ hordeAttack: {feature: 'horde', icon: 'mdi-sword', value: 0.2},
+ currencyHordeBoneGain: {feature: 'horde', icon: 'mdi-bone', value: 0.3},
+ currencyHordeMonsterPartGain: {feature: 'horde', icon: 'mdi-stomach', value: 0.15},
+ hordeItemMasteryGain: {feature: 'horde', unlock: 'hordeItemMastery', icon: 'mdi-seal', value: 0.1},
+ currencyHordeSoulCorruptedGain: {feature: 'horde', type: 'special', icon: 'mdi-ghost', unique: true, value: 0.1},
// Farm effects
- currencyFarmVegetableGain: {feature: 'farm', value: 0.35},
- currencyFarmFruitGain: {feature: 'farm', value: 0.35},
- currencyFarmGrainGain: {feature: 'farm', value: 0.35},
- currencyFarmFlowerGain: {feature: 'farm', value: 0.35},
- farmExperience: {feature: 'farm', unlock: 'farmCropExp', type: 'special', unique: true, value: 0.1},
+ currencyFarmVegetableGain: {feature: 'farm', icon: 'mdi-carrot', value: 0.35},
+ currencyFarmBerryGain: {feature: 'farm', icon: 'mdi-fruit-grapes', value: 0.35},
+ currencyFarmGrainGain: {feature: 'farm', icon: 'mdi-barley', value: 0.35},
+ currencyFarmFlowerGain: {feature: 'farm', icon: 'mdi-flower', value: 0.35},
+ farmExperience: {feature: 'farm', unlock: 'farmCropExp', type: 'special', icon: 'mdi-star', unique: true, value: 0.1},
// Gallery effects
- currencyGalleryBeautyGain: {feature: 'gallery', value: 0.4},
- currencyGalleryConverterGain: {feature: 'gallery', unlock: 'galleryConversion', value: 0.15},
- currencyGalleryPackageGain: {feature: 'gallery', unlock: 'galleryDrums', value: 0.15},
- currencyGalleryCashGain: {feature: 'gallery', type: 'special', unique: true, value: 0.1},
+ currencyGalleryBeautyGain: {feature: 'gallery', icon: 'mdi-image-filter-vintage', value: 0.4},
+ currencyGalleryConverterGain: {feature: 'gallery', unlock: 'galleryConversion', icon: 'mdi-recycle', value: 0.15},
+ currencyGalleryPackageGain: {feature: 'gallery', unlock: 'galleryDrums', icon: 'mdi-package-variant', value: 0.15},
+ currencyGalleryCashGain: {feature: 'gallery', type: 'special', icon: 'mdi-cash', unique: true, value: 0.1},
}
diff --git a/src/js/modules/village.js b/src/js/modules/village.js
index f26a7abb..06871e4d 100644
--- a/src/js/modules/village.js
+++ b/src/js/modules/village.js
@@ -2,6 +2,7 @@ import store from "../../store"
import achievement from "./village/achievement";
import upgradePrestige from "./village/upgradePrestige";
import upgrade from "./village/upgrade";
+import upgrade2 from "./village/upgrade2";
import upgradePremium from "./village/upgradePremium";
import building from "./village/building";
import { buildArray } from "../utils/array";
@@ -9,8 +10,10 @@ import relic from "./village/relic";
import job from "./village/job";
import offering from "./village/offering";
import policy from "./village/policy";
-import { SECONDS_PER_HOUR, VILLAGE_COINS_PER_FOOD, VILLAGE_MIN_HAPPINESS } from "../constants";
+import { SECONDS_PER_DAY, SECONDS_PER_HOUR, VILLAGE_COINS_PER_FOOD, VILLAGE_MIN_HAPPINESS } from "../constants";
import bookVillage from "./school/bookVillage";
+import craftingRecipe from "./village/craftingRecipe";
+import { randomRound } from "../utils/random";
let upgradeBuilding = {};
for (const [key, elem] of Object.entries(building)) {
@@ -21,70 +24,183 @@ export default {
name: 'village',
tickspeed: 1,
unlockNeeded: 'villageFeature',
- tick(seconds) {
+ tick(seconds, oldTime, newTime) {
store.commit('stat/add', {feature: 'village', name: 'timeSpent', value: seconds});
-
- store.dispatch('upgrade/tickQueue', {key: 'village_building', seconds: seconds * store.getters['mult/get']('queueSpeedVillageBuilding')});
-
- const happiness = store.getters['mult/get']('villageHappiness');
- const taxpayers = store.getters['mult/get']('villageTaxRate') * store.getters['village/employed'];
-
+ let diffs = {};
store.getters['currency/list']('village', 'regular').filter(elem => !['village_coin', 'village_joy'].includes(elem)).forEach(currency => {
- const name = currency.split('_')[1];
- const gain = store.getters['mult/get'](store.getters['currency/gainMultName']('village', name));
+ const gain = store.getters['mult/get'](store.getters['currency/gainMultName'](...currency.split('_')));
if (gain > 0) {
- store.dispatch('currency/gain', {feature: 'village', name, amount: gain * seconds});
+ if (diffs[currency] === undefined) {
+ diffs[currency] = 0;
+ }
+ diffs[currency] += gain * seconds;
}
});
- if (store.state.stat.village_faith.total >= 50) {
- store.commit('unlock/unlock', 'villagePrestige');
- }
+ if (store.state.system.features.village.currentSubfeature === 0) {
+ store.dispatch('upgrade/tickQueue', {key: 'village_building', seconds: seconds * store.getters['mult/get']('queueSpeedVillageBuilding')});
- if (taxpayers > 0) {
- store.getters['currency/list']('village', 'regular', 'food').forEach(foodName => {
- const food = foodName.split('_')[1];
- const foodConsumed = Math.min(taxpayers * seconds, store.getters['currency/value']('village_' + food));
- if (foodConsumed > 0) {
- store.dispatch('currency/spend', {feature: 'village', name: food, amount: foodConsumed});
- store.dispatch('currency/gain', {feature: 'village', name: 'coin', gainMult: true, amount: foodConsumed * VILLAGE_COINS_PER_FOOD});
+ const happiness = store.getters['mult/get']('villageHappiness');
+
+ if (store.state.stat.village_faith.total >= 50) {
+ store.commit('unlock/unlock', 'villagePrestige');
+ }
+
+ // Auto-gain 1% of offerings gained this run
+ const offeringGain = store.getters['village/offeringPerSecond'];
+ if (offeringGain > 0) {
+ let newOffering = store.state.village.offeringGen + offeringGain * seconds;
+ if (newOffering > 0) {
+ store.dispatch('currency/gain', {feature: 'village', name: 'offering', amount: Math.floor(newOffering)});
+ newOffering -= Math.floor(newOffering);
}
- });
- }
+ store.commit('village/updateKey', {key: 'offeringGen', value: newOffering});
+ }
- // Auto-gain 1% of offerings gained this run
- const offeringGain = store.getters['village/offeringPerSecond'];
- if (offeringGain > 0) {
- let newOffering = store.state.village.offeringGen + offeringGain * seconds;
- if (newOffering > 0) {
- store.dispatch('currency/gain', {feature: 'village', name: 'offering', amount: Math.floor(newOffering)});
- newOffering -= Math.floor(newOffering);
+ const joyGain = store.getters['village/joyGainBase'];
+ if (joyGain > 0) {
+ store.dispatch('currency/gain', {feature: 'village', name: 'joy', gainMult: true, amount: joyGain * seconds});
+ }
+ if (happiness <= VILLAGE_MIN_HAPPINESS) {
+ store.commit('stat/increaseTo', {feature: 'village', name: 'minHappiness', value: 1});
}
- store.commit('village/updateKey', {key: 'offeringGen', value: newOffering});
- }
- const joyGain = store.getters['village/joyGainBase'];
- if (joyGain > 0) {
- store.dispatch('currency/gain', {feature: 'village', name: 'joy', gainMult: true, amount: joyGain * seconds});
- }
- if (happiness <= VILLAGE_MIN_HAPPINESS) {
- store.commit('stat/increaseTo', {feature: 'village', name: 'minHappiness', value: 1});
+ const lootGain = store.getters['mult/get']('villageLootGain');
+ if (lootGain > 0) {
+ let newLoot = store.state.village.explorerProgress + seconds * lootGain / SECONDS_PER_HOUR;
+ if (newLoot >= 1) {
+ const lootDrops = Math.floor(newLoot);
+ store.dispatch('village/getLootDrops', lootDrops);
+ newLoot -= lootDrops;
+ }
+ store.commit('village/updateKey', {key: 'explorerProgress', value: newLoot});
+ store.commit('unlock/unlock', 'villageLoot');
+ }
+
+ store.commit('stat/increaseTo', {feature: 'village', name: 'highestPower', value: store.getters['mult/get']('villagePower')});
+ } else if (store.state.system.features.village.currentSubfeature === 1) {
+ for (let p = 0; p < 2; p++) {
+ for (const [key, elem] of Object.entries(store.state.village.crafting)) {
+ if (elem.isCrafting && elem.prio === p) {
+ let newProgress = elem.progress + seconds / elem.timeNeeded;
+ const payments = Math.ceil(newProgress) - Math.ceil(elem.progress);
+ if (payments > 0) {
+ let maxAfford = payments;
+ for (const [currency, value] of Object.entries(elem.price)) {
+ const split = currency.split('_');
+ if (elem.isSpecial) {
+ let newMaxAfford = 0;
+ let accumulatedPrice = 0;
+ while (newMaxAfford < maxAfford) {
+ accumulatedPrice += value(elem.owned + newMaxAfford);
+ if (split[0] === 'craft') {
+ if (store.state.village.crafting[split[1]].owned < accumulatedPrice) {
+ break;
+ }
+ } else {
+ // Can't afford any if cap is to small
+ if (store.state.currency[currency].cap !== null && store.state.currency[currency].cap < value(elem.owned + newMaxAfford)) {
+ break;
+ }
+ if ((store.state.currency[currency].value + (diffs[currency] ?? 0)) < accumulatedPrice) {
+ break;
+ }
+ }
+ newMaxAfford++;
+ }
+ maxAfford = newMaxAfford;
+ } else {
+ if (split[0] === 'craft') {
+ maxAfford = Math.min(Math.floor((store.state.village.crafting[split[1]].owned) / value), maxAfford);
+ } else {
+ // Can't afford any if cap is to small
+ if (store.state.currency[currency].cap !== null && store.state.currency[currency].cap < value) {
+ maxAfford = 0;
+ }
+ maxAfford = Math.min(Math.floor((store.state.currency[currency].value + (diffs[currency] ?? 0)) / value), maxAfford);
+ }
+ }
+ }
+ if (maxAfford > 0) {
+ for (const [currency, value] of Object.entries(elem.price)) {
+ const split = currency.split('_');
+ let priceValue = 0;
+ if (elem.isSpecial) {
+ for (let i = 0; i < maxAfford; i++) {
+ priceValue += value(elem.owned + i);
+ }
+ } else {
+ priceValue = value * maxAfford;
+ }
+ if (split[0] === 'craft') {
+ store.commit('village/updateSubkey', {key: 'crafting', name: split[1], subkey: 'owned', value: store.state.village.crafting[split[1]].owned - priceValue});
+ } else {
+ if (diffs[currency] === undefined) {
+ diffs[currency] = 0;
+ }
+ diffs[currency] -= priceValue;
+ }
+ }
+ }
+ if (maxAfford < payments) {
+ newProgress = maxAfford + Math.ceil(elem.progress);
+ }
+ }
+ if (newProgress >= 1) {
+ store.commit('village/updateSubkey', {key: 'crafting', name: key, subkey: 'owned', value: elem.owned + Math.floor(newProgress)});
+ store.commit('village/updateSubkey', {key: 'crafting', name: key, subkey: 'crafted', value: elem.crafted + Math.floor(newProgress)});
+ if (elem.isSpecial) {
+ store.dispatch('village/applySpecialCraftEffects', key);
+ } else {
+ store.dispatch('village/applyMilestoneEffects', key);
+ store.dispatch('village/applyMilestoneGlobalLevel');
+ }
+ newProgress -= Math.floor(newProgress);
+ }
+ store.commit('village/updateSubkey', {key: 'crafting', name: key, subkey: 'progress', value: newProgress});
+ }
+ if (elem.isSelling && elem.prio === p && elem.sellPrice > 0 && elem.owned > 0) {
+ const sold = Math.min(randomRound(seconds * elem.cacheSellChance), elem.owned);
+ if (sold > 0) {
+ store.dispatch('currency/gain', {feature: 'village', name: 'copperCoin', gainMult: true, amount: sold * elem.sellPrice});
+ store.commit('village/updateSubkey', {key: 'crafting', name: key, subkey: 'owned', value: elem.owned - sold});
+ }
+ }
+ }
+ }
}
- const lootGain = store.getters['mult/get']('villageLootGain');
- if (lootGain > 0) {
- let newLoot = store.state.village.explorerProgress + seconds * lootGain / SECONDS_PER_HOUR;
- if (newLoot >= 1) {
- const lootDrops = Math.floor(newLoot);
- store.dispatch('village/getLootDrops', lootDrops);
- newLoot -= lootDrops;
+ // Apply currency diffs
+ for (const [name, value] of Object.entries(diffs)) {
+ const split = name.split('_');
+ if (value > 0) {
+ store.dispatch('currency/gain', {feature: split[0], name: split[1], amount: value});
+ } else if (value < 0) {
+ store.dispatch('currency/spend', {feature: split[0], name: split[1], amount: -value});
}
- store.commit('village/updateKey', {key: 'explorerProgress', value: newLoot});
- store.commit('unlock/unlock', 'villageLoot');
}
- store.commit('stat/increaseTo', {feature: 'village', name: 'highestPower', value: store.getters['mult/get']('villagePower')});
+ if (store.state.system.features.village.currentSubfeature === 0) {
+ const taxpayers = store.getters['mult/get']('villageTaxRate') * store.getters['village/employed'];
+ if (taxpayers > 0) {
+ store.getters['currency/list']('village', 'regular', 'food').forEach(foodName => {
+ const food = foodName.split('_')[1];
+ const foodConsumed = Math.min(taxpayers * seconds, store.getters['currency/value']('village_' + food));
+ if (foodConsumed > 0) {
+ store.dispatch('currency/spend', {feature: 'village', name: food, amount: foodConsumed});
+ store.dispatch('currency/gain', {feature: 'village', name: 'coin', gainMult: true, amount: foodConsumed * VILLAGE_COINS_PER_FOOD});
+ }
+ });
+ }
+ }
+ // Get free boxes
+ if (store.state.unlock.villageSpecialIngredient.see) {
+ const dayDiff = Math.floor(newTime / (SECONDS_PER_DAY * 7)) - Math.floor(oldTime / (SECONDS_PER_DAY * 7));
+ if (dayDiff > 0) {
+ store.dispatch('consumable/gain', {name: 'village_ingredientBox', amount: dayDiff});
+ }
+ }
},
unlock: [
'villageFeature',
@@ -102,22 +218,26 @@ export default {
].map(elem => 'villageUpgrade' + elem),
...buildArray(4).map(elem => 'villageOffering' + (elem + 1)),
'villageLoot',
- 'villageCraftingSubfeature'
+ 'villageCraftingSubfeature',
+ 'villageSpecialIngredient'
],
stat: {
- maxBuilding: {},
+ maxBuilding: {showInStatistics: true},
maxHousing: {},
timeSpent: {display: 'time'},
- bestPrestige: {},
- prestigeCount: {},
- totalOffering: {},
+ bestPrestige0: {showInStatistics: true},
+ bestPrestige1: {showInStatistics: true},
+ prestigeCount: {showInStatistics: true},
+ totalOffering: {showInStatistics: true},
minHappiness: {},
- bestOffering: {},
+ bestOffering: {showInStatistics: true},
offeringAmount: {},
- highestPower: {},
+ highestPower: {showInStatistics: true},
},
mult: {
villageWorker: {baseValue: 1, round: true},
+ villageArtisan: {baseValue: 1, round: true},
+ villageCounter: {baseValue: 1, round: true},
queueSpeedVillageBuilding: {baseValue: 1},
villageTaxRate: {display: 'percent'},
villageHappiness: {display: 'percent', baseValue: 1, min: VILLAGE_MIN_HAPPINESS},
@@ -125,6 +245,9 @@ export default {
villagePollutionTolerance: {baseValue: 5, round: true},
villagePower: {min: 0},
villageOfferingPower: {},
+ villageIngredientCount: {baseValue: 1, round: true},
+ villageIngredientBoxAmount: {baseValue: 12, round: true},
+ villagePrestigeIncome: {group: ['currencyVillageFaithGain', 'currencyVillageFaithCap', 'currencyVillageSharesGain']},
// Upgrade cap mults
villageHousingCap: {},
@@ -174,6 +297,7 @@ export default {
return Math.min(taxpayers, nextAmount) * VILLAGE_COINS_PER_FOOD;
}).reduce((a, b) => a + b, 0));
}, timerIsEstimate: true},
+ copperCoin: {overcapMult: 0.5, color: 'orange', icon: 'mdi-circle-multiple', gainMult: {}, capMult: {baseValue: 4000}},
// Basic material
plantFiber: {subtype: 'material', overcapMult: 0.4, color: 'green', icon: 'mdi-leaf', gainMult: {display: 'perSecond'}, showGainMult: true, showGainTimer: true, capMult: {baseValue: 2000}},
@@ -210,8 +334,15 @@ export default {
loot4: {subtype: 'loot', color: 'amber', icon: 'mdi-trophy-variant'},
loot5: {subtype: 'loot', color: 'red', icon: 'mdi-trophy-variant'},
+ // Special crafting ingredients
+ acidVial: {subtype: 'specialIngredient', color: 'lime', icon: 'mdi-test-tube'},
+ snowflake: {subtype: 'specialIngredient', color: 'cyan', icon: 'mdi-snowflake-variant'},
+ chiliBundle: {subtype: 'specialIngredient', color: 'red-orange', icon: 'mdi-chili-hot'},
+ gears: {subtype: 'specialIngredient', color: 'blue-grey', icon: 'mdi-cogs'},
+
// Prestige currency
blessing: {type: 'prestige', alwaysVisible: true, color: 'yellow', icon: 'mdi-flare'},
+ shares: {type: 'prestige', alwaysVisible: true, color: 'beige', icon: 'mdi-certificate', gainMult: {}},
offering: {type: 'prestige', color: 'orange-red', icon: 'mdi-candle', gainMult: {display: 'perHour'}, showGainMult: true, gainTimerFunction() {
return store.getters['village/offeringPerSecond'] * SECONDS_PER_HOUR;
}, timerIsEstimate: true}
@@ -219,11 +350,19 @@ export default {
upgrade: {
...upgradeBuilding,
...upgrade,
+ ...upgrade2,
...upgradePrestige,
...upgradePremium,
...bookVillage
},
note: [...buildArray(31).map(() => 'g'), 'system'],
+ consumable: {
+ ingredientBox: {
+ icon: 'mdi-gift',
+ color: 'indigo',
+ price: {gem_sapphire: 80}
+ }
+ },
init() {
for (const [key, elem] of Object.entries(job)) {
store.commit('village/initJob', {name: key, ...elem});
@@ -234,6 +373,9 @@ export default {
for (const [key, elem] of Object.entries(policy)) {
store.commit('village/initPolicy', {name: key, ...elem});
}
+ for (const [key, elem] of Object.entries(craftingRecipe)) {
+ store.commit('village/initCrafting', {name: key, ...elem});
+ }
},
saveGame() {
let obj = {
@@ -249,7 +391,7 @@ export default {
obj.offering = {};
for (const [key, elem] of Object.entries(store.state.village.offering)) {
if (elem.offeringBought > 0 || elem.upgradeBought > 0) {
- obj.offering[key] = {offeringBought: elem.offeringBought, upgradeBought: elem.upgradeBought};
+ obj.offering[key] = [elem.offeringBought, elem.upgradeBought];
}
}
}
@@ -272,6 +414,24 @@ export default {
obj.offeringGen = store.state.village.offeringGen;
}
+ // Add crafting stuff
+ let crafting = {};
+ for (const [key, elem] of Object.entries(store.state.village.crafting)) {
+ if (elem.crafted > 0 || elem.isCrafting || elem.isSelling || elem.sellPrice !== elem.baseValue || elem.progress > 0) {
+ crafting[key] = {
+ isCrafting: elem.isCrafting,
+ isSelling: elem.isSelling,
+ sellPrice: elem.sellPrice,
+ progress: elem.progress,
+ owned: elem.owned,
+ crafted: elem.crafted
+ };
+ }
+ }
+ if (Object.keys(crafting).length > 0) {
+ obj.crafting = crafting;
+ }
+
return obj;
},
loadGame(data) {
@@ -285,8 +445,8 @@ export default {
if (data.offering !== undefined) {
for (const [key, elem] of Object.entries(data.offering)) {
if (store.state.village.offering[key] !== undefined) {
- store.commit('village/updateOfferingKey', {name: key, key: 'offeringBought', value: elem.offeringBought});
- store.commit('village/updateOfferingKey', {name: key, key: 'upgradeBought', value: elem.upgradeBought});
+ store.commit('village/updateOfferingKey', {name: key, key: 'offeringBought', value: elem[0]});
+ store.commit('village/updateOfferingKey', {name: key, key: 'upgradeBought', value: elem[1]});
}
}
}
@@ -298,6 +458,25 @@ export default {
}
}
}
+ if (data.crafting !== undefined) {
+ for (const [key, elem] of Object.entries(data.crafting)) {
+ if (store.state.village.crafting[key] !== undefined) {
+ store.commit('village/updateSubkey', {key: 'crafting', name: key, subkey: 'isCrafting', value: elem.isCrafting});
+ store.commit('village/updateSubkey', {key: 'crafting', name: key, subkey: 'isSelling', value: elem.isSelling});
+ store.commit('village/updateSubkey', {key: 'crafting', name: key, subkey: 'sellPrice', value: elem.sellPrice});
+ store.commit('village/updateSubkey', {key: 'crafting', name: key, subkey: 'progress', value: elem.progress});
+ store.commit('village/updateSubkey', {key: 'crafting', name: key, subkey: 'owned', value: elem.owned});
+ store.commit('village/updateSubkey', {key: 'crafting', name: key, subkey: 'crafted', value: elem.crafted});
+ if (store.state.village.crafting[key].isSpecial) {
+ if (elem.owned > 0) {
+ store.dispatch('village/applySpecialCraftEffects', key);
+ }
+ } else {
+ store.dispatch('village/applyMilestoneEffects', key);
+ }
+ }
+ }
+ }
if (data.explorerProgress !== undefined) {
store.commit('village/updateKey', {key: 'explorerProgress', value: data.explorerProgress});
}
diff --git a/src/js/modules/village/building.js b/src/js/modules/village/building.js
index 982ec974..99dac755 100644
--- a/src/js/modules/village/building.js
+++ b/src/js/modules/village/building.js
@@ -995,8 +995,8 @@ export default {
}, timeNeeded(lvl) {
return Math.ceil(Math.pow(2.5, lvl) * buildNum(150, 'B'));
}, effect: [
- {name: 'villageMaterialGain', type: 'mult', value: lvl => Math.pow(2, lvl)},
- {name: 'villageMaterialCap', type: 'mult', value: lvl => Math.pow(1.4, lvl)}
+ {name: 'villageMaterialGain', type: 'mult', value: lvl => Math.pow(1.4, lvl)},
+ {name: 'villageMaterialCap', type: 'mult', value: lvl => Math.pow(1.2, lvl)}
]},
antiquarian: {icon: 'mdi-store', cap: 12, requirement() {
return store.state.unlock.villageBuildings7.use;
@@ -1009,7 +1009,7 @@ export default {
}, timeNeeded(lvl) {
return Math.ceil(Math.pow(3, lvl) * buildNum(200, 'B'));
}, effect: [
- {name: 'currencyVillageCoinCap', type: 'mult', value: lvl => Math.pow(1.4, lvl)},
+ {name: 'currencyVillageCoinCap', type: 'mult', value: lvl => Math.pow(1.3, lvl)},
{name: 'villageUpgradeAmbition', type: 'unlock', value: lvl => lvl >= 1},
{name: 'villageUpgradeUnderstanding', type: 'unlock', value: lvl => lvl >= 2},
{name: 'villageUpgradeCuriosity', type: 'unlock', value: lvl => lvl >= 3},
diff --git a/src/js/modules/village/building2.js b/src/js/modules/village/building2.js
deleted file mode 100644
index b1c6ea43..00000000
--- a/src/js/modules/village/building2.js
+++ /dev/null
@@ -1 +0,0 @@
-export default {}
diff --git a/src/js/modules/village/card.js b/src/js/modules/village/card.js
index 353323e1..5c6c66b1 100644
--- a/src/js/modules/village/card.js
+++ b/src/js/modules/village/card.js
@@ -1,7 +1,19 @@
import cardList from "./cardList";
export default {
- feature: {prefix: 'VI', reward: [{name: 'villageResourceGain', type: 'mult', value: lvl => lvl * 0.03 + 1}], unlock: 'villageFeature'},
+ feature: {
+ prefix: 'VI',
+ reward: [{name: 'villageResourceGain', type: 'mult', value: lvl => lvl * 0.03 + 1}],
+ shinyReward: [
+ {name: 'villagePrestigeIncome', type: 'mult', value: lvl => lvl * 0.05 + 1},
+ ],
+ powerReward: [
+ {name: 'villageMaterialGain', type: 'mult', value: lvl => Math.pow(1.07, lvl)},
+ {name: 'villageMaterialCap', type: 'mult', value: lvl => Math.pow(1.03, lvl)},
+ {name: 'villagePrestigeIncome', type: 'mult', value: lvl => Math.pow(1.05, lvl)},
+ ],
+ unlock: 'villageFeature'
+ },
collection: {
neighborhood: {reward: [
{name: 'villageWorker', type: 'base', value: 8}
@@ -18,20 +30,20 @@ export default {
]},
},
pack: {
- meetingNewPeople: {unlock: 'villageBuildings3', amount: 5, price: 30, content: {
+ meetingNewPeople: {unlock: 'villageBuildings3', amount: 3, price: 18, content: {
'VI-0001': 1.11, 'VI-0003': 0.9, 'VI-0004': 1.04, 'VI-0005': 1.11,
'VI-0006': 2.4, 'VI-0007': 0.63, 'VI-0008': 2.8, 'VI-0010': 2.55, 'VI-0011': 1.85, 'VI-0012': 1.6, 'VI-0014': 0.7,
'VI-0015': 0.1, 'VI-0016': 1.11, 'VI-0017': 0.35, 'VI-0018': 0.1, 'VI-0019': 1.44,
'VI-0024': 0.97, 'VI-0025': 1.03, 'VI-0027': 0.7,
}},
- darkCult: {unlock: 'villageBuildings4', amount: 5, price: 45, content: {
+ darkCult: {unlock: 'villageBuildings4', amount: 5, price: 65, content: {
'VI-0002': 0.84, 'VI-0009': 1.75,
'VI-0015': 0.22, 'VI-0017': 0.82, 'VI-0018': 0.22, 'VI-0019': 1.33,
'VI-0020': 0.84, 'VI-0021': 1.25, 'VI-0022': 1.4,
'VI-0024': 1.07, 'VI-0025': 1.23, 'VI-0026': 2.55, 'VI-0027': 0.7,
'VI-0028': 2.3, 'VI-0029': 0.38, 'VI-0030': 1.6, 'VI-0031': 1.15,
}},
- technologicalAdvancement: {unlock: 'villageBuildings5', amount: 4, price: 50, content: {
+ technologicalAdvancement: {unlock: 'villageBuildings5', amount: 4, price: 115, content: {
'VI-0013': 0.5, 'VI-0023': 1.1,
'VI-0030': 2.6, 'VI-0031': 1.65, 'VI-0032': 0.38, 'VI-0033': 0.7,
'VI-0034': 1.32, 'VI-0035': 1.05, 'VI-0036': 0.82, 'VI-0037': 1.02, 'VI-0038': 1.4, 'VI-0039': 0.9,
diff --git a/src/js/modules/village/cardList.js b/src/js/modules/village/cardList.js
index 84213758..2761a44f 100644
--- a/src/js/modules/village/cardList.js
+++ b/src/js/modules/village/cardList.js
@@ -1,7 +1,7 @@
export default [
- {id: 1, collection: 'caveLocations', reward: [
- {name: 'currencyVillageStoneGain', type: 'mult', value: 1.5},
- {name: 'currencyVillageStoneCap', type: 'mult', value: 1.2}
+ {id: 1, collection: 'caveLocations', power: 2, reward: [
+ {name: 'currencyVillageStoneGain', type: 'mult', value: 1.2},
+ {name: 'currencyVillageStoneCap', type: 'mult', value: 1.1}
], color: 'teal', icons: [
{"x": 0.9, "y": 0.7, "rotate": 0, "size": 0.5, "icon": "mdi-human-handsdown"},
{"x": -1, "y": 0, "rotate": 10, "size": 1.8, "icon": "mdi-chart-bubble"},
@@ -10,9 +10,9 @@ export default [
{"x": 0, "y": 0.5, "rotate": 75, "size": 2.3, "icon": "mdi-chart-bubble"},
{"x": -1.2, "y": 0.6, "rotate": 0, "size": 0.8, "icon": "mdi-circle"}
]},
- {id: 2, collection: 'caveLocations', reward: [
- {name: 'currencyVillageGemGain', type: 'mult', value: 1.5},
- {name: 'currencyVillageGemCap', type: 'mult', value: 1.2}
+ {id: 2, collection: 'caveLocations', power: 3, reward: [
+ {name: 'currencyVillageGemGain', type: 'mult', value: 1.2},
+ {name: 'currencyVillageGemCap', type: 'mult', value: 1.1}
], color: 'pink-purple', icons: [
{"x": -0.9, "y": 0.65, "rotate": -20, "size": 1.8, "icon": "mdi-chart-bubble"},
{"x": -0.4, "y": -0.2, "rotate": -30, "size": 2, "icon": "mdi-chart-bubble"},
@@ -20,18 +20,18 @@ export default [
{"x": -0.3, "y": 0.3, "rotate": 65, "size": 0.75, "icon": "mdi-diamond-stone"},
{"x": 0.85, "y": 0.55, "rotate": 0, "size": 1.75, "icon": "mdi-human-handsdown"}
]},
- {id: 3, collection: 'caveLocations', reward: [
- {name: 'currencyVillageWaterGain', type: 'mult', value: 1.5},
- {name: 'currencyVillageWaterCap', type: 'mult', value: 1.2}
+ {id: 3, collection: 'caveLocations', power: 2, reward: [
+ {name: 'currencyVillageWaterGain', type: 'mult', value: 1.2},
+ {name: 'currencyVillageWaterCap', type: 'mult', value: 1.1}
], color: 'blue-grey', icons: [
{"x": -0.4, "y": -0.95, "rotate": 0, "size": 2, "icon": "mdi-nail"},
{"x": 0.65, "y": -1.05, "rotate": 0, "size": 1.6, "icon": "mdi-nail"},
{"x": 0, "y": 1.2, "rotate": 0, "size": 1, "icon": "mdi-triangle"},
{"x": 0.65, "y": 0, "rotate": 0, "size": 0.8, "icon": "mdi-water"}
]},
- {id: 4, collection: 'caveLocations', reward: [
- {name: 'currencyVillageMetalGain', type: 'mult', value: 1.5},
- {name: 'currencyVillageMetalCap', type: 'mult', value: 1.2}
+ {id: 4, collection: 'caveLocations', power: 2, reward: [
+ {name: 'currencyVillageMetalGain', type: 'mult', value: 1.2},
+ {name: 'currencyVillageMetalCap', type: 'mult', value: 1.1}
], color: 'cherry', icons: [
{"x": -0.8, "y": 0.8, "rotate": 75, "size": 2.75, "icon": "mdi-chart-bubble"},
{"x": 0.75, "y": 0.85, "rotate": 40, "size": 2.2, "icon": "mdi-chart-bubble"},
@@ -39,9 +39,9 @@ export default [
{"x": -0.55, "y": -0.85, "rotate": 20, "size": 2.15, "icon": "mdi-chart-bubble"},
{"x": 0.5, "y": -0.8, "rotate": -95, "size": 2.75, "icon": "mdi-chart-bubble"}
]},
- {id: 5, collection: 'caveLocations', reward: [
- {name: 'currencyVillagePlantFiberGain', type: 'mult', value: 1.5},
- {name: 'currencyVillagePlantFiberCap', type: 'mult', value: 1.2}
+ {id: 5, collection: 'caveLocations', power: 2, reward: [
+ {name: 'currencyVillagePlantFiberGain', type: 'mult', value: 1.2},
+ {name: 'currencyVillagePlantFiberCap', type: 'mult', value: 1.1}
], color: 'green', icons: [
{"x": 0.4, "y": 0.7, "rotate": -25, "size": 2.15, "icon": "mdi-chart-bubble"},
{"x": -0.45, "y": 0.5, "rotate": 40, "size": 2.55, "icon": "mdi-chart-bubble"},
@@ -50,16 +50,16 @@ export default [
{"x": 0.4, "y": -0.4, "rotate": 45, "size": 0.65, "icon": "mdi-flower"}
]},
- {id: 6, collection: 'neighborhood', reward: [
- {name: 'villageWorker', type: 'base', value: 12}
+ {id: 6, collection: 'neighborhood', power: 2, reward: [
+ {name: 'villageWorker', type: 'base', value: 8}
], color: 'green', icons: [
{"x": 0, "y": -0.2, "rotate": 0, "size": 2.5, "icon": "mdi-tent"},
{"x": 0.8, "y": -0.3, "rotate": 0, "size": 1, "icon": "mdi-grass"},
{"x": -0.75, "y": 0.7, "rotate": 0, "size": 1.2, "icon": "mdi-grass"},
{"x": 0.2, "y": 0.8, "rotate": 0, "size": 1.3, "icon": "mdi-grass"}
]},
- {id: 7, collection: 'neighborhood', reward: [
- {name: 'villageTaxRate', type: 'mult', value: 1.4}
+ {id: 7, collection: 'neighborhood', power: 2, reward: [
+ {name: 'villageTaxRate', type: 'mult', value: 1.25}
], color: 'pale-yellow', icons: [
{"x": -0.75, "y": -0.2, "rotate": 0, "size": 1.75, "icon": "mdi-slide"},
{"x": 0.75, "y": 0, "rotate": 0, "size": 1.75, "icon": "mdi-seesaw"},
@@ -67,10 +67,10 @@ export default [
{"x": 0.25, "y": 0.95, "rotate": 0, "size": 1, "icon": "mdi-human-child"},
{"x": -0.65, "y": -0.25, "rotate": -30, "size": 1, "icon": "mdi-human-child"}
]},
- {id: 8, collection: 'neighborhood', reward: [
- {name: 'currencyVillageWoodGain', type: 'mult', value: 1.4},
- {name: 'currencyVillageStoneGain', type: 'mult', value: 1.4},
- {name: 'currencyVillagePlantFiberGain', type: 'mult', value: 1.4}
+ {id: 8, collection: 'neighborhood', power: 2, reward: [
+ {name: 'currencyVillageWoodGain', type: 'mult', value: 1.2},
+ {name: 'currencyVillageStoneGain', type: 'mult', value: 1.2},
+ {name: 'currencyVillagePlantFiberGain', type: 'mult', value: 1.2}
], color: 'skyblue', icons: [
{"x": -0.8, "y": -0.3, "rotate": 0, "size": 1.75, "icon": "mdi-home"},
{"x": 0.8, "y": -0.3, "rotate": 0, "size": 1.75, "icon": "mdi-home"},
@@ -79,7 +79,7 @@ export default [
{"x": 0, "y": 0.6, "rotate": 90, "size": 1.5, "icon": "mdi-road"},
{"x": 0.7, "y": 0.6, "rotate": 90, "size": 1.5, "icon": "mdi-road"}
]},
- {id: 9, collection: 'neighborhood', reward: [
+ {id: 9, collection: 'neighborhood', power: 3, reward: [
{name: 'villageMentalGain', type: 'mult', value: 1.1}
], color: 'red', icons: [
{"x": -0.85, "y": 0, "rotate": 0, "size": 1.7, "icon": "mdi-fence"},
@@ -93,10 +93,10 @@ export default [
{"x": 0.65, "y": -1, "rotate": 0, "size": 1, "icon": "mdi-help"},
{"x": 0.35, "y": 0.85, "rotate": 0, "size": 1, "icon": "mdi-football"}
]},
- {id: 10, collection: 'neighborhood', reward: [
- {name: 'currencyVillageWoodCap', type: 'mult', value: 1.25},
- {name: 'currencyVillageStoneCap', type: 'mult', value: 1.25},
- {name: 'currencyVillagePlantFiberCap', type: 'mult', value: 1.25}
+ {id: 10, collection: 'neighborhood', power: 2, reward: [
+ {name: 'currencyVillageWoodCap', type: 'mult', value: 1.1},
+ {name: 'currencyVillageStoneCap', type: 'mult', value: 1.1},
+ {name: 'currencyVillagePlantFiberCap', type: 'mult', value: 1.1}
], color: 'lime', icons: [
{"x": -0.7, "y": -0.1, "rotate": 0, "size": 2.5, "icon": "mdi-home"},
{"x": 0, "y": 0.2, "rotate": 0, "size": 1, "icon": "mdi-fence"},
@@ -105,8 +105,8 @@ export default [
{"x": 0.75, "y": 0.75, "rotate": 0, "size": 1, "icon": "mdi-flower"},
{"x": -0.8, "y": 0.9, "rotate": 0, "size": 2, "icon": "mdi-tree"}
]},
- {id: 11, collection: 'neighborhood', reward: [
- {name: 'queueSpeedVillageBuilding', type: 'mult', value: 1.6}
+ {id: 11, collection: 'neighborhood', power: 2, reward: [
+ {name: 'queueSpeedVillageBuilding', type: 'mult', value: 1.2}
], color: 'cherry', icons: [
{"x": 0, "y": -0.65, "rotate": 0, "size": 4, "icon": "mdi-home-roof"},
{"x": -0.75, "y": 0.25, "rotate": 90, "size": 3, "icon": "mdi-minus"},
@@ -115,9 +115,7 @@ export default [
{"x": 0.3, "y": 0.9, "rotate": 0, "size": 2, "icon": "mdi-tow-truck"},
{"x": -0.6, "y": 1, "rotate": 0, "size": 1, "icon": "mdi-wall"}
]},
- {id: 12, collection: 'neighborhood', reward: [
- {name: 'villageMaterialGain', type: 'mult', value: 1.1}
- ], color: 'pale-green', icons: [
+ {id: 12, collection: 'neighborhood', power: 3, color: 'pale-green', icons: [
{"x": -0.5, "y": 0, "rotate": 0, "size": 1.75, "icon": "mdi-rv-truck"},
{"x": 0.15, "y": 0.6, "rotate": 0, "size": 1.25, "icon": "mdi-campfire"},
{"x": -0.8, "y": 0.9, "rotate": 0, "size": 1.4, "icon": "mdi-tree"},
@@ -126,8 +124,8 @@ export default [
{"x": 0.4, "y": -0.25, "rotate": 0, "size": 1.1, "icon": "mdi-pine-tree"},
{"x": 0.9, "y": -0.6, "rotate": 0, "size": 1.5, "icon": "mdi-pine-tree"}
]},
- {id: 13, collection: 'neighborhood', reward: [
- {name: 'villageWorker', type: 'base', value: 8},
+ {id: 13, collection: 'neighborhood', power: 4, reward: [
+ {name: 'villageWorker', type: 'base', value: 6},
{name: 'villageHappiness', type: 'base', value: 0.01}
], color: 'deep-purple', icons: [
{"x": -0.3, "y": -0.85, "rotate": 0, "size": 1.25, "icon": "mdi-window-open"},
@@ -137,7 +135,7 @@ export default [
{"x": 0, "y": 0.8, "rotate": 0, "size": 2, "icon": "mdi-rug"},
{"x": 0.9, "y": 0.1, "rotate": 0, "size": 1, "icon": "mdi-dresser"}
]},
- {id: 14, collection: 'neighborhood', reward: [
+ {id: 14, collection: 'neighborhood', power: 2, reward: [
{name: 'villageFoodGain', type: 'mult', value: 1.2}
], color: 'light-green', icons: [
{"x": -0.55, "y": 0, "rotate": 0, "size": 2.5, "icon": "mdi-home"},
@@ -146,8 +144,8 @@ export default [
{"x": 0.4, "y": 0.2, "rotate": 0, "size": 0.5, "icon": "mdi-tennis-ball"}
]},
- {id: 15, collection: 'plantsInTheCity', reward: [
- {name: 'currencyVillageGrainGain', type: 'mult', value: 1.8}
+ {id: 15, collection: 'plantsInTheCity', power: 2, reward: [
+ {name: 'currencyVillageGrainGain', type: 'mult', value: 1.6}
], color: 'light-blue', icons: [
{"x": 0, "y": 0.4, "rotate": 0, "size": 3, "icon": "mdi-home-city"},
{"x": 0, "y": -0.55, "rotate": 0, "size": 1, "icon": "mdi-flower"},
@@ -155,25 +153,25 @@ export default [
{"x": 0.35, "y": -1, "rotate": 0, "size": 1.3, "icon": "mdi-tree"},
{"x": 0.38, "y": -0.5, "rotate": 90, "size": 1.3, "icon": "mdi-minus"}
]},
- {id: 16, collection: 'plantsInTheCity', reward: [
- {name: 'currencyVillageWoodGain', type: 'mult', value: 1.5},
- {name: 'currencyVillageWoodCap', type: 'mult', value: 1.2}
+ {id: 16, collection: 'plantsInTheCity', power: 2, reward: [
+ {name: 'currencyVillageWoodGain', type: 'mult', value: 1.2},
+ {name: 'currencyVillageWoodCap', type: 'mult', value: 1.1}
], color: 'beige', icons: [
{"x": 0, "y": -0.1, "rotate": 0, "size": 4, "icon": "mdi-tree"},
{"x": 0, "y": 0.8, "rotate": 0, "size": 1, "icon": "mdi-triangle"},
{"x": 0.45, "y": 0.85, "rotate": 0, "size": 0.5, "icon": "mdi-sign-text"},
{"x": -0.8, "y": 0.8, "rotate": 0, "size": 0.75, "icon": "mdi-human-male-female-child"}
]},
- {id: 17, collection: 'plantsInTheCity', reward: [
- {name: 'villageResourceGain', type: 'mult', value: 1.05}
+ {id: 17, collection: 'plantsInTheCity', power: 2, reward: [
+ {name: 'villageResourceGain', type: 'mult', value: 1.1}
], color: 'cherry', icons: [
{"x": 0.45, "y": 0.15, "rotate": 0, "size": 3, "icon": "mdi-truck-flatbed"},
{"x": 0.1, "y": -0.1, "rotate": -50, "size": 2, "icon": "mdi-tree"},
{"x": -0.85, "y": 0.45, "rotate": 0, "size": 1.25, "icon": "mdi-human-handsup"},
{"x": -0.6, "y": 0.05, "rotate": -55, "size": 1, "icon": "mdi-axe"}
]},
- {id: 18, collection: 'plantsInTheCity', reward: [
- {name: 'currencyVillageFruitGain', type: 'mult', value: 1.8}
+ {id: 18, collection: 'plantsInTheCity', power: 2, reward: [
+ {name: 'currencyVillageFruitGain', type: 'mult', value: 1.6}
], color: 'green', icons: [
{"x": -0.65, "y": 0.65, "rotate": 0, "size": 2, "icon": "mdi-layers-outline"},
{"x": -0.65, "y": 0.25, "rotate": 0, "size": 1.25, "icon": "mdi-flower"},
@@ -182,7 +180,7 @@ export default [
{"x": 0, "y": -0.4, "rotate": 0, "size": 2, "icon": "mdi-layers-outline"},
{"x": 0, "y": -0.8, "rotate": 0, "size": 1.25, "icon": "mdi-flower-tulip"}
]},
- {id: 19, collection: 'plantsInTheCity', reward: [
+ {id: 19, collection: 'plantsInTheCity', power: 1, reward: [
{name: 'currencyVillagePlantFiberGain', type: 'mult', value: 1.75}
], color: 'light-green', icons: [
{"x": -0.7, "y": 0, "rotate": 0, "size": 2, "icon": "mdi-human-handsdown"},
@@ -191,18 +189,18 @@ export default [
{"x": 0.9, "y": 0.3, "rotate": 0, "size": 0.8, "icon": "mdi-sprout"}
]},
- {id: 20, collection: 'industrialRevolution', reward: [
- {name: 'currencyVillageHardwoodGain', type: 'mult', value: 1.5},
- {name: 'currencyVillageHardwoodCap', type: 'mult', value: 1.2}
+ {id: 20, collection: 'industrialRevolution', power: 3, reward: [
+ {name: 'currencyVillageHardwoodGain', type: 'mult', value: 1.2},
+ {name: 'currencyVillageHardwoodCap', type: 'mult', value: 1.1}
], color: 'cherry', icons: [
{"x": 0.6, "y": 0.4, "rotate": 55, "size": 3, "icon": "mdi-tree"},
{"x": -0.3, "y": 0.8, "rotate": 90, "size": 0.5, "icon": "mdi-rectangle"},
{"x": -0.95, "y": 0.5, "rotate": 0, "size": 1.5, "icon": "mdi-human-handsdown"},
{"x": -0.55, "y": 0.5, "rotate": 0, "size": 0.9, "icon": "mdi-axe"}
]},
- {id: 21, collection: 'industrialRevolution', reward: [
- {name: 'currencyVillageWoodCap', type: 'mult', value: 1.25},
- {name: 'currencyVillageHardwoodCap', type: 'mult', value: 1.25}
+ {id: 21, collection: 'industrialRevolution', power: 3, reward: [
+ {name: 'currencyVillageWoodCap', type: 'mult', value: 1.15},
+ {name: 'currencyVillageHardwoodCap', type: 'mult', value: 1.15}
], color: 'brown', icons: [
{"x": 0, "y": 0, "rotate": 0, "size": 4, "icon": "mdi-truck-flatbed"},
{"x": -0.85, "y": -0.1, "rotate": 0, "size": 1, "icon": "mdi-rectangle"},
@@ -215,7 +213,7 @@ export default [
{"x": -0.5, "y": -0.9, "rotate": 0, "size": 1, "icon": "mdi-rectangle"},
{"x": -0.15, "y": -0.9, "rotate": 0, "size": 1, "icon": "mdi-rectangle"}
]},
- {id: 22, collection: 'industrialRevolution', reward: [
+ {id: 22, collection: 'industrialRevolution', power: 3, reward: [
{name: 'currencyVillageKnowledgeCap', type: 'mult', value: 1.1}
], color: 'pale-purple', icons: [
{"x": -0.5, "y": -0.3, "rotate": 0, "size": 3, "icon": "mdi-minus"},
@@ -228,29 +226,29 @@ export default [
{"x": 0.55, "y": -0.6, "rotate": 0, "size": 1, "icon": "mdi-bottle-tonic"},
{"x": -0.2, "y": 0.5, "rotate": 45, "size": 0.5, "icon": "mdi-pencil"}
]},
- {id: 23, collection: 'industrialRevolution', reward: [
- {name: 'currencyVillageScienceGain', type: 'mult', value: 1.35}
+ {id: 23, collection: 'industrialRevolution', power: 4, reward: [
+ {name: 'currencyVillageScienceGain', type: 'mult', value: 1.3}
], color: 'cyan', icons: [
{"x": -0.3, "y": 0.3, "rotate": 0, "size": 1, "icon": "mdi-test-tube"},
{"x": 0, "y": 0.3, "rotate": 0, "size": 1, "icon": "mdi-test-tube-empty"},
{"x": 0.3, "y": 0.3, "rotate": 0, "size": 1, "icon": "mdi-test-tube-empty"},
{"x": -0.1, "y": -0.3, "rotate": 0, "size": 1, "icon": "mdi-eyedropper"}
]},
- {id: 24, collection: 'industrialRevolution', reward: [
- {name: 'currencyVillageGlassGain', type: 'mult', value: 1.5},
- {name: 'currencyVillageGlassCap', type: 'mult', value: 1.2}
+ {id: 24, collection: 'industrialRevolution', power: 2, reward: [
+ {name: 'currencyVillageGlassGain', type: 'mult', value: 1.2},
+ {name: 'currencyVillageGlassCap', type: 'mult', value: 1.1}
], color: 'lime', icons: [
{"x": 0, "y": 0, "rotate": 0, "size": 4, "icon": "mdi-microscope"},
{"x": 0.4, "y": 0, "rotate": -90, "size": 0.7, "icon": "mdi-bacteria"},
{"x": 0.75, "y": 0, "rotate": 0, "size": 0.7, "icon": "mdi-virus"}
]},
- {id: 25, collection: 'industrialRevolution', reward: [
- {name: 'currencyVillageCoinCap', type: 'mult', value: 1.45}
+ {id: 25, collection: 'industrialRevolution', power: 2, reward: [
+ {name: 'currencyVillageCoinCap', type: 'mult', value: 1.18}
], color: 'amber', icons: [
{"x": -0.4, "y": -0.05, "rotate": 70, "size": 2, "icon": "mdi-bowl-mix"},
{"x": 0.5, "y": 0.5, "rotate": 0, "size": 2, "icon": "mdi-gold"}
]},
- {id: 26, collection: 'industrialRevolution', reward: [
+ {id: 26, collection: 'industrialRevolution', power: 3, reward: [
{name: 'currencyVillageFaithGain', type: 'mult', value: 1.2}
], color: 'light-grey', icons: [
{"x": -0.5, "y": 0.35, "rotate": 0, "size": 3, "icon": "mdi-minus"},
@@ -263,8 +261,8 @@ export default [
{"x": 0.15, "y": 0.2, "rotate": 80, "size": 1, "icon": "mdi-nail"},
{"x": 0.8, "y": 0.05, "rotate": 180, "size": 1, "icon": "mdi-nail"}
]},
- {id: 27, collection: 'industrialRevolution', reward: [
- {name: 'currencyVillageKnowledgeGain', type: 'mult', value: 1.35}
+ {id: 27, collection: 'industrialRevolution', power: 2, reward: [
+ {name: 'currencyVillageKnowledgeGain', type: 'mult', value: 1.3}
], color: 'pale-orange', icons: [
{"x": -0.55, "y": 0, "rotate": 0, "size": 1.5, "icon": "mdi-bookshelf"},
{"x": -0.05, "y": 0, "rotate": 0, "size": 1.5, "icon": "mdi-bookshelf"},
@@ -275,16 +273,16 @@ export default [
{"x": 0.5, "y": -0.85, "rotate": 0, "size": 1.25, "icon": "mdi-book"},
{"x": -0.2, "y": -0.8, "rotate": 0, "size": 1, "icon": "mdi-candle"}
]},
- {id: 28, collection: 'industrialRevolution', reward: [
- {name: 'currencyVillageFaithCap', type: 'mult', value: 1.3}
+ {id: 28, collection: 'industrialRevolution', power: 3, reward: [
+ {name: 'currencyVillageFaithCap', type: 'mult', value: 1.25}
], color: 'blue-grey', icons: [
{"x": 0, "y": 0, "rotate": 0, "size": 1.75, "icon": "mdi-cog"},
{"x": -0.7, "y": -0.25, "rotate": 10, "size": 1.5, "icon": "mdi-cog"},
{"x": -1, "y": 0.35, "rotate": 0, "size": 1.25, "icon": "mdi-cog"},
{"x": 0.8, "y": 0, "rotate": 30, "size": 1.6, "icon": "mdi-cog"}
]},
- {id: 29, collection: 'industrialRevolution', reward: [
- {name: 'currencyVillageFishGain', type: 'mult', value: 1.8}
+ {id: 29, collection: 'industrialRevolution', power: 3, reward: [
+ {name: 'currencyVillageFishGain', type: 'mult', value: 1.6}
], color: 'pale-blue', icons: [
{"x": 0.6, "y": 0.6, "rotate": 0, "size": 2, "icon": "mdi-stove"},
{"x": 0.4, "y": -0.1, "rotate": 0, "size": 1, "icon": "mdi-pot-mix"},
@@ -292,18 +290,18 @@ export default [
{"x": -0.35, "y": 0.3, "rotate": 0, "size": 3, "icon": "mdi-minus"},
{"x": 0.15, "y": -0.55, "rotate": 40, "size": 0.75, "icon": "mdi-food-apple"}
]},
- {id: 30, collection: 'industrialRevolution', reward: [
- {name: 'currencyVillageFaithGain', type: 'mult', value: 1.1},
- {name: 'currencyVillageFaithCap', type: 'mult', value: 1.2}
+ {id: 30, collection: 'industrialRevolution', power: 2, reward: [
+ {name: 'currencyVillageFaithGain', type: 'mult', value: 1.25},
+ {name: 'currencyVillageFaithCap', type: 'mult', value: 1.3}
], color: 'grey', icons: [
{"x": 0, "y": -0.6, "rotate": 0, "size": 3, "icon": "mdi-garage-open"},
{"x": -0.15, "y": 0.65, "rotate": 0, "size": 2, "icon": "mdi-human-handsdown"},
{"x": 0.3, "y": 0.6, "rotate": 15, "size": 0.75, "icon": "mdi-remote"},
{"x": 0, "y": -0.25, "rotate": 0, "size": 1, "icon": "mdi-car"}
]},
- {id: 31, collection: 'industrialRevolution', reward: [
+ {id: 31, collection: 'industrialRevolution', power: 3, reward: [
{name: 'currencyVillageFaithGain', type: 'mult', value: 1.12},
- {name: 'villageResourceGain', type: 'mult', value: 1.02}
+ {name: 'villageResourceGain', type: 'mult', value: 1.05}
], color: 'pale-red', icons: [
{"x": 0, "y": 0.5, "rotate": 0, "size": 3.5, "icon": "mdi-square-outline"},
{"x": 0, "y": 0.85, "rotate": 0, "size": 1, "icon": "mdi-power-socket"},
@@ -311,23 +309,23 @@ export default [
{"x": 0.45, "y": -0.9, "rotate": -65, "size": 1.5, "icon": "mdi-fuel"},
{"x": -0.05, "y": -0.55, "rotate": 0, "size": 0.4, "icon": "mdi-water"}
]},
- {id: 32, collection: 'industrialRevolution', reward: [
- {name: 'currencyVillageVegetableGain', type: 'mult', value: 1.8}
+ {id: 32, collection: 'industrialRevolution', power: 4, reward: [
+ {name: 'currencyVillageVegetableGain', type: 'mult', value: 1.6}
], color: 'yellow', icons: [
{"x": 0, "y": 0.25, "rotate": 0, "size": 3, "icon": "mdi-home"},
{"x": 0.3, "y": -0.5, "rotate": 45, "size": 1, "icon": "mdi-solar-panel"},
{"x": 0.7, "y": -0.1, "rotate": 45, "size": 1, "icon": "mdi-solar-panel"},
{"x": -0.85, "y": 1, "rotate": 0, "size": 2, "icon": "mdi-chart-line-variant"}
]},
- {id: 33, collection: 'industrialRevolution', reward: [
- {name: 'currencyVillageJoyGain', type: 'mult', value: 1.35}
+ {id: 33, collection: 'industrialRevolution', power: 4, reward: [
+ {name: 'currencyVillageJoyGain', type: 'mult', value: 1.3}
], color: 'indigo', icons: [
{"x": 0, "y": 0.2, "rotate": 0, "size": 4, "icon": "mdi-car-side"},
{"x": 0.2, "y": -0.1, "rotate": 0, "size": 0.5, "icon": "mdi-robot"},
{"x": 0, "y": -0.6, "rotate": 0, "size": 1, "icon": "mdi-antenna"}
]},
- {id: 34, collection: 'maintainingSafety', reward: [
+ {id: 34, collection: 'maintainingSafety', power: 2, reward: [
{name: 'villageWorker', type: 'mult', value: 1.1}
], color: 'orange', icons: [
{"x": 0.6, "y": 0.2, "rotate": 0, "size": 2.5, "icon": "mdi-home"},
@@ -336,16 +334,16 @@ export default [
{"x": 0.15, "y": -0.4, "rotate": 0, "size": 1.4, "icon": "mdi-smoke"},
{"x": -0.65, "y": 0.6, "rotate": 0, "size": 2, "icon": "mdi-fire-truck"}
]},
- {id: 35, collection: 'maintainingSafety', reward: [
- {name: 'currencyVillageHardwoodCap', type: 'mult', value: 1.3},
- {name: 'currencyVillageGemCap', type: 'mult', value: 1.3}
+ {id: 35, collection: 'maintainingSafety', power: 4, reward: [
+ {name: 'currencyVillageHardwoodCap', type: 'mult', value: 1.15},
+ {name: 'currencyVillageGemCap', type: 'mult', value: 1.15}
], color: 'dark-blue', icons: [
{"x": 0.5, "y": -0.4, "rotate": 0, "size": 2, "icon": "mdi-police-station"},
{"x": -0.6, "y": -0.05, "rotate": 0, "size": 1.25, "icon": "mdi-car-emergency"},
{"x": 0.05, "y": 0.65, "rotate": 0, "size": 1.25, "icon": "mdi-horse-human"}
]},
- {id: 36, collection: 'maintainingSafety', reward: [
- {name: 'currencyVillageWaterCap', type: 'mult', value: 1.5}
+ {id: 36, collection: 'maintainingSafety', power: 4, reward: [
+ {name: 'currencyVillageWaterCap', type: 'mult', value: 1.2}
], color: 'cyan', icons: [
{"x": 0.75, "y": 0.8, "rotate": 35, "size": 2.3, "icon": "mdi-chart-bubble"},
{"x": 0.75, "y": 0, "rotate": 45, "size": 2.5, "icon": "mdi-chart-bubble"},
@@ -355,9 +353,9 @@ export default [
{"x": -0.85, "y": 1, "rotate": 0, "size": 1.75, "icon": "mdi-waves"},
{"x": -0.85, "y": 0.1, "rotate": 0, "size": 1.75, "icon": "mdi-ferry"}
]},
- {id: 37, collection: 'maintainingSafety', reward: [
- {name: 'currencyVillageStoneCap', type: 'mult', value: 1.4},
- {name: 'currencyVillageMetalCap', type: 'mult', value: 1.25}
+ {id: 37, collection: 'maintainingSafety', power: 4, reward: [
+ {name: 'currencyVillageStoneCap', type: 'mult', value: 1.18},
+ {name: 'currencyVillageMetalCap', type: 'mult', value: 1.12}
], color: 'wooden', icons: [
{"x": 0, "y": -0.4, "rotate": 0, "size": 3, "icon": "mdi-tree"},
{"x": 0.025, "y": 0.75, "rotate": 90, "size": 3, "icon": "mdi-minus"},
@@ -367,17 +365,17 @@ export default [
{"x": -0.8, "y": 0.85, "rotate": 0, "size": 1.3, "icon": "mdi-fire-truck"},
{"x": 0.55, "y": 1, "rotate": 0, "size": 0.9, "icon": "mdi-human-handsup"}
]},
- {id: 38, collection: 'maintainingSafety', reward: [
- {name: 'villageTaxRate', type: 'mult', value: 1.25},
- {name: 'currencyVillageCoinCap', type: 'mult', value: 1.25}
+ {id: 38, collection: 'maintainingSafety', power: 4, reward: [
+ {name: 'villageTaxRate', type: 'mult', value: 1.15},
+ {name: 'currencyVillageCoinCap', type: 'mult', value: 1.1}
], color: 'red', icons: [
{"x": 0.5, "y": 0, "rotate": 0, "size": 2, "icon": "mdi-ambulance"},
{"x": -0.1, "y": -0.05, "rotate": 0, "size": 1.35, "icon": "mdi-human-baby-changing-table"},
{"x": -0.7, "y": 0.75, "rotate": 0, "size": 1.35, "icon": "mdi-human-male-female-child"}
]},
- {id: 39, collection: 'maintainingSafety', reward: [
- {name: 'currencyVillageMetalCap', type: 'mult', value: 1.2},
- {name: 'currencyVillageGlassCap', type: 'mult', value: 1.4}
+ {id: 39, collection: 'maintainingSafety', power: 3, reward: [
+ {name: 'currencyVillageMetalCap', type: 'mult', value: 1.15},
+ {name: 'currencyVillageGlassCap', type: 'mult', value: 1.25}
], color: 'beige', icons: [
{"x": -0.7, "y": 0.2, "rotate": 0, "size": 2, "icon": "mdi-tower-beach"},
{"x": -0.8, "y": 0.95, "rotate": 0, "size": 1.9, "icon": "mdi-ellipse"},
diff --git a/src/js/modules/village/craftingRecipe.js b/src/js/modules/village/craftingRecipe.js
new file mode 100644
index 00000000..59809f9b
--- /dev/null
+++ b/src/js/modules/village/craftingRecipe.js
@@ -0,0 +1,419 @@
+import { buildNum } from "../../utils/format";
+import { getSequence } from "../../utils/math";
+
+export default {
+ // Base recipes
+ rope: {
+ icon: 'mdi-lasso',
+ color: 'beige',
+ price: {village_plantFiber: buildNum(100, 'K')},
+ value: 10,
+ timeNeeded: 60,
+ milestone: {
+ 100: {type: 'villageCraft', name: 'pouch', value: true},
+ 750: {type: 'changeStat', name: 'timeNeeded', value: 40},
+ 4800: {type: 'changeStat', name: 'value', value: 14},
+ 27000: {type: 'changeStat', name: 'timeNeeded', value: 30},
+ }
+ },
+ woodenPlanks: {
+ icon: 'mdi-view-dashboard-variant',
+ color: 'brown',
+ price: {village_wood: buildNum(250, 'K')},
+ value: 22,
+ timeNeeded: 120,
+ milestone: {
+ 60: {type: 'changeStat', name: 'timeNeeded', value: 90},
+ 450: {type: 'villageCraft', name: 'cupboard', value: true},
+ 3200: {type: 'changeStat', name: 'value', value: 30},
+ 16500: {type: 'changeStat', name: 'timeNeeded', value: 75},
+ }
+ },
+ brick: {
+ icon: 'mdi-wall',
+ color: 'cherry',
+ price: {village_stone: buildNum(600, 'K')},
+ value: 48,
+ timeNeeded: 240,
+ milestone: {
+ 40: {type: 'changeStat', name: 'value', value: 66},
+ 300: {type: 'changeStat', name: 'timeNeeded', value: 180},
+ 2000: {type: 'villageCraft', name: 'weight', value: true},
+ 12000: {type: 'changeStat', name: 'value', value: 84},
+ }
+ },
+ screws: {
+ icon: 'mdi-screw-flat-top',
+ color: 'light-grey',
+ price: {village_metal: buildNum(800, 'K')},
+ value: 25,
+ timeNeeded: 120,
+ milestone: {
+ 100: {type: 'changeStat', name: 'value', value: 34},
+ 550: {type: 'changeStat', name: 'timeNeeded', value: 100},
+ 4400: {type: 'villageCraft', name: 'scissors', value: true},
+ 21000: {type: 'changeStat', name: 'value', value: 44},
+ }
+ },
+ waterBottle: {
+ icon: 'mdi-bottle-soda',
+ color: 'blue',
+ price: {village_water: buildNum(1.5, 'M')},
+ value: 15,
+ timeNeeded: 70,
+ milestone: {
+ 300: {type: 'changeStat', name: 'timeNeeded', value: 50},
+ 1700: {type: 'changeStat', name: 'timeNeeded', value: 35},
+ 9250: {type: 'villageCraft', name: 'herbTea', value: true},
+ 53000: {type: 'changeStat', name: 'timeNeeded', value: 25},
+ }
+ },
+ cocktailGlass: {
+ icon: 'mdi-glass-cocktail',
+ color: 'light-blue',
+ price: {village_glass: buildNum(2.5, 'M')},
+ value: 50,
+ timeNeeded: 210,
+ milestone: {
+ 45: {type: 'changeStat', name: 'value', value: 67},
+ 360: {type: 'changeStat', name: 'timeNeeded', value: 180},
+ 2500: {type: 'villageCraft', name: 'glasses', value: true},
+ 14500: {type: 'changeStat', name: 'value', value: 86},
+ }
+ },
+ boomerang: {
+ icon: 'mdi-boomerang',
+ color: 'cherry',
+ price: {village_hardwood: buildNum(4, 'M')},
+ value: 38,
+ timeNeeded: 140,
+ milestone: {
+ 45: {type: 'changeStat', name: 'value', value: 51},
+ 360: {type: 'changeStat', name: 'timeNeeded', value: 120},
+ // 2500: {type: 'villageCraft', name: 'weight', value: true},
+ 14500: {type: 'changeStat', name: 'value', value: 65},
+ }
+ },
+ polishedGem: {
+ icon: 'mdi-diamond-stone',
+ color: 'cyan',
+ price: {village_gem: buildNum(6.5, 'M')},
+ value: 36,
+ timeNeeded: 160,
+ milestone: {
+ 55: {type: 'changeStat', name: 'value', value: 47},
+ 380: {type: 'changeStat', name: 'timeNeeded', value: 140},
+ // 2475: {type: 'villageCraft', name: 'weight', value: true},
+ 13500: {type: 'changeStat', name: 'value', value: 60},
+ }
+ },
+ oilLamp: {
+ icon: 'mdi-oil-lamp',
+ color: 'pale-orange',
+ price: {village_oil: buildNum(10, 'M')},
+ value: 51,
+ timeNeeded: 270,
+ milestone: {
+ 40: {type: 'changeStat', name: 'value', value: 65},
+ 330: {type: 'changeStat', name: 'timeNeeded', value: 225},
+ // 2100: {type: 'villageCraft', name: 'weight', value: true},
+ 12400: {type: 'changeStat', name: 'value', value: 82},
+ }
+ },
+ shower: {
+ icon: 'mdi-shower',
+ color: 'pale-blue',
+ price: {village_marble: buildNum(15, 'M')},
+ value: 70,
+ timeNeeded: 360,
+ milestone: {
+ 40: {type: 'changeStat', name: 'timeNeeded', value: 300},
+ 330: {type: 'changeStat', name: 'value', value: 90},
+ // 2100: {type: 'villageCraft', name: 'weight', value: true},
+ 12400: {type: 'changeStat', name: 'timeNeeded', value: 250},
+ }
+ },
+
+ // Advanced recipes
+ pouch: {
+ icon: 'mdi-sack',
+ color: 'pale-orange',
+ price: {village_plantFiber: buildNum(1, 'M')},
+ value: 18,
+ timeNeeded: 90,
+ milestone: {
+ 80: {type: 'changeStat', name: 'value', value: 26},
+ 600: {type: 'changeStat', name: 'timeNeeded', value: 70},
+ 4000: {type: 'changeStat', name: 'value', value: 35},
+ 22000: {type: 'changeStat', name: 'timeNeeded', value: 60},
+ }
+ },
+ cupboard: {
+ icon: 'mdi-cupboard',
+ color: 'wooden',
+ price: {village_wood: buildNum(3, 'M')},
+ value: 33,
+ timeNeeded: 150,
+ milestone: {
+ 50: {type: 'changeStat', name: 'value', value: 42},
+ 400: {type: 'changeStat', name: 'timeNeeded', value: 125},
+ 2800: {type: 'changeStat', name: 'value', value: 52},
+ 15000: {type: 'changeStat', name: 'timeNeeded', value: 100},
+ }
+ },
+ weight: {
+ icon: 'mdi-weight',
+ color: 'dark-grey',
+ price: {village_stone: buildNum(7, 'M')},
+ value: 65,
+ timeNeeded: 300,
+ milestone: {
+ 50: {type: 'changeStat', name: 'value', value: 87},
+ 400: {type: 'changeStat', name: 'timeNeeded', value: 255},
+ 2800: {type: 'villageCraft', name: 'handSaw', value: true},
+ 15000: {type: 'changeStat', name: 'timeNeeded', value: 210},
+ }
+ },
+ scissors: {
+ icon: 'mdi-content-cut',
+ color: 'light-grey',
+ price: {village_metal: buildNum(8, 'M'), village_wood: buildNum(3, 'M')},
+ value: 30,
+ timeNeeded: 125,
+ milestone: {
+ 55: {type: 'changeStat', name: 'timeNeeded', value: 110},
+ 420: {type: 'changeStat', name: 'value', value: 40},
+ 3100: {type: 'changeStat', name: 'timeNeeded', value: 100},
+ 17000: {type: 'changeStat', name: 'value', value: 50},
+ }
+ },
+ herbTea: {
+ icon: 'mdi-tea',
+ color: 'green',
+ price: {village_water: buildNum(12, 'M'), village_plantFiber: buildNum(5, 'M')},
+ value: 54,
+ timeNeeded: 200,
+ milestone: {
+ 48: {type: 'changeStat', name: 'value', value: 78},
+ 380: {type: 'changeStat', name: 'value', value: 106},
+ 2600: {type: 'changeStat', name: 'timeNeeded', value: 170},
+ 14000: {type: 'changeStat', name: 'value', value: 140},
+ }
+ },
+ glasses: {
+ icon: 'mdi-glasses',
+ color: 'red-pink',
+ price: {village_glass: buildNum(14, 'M'), village_metal: buildNum(11, 'M')},
+ value: 21,
+ timeNeeded: 80,
+ milestone: {
+ 100: {type: 'changeStat', name: 'timeNeeded', value: 65},
+ 750: {type: 'changeStat', name: 'value', value: 28},
+ 5400: {type: 'changeStat', name: 'timeNeeded', value: 55},
+ 30000: {type: 'changeStat', name: 'timeNeeded', value: 45},
+ }
+ },
+
+ // Book recipes
+ arrows: {
+ icon: 'mdi-arrow-projectile-multiple',
+ color: 'wooden',
+ price: {village_wood: buildNum(1.25, 'M'), village_stone: buildNum(400, 'K')},
+ value: 21,
+ timeNeeded: 100,
+ milestone: {
+ 85: {type: 'changeStat', name: 'timeNeeded', value: 85},
+ 400: {type: 'changeStat', name: 'timeNeeded', value: 70},
+ // 2200: {type: 'villageCraft', name: 'weight', value: true},
+ 10000: {type: 'changeStat', name: 'timeNeeded', value: 60},
+ // 47500: {type: 'villageCraft', name: 'weight', value: true},
+ }
+ },
+ bowl: {
+ icon: 'mdi-bowl',
+ color: 'brown',
+ price: {village_wood: buildNum(2.5, 'M')},
+ value: 25,
+ timeNeeded: 130,
+ milestone: {
+ 90: {type: 'changeStat', name: 'timeNeeded', value: 100},
+ 675: {type: 'villageCraft', name: 'bush', value: true},
+ 4800: {type: 'changeStat', name: 'value', value: 34},
+ 25000: {type: 'changeStat', name: 'timeNeeded', value: 80},
+ }
+ },
+ chain: {
+ icon: 'mdi-link-variant',
+ color: 'light-grey',
+ price: {village_plantFiber: buildNum(3, 'M'), village_metal: buildNum(1.35, 'M')},
+ value: 19,
+ timeNeeded: 70,
+ milestone: {
+ 140: {type: 'changeStat', name: 'timeNeeded', value: 60},
+ 875: {type: 'villageCraft', name: 'garage', value: true},
+ 4300: {type: 'changeStat', name: 'value', value: 25},
+ 23000: {type: 'changeStat', name: 'timeNeeded', value: 50},
+ }
+ },
+ spear: {
+ icon: 'mdi-spear',
+ color: 'dark-grey',
+ price: {village_wood: buildNum(8, 'M'), village_metal: buildNum(1.75, 'M')},
+ value: 26,
+ timeNeeded: 120,
+ milestone: {
+ 110: {type: 'changeStat', name: 'timeNeeded', value: 95},
+ 800: {type: 'changeStat', name: 'value', value: 35},
+ 5750: {type: 'changeStat', name: 'timeNeeded', value: 75},
+ 28000: {type: 'changeStat', name: 'value', value: 45},
+ }
+ },
+ goldenRing: {
+ icon: 'mdi-circle-outline',
+ color: 'amber',
+ price: {village_metal: buildNum(5, 'M'), village_water: buildNum(750, 'K')},
+ value: 140,
+ timeNeeded: 600,
+ milestone: {
+ 30: {type: 'changeStat', name: 'value', value: 188},
+ 225: {type: 'changeStat', name: 'value', value: 239},
+ 1800: {type: 'changeStat', name: 'value', value: 295},
+ }
+ },
+
+ // Special ingredient recipes
+ poisonedArrows: {
+ icon: 'mdi-arrow-projectile-multiple',
+ color: 'light-green',
+ price: {craft_arrows: 5, village_acidVial: 1},
+ prio: 1,
+ value: 850,
+ timeNeeded: 600,
+ milestone: {
+ 120: {type: 'changeStat', name: 'value', value: 1100},
+ 700: {type: 'changeStat', name: 'value', value: 1400},
+ 5000: {type: 'changeStat', name: 'timeNeeded', value: 300},
+ }
+ },
+ frostSpear: {
+ icon: 'mdi-spear',
+ color: 'cyan',
+ price: {craft_spear: 10, village_snowflake: 1},
+ prio: 1,
+ value: 2200,
+ timeNeeded: 1500,
+ milestone: {
+ 55: {type: 'changeStat', name: 'value', value: 3000},
+ 300: {type: 'changeStat', name: 'value', value: 3950},
+ 2350: {type: 'changeStat', name: 'value', value: 5100},
+ }
+ },
+ spicySoup: {
+ icon: 'mdi-pot-steam',
+ color: 'orange-red',
+ price: {craft_bowl: 15, village_plantFiber: buildNum(250, 'M'), village_water: buildNum(35, 'M'), village_chiliBundle: 1},
+ prio: 1,
+ value: 2550,
+ timeNeeded: 75,
+ milestone: {
+ 40: {type: 'changeStat', name: 'value', value: 3400},
+ 240: {type: 'changeStat', name: 'value', value: 4500},
+ 1900: {type: 'changeStat', name: 'value', value: 5750},
+ }
+ },
+ stopwatch: {
+ icon: 'mdi-timer',
+ color: 'pale-blue',
+ price: {craft_screws: 20, village_metal: buildNum(1.44, 'B'), village_gears: 1},
+ prio: 1,
+ value: 8600,
+ timeNeeded: 3600,
+ milestone: {
+ 65: {type: 'changeStat', name: 'timeNeeded', value: 1800},
+ 335: {type: 'changeStat', name: 'value', value: buildNum(12.5, 'K')},
+ }
+ },
+
+ // Random recipes
+
+ // Special recipes
+ smallChest: {
+ icon: 'mdi-treasure-chest',
+ color: 'pale-yellow',
+ price: {
+ craft_rope: lvl => Math.pow(2, lvl) * 60,
+ craft_woodenPlanks: lvl => Math.pow(2, lvl) * 30,
+ craft_brick: lvl => Math.pow(2, lvl) * 15,
+ craft_screws: lvl => Math.pow(2, lvl) * 25
+ },
+ prio: 1,
+ isSpecial: true,
+ effect: [
+ {name: 'villageMaterialCap', type: 'mult', value: lvl => lvl * 0.1 + 1}
+ ],
+ timeNeeded: 7200
+ },
+ bush: {
+ icon: 'mdi-nature',
+ color: 'green',
+ price: {
+ village_water: lvl => Math.pow(1.25, lvl) * buildNum(500, 'K'),
+ craft_pouch: lvl => getSequence(5, lvl + 1) * 8,
+ craft_bowl: lvl => getSequence(2, lvl + 1) * 10
+ },
+ prio: 1,
+ isSpecial: true,
+ effect: [
+ {name: 'currencyVillagePlantFiberGain', type: 'mult', value: lvl => lvl * 0.05 + 1},
+ {name: 'currencyVillagePlantFiberCap', type: 'base', value: lvl => getSequence(2, lvl) * 500}
+ ],
+ timeNeeded: 3600
+ },
+ handSaw: {
+ icon: 'mdi-hand-saw',
+ color: 'light-grey',
+ price: {
+ village_metal: lvl => Math.pow(1.25, lvl) * buildNum(1.8, 'M'),
+ craft_weight: lvl => getSequence(3, lvl + 1) * 15
+ },
+ prio: 1,
+ isSpecial: true,
+ effect: [
+ {name: 'currencyVillageWoodGain', type: 'mult', value: lvl => lvl * 0.05 + 1},
+ {name: 'currencyVillageWoodCap', type: 'base', value: lvl => getSequence(2, lvl) * 500}
+ ],
+ timeNeeded: 3600
+ },
+ garage: {
+ icon: 'mdi-garage-open-variant',
+ color: 'dark-grey',
+ price: {
+ village_wood: lvl => Math.pow(1.25, lvl) * buildNum(14, 'M'),
+ craft_chain: lvl => getSequence(3, lvl + 1) * 15
+ },
+ prio: 1,
+ isSpecial: true,
+ effect: [
+ {name: 'currencyVillageStoneGain', type: 'mult', value: lvl => lvl * 0.05 + 1},
+ {name: 'currencyVillageStoneCap', type: 'base', value: lvl => getSequence(2, lvl) * 500}
+ ],
+ timeNeeded: 3600
+ },
+
+ diamondRing: {
+ icon: 'mdi-ring',
+ color: 'cyan',
+ price: {
+ village_metal: lvl => Math.pow(1.25, lvl) * buildNum(14, 'M'),
+ village_gem: lvl => Math.pow(1.25, lvl) * buildNum(2, 'M'),
+ craft_goldenRing: lvl => getSequence(2, lvl) * 5
+ },
+ prio: 1,
+ isSpecial: true,
+ effect: [
+ {name: 'currencyVillageCoinGain', type: 'mult', value: lvl => lvl * 0.2 + 1},
+ {name: 'currencyVillageCopperCoinGain', type: 'mult', value: lvl => lvl * 0.2 + 1},
+ ],
+ timeNeeded: 14400
+ },
+}
diff --git a/src/js/modules/village/job.js b/src/js/modules/village/job.js
index 7e807398..104b76ec 100644
--- a/src/js/modules/village/job.js
+++ b/src/js/modules/village/job.js
@@ -116,7 +116,7 @@ export default {
max: 0,
needed: 600,
rewards: [
- {type: 'base', name: 'villageLootGain', amount: 2}
+ {type: 'base', name: 'villageLootGain', amount: 0.5}
]
}
}
diff --git a/src/js/modules/village/upgrade2.js b/src/js/modules/village/upgrade2.js
new file mode 100644
index 00000000..8da29f18
--- /dev/null
+++ b/src/js/modules/village/upgrade2.js
@@ -0,0 +1,98 @@
+import store from "../../../store";
+import { buildNum } from "../../utils/format";
+import { getSequence } from "../../utils/math";
+
+export default {
+ cashRegister: {subfeature: 1, price(lvl) {
+ return {village_copperCoin: Math.pow(lvl * 0.25 + 2, lvl) * 2000};
+ }, effect: [
+ {name: 'villageCounter', type: 'base', value: lvl => lvl},
+ {name: 'currencyVillageCopperCoinCap', type: 'mult', value: lvl => Math.pow(2, lvl)}
+ ]},
+ decoration: {subfeature: 1, price(lvl) {
+ return {village_copperCoin: Math.pow(1.75, lvl) * 900};
+ }, effect: [
+ {name: 'currencyVillageCopperCoinGain', type: 'mult', value: lvl => Math.pow(1.175, lvl)}
+ ]},
+ plantFiberBin: {subfeature: 1, price(lvl) {
+ if (lvl === 0) {
+ return {};
+ }
+ return {village_copperCoin: Math.pow(3, lvl) * 100};
+ }, effect: [
+ {name: 'currencyVillagePlantFiberGain', type: 'base', value: lvl => getSequence(1, lvl) * 0.1},
+ {name: 'rope', type: 'villageCraft', value: lvl => lvl >= 1}
+ ]},
+ woodBin: {subfeature: 1, requirement() {
+ return store.state.upgrade.item.village_plantFiberBin.highestLevel >= 1;
+ }, price(lvl) {
+ return {village_copperCoin: Math.pow(3, lvl) * 200};
+ }, effect: [
+ {name: 'currencyVillageWoodGain', type: 'base', value: lvl => getSequence(1, lvl) * 0.1},
+ {name: 'woodenPlanks', type: 'villageCraft', value: lvl => lvl >= 1}
+ ]},
+ stoneBin: {subfeature: 1, requirement() {
+ return store.state.upgrade.item.village_woodBin.highestLevel >= 1;
+ }, price(lvl) {
+ return {village_copperCoin: Math.pow(3, lvl) * 500};
+ }, effect: [
+ {name: 'currencyVillageStoneGain', type: 'base', value: lvl => getSequence(1, lvl) * 0.1},
+ {name: 'brick', type: 'villageCraft', value: lvl => lvl >= 1}
+ ]},
+ metalBin: {subfeature: 1, requirement() {
+ return store.state.upgrade.item.village_stoneBin.highestLevel >= 1;
+ }, price(lvl) {
+ return {village_copperCoin: Math.pow(3, lvl) * buildNum(50, 'K')};
+ }, effect: [
+ {name: 'currencyVillageMetalGain', type: 'base', value: lvl => getSequence(1, lvl) * 0.075},
+ {name: 'screws', type: 'villageCraft', value: lvl => lvl >= 1}
+ ]},
+ waterBin: {subfeature: 1, requirement() {
+ return store.state.upgrade.item.village_metalBin.highestLevel >= 1;
+ }, price(lvl) {
+ return {village_copperCoin: Math.pow(3, lvl) * buildNum(600, 'K')};
+ }, effect: [
+ {name: 'currencyVillageWaterGain', type: 'base', value: lvl => getSequence(1, lvl) * 0.06},
+ {name: 'waterBottle', type: 'villageCraft', value: lvl => lvl >= 1}
+ ]},
+ glassBin: {subfeature: 1, requirement() {
+ return store.state.upgrade.item.village_waterBin.highestLevel >= 1;
+ }, price(lvl) {
+ return {village_copperCoin: Math.pow(3, lvl) * buildNum(14.5, 'M')};
+ }, effect: [
+ {name: 'currencyVillageGlassGain', type: 'base', value: lvl => getSequence(1, lvl) * 0.05},
+ {name: 'cocktailGlass', type: 'villageCraft', value: lvl => lvl >= 1}
+ ]},
+ hardwoodBin: {subfeature: 1, requirement() {
+ return store.state.upgrade.item.village_glassBin.highestLevel >= 1;
+ }, price(lvl) {
+ return {village_copperCoin: Math.pow(3, lvl) * buildNum(900, 'M')};
+ }, effect: [
+ {name: 'currencyVillageHardwoodGain', type: 'base', value: lvl => getSequence(1, lvl) * 0.025},
+ {name: 'boomerang', type: 'villageCraft', value: lvl => lvl >= 1}
+ ]},
+ gemBin: {subfeature: 1, requirement() {
+ return store.state.upgrade.item.village_hardwoodBin.highestLevel >= 1;
+ }, price(lvl) {
+ return {village_copperCoin: Math.pow(3, lvl) * buildNum(85, 'B')};
+ }, effect: [
+ {name: 'currencyVillageGemGain', type: 'base', value: lvl => getSequence(1, lvl) * 0.025},
+ {name: 'polishedGem', type: 'villageCraft', value: lvl => lvl >= 1}
+ ]},
+ oilBin: {subfeature: 1, requirement() {
+ return store.state.upgrade.item.village_gemBin.highestLevel >= 1;
+ }, price(lvl) {
+ return {village_copperCoin: Math.pow(3, lvl) * buildNum(9.6, 'T')};
+ }, effect: [
+ {name: 'currencyVillageOilGain', type: 'base', value: lvl => getSequence(1, lvl) * 0.015},
+ {name: 'oilLamp', type: 'villageCraft', value: lvl => lvl >= 1}
+ ]},
+ marbleBin: {subfeature: 1, requirement() {
+ return store.state.upgrade.item.village_oilBin.highestLevel >= 1;
+ }, price(lvl) {
+ return {village_copperCoin: Math.pow(3, lvl) * buildNum(1.44, 'Qa')};
+ }, effect: [
+ {name: 'currencyVillageMarbleGain', type: 'base', value: lvl => getSequence(1, lvl) * 0.01},
+ {name: 'shower', type: 'villageCraft', value: lvl => lvl >= 1}
+ ]},
+}
diff --git a/src/js/modules/village/upgradePrestige.js b/src/js/modules/village/upgradePrestige.js
index 6eb07cdc..37991236 100644
--- a/src/js/modules/village/upgradePrestige.js
+++ b/src/js/modules/village/upgradePrestige.js
@@ -1,5 +1,6 @@
import store from "../../../store";
import { buildNum } from "../../utils/format";
+import { getSequence } from "../../utils/math";
export default {
arch: {type: 'prestige', price(lvl) {
@@ -171,7 +172,7 @@ export default {
}, price(lvl) {
return {village_blessing: Math.pow(1.65, lvl) * buildNum(800, 'M')};
}, effect: [
- {name: 'villageLootGain', type: 'mult', value: lvl => Math.pow(1.15, lvl) * (lvl * 0.15 + 1)}
+ {name: 'villageLootGain', type: 'mult', value: lvl => Math.pow(1.05, lvl) * (lvl * 0.1 + 1)}
]},
holyChisel: {type: 'prestige', requirement() {
return store.state.unlock.villageBuildings7.see;
@@ -180,4 +181,101 @@ export default {
}, effect: [
{name: 'villageLootQuality', type: 'base', value: lvl => lvl * 2}
]},
+
+ hireArtisans: {type: 'prestige', requirement() {
+ return store.state.unlock.villageCraftingSubfeature.see;
+ }, price(lvl) {
+ return {village_shares: Math.pow(10, getSequence(1, lvl)) * 10};
+ }, effect: [
+ {name: 'villageArtisan', type: 'base', value: lvl => lvl}
+ ]},
+ hireWorkers: {type: 'prestige', requirement() {
+ return store.state.unlock.villageCraftingSubfeature.see;
+ }, price(lvl) {
+ return {village_shares: Math.pow(lvl * 0.02 + 1.65, lvl) * 5};
+ }, effect: [
+ {name: 'villageMaterialGain', type: 'mult', value: lvl => Math.pow(1.05, lvl) * (lvl * 0.05 + 1)}
+ ]},
+ hireAccountants: {type: 'prestige', requirement() {
+ return store.state.unlock.villageCraftingSubfeature.see;
+ }, price(lvl) {
+ return {village_shares: Math.pow(1.9, lvl) * 8};
+ }, effect: [
+ {name: 'currencyVillageCopperCoinCap', type: 'mult', value: lvl => Math.pow(1.75, lvl)}
+ ]},
+ recipeBook: {type: 'prestige', cap: 6, requirement() {
+ return store.state.unlock.villageCraftingSubfeature.see;
+ }, price(lvl) {
+ return {village_shares: Math.pow(2.5, lvl) * 60};
+ }, effect: [
+ {name: 'arrows', type: 'villageCraft', value: lvl => lvl >= 1},
+ {name: 'bowl', type: 'villageCraft', value: lvl => lvl >= 2},
+ {name: 'smallChest', type: 'villageCraft', value: lvl => lvl >= 3},
+ {name: 'chain', type: 'villageCraft', value: lvl => lvl >= 4},
+ {name: 'spear', type: 'villageCraft', value: lvl => lvl >= 5},
+ {name: 'goldenRing', type: 'villageCraft', value: lvl => lvl >= 6},
+ ]},
+ adCampaign: {type: 'prestige', requirement() {
+ return store.state.unlock.villageCraftingSubfeature.see;
+ }, price(lvl) {
+ return {village_shares: Math.pow(lvl * 0.05 + 1.9, lvl) * 80};
+ }, effect: [
+ {name: 'currencyVillageCopperCoinGain', type: 'mult', value: lvl => Math.pow(1.1, lvl) * (lvl * 0.2 + 1)}
+ ]},
+ hireExplorers: {type: 'prestige', cap: 4, requirement() {
+ return store.state.unlock.villageCraftingSubfeature.see;
+ }, price(lvl) {
+ return {village_shares: Math.pow(15, getSequence(1, lvl)) * 575};
+ }, effect: [
+ {name: 'villageSpecialIngredient', type: 'unlock', value: lvl => lvl >= 1},
+ {name: 'villageIngredientCount', type: 'base', value: lvl => lvl > 1 ? (lvl - 1) : null},
+ {name: 'villageIngredientBoxAmount', type: 'base', value: lvl => lvl > 1 ? (4 * (lvl - 1)) : null},
+ {name: 'poisonedArrows', type: 'villageCraft', value: lvl => lvl >= 1},
+ {name: 'frostSpear', type: 'villageCraft', value: lvl => lvl >= 2},
+ {name: 'spicySoup', type: 'villageCraft', value: lvl => lvl >= 3},
+ {name: 'stopwatch', type: 'villageCraft', value: lvl => lvl >= 4},
+ {name: 'villageIngredientBoxGet', type: 'text', value: lvl => lvl},
+ ], onBuy() {
+ store.dispatch('consumable/gain', {name: 'village_ingredientBox', amount: 3});
+ }},
+ hireGardeners: {type: 'prestige', requirement() {
+ return store.state.upgrade.item.village_woodBin.highestLevel >= 1;
+ }, price(lvl) {
+ return {village_shares: Math.pow(1.75, lvl) * 140};
+ }, effect: [
+ {name: 'currencyVillagePlantFiberGain', type: 'mult', value: lvl => lvl * 0.1 + 1},
+ {name: 'currencyVillageWoodGain', type: 'mult', value: lvl => lvl * 0.1 + 1},
+ {name: 'currencyVillagePlantFiberCap', type: 'mult', value: lvl => Math.pow(1.2, lvl)},
+ {name: 'currencyVillageWoodCap', type: 'mult', value: lvl => Math.pow(1.2, lvl)}
+ ]},
+ hireMiners: {type: 'prestige', requirement() {
+ return store.state.upgrade.item.village_metalBin.highestLevel >= 1;
+ }, price(lvl) {
+ return {village_shares: Math.pow(1.75, lvl) * 220};
+ }, effect: [
+ {name: 'currencyVillageStoneGain', type: 'mult', value: lvl => lvl * 0.1 + 1},
+ {name: 'currencyVillageMetalGain', type: 'mult', value: lvl => lvl * 0.1 + 1},
+ {name: 'currencyVillageStoneCap', type: 'mult', value: lvl => Math.pow(1.2, lvl)},
+ {name: 'currencyVillageMetalCap', type: 'mult', value: lvl => Math.pow(1.2, lvl)}
+ ]},
+ hireBartenders: {type: 'prestige', requirement() {
+ return store.state.upgrade.item.village_glassBin.highestLevel >= 1;
+ }, price(lvl) {
+ return {village_shares: Math.pow(1.75, lvl) * 335};
+ }, effect: [
+ {name: 'currencyVillageWaterGain', type: 'mult', value: lvl => lvl * 0.1 + 1},
+ {name: 'currencyVillageGlassGain', type: 'mult', value: lvl => lvl * 0.1 + 1},
+ {name: 'currencyVillageWaterCap', type: 'mult', value: lvl => Math.pow(1.2, lvl)},
+ {name: 'currencyVillageGlassCap', type: 'mult', value: lvl => Math.pow(1.2, lvl)}
+ ]},
+ hireExperts: {type: 'prestige', requirement() {
+ return store.state.upgrade.item.village_gemBin.highestLevel >= 1;
+ }, price(lvl) {
+ return {village_shares: Math.pow(1.75, lvl) * 520};
+ }, effect: [
+ {name: 'currencyVillageHardwoodGain', type: 'mult', value: lvl => lvl * 0.1 + 1},
+ {name: 'currencyVillageGemGain', type: 'mult', value: lvl => lvl * 0.1 + 1},
+ {name: 'currencyVillageHardwoodCap', type: 'mult', value: lvl => Math.pow(1.2, lvl)},
+ {name: 'currencyVillageGemCap', type: 'mult', value: lvl => Math.pow(1.2, lvl)}
+ ]},
}
diff --git a/src/js/savefile.js b/src/js/savefile.js
index ba0eaa29..b498cf14 100644
--- a/src/js/savefile.js
+++ b/src/js/savefile.js
@@ -23,15 +23,22 @@ import v1_3_4 from "./modules/migration/v1_3_4";
import v1_3_5 from "./modules/migration/v1_3_5";
import v1_4_0 from "./modules/migration/v1_4_0";
import v1_4_1 from "./modules/migration/v1_4_1";
+import { simpleHash } from "./utils/random";
+import v1_5_0 from "./modules/migration/v1_5_0";
+import v1_5_1 from "./modules/migration/v1_5_1";
+import v1_5_3 from "./modules/migration/v1_5_3";
const migrations = {
- '1.4.1': v1_4_1,
- '1.4.0': v1_4_0,
- '1.3.5': v1_3_5,
- '1.3.4': v1_3_4,
- '1.3.0': v1_3_0,
+ '1.1.0': v1_1_0,
'1.1.2': v1_1_2,
- '1.1.0': v1_1_0
+ '1.3.0': v1_3_0,
+ '1.3.4': v1_3_4,
+ '1.3.5': v1_3_5,
+ '1.4.0': v1_4_0,
+ '1.4.1': v1_4_1,
+ '1.5.0': v1_5_0,
+ '1.5.1': v1_5_1,
+ '1.5.3': v1_5_3,
};
export { checkLocal, saveLocal, loadFile, exportFile, cleanStore, getSavefile, getSavefileName, encodeFile, decodeFile }
@@ -142,6 +149,32 @@ function decodeFile(file, showErrors = true) {
return null;
}
+ // Check if loaded from different testing build
+ if (APP_TESTING && file.testing && file.version !== store.state.system.version) {
+ if (showErrors) {
+ store.commit('system/addNotification', {color: 'error', timeout: -1, message: {
+ type: 'import',
+ error: 'testingVersion'
+ }});
+ }
+ return null;
+ }
+
+ // Check for invalid checksum
+ // eslint-disable-next-line no-unused-vars
+ const {checksum: _, ...rawFile} = file;
+ if (semverCompare(file.version, '1.5.0') === 1 && simpleHash(JSON.stringify(rawFile)) !== file.checksum && Object.keys(file.cheatDetected).length === 0) {
+ if (showErrors) {
+ store.commit('system/addNotification', {color: APP_TESTING ? 'warning' : 'error', timeout: -1, message: {
+ type: 'import',
+ error: 'expected checksum ' + simpleHash(JSON.stringify(rawFile)) + ', but received ' + file.checksum + '.'
+ }});
+ }
+ if (!APP_TESTING) {
+ return null;
+ }
+ }
+
return file;
}
@@ -162,12 +195,16 @@ function loadFile(file) {
return;
}
- ['timestamp', 'currentDay', 'theme', 'backupTimer', 'playerId', 'noteHint'].forEach(elem => {
+ ['timestamp', 'currentDay', 'lastPlayedDays', 'theme', 'backupTimer', 'playerId', 'noteHint', 'cheaterSelfMark', 'cheatDetected'].forEach(elem => {
if (save[elem]) {
store.commit('system/updateKey', {key: elem, value: save[elem]});
}
});
+ if (save.playerName) {
+ store.commit('system/updateKey', {key: 'playerName', value: decodeURIComponent(save.playerName)})
+ }
+
// Generic systems
if (save.themesOwned) {
save.themesOwned.forEach(elem => {
@@ -188,6 +225,11 @@ function loadFile(file) {
store.commit('system/updateSubfeature', {key, value: elem});
}
}
+ if (save.nextSubfeature) {
+ for (const [key, elem] of Object.entries(save.nextSubfeature)) {
+ store.commit('system/updateNextSubfeature', {key, value: elem});
+ }
+ }
if (save.note) {
save.note.forEach(name => {
Vue.set(store.state.note[name], 'found', true);
@@ -199,6 +241,33 @@ function loadFile(file) {
Vue.set(store.state.unlock[key], 'see', true);
Vue.set(store.state.unlock[key], 'use', !!elem);
}
+
+ // Detect unobtainable unlocks
+ const illegalUnlocks = {
+ debugFeature: 'meta',
+ relicMuseum: 'relic',
+ treasureSpecialEffect: 'treasure',
+ treasureDual: 'treasure',
+ cardShiny: 'card',
+ generalOrladeeSubfeature: 'general',
+ generalOppenschroeSubfeature: 'general',
+ generalBelluxSubfeature: 'general',
+ generalOnocluaSubfeature: 'general',
+ generalOmnisolixSubfeature: 'general',
+ hordeChessItems: 'horde',
+ hordeClassAssassin: 'horde',
+ hordeClassShaman: 'horde',
+ hordeClassUndead: 'horde',
+ hordeClassCultist: 'horde',
+ hordeClassScholar: 'horde',
+ };
+ if (Object.keys(illegalUnlocks).includes(key)) {
+ store.commit('system/registerCheat', {
+ feature: illegalUnlocks[key] ?? 'meta',
+ name: 'illegalunlock:' + key,
+ severity: 200
+ });
+ }
}
}
if (save.currency) {
@@ -250,8 +319,8 @@ function loadFile(file) {
}
if (save.relic) {
save.relic.forEach(elem => {
- if (store.state.relic[elem]) {
- Vue.set(store.state.relic[elem], 'found', true);
+ if (store.state.relic.item[elem]) {
+ Vue.set(store.state.relic.item[elem], 'found', true);
store.dispatch('relic/apply', {name: elem});
}
});
@@ -332,9 +401,18 @@ function loadFile(file) {
// Update currency mults
if (save.currency) {
- for (const [key] of Object.entries(save.currency)) {
+ for (const [key, elem] of Object.entries(save.currency)) {
if (store.state.currency[key] !== undefined) {
store.dispatch('currency/updateCurrencyMult', key);
+
+ // Detect some cheats
+ if (save.stat[key] && elem > (save.stat[key][1] * 1.5)) {
+ store.commit('system/registerCheat', {
+ feature: store.state.currency[key].feature,
+ name: 'currencyoverstat:' + key.replace('_', '').toLowerCase(),
+ severity: 200
+ });
+ }
}
}
}
@@ -362,14 +440,18 @@ function getSavefile() {
version: store.state.system.version,
timestamp: store.state.system.timestamp,
currentDay: store.state.system.currentDay,
+ lastPlayedDays: store.state.system.lastPlayedDays,
theme: store.state.system.theme,
backupTimer: store.state.system.backupTimer,
playerId: store.state.system.playerId,
themesOwned: [],
completedTutorial: [],
+ cheaterSelfMark: store.state.system.cheaterSelfMark,
+ cheatDetected: store.state.system.cheatDetected,
// Generic systems
subfeature: {},
+ nextSubfeature: {},
unlock: {},
currency: {},
stat: {},
@@ -385,6 +467,10 @@ function getSavefile() {
cachePage: {}
};
+ if (store.state.system.playerName !== null) {
+ save.playerName = encodeURIComponent(store.state.system.playerName);
+ }
+
if (APP_TESTING) {
save.testing = true;
}
@@ -404,6 +490,9 @@ function getSavefile() {
if (elem.currentSubfeature > 0) {
save.subfeature[key] = elem.currentSubfeature;
}
+ if (elem.nextSubfeature > 0) {
+ save.nextSubfeature[key] = elem.nextSubfeature;
+ }
}
for (const [key, elem] of Object.entries(store.state.unlock)) {
if (elem.see) {
@@ -432,7 +521,7 @@ function getSavefile() {
save.upgradeQueue[key] = [...elem];
}
}
- for (const [key, elem] of Object.entries(store.state.relic)) {
+ for (const [key, elem] of Object.entries(store.state.relic.item)) {
if (elem.found) {
save.relic.push(key);
}
@@ -499,5 +588,7 @@ function getSavefile() {
save.timeMult = store.state.system.timeMult;
}
+ save.checksum = simpleHash(JSON.stringify(save));
+
return encodeFile(save);
}
diff --git a/src/js/theme/colors.js b/src/js/theme/colors.js
index a30d1fb7..2ff4831d 100644
--- a/src/js/theme/colors.js
+++ b/src/js/theme/colors.js
@@ -218,6 +218,20 @@ let obj = {
darken3: '#37474f',
darken4: '#263238'
},
+
+ // Full custom colors
+ babypink: {
+ base: '#E325B5',
+ lighten5: '#FDE8F8',
+ lighten4: '#F8C4EB',
+ lighten3: '#F49FDF',
+ lighten2: '#EF71D0',
+ lighten1: '#EB4CC5',
+ darken1: '#D219A5',
+ darken2: '#B3148D',
+ darken3: '#8E106F',
+ darken4: '#650B4F'
+ },
};
// Add pale variants
@@ -230,6 +244,7 @@ obj['orange-red'] = mergeColorObject(obj.orange, obj.red);
obj['red-pink'] = mergeColorObject(obj.red, obj.pink);
obj['pink-purple'] = mergeColorObject(obj.pink, obj.purple);
obj['dark-blue'] = mergeColorObject(obj.blue, obj.indigo);
+obj.aqua = mergeColorObject(obj.green, obj.teal, 0.75);
// Add custom colors
obj.wooden = filterColorObject(mergeColorObject(obj.brown, obj['orange-red']), color => color.blacken(0.8));
diff --git a/src/js/theme/sky.js b/src/js/theme/sky.js
index e3787896..489496f8 100644
--- a/src/js/theme/sky.js
+++ b/src/js/theme/sky.js
@@ -5,12 +5,12 @@ export default {
hasCustomNavbar: true,
hasCustomBackground: true,
light: {
- primary: '#FFD500',
+ primary: '#E89820',
secondary: '#A0A0A0',
accent: '#D18147',
},
dark: {
- primary: '#FFD500',
+ primary: '#E89820',
secondary: '#A0A0A0',
accent: '#D18147',
}
diff --git a/src/js/tick.js b/src/js/tick.js
index 93de088e..b1fe7672 100644
--- a/src/js/tick.js
+++ b/src/js/tick.js
@@ -28,9 +28,7 @@ function advance() {
const newDay = getDay(new Date(timestamp * 1000));
if (newDay !== oldDay) {
store.commit('system/updateKey', {key: 'currentDay', value: newDay});
- if (store.state.unlock.eventFeature.see) {
- store.dispatch('event/dayChange', {start: oldDay, end: newDay});
- }
+ store.commit('system/updateKey', {key: 'lastPlayedDays', value: [...store.state.system.lastPlayedDays, newDay].slice(-7)});
}
if (timeDiff > 0) {
@@ -82,10 +80,15 @@ function advance() {
function tick(newTime, oldTime) {
[meta, mining, village, horde, farm, gallery, gem, school, event, achievement, general, cryolab].forEach(module => {
const isFrozen = !!store.state.cryolab[module.name] && store.state.cryolab[module.name].active;
- if ((module.unlockNeeded === null || store.state.unlock[module.unlockNeeded].use) && !isFrozen) {
+ if ((module.unlockNeeded === null || store.state.unlock[module.unlockNeeded].use)) {
const diff = Math.floor(newTime * store.state.system.timeMult / module.tickspeed) - Math.floor(oldTime * store.state.system.timeMult / module.tickspeed);
if (diff > 0) {
- module.tick(diff, oldTime, newTime);
+ if (!isFrozen) {
+ module.tick(diff, oldTime, newTime);
+ }
+ if (module.forceTick !== undefined) {
+ module.forceTick(diff, oldTime, newTime);
+ }
}
}
});
diff --git a/src/js/utils/array.js b/src/js/utils/array.js
index a4864862..37c2766d 100644
--- a/src/js/utils/array.js
+++ b/src/js/utils/array.js
@@ -1,4 +1,4 @@
-export { buildArray, shuffleArray, fallbackArray }
+export { buildArray, shuffleArray, fallbackArray, filterUnique }
/**
* Create an array with a fixed length
@@ -38,3 +38,12 @@ function shuffleArray(array, rngGen = null) {
function fallbackArray(array = [], fallback = null, index = 0) {
return (index >= 0 && index < array.length) ? array[index] : fallback;
}
+
+/**
+ * Return the array with duplicates removed
+ * @param {Array} array
+ * @returns {Array}
+ */
+function filterUnique(array) {
+ return array.filter((v, i, a) => a.indexOf(v) === i);
+}
diff --git a/src/js/utils/format.js b/src/js/utils/format.js
index 9fe31ef3..6fc38769 100644
--- a/src/js/utils/format.js
+++ b/src/js/utils/format.js
@@ -56,7 +56,7 @@ function formatNum(amount, showDecimals = false) {
}
if (numBase < 4) {
- return negativePrefix + Math.round(amount);
+ return negativePrefix + Math.floor(amount);
} else if (Math.floor(numBase / 3) < numFormatters.length) {
const tempVal = amount / Math.pow(10, Math.floor(numBase / 3) * 3);
return negativePrefix + tempVal.toPrecision(4) + numFormatters[Math.floor(numBase / 3)];
@@ -71,24 +71,27 @@ function formatNum(amount, showDecimals = false) {
* @returns {String}
*/
function formatTime(seconds, minimumUnit = 's') {
- let min = ['s', 'm', 'h', 'd'].indexOf(minimumUnit);
+ let min = ['ms', 's', 'm', 'h', 'd'].indexOf(minimumUnit);
let negativePrefix = '';
if (seconds < 0) {
seconds = Math.abs(seconds);
negativePrefix = '-';
}
- if (seconds < 60 && min < 1) {
+ if (seconds < 1 && min < 1) {
+ // display milliseconds only
+ return negativePrefix + Math.floor(seconds * 1000) + 'ms';
+ } else if (seconds < 60 && min < 2) {
// display seconds only
return negativePrefix + Math.floor(seconds) + 's';
- } else if (seconds < 3600 && min < 2) {
+ } else if (seconds < 3600 && min < 3) {
// display minutes and seconds
- return negativePrefix + Math.floor(seconds / 60) + 'm' + (min < 1 ? (' ' + (Math.floor(seconds % 60) < 10 ? '0' : '') + Math.floor(seconds % 60) + 's') : '');
- } else if (seconds < 86400 && min < 3) {
+ return negativePrefix + Math.floor(seconds / 60) + 'm' + (min < 2 ? (' ' + (Math.floor(seconds % 60) < 10 ? '0' : '') + Math.floor(seconds % 60) + 's') : '');
+ } else if (seconds < 86400 && min < 4) {
// display hours and minutes
- return negativePrefix + Math.floor(seconds / 3600) + 'h' + (min < 2 ? (' ' + (Math.floor((seconds % 3600) / 60) < 10 ? '0' : '') + Math.floor((seconds % 3600) / 60) + 'm') : '');
+ return negativePrefix + Math.floor(seconds / 3600) + 'h' + (min < 3 ? (' ' + (Math.floor((seconds % 3600) / 60) < 10 ? '0' : '') + Math.floor((seconds % 3600) / 60) + 'm') : '');
} else if (seconds < 8640000) {
// display days and hours
- return negativePrefix + Math.floor(seconds / 86400) + 'd' + (min < 3 ? (' ' + (Math.floor((seconds % 86400) / 3600) < 10 ? '0' : '') + Math.floor((seconds % 86400) / 3600) + 'h') : '');
+ return negativePrefix + Math.floor(seconds / 86400) + 'd' + (min < 4 ? (' ' + (Math.floor((seconds % 86400) / 3600) < 10 ? '0' : '') + Math.floor((seconds % 86400) / 3600) + 'h') : '');
}
else {
// display days only
diff --git a/src/js/utils/math.js b/src/js/utils/math.js
index 8ea9d360..d7ed32bd 100644
--- a/src/js/utils/math.js
+++ b/src/js/utils/math.js
@@ -1,4 +1,4 @@
-export { logBase, getSequence, splicedLinear, splicedPow, splicedPowLinear, deltaLinear }
+export { logBase, getSequence, splicedLinear, splicedPow, splicedPowLinear, deltaLinear, digitSum }
/**
* Returns the logarithm of a number
@@ -36,3 +36,7 @@ function deltaLinear(base, increase, amount = 1, skip = 0) {
const finalBase = increase * skip + base;
return (finalBase + ((amount - 1) * increase / 2)) * amount;
}
+
+function digitSum(num) {
+ return `${num}`.split('').reduce((acc, n) => acc += parseInt(n), 0);
+}
diff --git a/src/lang/de.js b/src/lang/de.js
index 52a8b2ed..15840018 100644
--- a/src/lang/de.js
+++ b/src/lang/de.js
@@ -1,14 +1,15 @@
-import { de } from 'vuetify/lib/locale'
-import card from './de/card'
-import consumable from './de/consumable'
-import currency from './de/currency'
-import mult from './de/mult'
-import note from './de/note'
-import relic from './de/relic'
-import stat from './de/stat'
-import unlock from './de/unlock'
-import upgrade from './de/upgrade'
-import patchnote from './de/patchnote'
+import { de } from 'vuetify/lib/locale';
+import card from './de/card';
+import consumable from './de/consumable';
+import currency from './de/currency';
+import mult from './de/mult';
+import note from './de/note';
+import relic from './de/relic';
+import stat from './de/stat';
+import unlock from './de/unlock';
+import upgrade from './de/upgrade';
+import patchnote from './de/patchnote';
+import tag from './de/tag';
export default {
...de,
@@ -23,6 +24,9 @@ export default {
equip: 'Ausrüsten',
unequip: 'Ablegen',
unequipAll: 'Alle ablegen',
+ select: 'Auswählen',
+ deselect: 'Abwählen',
+ take: 'Nehmen',
max: 'Max',
maxed: 'Max',
free: 'Kostenlos',
@@ -46,6 +50,7 @@ export default {
saveManual: 'Speichern',
saveExport: 'Nach Datei exportieren',
saveImport: 'Aus Datei laden',
+ resetProgress: 'Fortschritt zurücksetzen',
closeAll: 'Alle schließen',
draw: 'Ziehen',
finish: 'Abschließen',
@@ -142,13 +147,29 @@ export default {
key: 'Dem geladenen Spielstand fehlen wichtige Daten',
version: 'Diese Datei ist von einer neueren Version des Spiels (v{0}, aktuelle Version: v{1})',
testing: 'Dateien vom Teststand können nicht in der Live-Version verwendet werden',
- migration: 'Ein Fehler ist beim Migrieren von v{0} nach v{1} aufgetreten'
+ testingVersion: 'Dateien von älteren Testversionen können nicht verwendet werden',
+ migration: 'Ein Fehler ist beim Migrieren von v{0} nach v{1} aufgetreten',
+ checksum: 'Ungültige Prüfsumme',
}
},
duplicateTab: {
title: 'Gooboo läuft bereits in einem anderen Tab',
description: 'Um Konflikte im Spielstand zu vermeiden, kann Gooboo nur einmal gleichzeitig laufen. Bitte schließe diesen Tab und kehre zum vorhandenen Tab mit dem Spiel zurück.'
},
+ reset: {
+ feature: 'Möchtest du neu anfangen? Hier kannst du den Fortschritt in einer einzelnen Funktion zurücksetzen, ohne den Rest des Spiels zu beeinflussen.',
+ warning: 'Das ist KEIN Prestige und es gibt dafür keine Belohnungen oder Erstattungen. Das Zurücksetzen kann nicht rückgängig gemacht werden',
+ deleteSave: 'Du kannst auch den gesamten Spielstand löschen:',
+ deleteButton: 'Spielstand löschen'
+ },
+ prestigeDescription: {
+ mining_ember: 'Erhalte einen Prozentsatz der Gräbertiefe als Glut',
+ village_blessing: 'Glaube wird in Segen umgewandelt',
+ village_shares: 'Erhalte 0.1% der aktuellen Kupfermünzen im Besitz als Aktien',
+ horde_soulEmpowered: 'Korrupte Seelen werden in verstärkte Seelen umgewandelt',
+ horde_courage: 'Erhalte Courage, wenn du Stufe 10 erreichst, und noch mehr für jede Stufe darüber',
+ gallery_cash: 'Erhalte Geld, abhängig von der in diesem Durchlauf erhaltenen Schönheitsmenge',
+ },
confirm: {
title: 'Aktion bestätigen',
prestige: 'Bei einem Prestige wird die Funktion im Austausch gegen Prestige-Währung zurückgesetzt. Möchtest du das wirklich tun?',
@@ -170,13 +191,18 @@ export default {
weatherChaosFishingRodBuy: 'Die Angel "{0}" kostet seltene Währung. Möchtest du das wirklich kaufen?',
summerFestivalCellBuy: 'Ein neues Inselfeld kostet seltene Währung. Möchtest du das wirklich kaufen?',
farmCrop: 'Die ausgewählten Pflanzen kosten seltene Währung. Möchtest du das wirklich kaufen?',
+ galleryMotivation: 'Motivation kostet seltene Währung. Möchtest du das wirklich kaufen?',
treasure: 'Ein neuer Schatz kostet seltene Währung. Möchtest du das wirklich kaufen?',
schoolExamPass: 'Ein Prüfungspass kostet seltene Währung. Möchtest du das wirklich kaufen?',
treasureFragment: 'Fragmente kosten seltene Währung. Möchtest du das wirklich kaufen?',
treasureDelete: 'Möchtest du den Schatz wirklich zerstören und in Fragmente umwandeln?',
casinoBingoBuy: 'Eine Bingokarte kostet seltene Währung. Möchtest du das wirklich kaufen?',
casinoWheelSpin: 'Ein Dreh am Glücksrad kostet seltene Währung. Möchtest du das wirklich kaufen?',
- consumable: 'Diese Aktion benötigt Verbrauchsgüter, die du nicht besitzt. Möchtest du sie automatisch für seltene Währung einkaufen?'
+ consumable: 'Diese Aktion benötigt Verbrauchsgüter, die du nicht besitzt. Möchtest du sie automatisch für seltene Währung einkaufen?',
+ reset: {
+ text: 'Möchtest du wirklich die {0}-Funktion zurücksetzen? Das kann nicht rückgängig gemacht werden!',
+ },
+ resetAll: 'Möchtest du wirklich deinen Spielstand löschen? Das kann nicht rückgängig gemacht werden!'
},
feature: {
subfeature: 'Unterfunktion',
@@ -203,6 +229,8 @@ export default {
// Subfeatures
miningGas: 'Gas',
+ villageCrafting: 'Handwerk',
+ hordeClasses: 'Klassen',
schoolLiterature: 'Literatur',
schoolHistory: 'Geschichte',
schoolArt: 'Kunst',
@@ -226,6 +254,7 @@ export default {
},
horde: {
0: 'Ausrüstung',
+ 1: 'Klassen',
},
farm: {
0: 'Garten',
@@ -236,13 +265,23 @@ export default {
},
unlock,
mult,
+ tag,
text: {
+ villageIngredientBoxGet: 'Erhalte 3 Zutatenkisten',
+ hordeBattlePassUpgrade: 'Neue Verbesserung',
+ hordeBattlePassPrestigeUpgrade: 'Neue Prestige-Verbesserung',
farmUnlockDna: 'Schalte alle DNA-Verbesserungen von Stufe-1-Genen frei',
- farmGnomeBoost: 'Angrenzende Gartenzwerge erhöhen sämtlichen Pflanzenertrag um 10%',
+ farmGnomeBoost: 'Erhöht sämtlichen Pflanzenertrag um 4% pro angrenzenden Gartenzwerg. Premium-Gartenzwerge zählen doppelt',
farmLonelyGrow: 'Pflanzen wachsen doppelt so schnell, wenn keine anderen Pflanzen der gleichen Art auf dem Feld sind',
- farmFertileBoost: 'Erhöht sämtlichen Pflanzenertrag um 30% vom Wachstumsbonus des Düngers',
- farmYieldConversion: '60% vom Ertrag wird in andere Ertragsarten umgewandelt (jeweils 20%)',
+ farmFertileBoost: 'Erhöht den Ertrag um 30% pro Saphirkosten des Düngers',
+ farmYieldConversion: '5% vom Ertrag wird an andere Ertragsarten gegeben',
farmFastPrestige: 'Prestige reduziert die Pflanzenstufe um 5, anstatt sie auf 0 zurückzusetzen',
+ farmLuckyHarvest: '1% chance to receive 8x harvest gain',
+ farmSelfless: 'Erhöht den Ertrag aller Pflanzen um +5%',
+ farmUnyielding: 'Beim Ernten der Pflanze wird sie zu 40% kostenlos neu gepflanzt',
+ farmTeamwork: 'Wenn dieses Gen auf einer Pflanze jeder Ertragsart vorhanden ist, wird der Ertrag aller Pflanzen verdoppelt',
+ farmHunter: 'Seltene Rohstofferträge, die auf dieser Pflanze heimisch sind, werden gejagt. Die Jagdchance beträgt 1% der Chance auf seltenen Ertrag. Bei jeder erfolgreichen Jagd steigt die Rohstoffkapazität um 10% des Grundwertes und senkt die Grund-Jagdchance um 5%',
+ farmPatient: 'Erhöht den Ertrag um +3% pro Tag nachdem dieses Gen ausgewählt wurde, bis zu +180% nach 60 Tagen',
},
upgrade,
currency,
@@ -319,6 +358,36 @@ export default {
github: 'GitHub',
website: 'Website',
googlefonts: 'Google Fonts'
+ },
+ cheater: {
+ 0: {
+ title: 'Ehrenhaft',
+ description: 'Hat das Spiel ohne die unten genannten Werkzeuge gespielt',
+ },
+ 100: {
+ title: 'Automatisiert',
+ description: 'Hat Werkzeuge genutzt, um automatisch menschenähnliche Aktionen durchzuführen, aber noch die Regeln des Spiels befolgt',
+ },
+ 200: {
+ title: 'Cheater',
+ description: 'Hat Spielvariablen bearbeitet oder Werkzeuge genutzt, um sonst unerreichbare Ergebnisse zu erzielen oder Ergebnisse vorhergesehen / verändert',
+ },
+ selfMark: 'Cheater-Status setzen',
+ selfMarkDescription: 'Du kannst dich hier selbst als Cheater markieren. Dies ist rein optisch und kann jederzeit rückgängig gemacht werden',
+ noDetected: 'Keine Cheats erkannt',
+ featureDetected: 'Cheats wurden in folgenden Funktionen erkannt:',
+ featureDetected2: 'Du kannst die Cheater-Markierung entfernen, indem du die betroffenen Funktionen vollständig zurücksetzt',
+ globalDetected: 'Cheats wurden erkannt und dein Spielstand wurde dauerhaft markiert',
+ selfMarkClick: 'Solltest du gecheatet haben und es wurde vom Spiel nicht erkannt, kannst du hier klicken um die Option anzuzeigen, sich selbst als Cheater zu markieren',
+ },
+ statistics: {
+ name: 'Statistiken',
+ overview: 'Übersicht',
+ other: 'Andere',
+ gained: 'Erhalten',
+ maxOwned: 'Höchstmenge',
+ currentTotal: 'aktuell / gesamt',
+ defaultPlayerName: 'Spieler',
}
},
error: {
@@ -729,6 +798,12 @@ export default {
ritualHintDescription: 'Chance, einen Hinweis auf eine Position oder Zutat zu erhalten. Hinweise werden nur bei erfolgreichen neuen Ritualen gegeben. Für jeden gefundenen Hinweis sinkt die Chance um {0}%. Hinweise und die reduzierte Chance werden zurückgesetzt, wenn das Ritual aus dem Hinweis gefunden wird.',
clickToAdd: 'Klicke auf Zutaten, um sie dem Ritual hinzuzufügen',
ingredientSizeDescription: 'Zutatengröße erlaubt es dir, mehrere Zutaten pro magischer Währung zu finden',
+ favouriteIngredient: {
+ title: 'Lieblingszutat',
+ description: 'Du kannst eine Zutat als Lieblingszutat definieren, und jedes Mal, wenn du eine Zutat findest, erhältst du auch deine Lieblingszutat',
+ copy: 'Gefundene Zutat kopieren',
+ },
+ sackDescription: 'Säcke tauchen bei hohen Magiemengen auf, verbrauchen 10x so viel Magie und enthalten 10x mehr Zutaten, welche gleichmäßig auf alle verfügbaren verteilt werden',
newDescription: {
empty: 'Hier kannst du sehen, ob das aktuelle Rezept neu ist (noch nie erfolgreich) oder nicht',
isNew: 'Das ist ein neues Rezept und du erhältst beim Erfolg einen Nachtjagd-Chip',
@@ -982,9 +1057,11 @@ export default {
mining_0: 'Tiefster zerbrochener Erzminen-Stein',
mining_1: 'Tiefster zerbrochener Gasriesen-Stein',
village_0: 'Maximaler Wohnraum',
+ village_1: 'Handwerks-Meilensteine erreicht',
horde_0: 'Höchster Zonenboss besiegt',
+ horde_1: 'Battlepass-Stufe',
farm_0: 'Summe aller Pflanzenstufen',
- gallery_0: 'Log5 der gesamten Schönheit',
+ gallery_0: 'Log4 der gesamten Schönheit',
debug: 'Debug'
},
theme: {
@@ -1077,6 +1154,10 @@ export default {
relativeUpgradeStats: {
name: 'Relative Verbesserungswerte',
description: 'Zeigt den Unterschied anstatt vorher / nacher Werte'
+ },
+ useLegacyFarmSelect: {
+ name: 'Alte Bauernhofauswahl',
+ description: 'Nutzt das alte Menü um Pflanzen und Gebäude im Bauernhof auszuwählen'
}
},
automation: {
@@ -1176,6 +1257,30 @@ export default {
name: 'Zeige Währungsschilder',
description: 'Währungseinkommen und Zeit bis zur Kapazität werden ohne Herüberfahren mit der Maus angezeigt'
}
+ },
+ mods_qol: {
+ name: 'Mods QOL',
+ progressNiterMiningSound: {
+ name: 'Sound at X times broken'
+ },
+ progressNiterMiningActiveSound: {
+ name: 'Enable Sound'
+ }
+ },
+ mods_automation: {
+ name: 'Mods automation',
+ progressNiterMining: {
+ name: 'Nitermining autoprogress at X times broken',
+ },
+ progressNiterMiningActive: {
+ name: 'Enable nitermining autoprogress'
+ }
+ },
+ mods_cheats: {
+ name: 'Mods cheats',
+ cheatsGo: {
+ name: 'TestSwitch',
+ }
}
},
statBreakdown: {
@@ -1190,12 +1295,24 @@ export default {
zoneCleared: 'Zone abgeschlossen',
zoneClearedTotal: 'Höchste Zone abgeschlossen',
zone: 'Zone',
+ hordeMaxDifficulty: 'Schwierigkeit abgeschlossen',
hordeBasicLoot: 'Einfache Beute',
hordeItemPermanent: 'Ausrüstungs-Effekt',
+ hordeMastery: 'Ausrüstungs-Meisterung',
+ hordeRest: 'Ruhe',
hordeNostalgia: 'Nostalgie',
hordeNostalgiaLost: 'Erbstücke gefunden',
+ hordeClassMult: 'Klassen-Multiplikator',
+ hordeClassLevel: 'Klassenstufe',
+ hordeBattlePass: 'Battlepass',
+ hordeEnergy: 'Energie',
+ hordeMana: 'Mana',
+ hordeTime: 'Zeit',
+ hordeSacrifice: 'Opfer',
farmEarlyGame: 'Erste Pflanzen',
+ galleryCanvas: 'Leinwand',
cards: 'Karten',
+ cardsShiny: 'Glitzerkarten',
treasure: 'Schätze',
debug: 'Debug',
bankInvestment: 'Investition',
@@ -1206,6 +1323,8 @@ export default {
ritualPotionLevel: 'Trank-Stufe',
ritualHint: 'Gefundene Hinweise',
ritualIngredient: 'Bonuszutat',
+ interest: 'Zinsen',
+ multiplier: 'Multiplikator',
},
// Feature specific translations
@@ -1251,7 +1370,9 @@ export default {
coal: 'Kann ab {0}m oder tiefer gefunden werden, wenn der Stein das erste Mal zerborchen wird',
sulfur: 'Kann ab {0}m oder tiefer gefunden werden, wenn der tiefste Stein getroffen wird',
niter: 'Kann ab {0}m oder tiefer gefunden werden, wenn der Stein zerbrochen wird und die Anzahl der Zerbrechungen einer Zehnerpotenz entspricht',
- obsidian: 'Kann ab {0}m oder tiefer gefunden werden, wenn die Spitzhacke nicht aufgewertet ist'
+ obsidian: 'Kann ab {0}m oder tiefer gefunden werden, wenn die Spitzhacke nicht aufgewertet ist',
+ deeprock: 'Kann ab {0}m oder tiefer gefunden werden, wenn die Ziffern der aktuellen Tiefe addiert 14 oder mehr ergeben',
+ glowshard: 'Kann ab {0}m oder tiefer gefunden werden, mit einer Chance von 0.1% pro Meter unter dem Limit. Pro erhaltene Leuchtscherbe musst du 1 Meter tiefer graben, das Limit wird aber jeden Tag um 10% reduziert',
},
rareEarthNotAffected: 'Dieser Rohstoff wird nicht durch Bodenschatz-Einkommen beeinflusst',
scrapGainHint: 'Du erhältst keinen Schrott für Steine, die du noch nie zerbrochen hast. Manchmal ist es klüger auf der aktuellen Tiefe zu bleiben, um mehr Schrott zu sammeln, anstatt direkt tiefer zu graben.',
@@ -1285,13 +1406,31 @@ export default {
barSteel: 'Spitz',
barTitanium: 'Ausgräber',
barShiny: 'Reich',
- barIridium: 'Geschmolzen'
+ barIridium: 'Geschmolzen',
+ barDarkIron: 'Leere'
},
gasGain: {
0: 'Erhalte ',
1: '% vom möglichen ',
2: ' wenn dieser Stein zerbrochen wird. Du kannst in dieser Tiefe bis zu ',
3: ' sammeln'
+ },
+ beacon: {
+ noBeacon: 'Kein Leuchtfeuer',
+ clickToPlace: 'Klicke, um Leuchtfeuer zu platzieren',
+ selectToPlace: 'Wähle ein Leuchtfeuer zum Platzieren aus',
+ place: 'Platzieren',
+ remove: 'Leuchtfeuer entfernen',
+ removeDescription: 'Du kannst Leuchtfeuer jederzeit entfernen, musst aber 20 Stunden warten bevor du das nächste entfernen kannst',
+ removeCooldown: 'Warte {0}, bevor du Leuchtfeuer entfernen kannst',
+ piercing: 'Bohr-Leuchtfeuer',
+ rich: 'Reichtum-Leuchtfeuer',
+ wonder: 'Wunder-Leuchtfeuer',
+ hope: 'Hoffnungs-Leuchtfeuer',
+ },
+ anomaly: {
+ name: 'Anomalie',
+ toughness: 'Dieser Stein hat 100x Zähigkeit',
}
},
village: {
@@ -1321,6 +1460,51 @@ export default {
religion: 'Religion',
scanning: 'Scannen',
},
+ crafting: {
+ unlockNew: 'Neues Handwerk-Rezept: ',
+ owned: '{0} im Besitz',
+ changeStat: {
+ value: 'Erhöhe den Wert auf {0}',
+ timeNeeded: 'Senke die Herstellungszeit auf {0}'
+ },
+ nextEffect: 'Effekt bei der nächsten Herstellung',
+ special: {
+ description: 'Spezielle Gegenstände bieten permanente Effekte, wenn sie hergestellt werden und der Fortschritt wird beim Prestige nicht zurückgesetzt. Deren Kosten steigt mit jeder Herstellung und sie haben keine Meilensteine'
+ },
+ crafts: '{0} / {1} hergestellt',
+ sellEvery: 'Verkaufe 1 alle ~{0}',
+ sellPrice: 'Verkaufspreis (Wert: {0})',
+ rope: 'Seil',
+ woodenPlanks: 'Holzbretter',
+ brick: 'Ziegel',
+ screws: 'Schrauben',
+ waterBottle: 'Wasserflasche',
+ cocktailGlass: 'Cocktailglas',
+ boomerang: 'Bumerang',
+ polishedGem: 'Polierter Edelstein',
+ oilLamp: 'Öllampe',
+ shower: 'Dusche',
+ pouch: 'Beutel',
+ cupboard: 'Schrank',
+ weight: 'Gewicht',
+ scissors: 'Schere',
+ herbTea: 'Kräutertee',
+ glasses: 'Brille',
+ arrows: 'Pfeile',
+ bowl: 'Schale',
+ chain: 'Kette',
+ spear: 'Speer',
+ goldenRing: 'Goldring',
+ poisonedArrows: 'Vergiftete Pfeile',
+ frostSpear: 'Eisspeer',
+ spicySoup: 'Würzige Suppe',
+ stopwatch: 'Stoppuhr',
+ smallChest: 'Kleine Truhe',
+ bush: 'Busch',
+ handSaw: 'Handsäge',
+ garage: 'Garage',
+ diamondRing: 'Diamantring',
+ },
buildings: 'Gebäude',
village: 'Dorf',
pray: 'Beten',
@@ -1339,6 +1523,8 @@ export default {
housingStat: 'Gesamte Wohnungszahl (erste 25 pro Gebäude)',
coinNotAffected: 'Münzen werden nicht durch gesamtes Rohstoffeinkommen beeinflusst',
faithNotAffected: 'Glaube wird nicht durch gesamtes Rohstoffeinkommen und Mentale-Ressourcen-Einkommen beeinflusst',
+ artisanDescription: 'Handwerker können Gegenstände für dich herstellen',
+ counterDescription: 'Mit Kassen kannst du hergestellte Gegenstände an deine Dorfbewohner verkaufen',
offering: {
name: 'Opfergaben',
description: {
@@ -1355,6 +1541,7 @@ export default {
food: 'Nahrung',
mental: 'Mentale Ressourcen',
loot: 'Beute',
+ specialIngredient: 'Besondere Zutaten',
foodConsume: 'Verbrauche bis zu {0} pro Sekunde'
},
horde: {
@@ -1367,6 +1554,7 @@ export default {
noLoadouts: 'Keine Sets vorhanden',
monsterPartHint: 'Gehe zu Zone 10+ und erreiche Gegner #101, um eine neue Währung zu entdecken! Diese Währung ist essentiell, um weiter fortzuschreiten, da sie beim Erhöhen der Knochen-Kapazität hilft.',
enemyDescription: 'Jeder Gegner in der selben Zone hat x{0} Angriff, x{1} Leben und +{2}% Knochen im Vergleich zum vorherigen Gegner. Dies ist Gegner #{3} und dieser hat x{4} Angriff, x{5} Leben und +{6}% Knochen. All diese Effekte werden bei deinem Tod zurückgesetzt.',
+ enemyDescriptionClasses: 'Jeder Gegner in der selben Zone hat x{0} Angriff, x{1} Leben und +{2}% Blut im Vergleich zum vorherigen Gegner. Dies ist Gegner #{3} und dieser hat x{4} Angriff, x{5} Leben und +{6}% Blut. All diese Effekte werden bei deinem Tod zurückgesetzt.',
enemySigil1: {
s: 'Gegner in dieser Zone haben {0} Zeichen',
p: 'Gegner in dieser Zone haben {0} Zeichen',
@@ -1390,7 +1578,8 @@ export default {
text: 'Normale Angriffe werden jede Sekunde ausgeführt und haben folgende Schadensverteilung: ',
physic: '{0}% physisch',
magic: '{0}% magisch',
- bio: '{0}% biologisch'
+ bio: '{0}% biologisch',
+ strengthAmp: 'Jeder Punkt an Stärke erhöht den Schaden von normalen Angriffen um +{0}%, für einen Gesamtwert von +{1}%. Dies erhöht den Schaden deiner normalen Angriffe auf {2}.'
},
healthDescription: 'Die Menge an Schaden, die du erleiden kannst, ohne zu sterben',
respawnDescription: 'Wie viel Zeit du benötigst, um dich vom Tod zu erholen',
@@ -1402,6 +1591,10 @@ export default {
spellbladeDescription: 'Richte zusätzlichen magischen Schaden an, nachdem du einen Ausrüstungseffekt benutzt hast. Das funktioniert bei Ausrüstungseffekten mit einer Abklingszeit von unter 10 Sekunden nicht immer',
cuttingDescription: 'Richte einen Prozentwert des aktuellen Lebens deines Ziels als biologischen Schaden an, nachdem du angegriffen hast',
recoveryDescription: 'Heile einen Prozentwert deines fehlenden Lebens, wenn du einen Gegner besiegst',
+ defenseDescription: 'Reduziert eingehenden Schaden um einen Prozentsatz deines maximalen Lebens',
+ executeDescription: 'Gegner unter einer gewissen Lebensgrenze werden sofort getötet',
+ energyDescription: 'Manche aktive Fähigkeiten benötigen Energie. Sie füllt sich mit der Zeit wieder auf',
+ manaDescription: 'Manche aktive Fähigkeiten benötigen Mana. Es füllt sich langsam mit der Zeit wieder auf',
boss: 'Boss',
miniboss: 'Miniboss',
minibossDescription: 'Minibosse nehmen den Platz regulärer Gegner ein und sind etwas stärker. Sie halten wertvolle Beute und bis zu 2 können auf einmal warten. Einen zu besiegen zählt als 4 besiegte normale Gegner',
@@ -1417,9 +1610,13 @@ export default {
stunResist: 'Schnellere Erholung von Betäubungen',
stunBoss: 'Bosse erhalten +2 Betäubungsresistenz',
stunMiniboss: 'Minibosse erhalten +1 Betäubungsresistenz',
- bossBioResist: 'Bosse erleiden nur 10% biologischen Schaden',
- minibossBioResist: 'Minibosse erleiden nur 50% biologischen Schaden',
+ bossBioResist: 'Bosse erleiden nur 10% biologischen Schaden, aber nehmen 35% mehr magischen Schaden',
+ minibossBioResist: 'Minibosse erleiden nur 50% biologischen Schaden, aber nehmen 10% mehr magischen Schaden',
enemyRespawn: 'Gegner brauchen {0} zum Erscheinen und bis zu {1} Gegner können warten. Wird ein Boss besiegt, erscheinen sofort alle Gegner',
+ bossBonusDifficulty: 'Boss-Schwierigkeit',
+ bossNoReward: 'Du kannst diesen Boss erneut auf jeder Schwierigkeit bekämpfen, erhältst dafür aber keine Belohnungen',
+ energyIncompatible: 'Deine aktuell ausgewählte Klasse kann diesen Schmuck nicht verwenden, weil er Energie benötigt',
+ manaIncompatible: 'Deine aktuell ausgewählte Klasse kann diesen Schmuck nicht verwenden, weil er Mana benötigt',
taunt: {
title: 'Spottmodus',
description: 'Im Spottmodus erscheinen Gegner auch dann, wenn keine warten. Alle Gegner, die frühzeitig erscheinen, halten aber keine Beute. Verspotten funktioniert nur auf dem Weg zum Boss',
@@ -1492,6 +1689,8 @@ export default {
rainbow: 'Regenbogen',
drain: 'Saugen',
shocking: 'Schock',
+ defense: 'Verteidigung',
+ executing: 'Hinrichten',
berserk: 'Berserker',
iceGiant: 'Eisriese',
generic: 'Gewöhnlich',
@@ -1499,12 +1698,14 @@ export default {
corruption: {
name: 'Korruption',
effects: 'Effekte',
- power: 'Angriff und Leben x',
- sigil: 'Zeichen +',
- revive: 'Wiederbelebung +'
+ power: 'Angriff und Leben x{0}',
+ sigil: 'Zeichen +{0}',
+ revive: 'Wiederbelebung +{0}',
+ execute: 'Hinrichten +{0}%'
},
activeCooldown: 'Effekt-Abklingzeit',
- itemsEquipped: 'Gegenstände ausgerüstet',
+ activeBuffFor: 'Für {0}:',
+ itemsEquipped: 'Ausrüstungsplätze benutzt',
cleared: 'Besiegt',
fighting: 'Im Kampf',
items: {
@@ -1572,10 +1773,24 @@ export default {
bomb: 'Bombe',
leechingStaff: 'Aussaugender Stab',
shatteredGem: 'Zersprungener Edelstein',
+ hourglass: 'Stundenglas',
+ glue: 'Kleber',
firework: 'Feuerwerk',
bowTie: 'Fliege',
+ forbiddenStopwatch: 'Verbotene Stoppuhr',
mysticalAccelerator: 'Mystischer Beschleuniger',
blazingStaff: 'Lodernder Stab',
+ shield: 'Schild',
+ armor: 'Rüstung',
+ natureStone: 'Naturstein',
+ evergrowingVine: 'Immerwachsende Ranke',
+ energyDrink: 'Energy-Drink',
+ dragonheart: 'Drachenherz',
+ prism: 'Prisma',
+ deathsword: 'Todesklinge',
+ needle: 'Nadel',
+ mine: 'Mine',
+ maskOfJoy: 'Maske der Freude',
// Chess pieces
pawn: 'Bauer',
@@ -1598,6 +1813,18 @@ export default {
0: 'Verursache',
1: 'biologischen Schaden'
},
+ maxdamagePhysic: {
+ 0: 'Verursache',
+ 1: 'der maximalen Leben als physischen Schaden'
+ },
+ maxdamageMagic: {
+ 0: 'Verursache',
+ 1: 'der maximalen Leben als magischen Schaden'
+ },
+ maxdamageBio: {
+ 0: 'Verursache',
+ 1: 'der maximalen Leben als biologischen Schaden'
+ },
heal: {
0: 'Heile',
1: 'Leben'
@@ -1606,6 +1833,10 @@ export default {
0: 'Erhalte',
1: 'Knochen der höchsten Zone'
},
+ blood: {
+ 0: 'Erhalte',
+ 1: 'Blut der höchsten Schwierigkeit'
+ },
monsterPart: {
0: 'Erhalte',
1: 'Monsterteile der höchsten Zone'
@@ -1626,10 +1857,6 @@ export default {
0: 'Entferne',
1: 'Angriff vom Gegner'
},
- raiseAttack: {
- 0: 'Erhöhe den Angriff dauerhaft um',
- 1: ''
- },
poison: {
0: 'Verursache',
1: 'Giftschaden'
@@ -1643,6 +1870,11 @@ export default {
2: ' um',
1: '(bis zum Prestige)'
},
+ gainStat: {
+ 0: 'Erhöhe ',
+ 2: ' um',
+ 1: '(bis zum Prestige)'
+ },
divisionShield: {
0: 'Erhalte',
1: 'Teilungsschild'
@@ -1651,6 +1883,24 @@ export default {
0: 'Entferne',
1: 'Teilungsschild vom Gegner'
},
+ executeKill: {
+ 0: 'Töte einen Gegner unter',
+ 1: 'Leben'
+ },
+ refillEnergy: {
+ 0: 'Stelle',
+ 1: 'Energie wieder her'
+ },
+ refillMana: {
+ 0: 'Stelle',
+ 1: 'Mana wieder her'
+ },
+ buff: {
+ duration: 'Schubdauer',
+ suffix: '(Schub)',
+ },
+ canCrit: 'kann mit {0}% Effizienz kritisch treffen',
+ canCritDiff: 'Aktive kritische Effizienz',
reviveAll: 'Stelle alle Wiederbelebungen her',
removeStun: 'Entferne Betäubungen',
},
@@ -1675,6 +1925,8 @@ export default {
brick: 'Ziegel',
heat: 'Hitze',
ice: 'Eis',
+ crystal: 'Kristall',
+ vitality: 'Vitalität',
},
itemMastery: {
name: 'Meistern',
@@ -1691,7 +1943,7 @@ export default {
tower: {
name: 'Türme',
description: 'Türme sind besondere Orte, welche einen Schlüssel zum Betreten benötigen. Du kannst Gegner für Kronen und einzigartige Erbstücke bekämpfen, bis du stirbst. Erreiche bestimmte Etagen, um neue Effekte freizuschalten',
- zoneDescription: 'Gegner in diesem Turm sind auf der höchsten erreichten Etage etwa so stark wie ein Gegner in Zone {0}. Sie starten mit der Kraft eines Zone-{1}-Gegners und werden pro Etage um etwa {2} Zonen stärker. Korruption ist in Türmen nicht vorhanden',
+ zoneDescription: 'Gegner in diesem Turm sind auf der höchsten erreichten Etage etwa so stark wie ein Gegner in Zone {0}. Sie starten mit der Kraft eines Zone-{1}-Gegners und werden pro Etage um etwa {2} Zonen stärker',
floorTitle: 'Höchste Etage besiegt',
floorDescription: 'Besiege Gegner auf betimmten Etagen um permanente Effekte freizuschalten:',
rewardTitle: 'Belohnungen',
@@ -1704,6 +1956,169 @@ export default {
brick: 'Ziegelturm',
fire: 'Feuerturm',
ice: 'Eisturm',
+ danger: 'Gefahrenturm',
+ toxic: 'Toxischer Turm',
+ },
+ classes: {
+ skill: 'Fähigkeiten',
+ skillPointsLeft: '{0} Fähigkeitspunkt(e) übrig',
+ skillPointCost: 'Benötigt {0} Fähigkeitspunkte zum Aufwerten',
+ skillTreeChoice: 'Hier kannst du eine Wahl treffen, das Auswählen einer Fähigkeit blockiert die anderen Pfade',
+ adventurer: {
+ name: 'Abenteurer',
+ description: 'Ein Kämpfer, der auf alles vorbereitet ist und mit jeder Situation klarkommt'
+ },
+ archer: {
+ name: 'Bogenschütze',
+ description: 'Ein Fernkämpfer, der sich auf kritische Treffer spezialisiert und konstanten Schaden anrichtet'
+ },
+ mage: {
+ name: 'Magier',
+ description: 'Ein Kämpfer, der Feinde schnell mit Zaubern besiegt und automatisch Fähigkeiten einsetzen kann'
+ },
+ knight: {
+ name: 'Ritter',
+ description: 'Ein hartnäckiger Kämpfer, der selbst starke Feinde langsam aber sicher ausschaltet'
+ },
+ assassin: {
+ name: 'Assassine',
+ description: 'Ein beweglicher Kämpfer, der auf das schnelle Ausschalten von Feinden spezialisiert ist'
+ },
+ shaman: {
+ name: 'Schamane',
+ description: 'Ein naturverbundener Kämpfer, der Kämpfe mit Heilung und Gift für sich entscheidet'
+ },
+ pirate: {
+ name: 'Pirat',
+ description: 'Der Pirat ist zwar kein guter Kämpfer, sticht aber durch das Sammeln von Beute heraus'
+ },
+ undead: {
+ name: 'Untoter',
+ description: 'Ein schwacher Kämpfer, der diese Schwäche mit Zahlen wieder ausgleicht'
+ },
+ cultist: {
+ name: 'Kultist',
+ description: 'Ein vielseitiger Kämpfer, der sich auf jeweils eine Aufgabe konzentriert'
+ },
+ scholar: {
+ name: 'Gelehrter',
+ description: 'Ein unterstützender Kämpfer, der anderen Klassen hilft'
+ }
+ },
+ battlePass: {
+ name: 'Battlepass',
+ quest: {
+ stat: 'Erreiche {0} {1}',
+ zone: 'Besiege {0} Zone {1}',
+ level: 'Erreiche Stufe {0}',
+ boss: 'Besiege {0} (+{1})'
+ },
+ statType: {
+ base: 'Grund-{0}',
+ total: 'Gesamt-{0}',
+ }
+ },
+ enemyName: {
+ soldier: 'Soldat',
+ officer: 'Polizist',
+ hunter: 'Jäger',
+ sniper: 'Scharfschütze',
+ strongMonkey: 'Starker Affe',
+ angryMonkey: 'Wütender Affe',
+ dartMonkey: 'Dartaffe',
+ monkeyWizard: 'Affenmagier',
+ monkeyDefender: 'Affenverteidiger',
+ monkeyMonk: 'Affenmönch',
+ puppy: 'Welpe',
+ kitten: 'Kätzchen',
+ seal: 'Seehund',
+ piglet: 'Ferkel',
+ panda: 'Panda',
+ koala: 'Koala',
+ rabbit: 'Hase',
+ guineaPig: 'Meerschweinchen',
+ },
+ bossName: {
+ ohilio_guard1: 'Wache A',
+ ohilio_guard2: 'Wache B',
+ ohilio: 'ohilio',
+ chriz1: 'Chriz',
+ chriz2: 'Chriz',
+ mina: 'mina',
+ },
+ area: {
+ zoneEndless: 'Endlose Zone',
+ zoneBoss: 'Boss ({0})',
+ zone: 'Zone {0}',
+ difficulty: '{0} Schwierigkeit',
+ enemyAmount: '{0} Gegner in dieser Zone',
+ warzone: 'Kriegsgebiet',
+ monkeyJungle: 'Affendschungel',
+ loveIsland: 'Liebesinsel',
+ },
+ sign: {
+ sign_1: {
+ text: 'Mein Aim ist perfekt, ich verfehle nie! Pass\' besser auf!',
+ signed: 'ohilio',
+ },
+ sign_2: {
+ text: 'Du denkst du kannst mir weh tun? Niemals! Ich weiche allem aus, du kannst mich nicht mal treffen! Ich bin unantastbar!',
+ signed: 'ohilio',
+ },
+ sign_3: {
+ text: 'Ich bin der Größte, der Beste, perfekt, unbesiegbar! Selbst meine Wachen sind nichts im Vergleich zu mir! Du denkst, du hast eine Chance gegen mich? Hah! Bereite dich darauf vor, zu sterben!',
+ signed: 'ohilio',
+ },
+ sign_4: {
+ text: 'Nachdem du dir diese niedlichen Tiere genau angesehen hast, fällt dir auf, dass sie nicht echt sind. Es sind nur Irrlichter! Aber warum sind sie hier? Damit du dich schlecht fühlst? Keine Zeit drüber nachzudenken, du musst kämpfen um an diesen Tiergeistern vorbeizukommen',
+ signed: '???',
+ },
+ },
+ quest: {
+ name: 'Aufgaben',
+ description: 'Schließe Aufgaben ab, um im Battlepass fortzuschreiten und permanente Belohnungen freizuschalten',
+ completed: '{0} abgeschlossen',
+ allCompleted: 'Alle Aufgaben abgeschlossen',
+ },
+ trinket: {
+ rarity: {
+ 0: 'Nicht gefunden',
+ 1: 'Gewöhnlich',
+ 2: 'Ungewöhnlich',
+ 3: 'Selten',
+ 4: 'Episch',
+ 5: 'Legendär',
+ 6: 'Mythisch',
+ 7: 'Extraordinär',
+ 8: 'Strahlend',
+ 9: 'Prismatisch',
+ 10: 'Abgeschlossen',
+ timeless: 'Zeitlos'
+ },
+ equipped: 'Schmuck ausgewählt (wird nach dem Prestige angelegt)',
+ vitality: 'Vitalität',
+ energy: 'Energie',
+ magic: 'Magie',
+ fists: 'Fäuste',
+ sparks: 'Funken',
+ haste: 'Eile',
+ precision: 'Präzision',
+ wrath: 'Zorn',
+ strength: 'Stärke',
+ toxins: 'Toxine',
+ wisdom: 'Weisheit',
+ extraction: 'Extraktion',
+ learning: 'Lernen',
+ preservation: 'Bewahrung',
+ energize: 'Aufladen',
+ automation: 'Automatisierung',
+ cure: 'Genesen',
+ duality: 'Dualiät',
+ love: 'Liebe',
+ },
+ sacrifice: {
+ name: 'Opfern',
+ description: 'Hier kannst du temporär Ausrüstungsplätze opfern, um dafür starke Effekte zu erhalten'
}
},
farm: {
@@ -1713,6 +2128,7 @@ export default {
expToLevelUp: 'Du brauchst noch {0} weitere Ernten, um die nächste Stufe zu erreichen',
yield: 'Ertrag',
rareDrops: 'Seltener Ertrag',
+ huntedRareDrops: 'Gejagter seltener Ertrag',
addRareDrop: 'Neuer seltener Ertrag ({0})',
addRareDropAmount: '{0}-Menge',
prestige: {
@@ -1765,7 +2181,12 @@ export default {
grapes: 'Weintrauben',
hops: 'Hopfen',
violet: 'Veilchen',
- goldenRose: 'Goldrose'
+ goldenRose: 'Goldrose',
+ sweetPotato: 'Süßkartoffel',
+ strawberry: 'Erdbeere',
+ sesame: 'Sesam',
+ sunflower: 'Sonnenblume',
+ spinach: 'Spinat',
},
gene: {
name: 'Gen',
@@ -1774,6 +2195,8 @@ export default {
dnaDuplicate: 'Ausgewählte Gene tauchen beim nächsten Prestige nicht auf. Wird kein Gen ausgewählt, sind beim nächsten Prestige alle 4 verfügbar',
dnaBlocked: 'Blockierte Gene',
hasUpgrade: 'Hat Gen-Verbesserung',
+ lockOnField: 'Dieses Gen kann nicht ausgewählt werden, wenn Pflanzen der Art auf dem Feld sind',
+ basics: 'Grundlagen',
yield: 'Ertrag',
gold: 'Gold',
exp: 'Erfahrung',
@@ -1789,17 +2212,25 @@ export default {
mystery: 'Mysterium',
conversion: 'Umwandlung',
prestige: 'Prestige',
- rareDropChance: 'Entdeckung'
+ rareDropChance: 'Entdeckung',
+ lucky: 'Glückspilz',
+ finalize: 'Letzter Schliff',
+ selfless: 'Selbstlos',
+ unyielding: 'Unnachgiebig',
+ teamwork: 'Teamwork',
+ hunter: 'Jäger',
+ patient: 'Geduldig',
},
fertilizerEffect: {
vegetable: 'Nur Gemüse',
- fruit: 'Nur Früchte',
+ berry: 'Nur Beeren',
grain: 'Nur Getreide',
flower: 'Nur Blumen'
},
building: {
premium: 'Premium-{0}',
premiumOwned: 'Premium: {0} in Besitz',
+ owned: '{0} in Besitz',
gardenGnome: {
name: 'Gartenzwerg',
description: 'Pflanzen können bei der Ernte Gold aufdecken, wenn der Gartenzwerg auf dem Feld steht. Die Chance hängt von der Wachstumszeit der Pflanze ab.',
@@ -1817,13 +2248,13 @@ export default {
},
pinwheel: {
name: 'Windrad',
- description: 'Erhöht die Chance auf seltenen Ertrag auf dem gesamten Feld um +1% für jede einzigartige Pflanze in den umliegenden 8 Feldern',
- descriptionPremium: 'Erhöht die Chance auf seltenen Ertrag auf dem gesamten Feld um +2% für jede einzigartige Pflanze in den umliegenden 8 Feldern',
+ description: 'Erhöht die Chance auf seltenen Ertrag auf dem gesamten Feld um +0.015x für jede einzigartige Pflanze in den umliegenden 8 Feldern',
+ descriptionPremium: 'Erhöht die Chance auf seltenen Ertrag auf dem gesamten Feld um +0.03x für jede einzigartige Pflanze in den umliegenden 8 Feldern',
},
flag: {
name: 'Flagge',
- description: 'Erhöht den Ertrag um +50%, wenn die Pflanze an der richtigen Position im Vergleich zur Flagge steht. Gemüse: Oben links, Frucht: Oben rechts, Getreide: Unten links, Blume: Unten rechts',
- descriptionPremium: 'Erhöht den Ertrag um +100%, wenn die Pflanze an der richtigen Position im Vergleich zur Flagge steht. Gemüse: Oben links, Frucht: Oben rechts, Getreide: Unten links, Blume: Unten rechts',
+ description: 'Erhöht den Ertrag um +50%, wenn die Pflanze an der richtigen Position im Vergleich zur Flagge steht. Gemüse: Oben links, Beeren: Oben rechts, Getreide: Unten links, Blume: Unten rechts',
+ descriptionPremium: 'Erhöht den Ertrag um +100%, wenn die Pflanze an der richtigen Position im Vergleich zur Flagge steht. Gemüse: Oben links, Beeren: Oben rechts, Getreide: Unten links, Blume: Unten rechts',
}
}
},
@@ -1833,6 +2264,9 @@ export default {
colorSuffix: 'Farbe',
openPackage: 'Öffnen',
colorGainReduced: 'Zusätzliches Einkommen wird nach 100 Farbe auf die Quadratwurzel reduziert',
+ drumCompounding: 'Um diese Farbtrommel finden zu können, musst du auch alle Farbtrommeln der vorherigen Farben im selben Paket finden. Dies reduziert die effektive Chance, diese Farbtrommel zu finden',
+ allConverterInfo: 'Das Umwandeln einer Farbe verbraucht immer alle Konverter',
+ converterOverload: 'Du hast deutlich mehr Konverter als Farbe für diese Umwandlung, weshalb diese Umwandlung x{0} Farbe gibt',
idea: {
tier: 'Stufe-{0}-Idee',
unlock: 'Idee freischalten',
@@ -1843,6 +2277,7 @@ export default {
sortWaste: 'Abfall sortieren',
advertise: 'Werben',
beImpatient: 'Ungeduldig sein',
+ beExcited: 'Aufgeregt sein',
makeLemonade: 'Limonade herstellen',
growATree: 'Einen Baum großziehen',
@@ -1850,16 +2285,80 @@ export default {
observeRainbow: 'Regenbogen beobachten',
buildRedReservoir: 'Rotes Reservoir bauen',
orderMassiveSafe: 'Massiven Safe bestellen',
+ buyPen: 'Füller kaufen',
drawOcean: 'Ozean zeichnen',
makeWine: 'Wein herstellen',
calculateOdds: 'Chancen ausrechnen',
buildOrangeReservoir: 'Oranges Reservoir bauen',
thinkHarder: 'Härter nachdenken',
+ paintFaster: 'Schneller malen',
+ buyBrush: 'Pinsel kaufen',
+
+ harvestOranges: 'Orangen ernten',
+ pulverizeGold: 'Gold zerstauben',
+ buildYellowReservoir: 'Gelbes Reservoir bauen',
+ paintForFun: 'Aus Spaß malen',
+ printNewspaper: 'Zeitung drucken',
+ expandCanvas: 'Leinwand erweitern',
+ hyperfocus: 'Hyperfokus',
+
+ cutGrass: 'Glas schneiden',
+ shapeClay: 'Ton formen',
+ buildGreenReservoir: 'Grünes Reservoir bauen',
+ beMysterious: 'Mysteriös sein',
+
+ lookAtTheSky: 'Den Himmel betrachten',
+ chewBubblegum: 'Kaugummi kauen',
+ buildBlueReservoir: 'Blaues Reservoir bauen',
},
nextInspiration: {
0: 'Nächste ',
1: ' in '
+ },
+ shapes: {
+ name: 'Formen',
+ upgrades: 'Form-Verbesserungen',
+ description: 'Ziehe eine Form an eine angrenzende, um die Positionen zu tauschen, oder klicke sie zum Sammeln an. Das Sammeln benötigt 5 gleiche verbundene Formen und die Menge erhaltener Formen pro Form hängt von der Größe der Kombo ab.',
+ cost: 'Jede Aktion kostet',
+ special: {
+ name: 'Besondere Formen',
+ description: 'Eine besondere Form hat eine {0}% Chance anstatt einer normalen Form zu erscheinen, und besonderes Sammeln gibt {1}x Formen. Es kann nur eine besondere Form auf einmal auf dem Gitter vorhanden sein',
+ bomb: 'Alle Formen in einer + Formation werden besonders gesammelt',
+ dice: 'Alle Formen die nicht der Form darüber (oder darunter in der obersten Reihe) entsprechen werden neu gewürfelt',
+ accelerator: 'Die 8 umliegenden Formen werden besonders gesammelt. Wenn alle 8 von ihnen gleich sind, wird sämtliche Motivation verbraucht um davon noch mehr Formen zu erhalten',
+ sparkles: 'Die 4 direkt anliegenden Formen werden regulär gesammelt (wenn möglich) und zählen als eine große Kombo',
+ hourglass: 'Erhalte sofort Konverter und Pakete, sammle Formen um die Zeit zu erhöhen',
+ chest: '10 naheliegende Formen werden besonders gesammelt, die 8 umliegenden und die links und rechts daneben. Wenn alle 10 Formen verschieden sind, gibt es eine besondere Belohnung'
+ },
+ buyFor: {
+ 0: 'Kaufe',
+ 1: 'für'
+ },
+ reroll: 'Das gesamte Gitter neu würfeln für',
+ unlock: 'Form freischalten: {0}',
+ circle: 'Kreis',
+ rectangle: 'Rechteck',
+ triangle: 'Dreieck',
+ star: 'Stern',
+ ellipse: 'Ellipse',
+ heart: 'Herz',
+ square: 'Quadrat',
+ octagon: 'Achteck',
+ pentagon: 'Fünfeck',
+ hexagon: 'Sechseck',
+ bomb: 'Bombe',
+ dice: 'Würfel',
+ accelerator: 'Beschleuniger',
+ sparkles: 'Glitzer',
+ hourglass: 'Stundenglas',
+ chest: 'Truhe',
+ },
+ canvas: {
+ name: 'Leinwand',
+ description: 'Setze Farben auf die Leinwand um die Leinwandstufe langsam zu erhöhen, was permanente Boni gewährt',
+ level: 'Leinwandstufe',
+ untilNextLevel: '{0} bis zur nächsten Stufe'
}
},
gem: {
diff --git a/src/lang/de/card.js b/src/lang/de/card.js
index d308c674..a796508b 100644
--- a/src/lang/de/card.js
+++ b/src/lang/de/card.js
@@ -1,6 +1,9 @@
export default {
cardPack: 'Kartenpaket',
cardsSuffix: '-Karten',
+ cardPower: 'Kartenkraft',
+ cardPowerValue: '{0} Kartenkraft',
+ cardPowerDescription: 'Die Kartenkraft aller aktiven Karten wird addiert und erhöht grundlegende Werte der Funktion',
notFound: 'Keine Karten gefunden',
fullCollectionReward: 'Belohnung für volle Sammlung',
canFind: 'Diese Karte kann in folgenden Paketen gefunden werden',
@@ -150,7 +153,7 @@ export default {
'FA-0008': 'Lebensmittel-Transport',
'FA-0009': 'Warmes Gewächshaus',
'FA-0010': 'Fruchtsmoothie',
- 'FA-0011': 'Backereiverkauf',
+ 'FA-0011': 'Bäckereiverkauf',
'FA-0012': 'Eiswagen',
'FA-0013': 'Fastfood-Bestellung',
'FA-0014': 'Festmahl',
diff --git a/src/lang/de/consumable.js b/src/lang/de/consumable.js
index 7e8c1640..a87b20de 100644
--- a/src/lang/de/consumable.js
+++ b/src/lang/de/consumable.js
@@ -9,6 +9,14 @@ export default {
name: 'Goldhammer',
description: 'Stelle die bestmögliche Spitzhacke her'
},
+ village_ingredientBox: {
+ name: 'Zutatenkiste',
+ description: 'Enthält besondere Zutaten, welche nur in diesen Kisten gefunden werden können'
+ },
+ horde_manaPotion: {
+ name: 'Manatrank',
+ description: 'Stellt 50% vom maximalen Mana wieder her'
+ },
farm_basic: {
name: 'Einfacher Dünger',
description: ''
@@ -33,6 +41,10 @@ export default {
name: 'Saftiger Dünger',
description: ''
},
+ farm_dissolving: {
+ name: 'Pflanzenauflöser',
+ description: ''
+ },
farm_potatoWater: {
name: 'Kartoffelwasser',
description: ''
@@ -53,6 +65,18 @@ export default {
name: 'Premiumdünger',
description: ''
},
+ farm_analyzing: {
+ name: 'Analysedünger',
+ description: ''
+ },
+ farm_superJuicy: {
+ name: 'Super-saftig',
+ description: ''
+ },
+ farm_pellets: {
+ name: 'Pellets',
+ description: ''
+ },
farm_sunshine: {
name: 'Sonnenschein',
description: ''
diff --git a/src/lang/de/currency.js b/src/lang/de/currency.js
index 5be55eca..84ca009d 100644
--- a/src/lang/de/currency.js
+++ b/src/lang/de/currency.js
@@ -335,6 +335,14 @@ export default {
name: 'Iridiumerz',
description: 'Irid... was? Der Name sagt dir nichts, hat es überhaupt einen Nutzen?'
},
+ mining_oreOsmium: {
+ name: 'Osmiumerz',
+ description: ''
+ },
+ mining_oreLead: {
+ name: 'Bleierz',
+ description: ''
+ },
mining_granite: {
name: 'Granit',
description: 'Massive Granitblöcke, aus dem Untergrund geschnitten. Überraschenderweise sind sie komplett schrottfrei'
@@ -359,6 +367,14 @@ export default {
name: 'Obsidian',
description: 'Wunderschöne lila Scherben, sie sehen zerbrechlich aus'
},
+ mining_deeprock: {
+ name: 'Tiefenstein',
+ description: ''
+ },
+ mining_glowshard: {
+ name: 'Leuchtscherbe',
+ description: ''
+ },
mining_barAluminium: {
name: 'Aluminiumbarren',
description: 'Der Erste von vielen'
@@ -383,6 +399,10 @@ export default {
name: 'Iridiumbarren',
description: 'Was für seltsame Eigenschaften dieser hier hat...'
},
+ mining_barDarkIron: {
+ name: 'Schwarzeisenbarren',
+ description: ''
+ },
mining_ember: {
name: 'Glut',
description: 'Achtung, sie ist noch heiß!'
@@ -431,6 +451,10 @@ export default {
name: 'Goldmünze',
description: 'Münzen, die du durch den Verkauf von Lebensmitteln an die Dorfbewohner erhalten hast'
},
+ village_copperCoin: {
+ name: 'Kupfermünze',
+ description: 'Münzen, die du durch den Verkauf von hergestellten Gegenständen an die Dorfbewohner erhalten hast'
+ },
village_wood: {
name: 'Holz',
description: 'Baumstämme von naheliegenden Bäumen'
@@ -495,6 +519,10 @@ export default {
name: 'Segen',
description: 'Die Hoffnungen deiner Dorfbewohner haben sich bewahrheitet! Dinge sind in der Zukunft besser! Es wird mit der Zeit einfacher!'
},
+ village_shares: {
+ name: 'Aktien',
+ description: 'Investiere, um mehr Geld zu verdienen!'
+ },
village_offering: {
name: 'Opfergabe',
description: 'Eine mysteriöse Opfergabe, für welche Ressourcen geopfert werden mussten'
@@ -539,6 +567,22 @@ export default {
name: 'Mythische Beute',
description: 'Und du dachtest sie wäre für immer verschollen'
},
+ village_acidVial: {
+ name: 'Säurephiole',
+ description: 'Sei vorsichtig!'
+ },
+ village_snowflake: {
+ name: 'Schneeflocke',
+ description: ''
+ },
+ village_chiliBundle: {
+ name: 'Chilibündel',
+ description: ''
+ },
+ village_gears: {
+ name: 'Zahnräder',
+ description: ''
+ },
horde_bone: {
name: 'Knochen',
description: 'Knöcherne Reste von besiegten Gegnern'
@@ -563,6 +607,10 @@ export default {
name: 'Verstärkte Seele',
description: 'Ehemals verdorbene Seelen, welche durch ein komplexes Ritual gereinigt und bestärkt wurden'
},
+ horde_courage: {
+ name: 'Courage',
+ description: 'Mut ist eine wichtige Tugend, wenn man es mit einer nicht endenden Horde zu tun hat'
+ },
horde_crown: {
name: 'Krone',
description: 'Sie haben einst über die Türme geherrscht, sind jetzt aber entthront'
@@ -571,13 +619,21 @@ export default {
name: 'Turmschlüssel',
description: 'Ein seltener Schlüssel, der dir Zugang zu einem Turm gewährt'
},
+ horde_blood: {
+ name: 'Blut',
+ description: 'Iih!'
+ },
+ horde_lockpick: {
+ name: 'Dietrich',
+ description: 'Erlaubt es dir von einen bereits besiegten Boss Schmuckstücke zu erhalten. Nur für den Pirat'
+ },
farm_vegetable: {
name: 'Gemüse',
description: 'Iss dein Gemüse!'
},
- farm_fruit: {
- name: 'Frucht',
- description: 'Der fruchtbare Boden auf dem Bauernhof gibt den Früchten einen intensiven Geschmack'
+ farm_berry: {
+ name: 'Beeren',
+ description: 'Der fruchtbare Boden auf dem Bauernhof gibt den Beeren einen intensiven Geschmack'
},
farm_grain: {
name: 'Getreide',
@@ -631,6 +687,10 @@ export default {
name: 'Goldenes Blütenblatt',
description: 'Dieses extrem seltene Blütenblatt kann nur auf Rosen gefunden werden. Gerüchte behaupten, dass Rosen mit solchen Blütenblättern dunkler als gewöhnlich sind'
},
+ farm_smallSeed: {
+ name: 'Kleine Saat',
+ description: ''
+ },
gallery_beauty: {
name: 'Schönheit',
description: 'Dieses Bild wird nur schöner, je länger du malst'
@@ -743,6 +803,54 @@ export default {
name: 'Pinke Farbtrommel',
description: ''
},
+ gallery_motivation: {
+ name: 'Motivation',
+ description: ''
+ },
+ gallery_mysteryShape: {
+ name: 'Mysterienform',
+ description: 'Was ist diese Form? Sie sieht seltsam aus, als würde sie nicht in diese Dimension gehören'
+ },
+ gallery_circle: {
+ name: 'Kreis',
+ description: ''
+ },
+ gallery_rectangle: {
+ name: 'Rechteck',
+ description: ''
+ },
+ gallery_triangle: {
+ name: 'Dreieck',
+ description: 'Achtung, sie sind gefährlich'
+ },
+ gallery_star: {
+ name: 'Stern',
+ description: ''
+ },
+ gallery_ellipse: {
+ name: 'Ellipse',
+ description: ''
+ },
+ gallery_heart: {
+ name: 'Herz',
+ description: '<3'
+ },
+ gallery_square: {
+ name: 'Quadrat',
+ description: ''
+ },
+ gallery_octagon: {
+ name: 'Achteck',
+ description: ''
+ },
+ gallery_pentagon: {
+ name: 'Fünfeck',
+ description: 'Eine Form, kein Gebäude'
+ },
+ gallery_hexagon: {
+ name: 'Sechseck',
+ description: ''
+ },
gallery_cash: {
name: 'Geld',
description: 'Leicht verdientes Geld!'
@@ -759,6 +867,10 @@ export default {
name: 'Prüfungspass',
description: 'Seltsam, bei unserer alten Schule haben wir sowas nicht gebraucht. Hier sind sie nötig, um eine Prüfung zu schreiben'
},
+ card_shinyDust: {
+ name: 'Glitzerstaub',
+ description: ''
+ },
treasure_fragment: {
name: 'Fragment',
description: 'Zerbrochenes Stück eines Schatzes'
diff --git a/src/lang/de/mult.js b/src/lang/de/mult.js
index 30d52f4f..7a7ae672 100644
--- a/src/lang/de/mult.js
+++ b/src/lang/de/mult.js
@@ -2,6 +2,7 @@ export default {
miningDamage: 'Schaden',
miningToughness: 'Zähigkeit',
miningOreGain: 'Erz-Einkommen',
+ miningOreCap: 'Erz-Kapazität',
miningRareEarthGain: 'Bodenschatz-Einkommen',
miningPickaxeCraftingPower: 'Handwerkskraft',
miningPickaxeCraftingSlots: 'Herstellplätze',
@@ -21,7 +22,14 @@ export default {
currencyMiningRadonIncrement: 'Radon-Anstieg',
miningEnhancementBarsIncrement: 'Barren-Anstieg',
miningEnhancementFinalIncrement: 'Aufwertungs-Anstieg',
+ miningPrestigeIncome: 'Prestigeeinkommen',
+ miningBeaconPiercing: 'Bohr-Leuchtfeuer',
+ miningBeaconRich: 'Reichtum-Leuchtfeuer',
+ miningBeaconWonder: 'Wunder-Leuchtfeuer',
+ miningBeaconHope: 'Hoffnungs-Leuchtfeuer',
villageWorker: 'Arbeiter',
+ villageArtisan: 'Handwerker',
+ villageCounter: 'Kassen',
villageTaxRate: 'Steuersatz',
queueSpeedVillageBuilding: 'Bautempo',
villageOfferingPower: 'Opfergaben-Kraft',
@@ -42,6 +50,9 @@ export default {
villagePower: 'Energie',
villageLootGain: 'Beuteeinkommen',
villageLootQuality: 'Beutequalität',
+ villageIngredientCount: 'Findbare Zutaten',
+ villageIngredientBoxAmount: 'Zutaten pro Kiste',
+ villagePrestigeIncome: 'Prestigeeinkommen',
hordeAttack: 'Angriff',
hordeHealth: 'Leben',
hordeRecovery: 'Erholung',
@@ -54,6 +65,9 @@ export default {
hordeSpellblade: 'Zauberklinge',
hordeCutting: 'Schneiden',
hordeDivisionShield: 'Teilungsschild',
+ hordeDefense: 'Verteidigung',
+ hordeExecute: 'Hinrichten',
+ hordeHealing: 'Heilung',
hordeStunResist: 'Betäubungsresistenz',
hordeShieldbreak: 'Schildbruch',
hordeEnemyActiveStart: 'Gegnerische Anfangs-Abklingzeit',
@@ -78,6 +92,22 @@ export default {
hordeItemMasteryGain: 'Meisterungspunkte-Einkommen',
hordeMinibossTime: 'Miniboss-Zeit',
hordeShardChance: 'Mystische-Scherben-Chance',
+ hordeEnergy: 'Energie',
+ hordeEnergyRegen: 'Energieregeneration',
+ hordeMana: 'Mana',
+ hordeManaRegen: 'Manaregeneration',
+ hordeHaste: 'Eile',
+ hordeStrength: 'Stärke',
+ hordeIntelligence: 'Intelligenz',
+ hordeAutocast: 'Autoaktiv-Plätze',
+ hordeMaxTrinkets: 'Schmuck-Kapazität',
+ hordeExpBase: 'Stufenzeit',
+ hordeExpIncrement: 'Stufenanstieg',
+ hordeTrinketGain: 'Schmuck-Höchsteinkommen',
+ hordeTrinketQuality: 'Schmuckqualität',
+ hordeMaxSacrifice: 'Maximales Opfer',
+ hordeSkillPointsPerLevel: 'Fähigkeitspunkte pro Stufe',
+ hordePrestigeIncome: 'Prestigeeinkommen',
powerHeirloomEffect: 'Kraft-Effekt',
fortitudeHeirloomEffect: 'Resistenz-Effekt',
wealthHeirloomEffect: 'Reichtum-Effekt',
@@ -98,6 +128,10 @@ export default {
farmDnaNext: 'DNA nach Prestige',
farmCropGain: 'Ertrag',
farmAllGain: 'Sämtlicher Pflanzenertrag',
+ farmCropCost: 'Pflanzenkosten',
+ farmFertilizerCost: 'Düngerkosten',
+ farmLuckyHarvestMult: 'Glücksernte-Einkommen',
+ farmHuntChance: 'Jagdchance',
galleryInspirationBase: 'Inspiration-Grundzeit',
galleryInspirationIncrement: 'Inspiration-Zeitanstieg',
galleryInspirationStart: 'Anfangs-Inspiration',
@@ -128,6 +162,11 @@ export default {
"galleryLight-blueDrumChance": 'Hellblaue-Farbtrommel-Chance',
galleryPinkConversion: 'Pinke Umwandlung',
galleryPinkDrumChance: 'Pinke-Farbtrommel-Chance',
+ galleryShapeGain: 'Formeinkommen',
+ gallerySpecialShapeChance: 'Chance auf besondere Formen',
+ gallerySpecialShapeMult: 'Multiplikator für besonderes Sammeln',
+ galleryCanvasSize: 'Leinwandgröße',
+ galleryCanvasSpeed: 'Leinwandtempo',
miningCardCap: 'Bergbau-Kartenlimit',
villageCardCap: 'Dorf-Kartenlimit',
hordeCardCap: 'Horde-Kartenlimit',
@@ -185,6 +224,7 @@ export default {
summerFestivalMaterialStackCap: 'Material-Stapelgröße',
nightHuntFindableIngredients: 'Mögliche Zutaten',
nightHuntIngredientSize: 'Zutatengröße',
+ nightHuntFavouriteIngredientSize: 'Lieblingszutatengröße',
nightHuntMaxIngredients: 'Ritualzutaten',
nightHuntBonusIngredientCount: 'Bonuszutaten',
nightHuntBonusIngredientAmount: 'Bonuszutaten-Menge',
diff --git a/src/lang/de/note.js b/src/lang/de/note.js
index 19ccc7b8..3ae7247b 100644
--- a/src/lang/de/note.js
+++ b/src/lang/de/note.js
@@ -136,7 +136,7 @@ export default {
farm_14: 'Kleine Glückskäfer. Stinken auch nicht. Wirken gut.',
farm_15: 'Bauernhof ist friedlich. Fast Gemetzel bei der Horde vergessen.',
farm_16: 'Jäger des Gartens. Hält Käfer unter Kontrolle.',
- farm_17: 'Windrad interessant. Setze einzigartige Pflanzen daneben. 8 Plätze um Windrad. Finde mehr Gold. Auf dem gesamten Feld.',
+ farm_17: 'Windrad interessant. Setze einzigartige Pflanzen daneben. 8 Plätze um Windrad. Finde mehr seltenen Ertrag. Auf dem gesamten Feld.',
farm_18: 'Mehr Dünger. Mehr Arten Gold und Edelsteine auszugeben.',
farm_19: 'Kleine Bienen. Immer am arbeiten. Und zahlreich.',
farm_20: 'Flagge kompliziert. Verstärkt bestimmte Pflanzenarten. Art hängt von der Position ab. Besser Anleitung lesen.',
diff --git a/src/lang/de/patchnote.js b/src/lang/de/patchnote.js
index 05fd60c6..2afcf32b 100644
--- a/src/lang/de/patchnote.js
+++ b/src/lang/de/patchnote.js
@@ -17,19 +17,33 @@ export default {
remove: 'Entfernt',
change: 'Änderung',
accessibility: 'Barrierefreiheit',
- appearance: 'Optik'
+ appearance: 'Optik',
+ anticheat: 'Anticheat',
},
text: {
addedFeature: 'Funktion hinzugefügt',
+ addedSubfeature: 'Unterfunktion hinzugefügt',
addedUpgrade: '{0} neue Verbesserung(en) hinzugefügt',
addedPrestigeUpgrade: '{0} neue Prestige-Verbesserung(en) hinzugefügt',
addedGemUpgrade: '{0} neue Edelstein-Verbesserung(en) hinzugefügt',
addedBuilding: '{0} neue Gebäude hinzugefügt',
+ addedRelic: '{0} neue Relikt(e) hinzugefügt',
addedAchievement: '{0} Erfolg(e) hinzugefügt',
secretAchievement: '{0} geheime(r) Erfolg(e) hinzugefügt',
addedHordeItem: '{0} neue Ausrüstungsgegenstände hinzugefügt',
addedHordeSigil: '{0} neue Zeichen hinzugefügt',
- addedHordeHeirloom: '{0} neue Erbstücke hinzugefügt',
+ addedHordeHeirloom: '{0} neue Erbstück(e) hinzugefügt',
+ addedVillageRecipe: '{0} neue Hundwerksrezept(e) hinzugefügt',
+ addedGalleryIdea: '{0} neue Idee(n) hinzugefügt',
+ addedOre: '{0} neue Erz(e) hinzugefügt',
+ addedRareEarth: '{0} neue Bodenschätze hinzugefügt',
+ addedRareDrop: '{0} neuer seltener Ertrag hinzugefügt',
+ addedGene: '{0} neue Gen(e) hinzugefügt',
+ addedCrop: '{0} neue Pflanze(n) hinzugefügt',
+ addedFertilizer: '{0} neue Dünger hinzugefügt',
+ addedTower: '{0} neue Türme hinzugefügt',
+ addedHordeClass: '{0} neue Kämpferklasse(n) hinzugefügt',
+ addedTrinket: '{0} neue Schmuckstück(e) hinzugefügt',
// v1.0.1
0: 'Die Menge an Schrott im Bergwerk wurde auf den Tiefen am Anfang leicht erhöht',
@@ -121,7 +135,7 @@ export default {
80: 'Die 35 garantierten Seelen bei Zone 20 wurden entfernt',
81: 'Erbstücke sind nicht mehr alle 10 Zonen garantiert',
82: 'Der Nostalgieeffekt ist nicht mehr auf +50% begrenzt',
- 83: 'Die Beschreibung vom "Tieflauf"-Erfolg wurde angepasst, um eine Verwechslung zwischen Metern und Minuten auszuschließen',
+ 83: 'Die Beschreibung vom "Tiefenlauf"-Erfolg wurde angepasst, um eine Verwechslung zwischen Metern und Minuten auszuschließen',
84: 'Seelenmengen-Anstieg pro Zone',
85: 'Grundwert Seelenmenge',
86: 'Grundwert Erbstücks-Chance',
@@ -358,6 +372,119 @@ export default {
297: 'Kosten von Stufe-4-Opfergaben steigen nun mit jedem Kauf',
298: 'Die Erfolgsnachricht hat jetzt einen Textschatten, wenn ein Relikt enthalten ist',
299: 'Die Anforderungen für den "Genie"-Erfolg wurden ab Stufe 10 erhöht',
+
+ // v1.4.2
+ '299_1': 'Ein Spielabsturz wurde behoben, der nach dem Ende vom Wetterchaos auftrat',
+ '299_2': 'Ausrüstungskapazität wurde von Horde-Karten entfernt',
+ '299_3': 'Ausrüstungskapazität wurde von einem Event-Relikt entfernt',
+ '299_4': 'Die meisten Gene steigern sich jetzt linear',
+
+ // v1.5.0
+ 300: 'Du kannst nun deinen gesamten Spielstand oder einzelne Funktionen zurücksetzen',
+ 301: 'Nach dem letzten Update wurde klar, dass die Stärke von Pflanzen durch die neuen Gene und Karten deutlich gestiegen ist. Das Spezialisieren, obwohl es gewünscht war, hat den Ertrag etwas zu weit nach vorne gebracht. Also gibt es einige Änderungen, damit Spieler sich nicht zu sehr auf eine Ertragsart fokussieren',
+ 302: 'Eine neue Genverbesserung, die sämtlichen Pflanzenertrag erhöht, ist jetzt von Anfang an verfügbar',
+ 303: 'Da 1-Sekunde-Prestiges die Gallerie übernommen haben, sind fundamentale Änderungen notwendig. Zusätzlich zu Balancing-Änderungen habe ich eine neue Mechanik hinzugefügt, welche die aktiven Aspekte der Gallerie bewahrt, ohne sie notwendig zu machen',
+ 304: 'Die Anzeige der Farben wurde leicht angepasst',
+ 305: 'Das Umwandeln von Farben verbraucht nun einmal die vorherige Farbe und alle Konverter',
+ 306: 'Werte zur Inspirationszeit werden jetzt im Tooltip angezeigt',
+ 307: 'Das Formen-Minispiel wurde hinzugefügt, eine aktive Art das Rohstoffeinkommen zu steigern',
+ 308: 'Minibosse sollten nun die korrekte Anzahl an Meisterungspunkten zeigen',
+ 309: 'Das Gluteinkommen hängt nun vom Tiefengräber ab',
+ 310: 'Das Exportieren vom Spielstand setzt nun den Datensicherungs-Hinweis korrekt in der ausgegebenen Datei zurück',
+ 311: 'Du kannst nun Statistiken auf der Informationsseite einsehen',
+ 312: 'Die Spielerkarte wurde zu den Statistiken hinzugefügt, welche einen Überblick von deinem Fortschritt gibt',
+ 313: 'Währungen und Preisschilder können nun von Assistenzprogrammen für Blinde eingelesen werden',
+ 314: 'Die selbe Karte kann nicht mehr mehrfach ausgerüstet werden',
+ 315: 'Ausrüstungsmeisterung zeigt nun den korrekten Prozentsatz zur nächsten Stufe',
+ 316: 'Die Prestigeformel wurde angepasst und gibt nun mehr Geld für hohe Schönheitswerte',
+ 317: 'Das Spiel weigert sich jetzt, bearbeitete Spielstände zu laden',
+ 318: 'Spieler, die mit Cheats oder Automatisierungsprogrammen erwischt werden, haben nun eine dauerhafte Markierung auf ihrer Spielerkarte',
+ 319: 'Damit problematische Karten in Zukunft weniger Ärger verursachen, gibt es ein paar Änderungen um den Karten eher generische Werte zu geben. Dadurch sollte auch die Diversität an Karten steigen',
+ 320: 'Kartenkraft wurde hinzugefügt, ein Wert der für die jeweilige Funktion generische Effekte gibt',
+ 321: 'Die meisten Karteneffekte wurden reduziert, um Kartenkraft hinzuzufügen',
+ 322: 'Die Preise der späten Kartenpakete wurde erhöht',
+ 323: 'Die Chance, seltene Karten zu finden, wurde erhöht',
+ 324: 'Findbarer seltener Ertrag wird nun als ??? angezeigt, solange die Chance -10% oder höher ist',
+ 325: 'Ein neues Auswahlmenü ist nun für das Auswählen von Pflanzen zuständig',
+ 326: 'Das Konvertereinkommen steigt nun mit der Zahl an Konvertern im Besitz',
+ 327: 'Leinwand hinzugefügt',
+ 328: 'Erfolgsstufen werden nun reduziert, wenn die Anforderungen in einem Update steigen',
+ 329: 'Die meisten Erfolge haben nun eine Maximalstufe von 20',
+ 330: 'Kryolaboreinkommen für das Dorf',
+ 331: 'Die Ebene von Eventschätzen wurde um 1 gesenkt',
+ 332: 'Grundfragmente für das Zerstören von Eventschätzen',
+ 333: 'Dünger pro Eventchip',
+ 334: 'Obst wurde in Beeren umbenannt',
+ 335: 'Die beste Ernte zählt nun für Pflanzen auf dem Feld, sie müssen nicht mehr dafür geerntet werden',
+ 336: 'Blütenblatt-Kapazität pro goldenem Blütenblatt',
+ 337: 'Seltene Erträge sind nun noch seltener, wenn sie von Karten stammen',
+ 338: 'Manche Pflanzen benötigen nun andere Währungen als Gold',
+ 339: 'Die meisten seltenen Erträge sind nun schwerer zu bekommen, es ist aber leichter an Chance für seltenen Ertrag zu kommen',
+ 340: 'Die meisten Düngereffekte wurden abgeschwächt',
+ 341: 'Das Riesig-Gen erhöht nun Pflanzen- und Düngerkosten um 4x, und kann nicht ausgewählt werden, wenn sich noch Pflanzen der Art auf dem Feld befinden',
+ 342: 'Du erhältst nun auch dann Turmschlüssel, wenn die Horde eingefroren ist',
+ 343: 'Die Chance auf mystische Scherben sinkt nun mit jeder Scherbe im Besitz',
+ 344: 'Angriff, Leben und Knocheneinkommen pro mystischer Scherbe',
+ 345: 'Einige aktive Ausrüstungseffekte wurden verändert, um das neue Schubsystem zu nutzen',
+ 346: 'Es gibt nun weniger Giftigkeit und Schneiden',
+ 347: 'Speedrun-Erfolge haben nun eine Maximalstufe von 10',
+ 348: 'Die "Riesenschmied"-Verbesserung ist nun auch in anderen Unterfunktionen aktiv',
+ 349: 'Schrotteinkommen',
+ 350: 'Grundpreis der "Riesenkiste"-Verbesserung',
+ 351: 'Schrottkapazität pro Stufe von "Riesenkiste"',
+ 352: 'Manchen Prestige-Verbesserungen wurde eine Maximalstufe hinzugefügt',
+ 353: 'Raucheinkommen wurde als Schatzeffekt hinzugefügt',
+ 354: 'Schätze haben nun ein Symbol, was auf ihrem Effekt basiert',
+ 355: 'Gebäude und Verbesserungen nach der Pyramide wurden abgeschwächt',
+ 356: 'Die Hauptfarbe vom Himmels-Farbschema wurde angepasst, um besser lesbar zu sein',
+ 357: 'Du erhältst nun 50 Rubine und 800 Amethyste, wenn du Edelsteine freischaltest',
+ 358: 'Du erhältst nun 100 Smaragde, wenn du Karten freischaltest',
+ 359: 'Du erhältst nun 500 Topas, wenn du Events freischaltest',
+ 360: 'Du erhältst nun 300 Smaragde, wenn du Schätze freischaltest',
+ 361: 'Die Menge an Goldstaub wird reduziert, wenn du mehr als 2000 pro Prüfung erhältst',
+ 362: 'Stufe-4-Opfergaben wurden zurückgesetzt und erstattet, vergiss\' nicht sie neu zu kaufen!',
+ 363: 'Alle Prestige-Verbesserungen wurden zurückgesetzt und erstattet, vergiss\' nicht sie neu zu kaufen!',
+ 364: 'Reservoir-Ideen',
+ 365: 'Effekt vom Zwerg-Gen',
+ 366: 'Der Effekt vom Fruchtbar-Gen erhöht nur noch den Ertrag und hängt von den Saphirkosten des Düngers ab',
+ 367: 'Das Umwandlungs-Gen reduziert nicht mehr den eigenen Ertrag und das Einkommen wird von jeder Ertragsart genommen, anstatt von der Ertragsart der Pflanze',
+ 368: 'Effekt vom Umwandlungs-Gen',
+ 369: 'Bosse nehmen nun mehr magischen Schaden',
+ 370: 'Gegner mit sehr hohen Korruptionswerten bekommen einen neuen tödlichen Effekt',
+ 371: 'Korruption ist nun in Türmen aktiv, abhängig vom Zonenwert der ersten Etage',
+ 372: 'Windradeffekt',
+ 373: 'Spätere Pflanzen benötigen nun mehr Erfahrung',
+ 374: 'Gold und die Stufe der "Goldwerkzeug"-Verbesserung wurden für Spieler mit hohen Goldwerten zurückgesetzt',
+ 375: 'Farbtrommeln benötigen nun die Farbtrommel der vorherigen Farbe, wenn Pakete geöffnet werden',
+ 376: 'Türme geben nun immer ihr besonderes Erbstück',
+ 377: 'Prestigewährungen erklären nun, woher sie stammen',
+ 378: 'Haupteffekt vorhandener Turm-Erbstücke',
+ 379: 'Die Goldchance-Formel wurde so verändert, dass sie Pflanzen mit längeren Wachstumszeiten mehr bevorzugt',
+ 380: 'Der Bauernhof merkt sich nun die Farbeinstellungen',
+ 381: '2 neue Farben hinzugefügt',
+ 382: 'Erbstück-Chance von der "Fortgeschrittenenglück"-Verbesserung',
+ 383: 'Chance auf seltenen Ertrag pro Marienkäfer',
+ 384: 'Zutaten erscheinen nun in größeren Stapeln und verbrauchen 10 Magie',
+ 385: 'Es kann nun eine Zutat als Lieblingszutat markiert werden',
+ 386: 'Säcke tauchen nun bei hohen Magiemengen auf',
+ 387: 'Sämtliche Ausrüstung in der Horde wurde abgelegt, vergiss\' nicht sie neu anzulegen!',
+
+ // v1.5.1
+ 388: 'Ausrüstung mit steigender kritischer Effizienz zeigen das nun beim Verbessern an',
+ 389: 'Ein Fehler wurde behoben, wo bei manchen Browsern alle Währungen in einer Spalte dargestellt wurden',
+ 390: 'Konverter pro Farbstufe gebraucht',
+ 391: 'Du erhältst nun mehr Farbe beim Umwandeln, wenn du deutlich mehr Konverter als nötige Farbe hast',
+ 392: 'Kartenkraft wird nun korrekt beim Prestige zurückgesetzt',
+ 393: 'Der Courage-Multiplikator einzelner Klassen wird nun korrekt beim Prestige zurückgesetzt',
+ 394: 'Der Tooltip bei der Umwandlung zeigt nun an, dass alle Konverter verbraucht werden',
+
+ // v1.5.2
+ 395: 'Konverter-Kapazität pro "Mülleimer"-Stufe',
+
+ // v1.5.3
+ 396: 'Ein Fehler wurde behoben, bei dem Opfergaben nicht mehr funktionieren, wenn man gewisse Versionen überspringt',
+ 397: 'Eventschätze werden jetzt korrekt im Shop angezeigt',
+ 398: 'Ein Fehler wurde behoben, wo manche Meilensteine die falsche Belohnung angezeigt haben',
},
v: {
1: {
@@ -366,7 +493,7 @@ export default {
2: 'Der Umwelt zuliebe',
3: 'Endlose Bosse',
4: 'Langsam und stetig',
- 5: '???',
+ 5: 'Handgemacht',
}
}
}
diff --git a/src/lang/de/relic.js b/src/lang/de/relic.js
index 57d35e24..c6ef30be 100644
--- a/src/lang/de/relic.js
+++ b/src/lang/de/relic.js
@@ -1,4 +1,7 @@
export default {
+ relics: 'Relikte',
+ museum: 'Museum',
+
torch: 'Fackel',
purpleHeart: 'Lila Herz',
rottenLeaf: 'Verrottetes Blatt',
@@ -71,6 +74,21 @@ export default {
simpleCalculator: 'Einfacher Taschenrechner',
orangeprint: 'Orangepause',
yellowBalloon: 'Gelber Luftballon',
+ fishbowl: 'Fischglas',
+ pencil: 'Bleistift',
+ smallBrush: 'Kleiner Pinsel',
+ strangePills: 'Seltsame Pillen',
+ strangeScroll: 'Seltsame Schriftrolle',
+ printingPress: 'Druckpresse',
+ yellowprint: 'Gelbpause',
+ greenBalloon: 'Grüner Luftballon',
+ woodenHanger: 'Kleiderbügel',
+ bedsheet: 'Bettlaken',
+ imageAlbum: 'Bilderalbum',
+ greenprint: 'Grünpause',
+ blueBalloon: 'Blauer Luftballon',
+ blueprint: 'Blaupause',
+ purpleBalloon: 'Lila Luftballon',
tinfoilHat: 'Aluhut',
cupOfWater: 'Wasserbecher',
combatStrategy: 'Kampfstrategie',
diff --git a/src/lang/de/stat.js b/src/lang/de/stat.js
index 9c0556ff..9bbd4976 100644
--- a/src/lang/de/stat.js
+++ b/src/lang/de/stat.js
@@ -9,7 +9,7 @@ export default {
description: 'Maximale Gasriesentiefe'
},
mining_maxDepthSpeedrun: {
- achievement: 'Tieflauf',
+ achievement: 'Tiefenlauf',
description: 'Maximale Tiefe in unter 15 Minuten'
},
mining_depthDwellerCap0: {
@@ -69,6 +69,15 @@ export default {
mining_timeSpent: {
description: 'Zeit verbracht'
},
+ mining_bestPrestige0: {
+ description: 'Meiste grüne Kristalle in einem Prestige'
+ },
+ mining_bestPrestige1: {
+ description: 'Meiste gelbe Kristalle in einem Prestige'
+ },
+ mining_prestigeCount: {
+ description: 'Prestigeanzahl'
+ },
// Village stats
village_maxBuilding: {
@@ -126,12 +135,24 @@ export default {
village_timeSpent: {
description: 'Zeit verbracht'
},
+ village_bestPrestige0: {
+ description: 'Meiste Segen in einem Prestige'
+ },
+ village_bestPrestige1: {
+ description: 'Meiste Aktien in einem Prestige'
+ },
+ village_prestigeCount: {
+ description: 'Prestigeanzahl'
+ },
// Horde stats
horde_maxZone: {
achievement: 'Entdecker',
description: 'Maximale Zone'
},
+ horde_maxDifficulty: {
+ description: 'Maximale Schwierigkeit'
+ },
horde_maxZoneSpeedrun: {
achievement: 'Schnelle Schläge',
description: 'Maximale Zone in unter 30 Minuten'
@@ -156,6 +177,10 @@ export default {
achievement: 'Seelenhirte',
description: 'Korrupte Seelen erhalten'
},
+ horde_maxCorruptionKill: {
+ achievement: 'Das Böse herausfordern',
+ description: 'Gegner mit der höchsten Korruption besiegt'
+ },
horde_maxMastery: {
achievement: 'Einseitig begabt',
description: 'Höchste Meisterungsstufe'
@@ -174,6 +199,15 @@ export default {
horde_timeSpent: {
description: 'Zeit verbracht'
},
+ horde_bestPrestige0: {
+ description: 'Meiste korrupte Seelen in einem Prestige'
+ },
+ horde_bestPrestige1: {
+ description: 'Meiste Courage in einem Prestige'
+ },
+ horde_prestigeCount: {
+ description: 'Prestigeanzahl'
+ },
// Farm stats
farm_harvests: {
@@ -192,9 +226,9 @@ export default {
achievement: 'Vegetarier',
description: 'Gemüse erhalten'
},
- farm_fruit: {
- achievement: 'Fruitarier',
- description: 'Früchte erhalten'
+ farm_berry: {
+ achievement: 'Rote Beere',
+ description: 'Beeren erhalten'
},
farm_grain: {
achievement: 'Bäcker',
@@ -217,6 +251,9 @@ export default {
farm_butterflyMax: {
description: 'Höchste Schmetterlingsmenge'
},
+ farm_totalMystery: {
+ description: 'Mysterium'
+ },
// Gallery stats
gallery_beauty: {
@@ -256,9 +293,28 @@ export default {
achievement: 'Dam dam dam',
description: 'Höchste Rote Farbtrommelmenge'
},
+ gallery_shapeComboTotal: {
+ achievement: 'Sammler',
+ description: 'Formen gesammelt'
+ },
+ gallery_shapeComboHighest: {
+ achievement: 'Genie',
+ description: 'Höchste Formenkombo'
+ },
+ gallery_canvasLevelTotal: {
+ achievement: 'Visionär',
+ description: 'Gesamte Leinwandstufe'
+ },
+ gallery_hourglassHighest: {
+ achievement: 'Geliehene Zeit',
+ description: 'Erreiche 1d an Stundenglaszeit'
+ },
gallery_timeSpent: {
description: 'Zeit verbracht'
},
+ gallery_prestigeCount: {
+ description: 'Prestigeanzahl'
+ },
// Meta stats
meta_totalLevel: {
diff --git a/src/lang/de/tag.js b/src/lang/de/tag.js
new file mode 100644
index 00000000..408db851
--- /dev/null
+++ b/src/lang/de/tag.js
@@ -0,0 +1,15 @@
+export default {
+ hordeEnergyToStr: '+{0} Stärke pro aktueller Energie',
+ hordeEnergyToEnergyReg: '+{0} Energieregeneration pro fehlender Energie',
+ hordeEnergyOnCrit: '+{0} Energie beim kritischen Treffer',
+ hordeHealOnCrit: 'Heilt {0} der maximalen Leben beim kritischen Treffer',
+ hordeRestoreCooldownOnCrit: 'Reduziert Abklingzeiten um {0} beim kritischen Treffer',
+ hordeBloodOnCrit: 'Erhalte {0} vom gegnerischen Blut beim kritischen Treffer',
+ hordeManaRest: 'Erhalte {1} Manaregeneration, wenn {0} keine aktiven Fähigkeiten benutzt werden',
+ hordeManasteal: 'Erhalte {0} Mana pro getöteten Gegner',
+ hordePassiveRecovery: 'Wende {0} der Erholung jede Sekunde an',
+ hordeActiveDamageCrit: 'Aktive Fähigkeiten mit Schaden können mit {0} Effizienz kritisch treffen',
+ hordeActiveHealCrit: 'Aktive Fähigkeiten mit Heilung können mit {0} Effizienz kritisch treffen',
+ hordeAttackAfterTime: 'Erhalte +{0} Angriff pro Minute im selben Kampf',
+ hordeStrIntAfterTime: 'Erhalte {0} Stärke und Intelligenz Angriff pro Minute im selben Kampf',
+}
diff --git a/src/lang/de/unlock.js b/src/lang/de/unlock.js
index 1a82c423..b45ed050 100644
--- a/src/lang/de/unlock.js
+++ b/src/lang/de/unlock.js
@@ -12,6 +12,8 @@ export default {
miningCompressTitanium: 'Titan komprimieren',
miningCompressPlatinum: 'Platin komprimieren',
miningCompressIridium: 'Iridium komprimieren',
+ miningCompressOsmium: 'Osmium komprimieren',
+ miningCompressLead: 'Blei komprimieren',
villageBuildings1: 'Stufe-1-Gebäude',
villageBuildings2: 'Stufe-2-Gebäude',
villageBuildings3: 'Stufe-3-Gebäude',
@@ -51,12 +53,24 @@ export default {
villageOffering2: 'Stufe-2-Opfergaben',
villageOffering3: 'Stufe-3-Opfergaben',
villageOffering4: 'Stufe-4-Opfergaben',
+ villageSpecialIngredient: 'Besondere Zutaten',
hordeCorruptedFlesh: 'Erbeute korruptes Fleisch',
hordeChessItems: 'Schach-Ausrüstung',
+ hordeSacrifice: 'Opfer',
hordeUpgradeRoyalArmor: 'Königliche-Rüstung-Verbesserung',
hordeUpgradeRoyalStorage: 'Königliches-Lager-Verbesserung',
hordeUpgradeRoyalButcher: 'Königlicher-Schlachter-Verbesserung',
hordeUpgradeRoyalCrypt: 'Königliches-Grab-Verbesserung',
+ hordeUpgradeRoyalSecret: 'Königliches-Geheimnis-Verbesserung',
+ hordeClassArcher: 'Bogenschützen-Klasse',
+ hordeClassMage: 'Magier-Klasse',
+ hordeClassKnight: 'Ritter-Klasse',
+ hordeClassAssassin: 'Assassine-Klasse',
+ hordeClassShaman: 'Schamane-Klasse',
+ hordeClassPirate: 'Pirat-Klasse',
+ hordeClassUndead: 'Untoter-Klasse',
+ hordeClassCultist: 'Kultist-Klasse',
+ hordeClassScholar: 'Gelehrter-Klasse',
farmDisableEarlyGame: 'Deaktiviere "Erste Pflanzen"',
farmCropExp: 'Pflanzenerfahrung',
farmFertilizer: 'Dünger',
@@ -64,6 +78,8 @@ export default {
galleryInspiration: 'Inspiration',
galleryAuction: 'Auktionen',
galleryDrums: 'Farbtrommeln',
+ galleryShape: 'Formen',
+ galleryCanvas: 'Leinwand',
treasureDual: 'Doppelte Schätze',
bloomPoppyFlower: 'Mohn',
bloomIrisFlower: 'Schwertlilie',
diff --git a/src/lang/de/upgrade.js b/src/lang/de/upgrade.js
index d1fab2dd..2217caa5 100644
--- a/src/lang/de/upgrade.js
+++ b/src/lang/de/upgrade.js
@@ -27,7 +27,7 @@ export default {
},
description: {
- mining_craftingStation: 'Die Werkbank erlaubt es dir, Orze zu verbrauchen, um deine Spitzhackenkraft zu erhöhen. Sie ist essentiell, um deinen Schaden zu steigern',
+ mining_craftingStation: 'Die Werkbank erlaubt es dir, Erze zu verbrauchen, um deine Spitzhackenkraft zu erhöhen. Sie ist essentiell, um deinen Schaden zu steigern',
mining_compressor: 'Mit dem Kompressor kannst du die Erzmenge pro Herstellplatz erhöhen, um die Reinheit der Spitzhacke zu verbessern',
mining_depthDweller: 'Dies gewährt dir Zugang zur Prestige-Möglichkeit vom Bergbau',
mining_smeltery: 'Hiermit kannst du Erze und Bodenschätze zu Barren schmelzen',
@@ -64,6 +64,7 @@ export default {
gallery_epiphany: 'Durch Ideen kannst du begrenzte Inspiration für einzigartige Boni nutzen',
gallery_auctionHouse: 'Dies gewährt dir Zugang zur Prestige-Möglichkeit von der Gallerie',
gallery_paintDrumStorage: 'Dies erlaubt das Sammeln von Paketen, welche manchmal Farbtrommeln enthalten',
+ gallery_emptyCanvas: 'Die Leinwand erlaubt es dir, Farben auszuwählen, um sie mit der Zeit zu verbessern',
},
// Mining upgrades
@@ -125,7 +126,15 @@ export default {
mining_iridiumExpansion: 'Iridiumexpansion',
mining_iridiumCache: 'Iridiumspeicher',
mining_iridiumTreetap: 'Iridium-Zapfhahn',
+ mining_deepCuts: 'Tiefe Schnitte',
mining_iridiumBombs: 'Iridiumbomben',
+ mining_oreBag: 'Erzbeutel',
+ mining_osmiumExpansion: 'Osmiumexpansion',
+ mining_osmiumCache: 'Osmiumspeicher',
+ mining_darkBombs: 'Dunkle Bomben',
+ mining_colossalScrapStorage: 'Kolossaler Schrottspeicher',
+ mining_stoneDissolver: 'Steinauflöser',
+ mining_leadExpansion: 'Bleiexpansion',
mining_fumes: 'Dämpfe',
mining_giantCrate: 'Riesenkiste',
@@ -154,6 +163,8 @@ export default {
mining_crystalTitaniumStorage: 'Kristall-Titanlager',
mining_crystalPlatinumStorage: 'Kristall-Platinlager',
mining_crystalIridiumStorage: 'Kristall-Iridiumlager',
+ mining_crystalOsmiumStorage: 'Kristall-Osmiumlager',
+ mining_crystalLeadStorage: 'Kristall-Bleilager',
mining_crystalDetector: 'Kristall-Detektor',
mining_crystalPreservarium: 'Kristall-Reservat',
mining_crystalTools: 'Kristall-Werkzeug',
@@ -168,6 +179,11 @@ export default {
mining_crystalCoal: 'Kristall-Kohle',
mining_crystalTruck: 'Kristall-LKW',
mining_crystalExpansion: 'Kristall-Expansion',
+ mining_crystalTnt: 'Kristall-TNT',
+ mining_crystalBeacon: 'Kristall-Leuchtfeuer',
+ mining_crystalNiter: 'Kristall-Salpeter',
+ mining_crystalBunker: 'Kristall-Bunker',
+ mining_crystalOreBag: 'Kristall-Erzbeutel',
mining_crystalSpikes: 'Kristall-Stacheln',
mining_crystalBooster: 'Kristall-Booster',
@@ -191,6 +207,8 @@ export default {
mining_moreTitanium: 'Mehr Titan',
mining_morePlatinum: 'Mehr Platin',
mining_moreIridium: 'Mehr Iridium',
+ mining_moreOsmium: 'Mehr Osmium',
+ mining_moreLead: 'Mehr Blei',
mining_premiumCraftingSlots: 'Premium-Herstellplätze',
mining_moreGreenCrystal: 'Mehr grüne Kristalle',
mining_moreRareEarth: 'Mehr Bodenschätze',
@@ -327,6 +345,19 @@ export default {
village_bartering: 'Feilschen',
village_sparks: 'Funken',
+ village_cashRegister: 'Kasse',
+ village_decoration: 'Dekoration',
+ village_plantFiberBin: 'Planzenfasertonne',
+ village_woodBin: 'Holztonne',
+ village_stoneBin: 'Steintonne',
+ village_metalBin: 'Metalltonne',
+ village_waterBin: 'Wassertonne',
+ village_glassBin: 'Glastonne',
+ village_hardwoodBin: 'Hartholztonne',
+ village_gemBin: 'Edelsteintonne',
+ village_oilBin: 'Öltonne',
+ village_marbleBin: 'Marmortonne',
+
// Village prestige upgrades
village_arch: 'Arche',
village_holyTree: 'Heiliger Baum',
@@ -355,6 +386,17 @@ export default {
village_holyLoot: 'Heilige Beute',
village_holyChisel: 'Heiliger Meißel',
+ village_hireArtisans: 'Handwerker einstellen',
+ village_hireExplorers: 'Erkunder einstellen',
+ village_recipeBook: 'Rezeptebuch',
+ village_hireWorkers: 'Arbeiter einstellen',
+ village_adCampaign: 'Werbekampagne',
+ village_hireAccountants: 'Buchhalter einstellen',
+ village_hireGardeners: 'Gärtner einstellen',
+ village_hireMiners: 'Minenarbeiter einstellen',
+ village_hireBartenders: 'Barkeeper einstellen',
+ village_hireExperts: 'Experten einstellen',
+
// Village premium upgrades
village_overtime: 'Überstunden',
village_goldenThrone: 'Goldener Thron',
@@ -409,8 +451,24 @@ export default {
horde_grossBag: 'Ekelbeutel',
horde_targetDummy: 'Trainingspuppe',
horde_milestone: 'Meilenstein',
+ horde_combatLesson: 'Kampflektion',
horde_mysticalBag: 'Mystischer Beutel',
+ horde_unlimitedAnger: 'Grenzenlose Wut',
+ horde_strangePower: 'Seltsame Kraft',
horde_collector: 'Sammler',
+ horde_prepareTheSacrifice: 'Das Opfer vorbereiten',
+
+ horde_transfusion: 'Transfusion',
+ horde_darkAttack: 'Dunkler Angriff',
+ horde_darkHealth: 'Dunkles Leben',
+ horde_harvest: 'Ernte',
+ horde_protectiveShell: 'Schützende Schale',
+ horde_bloodStorage: 'Blutspeicher',
+ horde_darkMilestone: 'Dunkler Meilenstein',
+ horde_endlessAnger: 'Endlose Wut',
+ horde_fistFight: 'Faustkampf',
+ horde_syringe: 'Spritze',
+ horde_bloodRitual: 'Blutritual',
// Horde prestige upgrades
horde_balance: 'Balance',
@@ -431,6 +489,21 @@ export default {
horde_lastWill: 'Letzter Wille',
horde_combatStudies: 'Kampf-Studien',
horde_boneChamber: 'Knochenkammer',
+ horde_deepHatred: 'Tiefer Hass',
+ horde_spiritLure: 'Gespensterköder',
+ horde_mysticalCondenser: 'Mystischer Kondensator',
+
+ horde_precision: 'Präzision',
+ horde_resolve: 'Durchhaltevermögen',
+ horde_determination: 'Zuversicht',
+ horde_education: 'Ausbildung',
+ horde_bloodChamber: 'Blutkammer',
+ horde_stoneSkin: 'Steinhaut',
+ horde_university: 'Universität',
+ horde_discovery: 'Entdeckung',
+ horde_innerFocus: 'Innerer Fokus',
+ horde_purge: 'Säubern',
+ horde_chaosCrate: 'Chaoskiste',
// Horde crown upgrades
horde_royalSword: 'Königliches Schwert',
@@ -438,6 +511,7 @@ export default {
horde_royalStorage: 'Königliches Lager',
horde_royalButcher: 'Königlicher Schlachter',
horde_royalCrypt: 'Königliches Grab',
+ horde_royalSecret: 'Königliches Geheimnis',
// Horde premium upgrades
horde_morePower: 'Mehr Kampfkraft',
@@ -478,6 +552,7 @@ export default {
farm_smallCrate: 'Kleine Kiste',
farm_sprinkler: 'Rasensprenger',
farm_scarecrow: 'Vogelscheuche',
+ farm_anthill: 'Ameisenhügel',
farm_magnifyingGlass: 'Lupe',
farm_bugPowder: 'Käferpulver',
farm_shed: 'Schuppen',
@@ -496,11 +571,17 @@ export default {
farm_artificialWebs: 'Künstliche Netze',
farm_studyInsects: 'Insekten studieren',
farm_beehive: 'Bienenstock',
+ farm_darkCorner: 'Dunkle Ecke',
farm_flag: 'Flagge',
+ farm_wormBait: 'Wurmköder',
+ farm_shinySoil: 'Glänzender Boden',
+ farm_bigFertilizerBag: 'Großer Düngerbeutel',
+ farm_openSesame: 'Sesam öffne dich',
+ farm_flowerPainting: 'Blumengemälde',
// Farm premium upgrades
farm_biggerVegetables: 'Größeres Gemüse',
- farm_biggerFruits: 'Größere Früchte',
+ farm_biggerBerries: 'Größere Beeren',
farm_biggerGrain: 'Größeres Getreide',
farm_biggerFlowers: 'Größere Blumen',
farm_moreExperience: 'Mehr Erfahrung',
@@ -545,6 +626,48 @@ export default {
gallery_purplePower: 'Lila Kraft',
gallery_blueLuck: 'Blaues Glück',
gallery_purpleConversion: 'Lila Umwandlung',
+ gallery_deepOrangePower: 'Rotorange Kraft',
+ gallery_purpleLuck: 'Lila Glück',
+ gallery_deepOrangeConversion: 'Rotorange Umwandlung',
+ gallery_emptyCanvas: 'Leere Leinwand',
+ gallery_linen: 'Leinen',
+ gallery_amberPower: 'Goldene Kraft',
+ gallery_deepOrangeLuck: 'Rotoranges Glück',
+ gallery_amberConversion: 'Goldene Umwandlung',
+ gallery_lightGreenPower: 'Hellgrüne Kraft',
+ gallery_amberLuck: 'Goldenes Glück',
+ gallery_lightGreenConversion: 'Hellgrüne Umwandlung',
+ gallery_tealPower: 'Türkise Kraft',
+ gallery_lightGreenLuck: 'Hellgrünes Glück',
+ gallery_tealConversion: 'Türkise Umwandlung',
+ gallery_lightBluePower: 'Hellblaue Kraft',
+ gallery_tealLuck: 'Türkises Glück',
+ gallery_lightBlueConversion: 'Hellblaue Umwandlung',
+ gallery_pinkPower: 'Pinke Kraft',
+ gallery_lightBlueLuck: 'Hellblaues Glück',
+ gallery_pinkConversion: 'Pinke Umwandlung',
+
+ // Gallery shape upgrades
+ gallery_bigCircle: 'Großer Kreis',
+ gallery_wellDrawnCircle: 'Gut gezeichneter Kreis',
+ gallery_bigRectangle: 'Großes Rechteck',
+ gallery_wellDrawnRectangle: 'Gut gezeichnetes Rechteck',
+ gallery_creativity: 'Kreativität',
+ gallery_wellDrawnTriangle: 'Gut gezeichnetes Dreieck',
+ gallery_luckyStar: 'Glücksstern',
+ gallery_wellDrawnStar: 'Gut gezeichneter Stern',
+ gallery_bigEllipse: 'Große Ellipse',
+ gallery_wellDrawnEllipse: 'Gut gezeichnete Ellipse',
+ gallery_bigHeart: 'Großes Herz',
+ gallery_wellDrawnHeart: 'Gut gezeichneter Herz',
+ gallery_bigSquare: 'Großes Quadrat',
+ gallery_wellDrawnSquare: 'Gut gezeichnetes Quadrat',
+ gallery_bigOctagon: 'Großes Achteck',
+ gallery_wellDrawnOctagon: 'Gut gezeichnetes Achteck',
+ gallery_bigPentagon: 'Großes Fünfeck',
+ gallery_wellDrawnPentagon: 'Gut gezeichnetes Fünfeck',
+ gallery_bigHexagon: 'Großes Sechseck',
+ gallery_wellDrawnHexagon: 'Gut gezeichnetes Sechseck',
// Gallery prestige upgrades
gallery_artAcademy: 'Kunstakademie',
@@ -552,13 +675,14 @@ export default {
gallery_rainbowJar: 'Regenbogenglas',
gallery_trashContainer: 'Abfallcontainer',
gallery_orangeCrayon: 'Oranger Malstift',
- gallery_headstart: 'Vorsprung',
+ gallery_shapes: 'Formen',
gallery_forklift: 'Gabelstapler',
gallery_redCrate: 'Rote Kiste',
gallery_yellowCrayon: 'Gelber Malstift',
gallery_inspiringBooks: 'Inspirierende Bücher',
gallery_expressDelivery: 'Expresslieferung',
gallery_orangeCrate: 'Orange Kiste',
+ gallery_biggerShapes: 'Größere Formen',
gallery_greenCrayon: 'Grüne Malstift',
gallery_sortingSystem: 'Sortiersystem',
gallery_redTruck: 'Roter LKW',
@@ -566,17 +690,36 @@ export default {
gallery_blueCrayon: 'Blauer Malstift',
gallery_orangeTruck: 'Oranger LKW',
gallery_greenCrate: 'Grüne Kiste',
+ gallery_investment: 'Investment',
gallery_purpleCrayon: 'Lila Malstift',
+ gallery_yellowTruck: 'Gelber LKW',
+ gallery_blueCrate: 'Blaue Kiste',
+ gallery_artClass: 'Kunstkurs',
+ gallery_preparation: 'Vorbereitung',
+ gallery_deepOrangeCrayon: 'Rotoranger Malstift',
+ gallery_greenTruck: 'Grüner LKW',
+ gallery_purpleCrate: 'Lila Kiste',
+ gallery_amberCrayon: 'Goldener Malstift',
+ gallery_truckConvoy: 'LKW-Convoy',
+ gallery_lightGreenCrayon: 'Hellgrüner Malstift',
+ gallery_tealCrayon: 'Türkiser Malstift',
+ gallery_lightBlueCrayon: 'Hellblauer Malstift',
+ gallery_pinkCrayon: 'Pinker Malstift',
// Gallery premium upgrades
gallery_prettyColors: 'Schöne Farben',
gallery_prettyConverter: 'Schöner Umwandler',
gallery_prettyCash: 'Schönes Geld',
+ gallery_prettyShapes: 'Schöne Formen',
+ gallery_prettyCanvas: 'Schöne Leinwand',
gallery_prettyRed: 'Schönes Rot',
gallery_prettyOrange: 'Schönes Orange',
gallery_prettyYellow: 'Schönes Gelb',
gallery_prettyGreen: 'Schönes Grün',
gallery_prettyBlue: 'Schönes Blau',
+ gallery_prettyPurple: 'Schönes Lila',
+ 'gallery_prettyDeep-orange': 'Schönes Rotorange',
+ gallery_prettyAmber: 'Schönes Gold',
// Gallery books
gallery_bookRedPower: 'Buch: Rote Kraft',
diff --git a/src/lang/en.js b/src/lang/en.js
index d9294042..1f55af1d 100644
--- a/src/lang/en.js
+++ b/src/lang/en.js
@@ -1,14 +1,15 @@
-import { en } from 'vuetify/lib/locale'
-import card from './en/card'
-import consumable from './en/consumable'
-import currency from './en/currency'
-import mult from './en/mult'
-import note from './en/note'
-import relic from './en/relic'
-import stat from './en/stat'
-import unlock from './en/unlock'
-import upgrade from './en/upgrade'
-import patchnote from './en/patchnote'
+import { en } from 'vuetify/lib/locale';
+import card from './en/card';
+import consumable from './en/consumable';
+import currency from './en/currency';
+import mult from './en/mult';
+import note from './en/note';
+import relic from './en/relic';
+import stat from './en/stat';
+import unlock from './en/unlock';
+import upgrade from './en/upgrade';
+import patchnote from './en/patchnote';
+import tag from './en/tag';
export default {
...en,
@@ -23,6 +24,9 @@ export default {
equip: 'Equip',
unequip: 'Unequip',
unequipAll: 'Unequip all',
+ select: 'Select',
+ deselect: 'Deselect',
+ take: 'Take',
max: 'Max',
maxed: 'Max',
free: 'Free',
@@ -46,6 +50,7 @@ export default {
saveManual: 'Save',
saveExport: 'Export to file',
saveImport: 'Load from file',
+ resetProgress: 'Reset progress',
closeAll: 'Close all',
draw: 'Draw',
finish: 'Finish',
@@ -142,13 +147,29 @@ export default {
key: 'The loaded savefile is missing required data',
version: 'This file is from a newer version of the game (v{0}, current version: v{1})',
testing: 'Files from the testing build cannot be used in the live version',
- migration: 'An error occured while migrating from v{0} to v{1}'
+ testingVersion: 'Files from older testing builds cannot be used',
+ migration: 'An error occured while migrating from v{0} to v{1}',
+ checksum: 'Invalid checksum',
}
},
duplicateTab: {
title: 'Gooboo is already running in another tab',
description: 'To prevent inconsistencies with your savefile, Gooboo can only run once. Please close this tab and return to the game on the existing tab.'
},
+ reset: {
+ feature: 'Want to start over? Here you can reset your progress for a single feature without touching other parts of the game.',
+ warning: 'This is NOT a prestige and there will be no rewards or refunds for doing this. Resets cannot be undone',
+ deleteSave: 'You can also delete your entire savefile here:',
+ deleteButton: 'Delete savefile'
+ },
+ prestigeDescription: {
+ mining_ember: 'Gain ember equal to a percentage of your current dweller depth',
+ village_blessing: 'Faith will be transformed into blessings',
+ village_shares: 'Gain shares equal to 0.1% of your current amount of copper coins',
+ horde_soulEmpowered: 'Corrupted souls will be transformed into empowered souls',
+ horde_courage: 'Gain courage when you reach level 10, and gain more for each level reached after',
+ gallery_cash: 'Gain cash based on your total amount of beauty gained this run',
+ },
confirm: {
title: 'Confirm action',
prestige: 'You are about to prestige, resetting all of your progress in this feature in exchange for prestige currency. Are you sure you want to prestige?',
@@ -170,13 +191,18 @@ export default {
weatherChaosFishingRodBuy: 'You are about to buy the fishing rod "{0}", which costs rare currency. Are you sure you want to buy this?',
summerFestivalCellBuy: 'You are about to buy a new island cell, which costs rare currency. Are you sure you want to buy this?',
farmCrop: 'You are about to plant crops that cost rare currency. Are you sure you want to buy this?',
+ galleryMotivation: 'You are about to buy motivation, which cost rare currency. Are you sure you want to buy this?',
treasure: 'You are about to buy a new treasure, which costs rare currency. Are you sure you want to buy this?',
schoolExamPass: 'You are about to buy an exam pass, which cost rare currency. Are you sure you want to buy this?',
treasureFragment: 'You are about to buy fragments, which cost rare currency. Are you sure you want to buy this?',
treasureDelete: 'You are about to destroy a treasure, which will give fragments in return. Are you sure you want to buy this?',
casinoBingoBuy: 'You are about to buy a bingo card, which costs rare currency. Are you sure you want to buy this?',
casinoWheelSpin: 'You are about to spin the wheel of fortune, which costs rare currency. Are you sure you want to buy this?',
- consumable: 'This action requires consumables that you do not have. Do you want to buy these for rare currency?'
+ consumable: 'This action requires consumables that you do not have. Do you want to buy these for rare currency?',
+ reset: {
+ text: 'Are you sure you want to reset the {0} feature? This action cannot be undone!',
+ },
+ resetAll: 'Are you sure you want to delete your savefile? This action cannot be undone!'
},
feature: {
subfeature: 'Subfeature',
@@ -203,6 +229,8 @@ export default {
// Subfeatures
miningGas: 'Gas',
+ villageCrafting: 'Crafting',
+ hordeClasses: 'Classes',
schoolLiterature: 'Literature',
schoolHistory: 'History',
schoolArt: 'Art',
@@ -226,6 +254,7 @@ export default {
},
horde: {
0: 'Equipment',
+ 1: 'Classes',
},
farm: {
0: 'Garden',
@@ -236,13 +265,23 @@ export default {
},
unlock,
mult,
+ tag,
text: {
+ villageIngredientBoxGet: 'Receive 3 ingredient boxes',
+ hordeBattlePassUpgrade: 'New upgrade',
+ hordeBattlePassPrestigeUpgrade: 'New prestige upgrade',
farmUnlockDna: 'Unlock all DNA upgrades from level 1 genes',
- farmGnomeBoost: 'Nearby garden gnomes increase all crop gains by 10%',
+ farmGnomeBoost: 'Increase all harvest gain by 4% for each nearby garden gnome. Premium garden gnomes count as 2',
farmLonelyGrow: 'Grow twice as fast if no other crops of this type are on the field',
- farmFertileBoost: 'Increase all crop gains by 30% of fertilizer grow time reduction',
- farmYieldConversion: 'Convert 60% of yield to other yield types (20% each)',
+ farmFertileBoost: 'Increase yield by 30% per sapphire cost of fertilizer',
+ farmYieldConversion: 'Gain 5% of yield to other yield types',
farmFastPrestige: 'Prestige reduces crop level by 5 instead of resetting it to 0',
+ farmLuckyHarvest: '1% chance to receive 8x harvest gain',
+ farmSelfless: 'Increase yield by +5% for all crops',
+ farmUnyielding: '40% chance to replant this crop for free when harvested',
+ farmTeamwork: 'Having this gene on one crop of each type doubles all crop yield',
+ farmHunter: 'Resource rare drops native to this plant become hunted. Hunt chance is equal to 1% of your rare drop chance. Each time a hunt is successful, resource capacity is increased by 10% of the base value and base hunt chance gets reduced by 5%',
+ farmPatient: 'Increases yield by +3% per day passed since this gene was chosen, up to +180% at 60 days',
},
upgrade,
currency,
@@ -319,6 +358,36 @@ export default {
github: 'GitHub',
website: 'Website',
googlefonts: 'Google Fonts'
+ },
+ cheater: {
+ 0: {
+ title: 'Honorable',
+ description: 'Played the game without any of the tools mentioned below',
+ },
+ 100: {
+ title: 'Automated',
+ description: 'Used tools to automatically perform human-like actions, while still following the game\'s rules',
+ },
+ 200: {
+ title: 'Cheater',
+ description: 'Edited game variables or used tools to achieve otherwise impossible results or predicted / altered outcomes',
+ },
+ selfMark: 'Set cheater status',
+ selfMarkDescription: 'You can mark yourself as a cheater here. This is purely visual and can be reversed at any time',
+ noDetected: 'No cheats detected',
+ featureDetected: 'Cheats were detected in the following features:',
+ featureDetected2: 'You can remove the cheater mark by fully resetting these features',
+ globalDetected: 'Cheats were detected and your savefile has been permanently marked',
+ selfMarkClick: 'If you were cheating and the game did not detect it properly, you can click to see options to mark yourself as cheater',
+ },
+ statistics: {
+ name: 'Statistics',
+ overview: 'Overview',
+ other: 'Other',
+ gained: 'Gained',
+ maxOwned: 'Highest amount',
+ currentTotal: 'current / total',
+ defaultPlayerName: 'Player',
}
},
error: {
@@ -729,6 +798,12 @@ export default {
ritualHintDescription: 'Chance to reveal a hint about either a slot or the amount of an ingredient. Hints are only given on successful new rituals. For each found hint, this chance is reduced by {0}%. Hints and the hint chance penalty reset when the hinted ritual is found.',
clickToAdd: 'Click on ingredients to add them to the ritual',
ingredientSizeDescription: 'Ingredient size allows you to find more ingredients per magical currency',
+ favouriteIngredient: {
+ title: 'Favourite ingredient',
+ description: 'You can select one ingredient as favourite, and each time you find an ingredient you also receive your favourite ingredient',
+ copy: 'Copy found ingredient',
+ },
+ sackDescription: 'Sacks can appear with high magic amounts, consume 10x more magic and contain 10x the amount of ingredients, split evenly among all available ones',
newDescription: {
empty: 'Here you can see if the current recipe is new (not succeeded before) or not',
isNew: 'This is a new recipe and you will receive a night hunt token if it succeeds',
@@ -897,7 +972,7 @@ export default {
},
starShield: {
name: 'Star shield',
- description: 'The player gets 5 armor in the first 3 turns'
+ description: 'The player gets 5 defense in the first 3 turns'
},
coffee: {
name: 'Coffee',
@@ -982,9 +1057,11 @@ export default {
mining_0: 'Deepest ore mine rock broken',
mining_1: 'Deepest gas giant rock broken',
village_0: 'Maximum housing',
+ village_1: 'Crafting milestones hit',
horde_0: 'Highest zone boss defeated',
+ horde_1: 'Battle pass level',
farm_0: 'Sum of all crop levels',
- gallery_0: 'Log5 of total beauty',
+ gallery_0: 'Log4 of total beauty',
debug: 'Debug'
},
theme: {
@@ -1077,6 +1154,10 @@ export default {
relativeUpgradeStats: {
name: 'Relative upgrade stats',
description: 'Shows the difference instead of before / after values'
+ },
+ useLegacyFarmSelect: {
+ name: 'Old farm selection',
+ description: 'Uses the old menu to select crops and buildings in the farm'
}
},
automation: {
@@ -1176,6 +1257,30 @@ export default {
name: 'Show currency labels',
description: 'Display currency gain and time until you reach capacity without needing to hover'
}
+ },
+ mods_qol: {
+ name: 'Mods QOL',
+ progressNiterMiningSound: {
+ name: 'Sound at X times broken'
+ },
+ progressNiterMiningActiveSound: {
+ name: 'Enable Sound'
+ }
+ },
+ mods_automation: {
+ name: 'Mods automation',
+ progressNiterMining: {
+ name: 'Nitermining autoprogress at X times broken',
+ },
+ progressNiterMiningActive: {
+ name: 'Enable nitermining autoprogress'
+ }
+ },
+ mods_cheats: {
+ name: 'Mods cheats',
+ cheatsGo: {
+ name: 'TestSwitch',
+ }
}
},
statBreakdown: {
@@ -1190,12 +1295,24 @@ export default {
zoneCleared: 'Zone cleared',
zoneClearedTotal: 'Highest zone cleared',
zone: 'Zone',
+ hordeMaxDifficulty: 'Difficulty cleared',
hordeBasicLoot: 'Basic loot',
hordeItemPermanent: 'Equipment effect',
+ hordeMastery: 'Equipment mastery',
+ hordeRest: 'Rest',
hordeNostalgia: 'Nostalgia',
hordeNostalgiaLost: 'Heirlooms found',
+ hordeClassMult: 'Class multiplier',
+ hordeClassLevel: 'Class level',
+ hordeBattlePass: 'Battle pass',
+ hordeEnergy: 'Energy',
+ hordeMana: 'Mana',
+ hordeTime: 'Time',
+ hordeSacrifice: 'Sacrifice',
farmEarlyGame: 'First crops',
+ galleryCanvas: 'Canvas',
cards: 'Cards',
+ cardsShiny: 'Shiny cards',
treasure: 'Treasure',
debug: 'Debug',
bankInvestment: 'Investment',
@@ -1206,6 +1323,8 @@ export default {
ritualPotionLevel: 'Potion level',
ritualHint: 'Discovered hints',
ritualIngredient: 'Bonus ingredient',
+ interest: 'Interest',
+ multiplier: 'Multiplier',
},
// Feature specific translations
@@ -1251,7 +1370,9 @@ export default {
coal: 'Can be found at {0}m or below on each rocks first break',
sulfur: 'Can be found at {0}m or below when hitting the deepest rock',
niter: 'Can be found at {0}m or below on power of 10 rock breaks',
- obsidian: 'Can be found at {0}m or below if your pickaxe is not enhanced'
+ obsidian: 'Can be found at {0}m or below if your pickaxe is not enhanced',
+ deeprock: 'Can be found at {0}m or below if the digits of the current depth add to 14 or higher',
+ glowshard: 'Can be found at {0}m or below, with a chance of 0.1% per meter below the limit. Obtaining one requires you to dig 1m deeper, this limit gets reduced each day by 10%',
},
rareEarthNotAffected: 'This resource is not affected by rare earth gain',
scrapGainHint: 'You do not get scrap when hitting rocks you have never broken before. Sometimes it is smarter to stay on your current depth to collect more scrap instead of digging down immediately.',
@@ -1285,13 +1406,31 @@ export default {
barSteel: 'Sharp',
barTitanium: 'Excavator',
barShiny: 'Rich',
- barIridium: 'Molten'
+ barIridium: 'Molten',
+ barDarkIron: 'Void'
},
gasGain: {
0: 'Gain ',
1: '% of your obtainable ',
2: ' when you break this rock. You can get up to ',
3: ' in this depth'
+ },
+ beacon: {
+ noBeacon: 'No beacon',
+ clickToPlace: 'Click to place beacons',
+ selectToPlace: 'Select a beacon to place',
+ place: 'Place',
+ remove: 'Remove beacon',
+ removeDescription: 'You can remove a beacon at any time, but you\'ll need to wait 20 hours to remove another one',
+ removeCooldown: 'Wait {0} before you can remove beacons again',
+ piercing: 'Piercing beacon',
+ rich: 'Rich beacon',
+ wonder: 'Wonder beacon',
+ hope: 'Hope beacon',
+ },
+ anomaly: {
+ name: 'Anomaly',
+ toughness: 'This rock has 100x toughness',
}
},
village: {
@@ -1321,6 +1460,51 @@ export default {
religion: 'Religion',
scanning: 'Scanning',
},
+ crafting: {
+ unlockNew: 'New crafting recipe: ',
+ owned: '{0} owned',
+ changeStat: {
+ value: 'Increase value to {0}',
+ timeNeeded: 'Decrease crafting time to {0}'
+ },
+ nextEffect: 'Next craft effects',
+ special: {
+ description: 'Special crafts provide permanent bonuses when crafted and their progress does not reset on prestige. Their cost increases with every craft and they do not have milestones'
+ },
+ crafts: '{0} / {1} crafts',
+ sellEvery: 'Sell 1 every ~{0}',
+ sellPrice: 'Sell price (Value: {0})',
+ rope: 'Rope',
+ woodenPlanks: 'Wooden planks',
+ brick: 'Brick',
+ screws: 'Screws',
+ waterBottle: 'Water bottle',
+ cocktailGlass: 'Cocktail glass',
+ boomerang: 'Boomerang',
+ polishedGem: 'Polished gem',
+ oilLamp: 'Oil lamp',
+ shower: 'Shower',
+ pouch: 'Pouch',
+ cupboard: 'Cupboard',
+ weight: 'Weight',
+ scissors: 'Scissors',
+ herbTea: 'Herb tea',
+ glasses: 'Glasses',
+ arrows: 'Arrows',
+ bowl: 'Bowl',
+ chain: 'Chain',
+ spear: 'Spear',
+ goldenRing: 'Golden ring',
+ poisonedArrows: 'Poisoned arrows',
+ frostSpear: 'Frost spear',
+ spicySoup: 'Spicy soup',
+ stopwatch: 'Stopwatch',
+ smallChest: 'Small chest',
+ bush: 'Bush',
+ handSaw: 'Hand saw',
+ garage: 'Garage',
+ diamondRing: 'Diamond ring',
+ },
buildings: 'Buildings',
village: 'Village',
pray: 'Pray',
@@ -1339,6 +1523,8 @@ export default {
housingStat: 'Total housing constructed (first 25 per building)',
coinNotAffected: 'Coins are not affected by "All resource gain"',
faithNotAffected: 'Faith is not affected by "All resource gain" and "Mental resource gain"',
+ artisanDescription: 'Artisans can be assigned to craft items for you',
+ counterDescription: 'Counters can be used to sell crafted items to your villagers',
offering: {
name: 'Offerings',
description: {
@@ -1355,6 +1541,7 @@ export default {
food: 'Food',
mental: 'Mental resources',
loot: 'Loot',
+ specialIngredient: 'Special ingredients',
foodConsume: 'Consuming up to {0} per second'
},
horde: {
@@ -1367,6 +1554,7 @@ export default {
noLoadouts: 'No loadouts',
monsterPartHint: 'Go to zone 10+ and reach enemy #101 to discover a new currency! That currency is essential to progess further, as it helps you raise your bone capacity.',
enemyDescription: 'Each enemy in the same zone has x{0} attack, x{1} health and +{2}% bones compared to the previous enemy. This is enemy #{3} and has x{4} attack, x{5} health and +{6}% bones. All of these effects reset when you die.',
+ enemyDescriptionClasses: 'Each enemy in the same zone has x{0} attack, x{1} health and +{2}% blood compared to the previous enemy. This is enemy #{3} and has x{4} attack, x{5} health and +{6}% blood. All of these effects reset when you die.',
enemySigil1: {
s: 'Enemies in this zone have {0} sigil',
p: 'Enemies in this zone have {0} sigils',
@@ -1390,7 +1578,8 @@ export default {
text: 'Regular attacks happen every second and have the following damage distribution: ',
physic: '{0}% physical',
magic: '{0}% magical',
- bio: '{0}% biological'
+ bio: '{0}% biological',
+ strengthAmp: 'Each point of strength increases the damage of your regular attacks by +{0}%, for a total of +{1}%. This increases the damage of your regular attacks to {2}.'
},
healthDescription: 'The amount of damage you can take before dying',
respawnDescription: 'How much time you need to recover from dying',
@@ -1402,6 +1591,10 @@ export default {
spellbladeDescription: 'Deal bonus magical damage after using an equipment effect. For equipment effects with a cooldown of below 10 seconds, this does not always work',
cuttingDescription: 'Deal a percentage of your targets current health as biological damage after attacking',
recoveryDescription: 'Heal a percentage of your missing health after killing an enemy',
+ defenseDescription: 'Reduce incoming damage by a percentage of your maximum health',
+ executeDescription: 'Instantly kill enemies if they are below a certain health threshold',
+ energyDescription: 'Some actives require energy to use. It refills automatically over time',
+ manaDescription: 'Some actives require mana to use. It refills slowly over time',
boss: 'Boss',
miniboss: 'Miniboss',
minibossDescription: 'Minibosses appear in place of regular enemies and are a bit stronger. They hold valuable loot and up to 2 can be waiting at once. Defeating one also counts as defeating 4 regular enemies',
@@ -1417,9 +1610,13 @@ export default {
stunResist: 'Recover faster from stuns',
stunBoss: 'Bosses receive +2 stun resist',
stunMiniboss: 'Minibosses receive +1 stun resist',
- bossBioResist: 'Bosses only take 10% biological damage',
- minibossBioResist: 'Minibosses only take 50% biological damage',
+ bossBioResist: 'Bosses only take 10% biological damage, but take 35% more magical damage',
+ minibossBioResist: 'Minibosses only take 50% biological damage, but take 10% more magical damage',
enemyRespawn: 'Enemies take {0} to respawn and up to {1} enemies can be waiting. Defeating a boss immediately respawns all enemies',
+ bossBonusDifficulty: 'Boss difficulty',
+ bossNoReward: 'You can fight this boss again at any difficulty, but will not receive rewards for doing so',
+ energyIncompatible: 'Your currently selected class cannot use this trinket because it requires energy',
+ manaIncompatible: 'Your currently selected class cannot use this trinket because it requires mana',
taunt: {
title: 'Taunt mode',
description: 'When taunted, enemies keep spawning even when none are waiting, but all enemies spawned early carry no loot. Taunting only works when trying to reach the boss',
@@ -1492,6 +1689,8 @@ export default {
rainbow: 'Rainbow',
drain: 'Drain',
shocking: 'Shocking',
+ defense: 'Defense',
+ executing: 'Executing',
berserk: 'Berserk',
iceGiant: 'Ice giant',
generic: 'Generic',
@@ -1499,12 +1698,14 @@ export default {
corruption: {
name: 'Corruption',
effects: 'Effects',
- power: 'Attack and health x',
- sigil: 'Sigil +',
- revive: 'Revive +'
+ power: 'Attack and health x{0}',
+ sigil: 'Sigil +{0}',
+ revive: 'Revive +{0}',
+ execute: 'Execute +{0}%'
},
activeCooldown: 'Active cooldown',
- itemsEquipped: 'items equipped',
+ activeBuffFor: 'For {0}:',
+ itemsEquipped: 'equipment slots used',
cleared: 'Cleared',
fighting: 'Fighting',
items: {
@@ -1572,10 +1773,24 @@ export default {
bomb: 'Bomb',
leechingStaff: 'Leeching staff',
shatteredGem: 'Shattered gem',
+ hourglass: 'Hourglass',
+ glue: 'Glue',
firework: 'Firework',
bowTie: 'Bow tie',
+ forbiddenStopwatch: 'Forbidden stopwatch',
mysticalAccelerator: 'Mystical accelerator',
blazingStaff: 'Blazing staff',
+ shield: 'Shield',
+ armor: 'Armor',
+ natureStone: 'Nature stone',
+ evergrowingVine: 'Evergrowing vine',
+ energyDrink: 'Energy drink',
+ dragonheart: 'Dragonheart',
+ prism: 'Prism',
+ deathsword: 'Deathsword',
+ needle: 'Needle',
+ mine: 'Mine',
+ maskOfJoy: 'Mask of joy',
// Chess pieces
pawn: 'Pawn',
@@ -1598,6 +1813,18 @@ export default {
0: 'Deal',
1: 'biological damage'
},
+ maxdamagePhysic: {
+ 0: 'Deal',
+ 1: 'enemy health physical damage'
+ },
+ maxdamageMagic: {
+ 0: 'Deal',
+ 1: 'enemy health magical damage'
+ },
+ maxdamageBio: {
+ 0: 'Deal',
+ 1: 'enemy health biological damage'
+ },
heal: {
0: 'Restore',
1: 'health'
@@ -1606,6 +1833,10 @@ export default {
0: 'Gain',
1: 'highest zone bones'
},
+ blood: {
+ 0: 'Gain',
+ 1: 'highest difficulty blood'
+ },
monsterPart: {
0: 'Gain',
1: 'highest zone monster parts'
@@ -1626,10 +1857,6 @@ export default {
0: 'Remove',
1: 'attack from the opponent'
},
- raiseAttack: {
- 0: 'Permanently increase attack by',
- 1: ''
- },
poison: {
0: 'Apply',
1: 'poison'
@@ -1643,6 +1870,11 @@ export default {
2: ' by',
1: '(until prestige)'
},
+ gainStat: {
+ 0: 'Permanently increase ',
+ 2: ' by',
+ 1: ''
+ },
divisionShield: {
0: 'Gain',
1: 'division shield'
@@ -1651,6 +1883,24 @@ export default {
0: 'Remove',
1: 'division shield from the opponent'
},
+ executeKill: {
+ 0: 'Kill an enemy below',
+ 1: 'health'
+ },
+ refillEnergy: {
+ 0: 'Restore',
+ 1: 'energy'
+ },
+ refillMana: {
+ 0: 'Restore',
+ 1: 'mana'
+ },
+ buff: {
+ duration: 'Buff duration',
+ suffix: '(buff)',
+ },
+ canCrit: 'can crit at {0}% efficiency',
+ canCritDiff: 'Active crit efficiency',
reviveAll: 'Refill all revives',
removeStun: 'Remove stuns',
},
@@ -1675,10 +1925,12 @@ export default {
brick: 'Brick',
heat: 'Heat',
ice: 'Ice',
+ crystal: 'Crystal',
+ vitality: 'Vitality',
},
itemMastery: {
name: 'Mastery',
- description: 'Defeat bosses or minibosses at zone {0} or higher with this item equipped to earn mastery points. Higher zone bosses earn more mastery points.',
+ description: 'Defeat bosses or minibosses at zone {0} or higher with this equipment to earn mastery points. Higher zone bosses earn more mastery points.',
gain: 'Receive {0} mastery points from bosses on this zone, and {1}% of that value ({2}) from minibosses',
bonuses: 'Raise your mastery level to unlock bonuses for this equipment',
current: 'This equipment has {0} / {1} mastery points',
@@ -1691,7 +1943,7 @@ export default {
tower: {
name: 'Towers',
description: 'Towers are special places that require a tower key to enter. You can fight enemies for crowns and unique heirlooms until you die. Reach specific floors to permanently unlock new bonuses',
- zoneDescription: 'Enemies in this tower on your highest reached floor are about as strong as a zone {0} enemy. They start at the power of a zone {1} enemy and gain {2} zones worth of stats every floor. Corruption is disabled in towers',
+ zoneDescription: 'Enemies in this tower on your highest reached floor are about as strong as a zone {0} enemy. They start at the power of a zone {1} enemy and gain {2} zones worth of stats every floor',
floorTitle: 'Highest floor defeated',
floorDescription: 'Defeat enemies on certain floors to unlock permanent bonuses:',
rewardTitle: 'Rewards',
@@ -1704,6 +1956,169 @@ export default {
brick: 'Brick tower',
fire: 'Fire tower',
ice: 'Ice tower',
+ danger: 'Danger tower',
+ toxic: 'Toxic tower',
+ },
+ classes: {
+ skill: 'Skill',
+ skillPointsLeft: '{0} skill point(s) left',
+ skillPointCost: 'Needs {0} skill points to level up',
+ skillTreeChoice: 'Here you can make a choice, picking one of these skills locks the other paths',
+ adventurer: {
+ name: 'Adventurer',
+ description: 'A versatile fighter that can deal with every situation'
+ },
+ archer: {
+ name: 'Archer',
+ description: 'A ranged fighter that focuses on critical strikes and consistent damage'
+ },
+ mage: {
+ name: 'Mage',
+ description: 'A fighter that utilizes spells to quickly deal with foes and allows autocasting'
+ },
+ knight: {
+ name: 'Knight',
+ description: 'A durable fighter that slowly takes down opponents, but can deal with strong enemies'
+ },
+ assassin: {
+ name: 'Assassin',
+ description: 'A nimble fighter that focuses on killing enemies quickly'
+ },
+ shaman: {
+ name: 'Shaman',
+ description: 'A fighter bound to nature that utilizes healing and poison to win fights'
+ },
+ pirate: {
+ name: 'Pirate',
+ description: 'The pirate may not be best combatant, but excels at looting'
+ },
+ undead: {
+ name: 'Undead',
+ description: 'A weak fighter that offsets this weakness with superior numbers'
+ },
+ cultist: {
+ name: 'Cultist',
+ description: 'A versatile fighter that specializes on one task at a time'
+ },
+ scholar: {
+ name: 'Scholar',
+ description: 'A supportive fighter that helps other classes'
+ }
+ },
+ battlePass: {
+ name: 'Battle pass',
+ quest: {
+ stat: 'Reach {0} {1}',
+ zone: 'Clear {0} zone {1}',
+ level: 'Reach level {0}',
+ boss: 'Defeat {0} (+{1})'
+ },
+ statType: {
+ base: 'base {0}',
+ total: 'total {0}',
+ }
+ },
+ enemyName: {
+ soldier: 'Soldier',
+ officer: 'Police officer',
+ hunter: 'Hunter',
+ sniper: 'Sniper',
+ strongMonkey: 'Strong monkey',
+ angryMonkey: 'Angry monkey',
+ dartMonkey: 'Dart monkey',
+ monkeyWizard: 'Monkey wizard',
+ monkeyDefender: 'Monkey defender',
+ monkeyMonk: 'Monkey Monk',
+ puppy: 'Puppy',
+ kitten: 'Kitten',
+ seal: 'Seal',
+ piglet: 'Piglet',
+ panda: 'Panda',
+ koala: 'Koala',
+ rabbit: 'Rabbit',
+ guineaPig: 'Guinea pig',
+ },
+ bossName: {
+ ohilio_guard1: 'Guard A',
+ ohilio_guard2: 'Guard B',
+ ohilio: 'ohilio',
+ chriz1: 'Chriz',
+ chriz2: 'Chriz',
+ mina: 'mina',
+ },
+ area: {
+ zoneEndless: 'Endless zone',
+ zoneBoss: 'Boss ({0})',
+ zone: 'Zone {0}',
+ difficulty: '{0} difficulty',
+ enemyAmount: '{0} enemies in this zone',
+ warzone: 'Warzone',
+ monkeyJungle: 'Monkey jungle',
+ loveIsland: 'Love island',
+ },
+ sign: {
+ sign_1: {
+ text: 'My aim is perfect, I never miss! You better watch out!',
+ signed: 'ohilio',
+ },
+ sign_2: {
+ text: 'Think you can hurt me? Never! I\'ll dodge everything, you won\' even be able to hit me! I\'m untouchable!',
+ signed: 'ohilio',
+ },
+ sign_3: {
+ text: 'I am the greatest, the best, perfect, undefeatable! Even my guards are nothing compared to me! You think you stand a chance against me? Hah! Prepare to die!',
+ signed: 'ohilio',
+ },
+ sign_4: {
+ text: 'After taking a close look at these cute animals, you notice they are not real. They are just will-o-wisps! But why are they here? To make you feel bad? No time to think about it, you need to fight to get past these animal spirits',
+ signed: '???',
+ },
+ },
+ quest: {
+ name: 'Quests',
+ description: 'Complete quests to advance your battle pass and unlock permanent rewards',
+ completed: '{0} completed',
+ allCompleted: 'All quests completed',
+ },
+ trinket: {
+ rarity: {
+ 0: 'Unowned',
+ 1: 'Common',
+ 2: 'Uncommon',
+ 3: 'Rare',
+ 4: 'Epic',
+ 5: 'Legendary',
+ 6: 'Mythic',
+ 7: 'Extraordinary',
+ 8: 'Radiant',
+ 9: 'Prismatic',
+ 10: 'Finalized',
+ timeless: 'Timeless'
+ },
+ equipped: 'trinkets selected (equipped after prestige)',
+ vitality: 'Vitality',
+ energy: 'Energy',
+ magic: 'Magic',
+ fists: 'Fists',
+ sparks: 'Sparks',
+ haste: 'Haste',
+ precision: 'Precision',
+ wrath: 'Wrath',
+ strength: 'Strength',
+ toxins: 'Toxins',
+ wisdom: 'Wisdom',
+ extraction: 'Extraction',
+ learning: 'Learning',
+ preservation: 'Preservation',
+ energize: 'Energize',
+ automation: 'Automation',
+ cure: 'Cure',
+ duality: 'Duality',
+ love: 'Love',
+ },
+ sacrifice: {
+ name: 'Sacrifice',
+ description: 'Here you can temporarily sacrifice equipment slots to receive powerful bonuses in exchange'
}
},
farm: {
@@ -1713,6 +2128,7 @@ export default {
expToLevelUp: 'You need {0} more harvests to reach the next level',
yield: 'Yield',
rareDrops: 'Rare drops',
+ huntedRareDrops: 'Hunted rare drops',
addRareDrop: 'Add rare drop ({0})',
addRareDropAmount: '{0} amount',
prestige: {
@@ -1765,7 +2181,12 @@ export default {
grapes: 'Grapes',
hops: 'Hops',
violet: 'Violet',
- goldenRose: 'Golden rose'
+ goldenRose: 'Golden rose',
+ sweetPotato: 'Sweet potato',
+ strawberry: 'Strawberry',
+ sesame: 'Sesame',
+ sunflower: 'Sunflower',
+ spinach: 'Spinach',
},
gene: {
name: 'Gene',
@@ -1774,6 +2195,8 @@ export default {
dnaDuplicate: 'Genes you choose do not appear on your next prestige. Not picking genes makes all 4 available on the next prestige',
dnaBlocked: 'Blocked genes',
hasUpgrade: 'Has gene upgrade',
+ lockOnField: 'This gene cannot be picked with this crop on the field',
+ basics: 'Basics',
yield: 'Yield',
gold: 'Gold',
exp: 'Experience',
@@ -1789,17 +2212,25 @@ export default {
mystery: 'Mystery',
conversion: 'Conversion',
prestige: 'Prestige',
- rareDropChance: 'Discovery'
+ rareDropChance: 'Discovery',
+ lucky: 'Lucky',
+ finalize: 'Finalize',
+ selfless: 'Selfless',
+ unyielding: 'Unyielding',
+ teamwork: 'Teamwork',
+ hunter: 'Hunter',
+ patient: 'Patient',
},
fertilizerEffect: {
vegetable: 'Vegetables only',
- fruit: 'Fruits only',
+ berry: 'Berries only',
grain: 'Grains only',
flower: 'Flowers only'
},
building: {
premium: 'Premium {0}',
premiumOwned: 'Premium: {0} owned',
+ owned: '{0} owned',
gardenGnome: {
name: 'Garden gnome',
description: 'Crops on the field may give gold on harvest when the garden gnome is placed on the field. The chance is based on crop grow time.',
@@ -1817,13 +2248,13 @@ export default {
},
pinwheel: {
name: 'Pinwheel',
- description: 'Increases the drop chance on the field by +1% for each unique crop in the surrounding 8 tiles',
- descriptionPremium: 'Increases the drop chance on the field by +2% for each unique crop in the surrounding 8 tiles',
+ description: 'Increases the drop chance on the field by +0.015x for each unique crop in the surrounding 8 tiles',
+ descriptionPremium: 'Increases the drop chance on the field by +0.03x for each unique crop in the surrounding 8 tiles',
},
flag: {
name: 'Flag',
- description: 'Increases crop gain by +50% if they are in the correct position related to the flag. Vegetable: Top left, Fruit: Top right, Grain: Bottom left, Flower: Bottom right',
- descriptionPremium: 'Increases crop gain by +100% if they are in the correct position related to the flag. Vegetable: Top left, Fruit: Top right, Grain: Bottom left, Flower: Bottom right',
+ description: 'Increases crop gain by +50% if they are in the correct position related to the flag. Vegetable: Top left, Berry: Top right, Grain: Bottom left, Flower: Bottom right',
+ descriptionPremium: 'Increases crop gain by +100% if they are in the correct position related to the flag. Vegetable: Top left, Berry: Top right, Grain: Bottom left, Flower: Bottom right',
}
}
},
@@ -1833,6 +2264,9 @@ export default {
colorSuffix: 'color',
openPackage: 'Open',
colorGainReduced: 'Additional gains are reduced to square root after 100 color',
+ drumCompounding: 'To be able to find this drum, you must also find all drums of previous colors in the same package. This reduces the effective chance of finding this drum',
+ allConverterInfo: 'Converting a color always consumes all converters',
+ converterOverload: 'You have way more converters than color for this conversion, resulting in x{0} conversion gain',
idea: {
tier: 'Tier {0} idea',
unlock: 'Unlock idea',
@@ -1843,6 +2277,7 @@ export default {
sortWaste: 'Sort waste',
advertise: 'Advertise',
beImpatient: 'Be impatient',
+ beExcited: 'Be excited',
makeLemonade: 'Make lemonade',
growATree: 'Grow a tree',
@@ -1850,16 +2285,80 @@ export default {
observeRainbow: 'Observe rainbow',
buildRedReservoir: 'Build red reservoir',
orderMassiveSafe: 'Order massive safe',
+ buyPen: 'Buy pen',
drawOcean: 'Draw ocean',
makeWine: 'Make wine',
calculateOdds: 'Calculate odds',
buildOrangeReservoir: 'Build orange reservoir',
thinkHarder: 'Think harder',
+ paintFaster: 'Paint faster',
+ buyBrush: 'Buy brush',
+
+ harvestOranges: 'Harvest oranges',
+ pulverizeGold: 'Pulverize gold',
+ buildYellowReservoir: 'Build yellow reservoir',
+ paintForFun: 'Paint for fun',
+ printNewspaper: 'Print newspaper',
+ expandCanvas: 'Expand canvas',
+ hyperfocus: 'Hyperfocus',
+
+ cutGrass: 'Cut grass',
+ shapeClay: 'Shape clay',
+ buildGreenReservoir: 'Build green reservoir',
+ beMysterious: 'Be mysterious',
+
+ lookAtTheSky: 'Look at the sky',
+ chewBubblegum: 'Chew bubblegum',
+ buildBlueReservoir: 'Build blue reservoir',
},
nextInspiration: {
0: 'Next ',
1: ' in '
+ },
+ shapes: {
+ name: 'Shapes',
+ upgrades: 'Shape upgrades',
+ description: 'Drag a shape to an adjacent one to switch postitons, or click one to collect it. Collecting requires 5 shapes of the same type to be connected and the amount of shapes gained per shape is equal to the collection combo.',
+ cost: 'Each action costs',
+ special: {
+ name: 'Special shapes',
+ description: 'A special shape has a {0}% chance to appear instead of a regular shape, and special collections give {1}x shapes. There can only be one special shape on the grid',
+ bomb: 'All shapes in a + formation are special collected',
+ dice: 'All shapes that do not match the shape above (or below if at top row) this get rerolled',
+ accelerator: 'The surrounding 8 shapes are special collected. If all 8 of them are the same, spend all motivation to gain even more shapes',
+ sparkles: 'The 4 directly adjacent shapes get regular collected if possible and count as one big combo',
+ hourglass: 'Immediately get converters and packages, collect shapes to increase the time',
+ chest: 'Special collect 10 nearby shapes, the 8 surrounding ones and the ones to the left and right. If all 10 shapes are different, receive a special reward'
+ },
+ buyFor: {
+ 0: 'Buy',
+ 1: 'for'
+ },
+ reroll: 'Reroll the entire grid for',
+ unlock: 'Unlock shape: {0}',
+ circle: 'Circle',
+ rectangle: 'Rectangle',
+ triangle: 'Triangle',
+ star: 'Star',
+ ellipse: 'Ellipse',
+ heart: 'Heart',
+ square: 'Square',
+ octagon: 'Octagon',
+ pentagon: 'Pentagon',
+ hexagon: 'Hexagon',
+ bomb: 'Bomb',
+ dice: 'Dice',
+ accelerator: 'Accelerator',
+ sparkles: 'Sparkles',
+ hourglass: 'Hourglass',
+ chest: 'Chest',
+ },
+ canvas: {
+ name: 'Canvas',
+ description: 'Put colors on the canvas to slowly increase their canvas level, granting you permanent bonuses',
+ level: 'Canvas level',
+ untilNextLevel: '{0} until next level'
}
},
gem: {
diff --git a/src/lang/en/card.js b/src/lang/en/card.js
index f1bbccf0..c141c731 100644
--- a/src/lang/en/card.js
+++ b/src/lang/en/card.js
@@ -1,6 +1,9 @@
export default {
cardPack: 'Card pack',
cardsSuffix: ' cards',
+ cardPower: 'Card power',
+ cardPowerValue: '{0} card power',
+ cardPowerDescription: 'Card power is added for all active cards and increases basic stats of that feature',
notFound: 'No cards found',
fullCollectionReward: 'Full collection reward',
canFind: 'This card can be found in the following packs',
diff --git a/src/lang/en/consumable.js b/src/lang/en/consumable.js
index 91caee84..23c9d03a 100644
--- a/src/lang/en/consumable.js
+++ b/src/lang/en/consumable.js
@@ -9,6 +9,14 @@ export default {
name: 'Golden hammer',
description: 'Get the best pickaxe possible for this craft'
},
+ village_ingredientBox: {
+ name: 'Ingredient box',
+ description: 'Contains special ingredients that can only be found in these boxes'
+ },
+ horde_manaPotion: {
+ name: 'Mana potion',
+ description: 'Refill 50% of your maximum mana'
+ },
farm_basic: {
name: 'Basic fertilizer',
description: ''
@@ -33,6 +41,10 @@ export default {
name: 'Juicy fertilizer',
description: ''
},
+ farm_dissolving: {
+ name: 'Crop dissolver',
+ description: ''
+ },
farm_potatoWater: {
name: 'Potato water',
description: ''
@@ -53,6 +65,18 @@ export default {
name: 'Premium fertilizer',
description: ''
},
+ farm_analyzing: {
+ name: 'Analyzing fertilizer',
+ description: ''
+ },
+ farm_superJuicy: {
+ name: 'Super-juicy',
+ description: ''
+ },
+ farm_pellets: {
+ name: 'Pellets',
+ description: ''
+ },
farm_sunshine: {
name: 'Sunshine',
description: ''
diff --git a/src/lang/en/currency.js b/src/lang/en/currency.js
index 4b8182c1..1adcfe42 100644
--- a/src/lang/en/currency.js
+++ b/src/lang/en/currency.js
@@ -335,6 +335,14 @@ export default {
name: 'Iridium ore',
description: 'Irid... what? You never heard of this one before, can it even be used for anything?'
},
+ mining_oreOsmium: {
+ name: 'Osmium ore',
+ description: ''
+ },
+ mining_oreLead: {
+ name: 'Lead ore',
+ description: ''
+ },
mining_granite: {
name: 'Granite',
description: 'Huge blocks of granite cut from the underground. Surprisingly, there is no scrap in them'
@@ -359,6 +367,14 @@ export default {
name: 'Obsidian',
description: 'Beautiful purple shards, they look fragile'
},
+ mining_deeprock: {
+ name: 'Deeprock',
+ description: ''
+ },
+ mining_glowshard: {
+ name: 'Glowshard',
+ description: ''
+ },
mining_barAluminium: {
name: 'Aluminium bar',
description: 'The first of many'
@@ -383,6 +399,10 @@ export default {
name: 'Iridium bar',
description: 'What strange properties does this one have...'
},
+ mining_barDarkIron: {
+ name: 'Dark iron bar',
+ description: ''
+ },
mining_ember: {
name: 'Ember',
description: 'Careful, it\'s still hot!'
@@ -431,6 +451,10 @@ export default {
name: 'Gold coin',
description: 'Coins earned by selling food to your villagers'
},
+ village_copperCoin: {
+ name: 'Copper coin',
+ description: 'Coins earned by selling crafted items to your villagers'
+ },
village_wood: {
name: 'Wood',
description: 'Logs harvested from nearby trees'
@@ -495,6 +519,10 @@ export default {
name: 'Blessing',
description: 'The hopes of your villagers turned out to be true! Things are better in the future! It will get easier over time!'
},
+ village_shares: {
+ name: 'Shares',
+ description: 'Invest to make more money!'
+ },
village_offering: {
name: 'Offering',
description: 'A mysterious offering that required a resource sacrifice'
@@ -539,6 +567,22 @@ export default {
name: 'Mythical loot',
description: 'And you thought these were lost forever'
},
+ village_acidVial: {
+ name: 'Acid vial',
+ description: 'Be careful!'
+ },
+ village_snowflake: {
+ name: 'Snowflake',
+ description: ''
+ },
+ village_chiliBundle: {
+ name: 'Chili bundle',
+ description: ''
+ },
+ village_gears: {
+ name: 'Gears',
+ description: ''
+ },
horde_bone: {
name: 'Bone',
description: 'Skeletal remains of the enemies you have slain'
@@ -563,6 +607,10 @@ export default {
name: 'Empowered soul',
description: 'Formerly corrupted souls that were purified and strengthened by a complex ritual'
},
+ horde_courage: {
+ name: 'Courage',
+ description: 'Bravery is a much needed virtue when facing a neverending horde'
+ },
horde_crown: {
name: 'Crown',
description: 'They used to rule the towers, but are now dethroned'
@@ -571,13 +619,21 @@ export default {
name: 'Tower key',
description: 'A rare key that allows you to access a tower'
},
+ horde_blood: {
+ name: 'Blood',
+ description: 'Eww!'
+ },
+ horde_lockpick: {
+ name: 'Lockpick',
+ description: 'Allows you to receive trinkets from already defeated bosses. Exclusive to the pirate'
+ },
farm_vegetable: {
name: 'Vegetable',
description: 'Eat your veggies!'
},
- farm_fruit: {
- name: 'Fruit',
- description: 'The fertile soil on this farm gives the fruit an intense taste'
+ farm_berry: {
+ name: 'Berry',
+ description: 'The fertile soil on this farm gives the berries an intense taste'
},
farm_grain: {
name: 'Grain',
@@ -631,6 +687,10 @@ export default {
name: 'Golden petal',
description: 'This extremely rare petal can only be found on roses. Rumors say the roses with these petals look darker than others'
},
+ farm_smallSeed: {
+ name: 'Small seed',
+ description: ''
+ },
gallery_beauty: {
name: 'Beauty',
description: 'This painting only gets more beautiful the more time you spend on it'
@@ -743,6 +803,54 @@ export default {
name: 'Pink drum',
description: ''
},
+ gallery_motivation: {
+ name: 'Motivation',
+ description: ''
+ },
+ gallery_mysteryShape: {
+ name: 'Mystery shape',
+ description: 'What is this shape? It looks strange, like it doesn\'t belong in this dimension'
+ },
+ gallery_circle: {
+ name: 'Circle',
+ description: ''
+ },
+ gallery_rectangle: {
+ name: 'Rectangle',
+ description: ''
+ },
+ gallery_triangle: {
+ name: 'Triangle',
+ description: 'Careful, those are dangerous'
+ },
+ gallery_star: {
+ name: 'Star',
+ description: ''
+ },
+ gallery_ellipse: {
+ name: 'Ellipse',
+ description: ''
+ },
+ gallery_heart: {
+ name: 'Heart',
+ description: '<3'
+ },
+ gallery_square: {
+ name: 'Square',
+ description: ''
+ },
+ gallery_octagon: {
+ name: 'Octagon',
+ description: ''
+ },
+ gallery_pentagon: {
+ name: 'Pentagon',
+ description: 'It\'s a shape, not a building'
+ },
+ gallery_hexagon: {
+ name: 'Hexagon',
+ description: ''
+ },
gallery_cash: {
name: 'Cash',
description: 'Easy money!'
@@ -759,6 +867,10 @@ export default {
name: 'Exam pass',
description: 'Strange, we didn\'t need them at our old school. Here they are needed to take an exam'
},
+ card_shinyDust: {
+ name: 'Shiny dust',
+ description: ''
+ },
treasure_fragment: {
name: 'Fragment',
description: 'Broken pieces of treasure'
diff --git a/src/lang/en/mult.js b/src/lang/en/mult.js
index 2c004fc9..3fc1d242 100644
--- a/src/lang/en/mult.js
+++ b/src/lang/en/mult.js
@@ -2,6 +2,7 @@ export default {
miningDamage: 'Damage',
miningToughness: 'Toughness',
miningOreGain: 'Ore gain',
+ miningOreCap: 'Ore capacity',
miningRareEarthGain: 'Rare earth gain',
miningPickaxeCraftingPower: 'Crafting power',
miningPickaxeCraftingSlots: 'Crafting slots',
@@ -21,7 +22,14 @@ export default {
currencyMiningRadonIncrement: 'Radon increment',
miningEnhancementBarsIncrement: 'Bar increment',
miningEnhancementFinalIncrement: 'Enhancement increment',
+ miningPrestigeIncome: 'Prestige income',
+ miningBeaconPiercing: 'Piercing beacon',
+ miningBeaconRich: 'Rich beacon',
+ miningBeaconWonder: 'Wonder beacon',
+ miningBeaconHope: 'Hope beacon',
villageWorker: 'Workers',
+ villageArtisan: 'Artisans',
+ villageCounter: 'Counters',
villageTaxRate: 'Tax rate',
queueSpeedVillageBuilding: 'Building speed',
villageOfferingPower: 'Offering power',
@@ -42,6 +50,9 @@ export default {
villagePower: 'Power',
villageLootGain: 'Loot gain',
villageLootQuality: 'Loot quality',
+ villageIngredientCount: 'Findable ingredients',
+ villageIngredientBoxAmount: 'Ingredients per box',
+ villagePrestigeIncome: 'Prestige income',
hordeAttack: 'Attack',
hordeHealth: 'Health',
hordeRecovery: 'Recovery',
@@ -54,6 +65,9 @@ export default {
hordeSpellblade: 'Spellblade',
hordeCutting: 'Cutting',
hordeDivisionShield: 'Division shield',
+ hordeDefense: 'Defense',
+ hordeExecute: 'Execute',
+ hordeHealing: 'Healing',
hordeStunResist: 'Stun resist',
hordeShieldbreak: 'Shieldbreak',
hordeEnemyActiveStart: 'Enemy start cooldown',
@@ -78,6 +92,22 @@ export default {
hordeItemMasteryGain: 'Mastery point gain',
hordeMinibossTime: 'Miniboss time',
hordeShardChance: 'Mystical shard chance',
+ hordeEnergy: 'Energy',
+ hordeEnergyRegen: 'Energy regeneration',
+ hordeMana: 'Mana',
+ hordeManaRegen: 'Mana regeneration',
+ hordeHaste: 'Haste',
+ hordeStrength: 'Strength',
+ hordeIntelligence: 'Intelligence',
+ hordeAutocast: 'Autocast slots',
+ hordeMaxTrinkets: 'Trinket capacity',
+ hordeExpBase: 'Level time',
+ hordeExpIncrement: 'Level increment',
+ hordeTrinketGain: 'Maximum trinket gain',
+ hordeTrinketQuality: 'Trinket quality',
+ hordeMaxSacrifice: 'Maximum sacrifice',
+ hordeSkillPointsPerLevel: 'Skill points per level',
+ hordePrestigeIncome: 'Prestige income',
powerHeirloomEffect: 'Power effect',
fortitudeHeirloomEffect: 'Fortitude effect',
wealthHeirloomEffect: 'Wealth effect',
@@ -98,6 +128,10 @@ export default {
farmDnaNext: 'Next prestige DNA',
farmCropGain: 'Crop gain',
farmAllGain: 'All harvest gain',
+ farmCropCost: 'Crop cost',
+ farmFertilizerCost: 'Fertilizer cost',
+ farmLuckyHarvestMult: 'Lucky harvest gain',
+ farmHuntChance: 'Hunt chance',
galleryInspirationBase: 'Inspiration time base',
galleryInspirationIncrement: 'Inspiration time increment',
galleryInspirationStart: 'Starting inspiration',
@@ -128,6 +162,11 @@ export default {
"galleryLight-blueDrumChance": 'Light blue drum chance',
galleryPinkConversion: 'Pink conversion',
galleryPinkDrumChance: 'Pink drum chance',
+ galleryShapeGain: 'Shape gain',
+ gallerySpecialShapeChance: 'Special shape chance',
+ gallerySpecialShapeMult: 'Special shape multiplier',
+ galleryCanvasSize: 'Canvas size',
+ galleryCanvasSpeed: 'Canvas speed',
miningCardCap: 'Mining card capacity',
villageCardCap: 'Village card capacity',
hordeCardCap: 'Horde card capacity',
@@ -185,6 +224,7 @@ export default {
summerFestivalMaterialStackCap: 'Material stack capacity',
nightHuntFindableIngredients: 'Findable ingredients',
nightHuntIngredientSize: 'Ingredient size',
+ nightHuntFavouriteIngredientSize: 'Favourite ingredient size',
nightHuntMaxIngredients: 'Ritual ingredients',
nightHuntBonusIngredientCount: 'Bonus ingredients',
nightHuntBonusIngredientAmount: 'Bonus ingredient amount',
diff --git a/src/lang/en/note.js b/src/lang/en/note.js
index e595fa73..6d341b2e 100644
--- a/src/lang/en/note.js
+++ b/src/lang/en/note.js
@@ -136,7 +136,7 @@ export default {
farm_14: 'Small lucky bugs. Also not stinky. Seem nice.',
farm_15: 'Farm is peaceful. Almost forget mass killing at horde.',
farm_16: 'Hunter of the garden. Keeps bugs in check.',
- farm_17: 'Pinwheel interesting. Place unique crops nearby. 8 spots around pinwheel. Find more gold. On the entire field.',
+ farm_17: 'Pinwheel interesting. Place unique crops nearby. 8 spots around pinwheel. Find more rare drops. On the entire field.',
farm_18: 'More fertilizers. More ways to spend gold and gems.',
farm_19: 'Litte bees. Always working. And numerous.',
farm_20: 'Flag complicated. Improves crops of a type. Type depends on position. Better read manual.',
diff --git a/src/lang/en/patchnote.js b/src/lang/en/patchnote.js
index dd457b5d..ea1c2c1e 100644
--- a/src/lang/en/patchnote.js
+++ b/src/lang/en/patchnote.js
@@ -17,19 +17,33 @@ export default {
remove: 'Removed',
change: 'Change',
accessibility: 'Accessibility',
- appearance: 'Appearance'
+ appearance: 'Appearance',
+ anticheat: 'Anticheat',
},
text: {
addedFeature: 'Added the feature',
+ addedSubfeature: 'Added the subfeature',
addedUpgrade: 'Added {0} new upgrade(s)',
addedPrestigeUpgrade: 'Added {0} new prestige upgrade(s)',
addedGemUpgrade: 'Added {0} new gem upgrade(s)',
addedBuilding: 'Added {0} new building(s)',
+ addedRelic: 'Added {0} relic(s)',
addedAchievement: 'Added {0} achievement(s)',
secretAchievement: 'Added {0} secret achievement(s)',
- addedHordeItem: 'Added {0} new equipment items',
- addedHordeSigil: 'Added {0} new sigils',
- addedHordeHeirloom: 'Added {0} new heirlooms',
+ addedHordeItem: 'Added {0} new equipment item(s)',
+ addedHordeSigil: 'Added {0} new sigil(s)',
+ addedHordeHeirloom: 'Added {0} new heirloom(s)',
+ addedVillageRecipe: 'Added {0} new crafting recipe(s)',
+ addedGalleryIdea: 'Added {0} new idea(s)',
+ addedOre: 'Added {0} new ore(s)',
+ addedRareEarth: 'Added {0} new rare earth(s)',
+ addedRareDrop: 'Added {0} new rare drop(s)',
+ addedGene: 'Added {0} new gene(s)',
+ addedCrop: 'Added {0} new crop(s)',
+ addedFertilizer: 'Added {0} new fertilizer(s)',
+ addedTower: 'Added {0} new tower(s)',
+ addedHordeClass: 'Added {0} new fighter class(es)',
+ addedTrinket: 'Added {0} new trinket(s)',
// v1.0.1
0: 'Slighlty increased the amount of scrap gained at the early mining depths',
@@ -358,6 +372,119 @@ export default {
297: 'Tier 4 offerings now increase their cost with each purchase',
298: 'Added a text shadow to the achievement message if it contains relics',
299: 'Increased the requirement for the "Mastermind" achievement after level 10',
+
+ // v1.4.2
+ '299_1': 'Fixed a game crash when the weather chaos event ends',
+ '299_2': 'Removed equipment capacity from horde cards',
+ '299_3': 'Removed equipment capacity from an event relic',
+ '299_4': 'Changed most genes to a linear scaling',
+
+ // v1.5.0
+ 300: 'You can now delete your savefile or reset single features',
+ 301: 'After reviewing the changes in the last update, it became clear that the new crop gene and card system greatly increased the power level of crops. Specializing crops, while intended, was pushing gains a little too far, so I\'m introducing a few changes to prevent players from focusing too hard on one type of crop gain',
+ 302: 'Added a gene upgrade to increase all crop gains that is available from the beginning',
+ 303: 'With 1-second-prestiges taking over the gallery, fundamental changes were necessary. In addition to balance changes, I also added a new mechanic to preserve some of the active aspects of the gallery without making it mandatory to progress',
+ 304: 'Slightly changed the color display',
+ 305: 'Converting colors now consumes the previous color once and all converters',
+ 306: 'Inspiration time stats are now shown in the tooltip',
+ 307: 'Added the shape minigame, an active way to increase your resource gains',
+ 308: 'Minibosses now show the correct amount of mastery points gained',
+ 309: 'Ember gain is now based on dweller depth',
+ 310: 'Exporting your savefile now properly resets the backup reminder for the exported file',
+ 311: 'You can now view statistics on the information page',
+ 312: 'Added the player card to statistics, which gives an overview of your progress',
+ 313: 'Added screen reader support for currencies and price tags',
+ 314: 'You can no longer equip the same card multiple times',
+ 315: 'Equipment mastery now shows the correct percentage for the next level',
+ 316: 'Changed the prestige formula to give more cash for higher amounts of beauty',
+ 317: 'The game now refuses to load edited savefiles',
+ 318: 'Players caught using cheats or automation tools will now have their player card marked with a cheater status',
+ 319: 'To prevent problematic cards from causing too many issues in the future, I am making a few changes to give them more generic stats. This should also help increase card diversity',
+ 320: 'Added card power, a new stat that gives generic effects for that feature',
+ 321: 'Reduced the effect of most cards to give them card power',
+ 322: 'Raised the price of later card packs',
+ 323: 'Increased the chance to receive rare cards',
+ 324: 'Obtainable rare drops are now shown as ???, as long as the chance is -10% or higher',
+ 325: 'Added a new dropdown menu to select crops',
+ 326: 'Converter gain is increased based on converters owned',
+ 327: 'Added canvas',
+ 328: 'Achievement levels are now downgraded if the requirement increased in a newer version',
+ 329: 'Most achievements now have a maximum level of 20',
+ 330: 'Village cryo lab gains',
+ 331: 'Reduced the tier of event treasures by 1',
+ 332: 'Base fragments from destroying event treasures',
+ 333: 'Fertilizer per event token',
+ 334: 'Renamed fruit to berries',
+ 335: 'Best harvest now counts crops on the field and does not require you to harvest them',
+ 336: 'Petal capacity per golden petal',
+ 337: 'Rare drops from cards are less likely to drop',
+ 338: 'Some crops now require currencies other than gold',
+ 339: 'Reduced the base drop chance of most rare drops, but rare drop chance is now easier to get',
+ 340: 'Reduced most fertilizer effects',
+ 341: 'The giant gene now increases crop and fertilizer cost by 4x, and cannot be chosen with plants of that crop on the field',
+ 342: 'You now gain tower keys even when the horde is frozen',
+ 343: 'Mystical shard chance is now reduced for each shard owned',
+ 344: 'Attack, health and bone gain per mystical shard',
+ 345: 'Changed some equipment actives to use the new buff system',
+ 346: 'Reduced the amount of toxicity and cutting',
+ 347: 'Speedrun achievements now have a maximum level of 10',
+ 348: 'The "Giant forge" upgrade is now active in other subfeatures',
+ 349: 'Scrap gain',
+ 350: 'Base price of the "Giant crate" upgrade',
+ 351: 'Scrap capacity per level of "Giant crate"',
+ 352: 'Added a maximum level to some prestige upgrades',
+ 353: 'Added smoke gain as treasure effect',
+ 354: 'Treasures now have an icon based on their effect',
+ 355: 'Reduced the effect of buildings and upgrades after the pyramid',
+ 356: 'Changed the primary color of the sky theme to be easier to read',
+ 357: 'You now get 50 rubies and 800 amethyst when unlocking the gem feature',
+ 358: 'You now get 100 emeralds when unlocking the card feature',
+ 359: 'You now get 500 topaz when unlocking the event feature',
+ 360: 'You now get 300 emeralds when unlocking the treasure feature',
+ 361: 'Reduce golden dust gain if you get over 2000 per exam',
+ 362: 'Reset and refunded tier 4 offerings, don\'t forget to buy them again!',
+ 363: 'Reset and refunded all prestige upgrades, don\'t forget to buy them again!',
+ 364: 'Reservoir ideas are less powerful, but the downside was removed',
+ 365: 'Gnome gene effect',
+ 366: 'The fertile gene effect now only increases yield and is based on sapphire cost of the fertilizer',
+ 367: 'The conversion gene no longer reduces its own yield and gain multipliers are taken for each yield type instead of the crop type',
+ 368: 'Conversion gene effect',
+ 369: 'Bosses now take more magical damage',
+ 370: 'Enemies with very high corruption levels get a new deadly effect',
+ 371: 'Corruption is now enabled in towers, based on the zone equivalent of the first floor',
+ 372: 'Pinwheel effect',
+ 373: 'Higher tier crops now require more experience',
+ 374: 'Reset gold and levels of the "Golden tools" upgrade for players with a high amount',
+ 375: 'Drums now require you to get the drum of the previous color when opening packages',
+ 376: 'Towers now always give their unique heirloom',
+ 377: 'Prestige gain now explains where you get it from',
+ 378: 'Primary effect of existing tower heirlooms',
+ 379: 'Changed the gold chance formula to favor crops with long grow times more',
+ 380: 'The farm now remembers your color settings',
+ 381: 'Added 2 new colors',
+ 382: 'Heirloom chance gained from the "Advanced luck" upgrade',
+ 383: 'Rare drop chance per ladybug',
+ 384: 'Ingredients now appear in larger stacks and consume 10 magic',
+ 385: 'Added the option to mark an ingredient as favourite',
+ 386: 'Sacks now appear for high magic amounts',
+ 387: 'Unequipped all horde equipment, don\'t forget to equip it again!',
+
+ // v1.5.1
+ 388: 'Fixed item actives with increasing crit efficiency not showing this on upgrade',
+ 389: 'Fixed currencies showing all in one column in some browsers',
+ 390: 'Converters needed per color tier',
+ 391: 'You now get more color per conversion if you have way more converters than color needed',
+ 392: 'Fixed card power not properly resetting on prestige',
+ 393: 'Fixed the class courage gain multiplier not properly resetting on prestige',
+ 394: 'The conversion tooltip now states that all converters will be used',
+
+ // v1.5.2
+ 395: 'Converter capacity per level of "Trash can"',
+
+ // v1.5.3
+ 396: 'Fixed a bug with offerings breaking when updating multiple versions at once',
+ 397: 'Bugged treasures from event rewards are now displayed correctly',
+ 398: 'Fixed a bug where crafting milestones displayed the wrong rewards',
},
v: {
1: {
@@ -366,7 +493,7 @@ export default {
2: 'Eco-friendly',
3: 'Neverending bosses',
4: 'Slow and steady',
- 5: '???',
+ 5: 'Handmade',
}
}
}
diff --git a/src/lang/en/relic.js b/src/lang/en/relic.js
index 9880b73c..2cd807e7 100644
--- a/src/lang/en/relic.js
+++ b/src/lang/en/relic.js
@@ -1,4 +1,7 @@
export default {
+ relics: 'Relics',
+ museum: 'Museum',
+
torch: 'Torch',
purpleHeart: 'Purple heart',
rottenLeaf: 'Rotten leaf',
@@ -71,6 +74,21 @@ export default {
simpleCalculator: 'Simple calculator',
orangeprint: 'Orangeprint',
yellowBalloon: 'Yellow balloon',
+ fishbowl: 'Fishbowl',
+ pencil: 'Pencil',
+ smallBrush: 'Small brush',
+ strangePills: 'Strange pills',
+ strangeScroll: 'Strange scroll',
+ printingPress: 'Printing press',
+ yellowprint: 'Yellowprint',
+ greenBalloon: 'Green balloon',
+ woodenHanger: 'Wooden hanger',
+ bedsheet: 'Bedsheet',
+ imageAlbum: 'Image album',
+ greenprint: 'Greenprint',
+ blueBalloon: 'Blue balloon',
+ blueprint: 'Blueprint',
+ purpleBalloon: 'Purple balloon',
tinfoilHat: 'Tinfoil hat',
cupOfWater: 'Cup of water',
combatStrategy: 'Combat strategy',
diff --git a/src/lang/en/stat.js b/src/lang/en/stat.js
index 5ea8e101..bb4500a4 100644
--- a/src/lang/en/stat.js
+++ b/src/lang/en/stat.js
@@ -69,6 +69,15 @@ export default {
mining_timeSpent: {
description: 'Time spent'
},
+ mining_bestPrestige0: {
+ description: 'Best prestige (ore mine)'
+ },
+ mining_bestPrestige1: {
+ description: 'Best prestige (gas giant)'
+ },
+ mining_prestigeCount: {
+ description: 'Prestiges'
+ },
// Village stats
village_maxBuilding: {
@@ -126,12 +135,24 @@ export default {
village_timeSpent: {
description: 'Time spent'
},
+ village_bestPrestige0: {
+ description: 'Best prestige (workers)'
+ },
+ village_bestPrestige1: {
+ description: 'Best prestige (crafters guild)'
+ },
+ village_prestigeCount: {
+ description: 'Prestiges'
+ },
// Horde stats
horde_maxZone: {
achievement: 'Explorer',
description: 'Maximum zone'
},
+ horde_maxDifficulty: {
+ description: 'Maximum difficulty'
+ },
horde_maxZoneSpeedrun: {
achievement: 'Swift strikes',
description: 'Maximum zone in under 30 minutes'
@@ -156,6 +177,10 @@ export default {
achievement: 'Shepherd of souls',
description: 'Corrupted souls gained'
},
+ horde_maxCorruptionKill: {
+ achievement: 'Challenging evil',
+ description: 'Highest corruption enemy defeated'
+ },
horde_maxMastery: {
achievement: 'One-trick',
description: 'Highest mastery level'
@@ -174,6 +199,15 @@ export default {
horde_timeSpent: {
description: 'Time spent'
},
+ horde_bestPrestige0: {
+ description: 'Best prestige (equipment)'
+ },
+ horde_bestPrestige1: {
+ description: 'Best prestige (classes)'
+ },
+ horde_prestigeCount: {
+ description: 'Prestiges'
+ },
// Farm stats
farm_harvests: {
@@ -192,9 +226,9 @@ export default {
achievement: 'Vegetarian',
description: 'Vegetables gained'
},
- farm_fruit: {
- achievement: 'Fruitarian',
- description: 'Fruits gained'
+ farm_berry: {
+ achievement: 'Berry good',
+ description: 'Berries gained'
},
farm_grain: {
achievement: 'Baker',
@@ -217,6 +251,9 @@ export default {
farm_butterflyMax: {
description: 'Highest butterfly amount'
},
+ farm_totalMystery: {
+ description: 'Mystery'
+ },
// Gallery stats
gallery_beauty: {
@@ -256,9 +293,28 @@ export default {
achievement: 'Dum dum dum',
description: 'Highest red drum amount'
},
+ gallery_shapeComboTotal: {
+ achievement: 'Collector',
+ description: 'Total shapes collected'
+ },
+ gallery_shapeComboHighest: {
+ achievement: 'Genius',
+ description: 'Highest shape combo'
+ },
+ gallery_canvasLevelTotal: {
+ achievement: 'Visionary',
+ description: 'Total canvas level'
+ },
+ gallery_hourglassHighest: {
+ achievement: 'Borrowed time',
+ description: 'Reach 1d of hourglass time'
+ },
gallery_timeSpent: {
description: 'Time spent'
},
+ gallery_prestigeCount: {
+ description: 'Prestiges'
+ },
// Meta stats
meta_totalLevel: {
diff --git a/src/lang/en/tag.js b/src/lang/en/tag.js
new file mode 100644
index 00000000..cb8d2f1b
--- /dev/null
+++ b/src/lang/en/tag.js
@@ -0,0 +1,15 @@
+export default {
+ hordeEnergyToStr: '+{0} strength per current energy',
+ hordeEnergyToEnergyReg: '+{0} energy regeneration per missing energy',
+ hordeEnergyOnCrit: '+{0} energy on critical hit',
+ hordeHealOnCrit: 'Heal {0} maximum health on critical hit',
+ hordeRestoreCooldownOnCrit: 'Reduce cooldowns by {0} on critical hit',
+ hordeBloodOnCrit: 'Gain {0} enemy blood on critical hit',
+ hordeManaRest: 'Gain {1} mana regeneration after not using actives for {0}',
+ hordeManasteal: 'Gain {0} mana on kill',
+ hordePassiveRecovery: 'Apply {0} of recovery each second',
+ hordeActiveDamageCrit: 'Damaging actives can crit at {0} efficiency',
+ hordeActiveHealCrit: 'Healing actives can crit at {0} efficiency',
+ hordeAttackAfterTime: 'Gain +{0} attack per minute in the same fight',
+ hordeStrIntAfterTime: 'Gain {0} strength and intelligence per minute in the same fight',
+}
diff --git a/src/lang/en/unlock.js b/src/lang/en/unlock.js
index 04d9aaa4..55eaa59c 100644
--- a/src/lang/en/unlock.js
+++ b/src/lang/en/unlock.js
@@ -12,6 +12,8 @@ export default {
miningCompressTitanium: 'Titanium compression',
miningCompressPlatinum: 'Platinum compression',
miningCompressIridium: 'Iridium compression',
+ miningCompressOsmium: 'Osmium compression',
+ miningCompressLead: 'Lead compression',
villageBuildings1: 'Tier 1 buildings',
villageBuildings2: 'Tier 2 buildings',
villageBuildings3: 'Tier 3 buildings',
@@ -51,12 +53,24 @@ export default {
villageOffering2: 'Tier 2 offerings',
villageOffering3: 'Tier 3 offerings',
villageOffering4: 'Tier 4 offerings',
+ villageSpecialIngredient: 'Special ingredients',
hordeCorruptedFlesh: 'Loot corrupted flesh',
+ hordeSacrifice: 'Sacrifice',
hordeChessItems: 'Chess equipment',
hordeUpgradeRoyalArmor: 'Royal armor upgrade',
hordeUpgradeRoyalStorage: 'Royal storage upgrade',
hordeUpgradeRoyalButcher: 'Royal butcher upgrade',
hordeUpgradeRoyalCrypt: 'Royal crypt upgrade',
+ hordeUpgradeRoyalSecret: 'Royal secret upgrade',
+ hordeClassArcher: 'Archer class',
+ hordeClassMage: 'Mage class',
+ hordeClassKnight: 'Knight class',
+ hordeClassAssassin: 'Assassin class',
+ hordeClassShaman: 'Shaman class',
+ hordeClassPirate: 'Pirate class',
+ hordeClassUndead: 'Undead class',
+ hordeClassCultist: 'Cultist class',
+ hordeClassScholar: 'Scholar class',
farmDisableEarlyGame: 'Disable "First crops"',
farmCropExp: 'Crop experience',
farmFertilizer: 'Fertilizer',
@@ -64,6 +78,8 @@ export default {
galleryInspiration: 'Inspiration',
galleryAuction: 'Auctions',
galleryDrums: 'Drums',
+ galleryShape: 'Shapes',
+ galleryCanvas: 'Canvas',
treasureDual: 'Dual treasure',
bloomPoppyFlower: 'Poppy',
bloomIrisFlower: 'Iris',
diff --git a/src/lang/en/upgrade.js b/src/lang/en/upgrade.js
index 5a720254..328803d4 100644
--- a/src/lang/en/upgrade.js
+++ b/src/lang/en/upgrade.js
@@ -64,6 +64,7 @@ export default {
gallery_epiphany: 'Ideas allow you to spend limited inspiration on unique bonuses',
gallery_auctionHouse: 'This gives you access to the prestige option of the gallery',
gallery_paintDrumStorage: 'This lets you collect packages, which sometimes contain drums',
+ gallery_emptyCanvas: 'Canvas lets you choose colors to slowly improve over time',
},
// Mining upgrades
@@ -125,7 +126,15 @@ export default {
mining_iridiumExpansion: 'Iridium expansion',
mining_iridiumCache: 'Iridium cache',
mining_iridiumTreetap: 'Iridium treetap',
+ mining_deepCuts: 'Deep cuts',
mining_iridiumBombs: 'Iridium bombs',
+ mining_oreBag: 'Ore bag',
+ mining_osmiumExpansion: 'Osmium expansion',
+ mining_osmiumCache: 'Osmium cache',
+ mining_darkBombs: 'Dark bombs',
+ mining_colossalScrapStorage: 'Colossal scrap storage',
+ mining_stoneDissolver: 'Stone dissolver',
+ mining_leadExpansion: 'Lead expansion',
mining_fumes: 'Fumes',
mining_giantCrate: 'Giant crate',
@@ -154,6 +163,8 @@ export default {
mining_crystalTitaniumStorage: 'Crystal titanium storage',
mining_crystalPlatinumStorage: 'Crystal platinum storage',
mining_crystalIridiumStorage: 'Crystal iridium storage',
+ mining_crystalOsmiumStorage: 'Crystal osmium storage',
+ mining_crystalLeadStorage: 'Crystal lead storage',
mining_crystalDetector: 'Crystal detector',
mining_crystalPreservarium: 'Crystal preservarium',
mining_crystalTools: 'Crystal tools',
@@ -168,6 +179,11 @@ export default {
mining_crystalCoal: 'Crystal coal',
mining_crystalTruck: 'Crystal truck',
mining_crystalExpansion: 'Crystal expansion',
+ mining_crystalTnt: 'Crystal TNT',
+ mining_crystalBeacon: 'Crystal beacon',
+ mining_crystalNiter: 'Crystal niter',
+ mining_crystalBunker: 'Crystal bunker',
+ mining_crystalOreBag: 'Crystal ore bag',
mining_crystalSpikes: 'Crystal spikes',
mining_crystalBooster: 'Crystal booster',
@@ -191,6 +207,8 @@ export default {
mining_moreTitanium: 'More titanium',
mining_morePlatinum: 'More platinum',
mining_moreIridium: 'More iridium',
+ mining_moreOsmium: 'More osmium',
+ mining_moreLead: 'More lead',
mining_premiumCraftingSlots: 'Premium crafting slots',
mining_moreGreenCrystal: 'More green crystals',
mining_moreRareEarth: 'More rare earth',
@@ -327,6 +345,19 @@ export default {
village_bartering: 'Bartering',
village_sparks: 'Sparks',
+ village_cashRegister: 'Cash register',
+ village_decoration: 'Decoration',
+ village_plantFiberBin: 'Plant fiber bin',
+ village_woodBin: 'Wood bin',
+ village_stoneBin: 'Stone bin',
+ village_metalBin: 'Metal bin',
+ village_waterBin: 'Water bin',
+ village_glassBin: 'Glass bin',
+ village_hardwoodBin: 'Hardwood bin',
+ village_gemBin: 'Gem bin',
+ village_oilBin: 'Oil bin',
+ village_marbleBin: 'Marble bin',
+
// Village prestige upgrades
village_arch: 'Ark',
village_holyTree: 'Holy tree',
@@ -355,6 +386,17 @@ export default {
village_holyLoot: 'Holy loot',
village_holyChisel: 'Holy chisel',
+ village_hireArtisans: 'Hire artisans',
+ village_hireExplorers: 'Hire explorers',
+ village_recipeBook: 'Recipe book',
+ village_hireWorkers: 'Hire workers',
+ village_adCampaign: 'Ad campaign',
+ village_hireAccountants: 'Hire accountants',
+ village_hireGardeners: 'Hire gardeners',
+ village_hireMiners: 'Hire miners',
+ village_hireBartenders: 'Hire bartenders',
+ village_hireExperts: 'Hire experts',
+
// Village premium upgrades
village_overtime: 'Overtime',
village_goldenThrone: 'Golden throne',
@@ -409,8 +451,24 @@ export default {
horde_grossBag: 'Gross bag',
horde_targetDummy: 'Target dummy',
horde_milestone: 'Milestone',
+ horde_combatLesson: 'Combat lesson',
horde_mysticalBag: 'Mystical bag',
+ horde_unlimitedAnger: 'Unlimited anger',
+ horde_strangePower: 'Strange power',
horde_collector: 'Collector',
+ horde_prepareTheSacrifice: 'Prepare the sacrifice',
+
+ horde_transfusion: 'Transfusion',
+ horde_darkAttack: 'Dark attack',
+ horde_darkHealth: 'Dark health',
+ horde_harvest: 'Harvest',
+ horde_protectiveShell: 'Protective shell',
+ horde_bloodStorage: 'Blood storage',
+ horde_darkMilestone: 'Dark milestone',
+ horde_endlessAnger: 'Endless anger',
+ horde_fistFight: 'Fist fight',
+ horde_syringe: 'Syringe',
+ horde_bloodRitual: 'Blood ritual',
// Horde prestige upgrades
horde_balance: 'Balance',
@@ -431,6 +489,21 @@ export default {
horde_lastWill: 'Last will',
horde_combatStudies: 'Combat studies',
horde_boneChamber: 'Bone chamber',
+ horde_deepHatred: 'Deep hatred',
+ horde_spiritLure: 'Spirit lure',
+ horde_mysticalCondenser: 'Mystical condenser',
+
+ horde_precision: 'Precision',
+ horde_resolve: 'Resolve',
+ horde_determination: 'Determination',
+ horde_education: 'Education',
+ horde_bloodChamber: 'Blood chamber',
+ horde_stoneSkin: 'Stone skin',
+ horde_university: 'University',
+ horde_discovery: 'Discovery',
+ horde_innerFocus: 'Inner focus',
+ horde_purge: 'Purge',
+ horde_chaosCrate: 'Chaos crate',
// Horde crown upgrades
horde_royalSword: 'Royal sword',
@@ -438,6 +511,7 @@ export default {
horde_royalStorage: 'Royal storage',
horde_royalButcher: 'Royal butcher',
horde_royalCrypt: 'Royal crypt',
+ horde_royalSecret: 'Royal secret',
// Horde premium upgrades
horde_morePower: 'More power',
@@ -478,6 +552,7 @@ export default {
farm_smallCrate: 'Small crate',
farm_sprinkler: 'Sprinkler',
farm_scarecrow: 'Scarecrow',
+ farm_anthill: 'Anthill',
farm_magnifyingGlass: 'Magnifying glass',
farm_bugPowder: 'Bug powder',
farm_shed: 'Shed',
@@ -496,11 +571,17 @@ export default {
farm_artificialWebs: 'Artificial webs',
farm_studyInsects: 'Study insects',
farm_beehive: 'Beehive',
+ farm_darkCorner: 'Dark corner',
farm_flag: 'Flag',
+ farm_wormBait: 'Worm bait',
+ farm_shinySoil: 'Shiny soil',
+ farm_bigFertilizerBag: 'Big fertilizer bag',
+ farm_openSesame: 'Open sesame',
+ farm_flowerPainting: 'Flower painting',
// Farm premium upgrades
farm_biggerVegetables: 'Bigger vegetables',
- farm_biggerFruits: 'Bigger fruits',
+ farm_biggerBerries: 'Bigger berries',
farm_biggerGrain: 'Bigger grain',
farm_biggerFlowers: 'Bigger flowers',
farm_moreExperience: 'More experience',
@@ -545,6 +626,48 @@ export default {
gallery_purplePower: 'Purple power',
gallery_blueLuck: 'Blue luck',
gallery_purpleConversion: 'Purple conversion',
+ gallery_deepOrangePower: 'Red-orange power',
+ gallery_purpleLuck: 'Purple luck',
+ gallery_deepOrangeConversion: 'Red-orange conversion',
+ gallery_emptyCanvas: 'Empty canvas',
+ gallery_linen: 'Linen',
+ gallery_amberPower: 'Golden power',
+ gallery_deepOrangeLuck: 'Red-orange luck',
+ gallery_amberConversion: 'Golden conversion',
+ gallery_lightGreenPower: 'Light green power',
+ gallery_amberLuck: 'Golden luck',
+ gallery_lightGreenConversion: 'Light green conversion',
+ gallery_tealPower: 'Teal power',
+ gallery_lightGreenLuck: 'Light green luck',
+ gallery_tealConversion: 'Teal conversion',
+ gallery_lightBluePower: 'Light blue power',
+ gallery_tealLuck: 'Teal luck',
+ gallery_lightBlueConversion: 'Light blue conversion',
+ gallery_pinkPower: 'Pink power',
+ gallery_lightBlueLuck: 'Light blue luck',
+ gallery_pinkConversion: 'Pink conversion',
+
+ // Gallery shape upgrades
+ gallery_bigCircle: 'Big circle',
+ gallery_wellDrawnCircle: 'Well drawn circle',
+ gallery_bigRectangle: 'Big rectangle',
+ gallery_wellDrawnRectangle: 'Well drawn rectangle',
+ gallery_creativity: 'Creativity',
+ gallery_wellDrawnTriangle: 'Well drawn triangle',
+ gallery_luckyStar: 'Lucky star',
+ gallery_wellDrawnStar: 'Well drawn star',
+ gallery_bigEllipse: 'Big ellipse',
+ gallery_wellDrawnEllipse: 'Well drawn ellipse',
+ gallery_bigHeart: 'Big heart',
+ gallery_wellDrawnHeart: 'Well drawn heart',
+ gallery_bigSquare: 'Big square',
+ gallery_wellDrawnSquare: 'Well drawn square',
+ gallery_bigOctagon: 'Big octagon',
+ gallery_wellDrawnOctagon: 'Well drawn octagon',
+ gallery_bigPentagon: 'Big pentagon',
+ gallery_wellDrawnPentagon: 'Well drawn pentagon',
+ gallery_bigHexagon: 'Big hexagon',
+ gallery_wellDrawnHexagon: 'Well drawn hexagon',
// Gallery prestige upgrades
gallery_artAcademy: 'Art academy',
@@ -552,13 +675,14 @@ export default {
gallery_rainbowJar: 'Rainbow jar',
gallery_trashContainer: 'Trash container',
gallery_orangeCrayon: 'Orange crayon',
- gallery_headstart: 'Headstart',
+ gallery_shapes: 'Shapes',
gallery_forklift: 'Forklift',
gallery_redCrate: 'Red crate',
gallery_yellowCrayon: 'Yellow crayon',
gallery_inspiringBooks: 'Inspiring books',
gallery_expressDelivery: 'Express delivery',
gallery_orangeCrate: 'Orange crate',
+ gallery_biggerShapes: 'Bigger shapes',
gallery_greenCrayon: 'Green crayon',
gallery_sortingSystem: 'Sorting system',
gallery_redTruck: 'Red truck',
@@ -566,17 +690,36 @@ export default {
gallery_blueCrayon: 'Blue crayon',
gallery_orangeTruck: 'Orange truck',
gallery_greenCrate: 'Green crate',
+ gallery_investment: 'Investment',
gallery_purpleCrayon: 'Purple crayon',
+ gallery_yellowTruck: 'Yellow truck',
+ gallery_blueCrate: 'Blue crate',
+ gallery_artClass: 'Art class',
+ gallery_preparation: 'Preparation',
+ gallery_deepOrangeCrayon: 'Red-orange crayon',
+ gallery_greenTruck: 'Green truck',
+ gallery_purpleCrate: 'Purple crate',
+ gallery_amberCrayon: 'Golden crayon',
+ gallery_truckConvoy: 'Truck convoy',
+ gallery_lightGreenCrayon: 'Light green crayon',
+ gallery_tealCrayon: 'Teal crayon',
+ gallery_lightBlueCrayon: 'Light blue crayon',
+ gallery_pinkCrayon: 'Pink crayon',
// Gallery premium upgrades
gallery_prettyColors: 'Pretty colors',
gallery_prettyConverter: 'Pretty converter',
gallery_prettyCash: 'Pretty cash',
+ gallery_prettyShapes: 'Pretty shapes',
+ gallery_prettyCanvas: 'Pretty canvas',
gallery_prettyRed: 'Pretty red',
gallery_prettyOrange: 'Pretty orange',
gallery_prettyYellow: 'Pretty yellow',
gallery_prettyGreen: 'Pretty green',
gallery_prettyBlue: 'Pretty blue',
+ gallery_prettyPurple: 'Pretty purple',
+ 'gallery_prettyDeep-orange': 'Pretty red-orange',
+ gallery_prettyAmber: 'Pretty gold',
// Gallery books
gallery_bookRedPower: 'Book: Red power',
diff --git a/src/store/achievement.js b/src/store/achievement.js
index fa19a92e..65f090cc 100644
--- a/src/store/achievement.js
+++ b/src/store/achievement.js
@@ -8,7 +8,7 @@ export default {
let arr = [];
for (const [key, elem] of Object.entries(state)) {
- if ((feature === null || elem.feature === feature) && (!elem.secret || elem.level > 0) && elem.value() > elem.default) {
+ if ((feature === null || elem.feature === feature) && (!elem.secret || elem.level > 0) && (elem.level > 0 || elem.value() > elem.default)) {
arr.push(key);
}
}
@@ -31,9 +31,10 @@ export default {
init(state, o) {
Vue.set(state, (o.feature ?? 'meta') + '_' + o.name, {
feature: o.feature ?? 'meta',
- cap: o.cap ?? null,
+ cap: o.cap ?? 20,
display: o.display ?? 'number',
level: 0,
+ cacheHideNotification: 0,
value: o.value ?? (() => 0),
default: o.default ?? 0,
milestones: o.milestones,
@@ -50,6 +51,41 @@ export default {
for (const [key] of Object.entries(state)) {
commit('updateKey', {name: key, key: 'level', value: 0});
}
+ },
+ reset({ state, commit }, feature) {
+ for (const [key, elem] of Object.entries(state)) {
+ if (elem.feature === feature && !elem.secret) {
+ commit('updateKey', {name: key, key: 'level', value: 0});
+ }
+ }
+ },
+ check({ state, rootState, commit, dispatch }) {
+ for (let [key, elem] of Object.entries(state)) {
+
+ const oldLevel = Math.max(elem.level, elem.cacheHideNotification);
+ const value = elem.value();
+ let gainedRelic = false;
+ while ((elem.cap === null || elem.level < elem.cap) && value >= elem.milestones(elem.level)) {
+
+ // Award relic if one is the reward
+ if (elem.relic[elem.level]) {
+ dispatch('relic/find', elem.relic[elem.level], {root: true});
+ gainedRelic = true;
+ }
+ commit('achievement/updateKey', {name: key, key: 'level', value: elem.level + 1}, {root: true});
+ elem = state[key];
+ }
+
+ // Create a notification if setting is on, also group multiple of the same achievement
+ if (rootState.system.settings.notification.items.achievement.value && elem.level > oldLevel) {
+ commit('system/addNotification', {color: elem.secret ? 'purple' : 'success', timeout: gainedRelic ? -1 : 5000, message: {
+ type: 'achievement',
+ name: key,
+ value: elem.level,
+ oldValue: oldLevel
+ }}, {root: true});
+ }
+ }
}
}
}
diff --git a/src/store/bloom.js b/src/store/bloom.js
index eb6b0bd1..5b983986 100644
--- a/src/store/bloom.js
+++ b/src/store/bloom.js
@@ -189,7 +189,7 @@ export default {
const statName = 'bloomMax' + capitalize(o.type);
const amount = Math.max(0, o.tier - rootState.stat['event_' + statName].value);
if (amount > 0) {
- dispatch('currency/gain', {feature: 'event', name: 'bloomToken', amount: amount * state.flower[o.type].tokens}, {root: true});
+ dispatch('event/giveTokens', {event: 'bloom', amount: amount * state.flower[o.type].tokens}, {root: true});
dispatch('note/find', 'event_14', {root: true});
}
commit('stat/increaseTo', {feature: 'event', name: statName, value: o.tier}, {root: true});
diff --git a/src/store/card.js b/src/store/card.js
index ed7a542a..2598b2fd 100644
--- a/src/store/card.js
+++ b/src/store/card.js
@@ -1,5 +1,5 @@
-import Vue from "vue"
-import { weightSelect } from "../js/utils/random";
+import Vue from "vue";
+import { chance, weightSelect } from "../js/utils/random";
export default {
namespaced: true,
@@ -21,8 +21,10 @@ export default {
id: o.id,
group: o.group ?? null,
instant: o.instant ?? false,
- reward: o.reward,
+ power: o.power ?? 0,
+ reward: o.reward ?? [],
amount: 0,
+ foundShiny: false,
collection: o.collection,
color: o.color ?? 'red',
icons: o.icons ?? []
@@ -34,7 +36,8 @@ export default {
name: o.name,
reward: o.reward,
cards: [],
- cacheCards: 0
+ cacheCards: 0,
+ cacheShinyCards: 0
});
},
initPack(state, o) {
@@ -46,11 +49,15 @@ export default {
cacheContent.push(key);
}
+ const amount = o.amount ?? 1;
+ const shinyPrice = (o.price !== null) ? Math.ceil(o.price / amount) : null;
+
Vue.set(state.pack, o.name, {
feature: o.feature ?? null,
price: o.price ?? null,
+ shinyPrice,
unlock: o.unlock ?? null,
- amount: o.amount ?? 1,
+ amount,
content: o.content,
cacheWeight,
cacheWeightTotal: cacheWeight.reduce((a, b) => a + b),
@@ -60,10 +67,13 @@ export default {
initFeature(state, o) {
Vue.set(state.feature, o.name, {
prefix: o.prefix,
- reward: o.reward,
+ reward: o.reward ?? [],
+ shinyReward: o.shinyReward ?? [],
+ powerReward: o.powerReward ?? [],
cardSelected: [],
cardEquipped: [],
- cacheCards: 0
+ cacheCards: 0,
+ cacheShinyCards: 0
});
},
updateKey(state, o) {
@@ -77,11 +87,13 @@ export default {
}
for (const [key] of Object.entries(state.collection)) {
commit('updateKey', {type: 'collection', name: key, key: 'cacheCards', value: 0});
+ commit('updateKey', {type: 'collection', name: key, key: 'cacheShinyCards', value: 0});
}
for (const [key] of Object.entries(state.feature)) {
commit('updateKey', {type: 'feature', name: key, key: 'cardSelected', value: []});
commit('updateKey', {type: 'feature', name: key, key: 'cardEquipped', value: []});
commit('updateKey', {type: 'feature', name: key, key: 'cacheCards', value: 0});
+ commit('updateKey', {type: 'feature', name: key, key: 'cacheShinyCards', value: 0});
}
},
buyPack({ state, rootState, rootGetters, dispatch }, o) {
@@ -97,13 +109,18 @@ export default {
let content = {};
for (let i = 0, n = o.amount; i < n; i++) {
let rngGen = rootGetters['system/getRng']('cardPack_' + o.name);
+ let rngGenShiny = rootGetters['system/getRng']('cardPackShiny_' + o.name);
for (let j = 0, m = pack.amount; j < m; j++) {
const cardChosen = pack.cacheContent[weightSelect(pack.cacheWeight, rngGen())];
const card = state.card[cardChosen];
if (content[cardChosen] === undefined) {
- content[cardChosen] = {amount: 0, isNew: card.amount <= 0};
+ content[cardChosen] = {amount: 0, shiny: 0, isNew: card.amount <= 0};
}
content[cardChosen].amount++;
+ const gotShiny = rootState.unlock.cardShiny.use && chance(rootGetters['mult/get']('cardShinyChance'), rngGenShiny());
+ if (gotShiny) {
+ content[cardChosen].shiny++;
+ }
if (card.amount <= 0) {
const feature = state.feature[card.feature];
const collection = state.collection[card.collection];
@@ -154,8 +171,26 @@ export default {
} else {
commit('updateKey', {type: 'card', name: cardChosen, key: 'amount', value: card.amount + 1});
}
+ if (gotShiny) {
+ if (card.foundShiny) {
+ // get shiny dust
+ dispatch('currency/gain', {feature: 'card', name: 'shinyDust', amount: 1}, {root: true});
+ } else {
+ // find shiny card
+ commit('updateKey', {type: 'card', name: cardChosen, key: 'foundShiny', value: true});
+
+ const feature = state.feature[card.feature];
+ const collection = state.collection[card.collection];
+ commit('updateKey', {type: 'collection', name: card.collection, key: 'cacheShinyCards', value: collection.cacheShinyCards + 1});
+ commit('updateKey', {type: 'feature', name: card.feature, key: 'cacheShinyCards', value: feature.cacheShinyCards + 1});
+ dispatch('applyFeatureEffects', card.feature);
+ }
+ }
}
commit('system/nextRng', {name: 'cardPack_' + o.name, amount: 1}, {root: true});
+ if (rootState.unlock.cardShiny.use) {
+ commit('system/nextRng', {name: 'cardPackShiny_' + o.name, amount: 1}, {root: true});
+ }
}
if (o.notify && rootState.system.settings.notification.items.cardPackContent.value) {
commit('system/addNotification', {color: 'success', timeout: 5000, message: {
@@ -172,21 +207,31 @@ export default {
// Reset existing caches
for (const [key] of Object.entries(state.collection)) {
commit('updateKey', {type: 'collection', name: key, key: 'cacheCards', value: 0});
+ commit('updateKey', {type: 'collection', name: key, key: 'cacheShinyCards', value: 0});
}
for (const [key] of Object.entries(state.feature)) {
commit('updateKey', {type: 'feature', name: key, key: 'cacheCards', value: 0});
+ commit('updateKey', {type: 'feature', name: key, key: 'cacheShinyCards', value: 0});
}
for (const [, elem] of Object.entries(state.card)) {
if (elem.amount > 0) {
commit('updateKey', {type: 'collection', name: elem.collection, key: 'cacheCards', value: state.collection[elem.collection].cacheCards + 1});
commit('updateKey', {type: 'feature', name: elem.feature, key: 'cacheCards', value: state.feature[elem.feature].cacheCards + 1});
}
+ if (elem.foundShiny) {
+ commit('updateKey', {type: 'collection', name: elem.collection, key: 'cacheShinyCards', value: state.collection[elem.collection].cacheShinyCards + 1});
+ commit('updateKey', {type: 'feature', name: elem.feature, key: 'cacheShinyCards', value: state.feature[elem.feature].cacheShinyCards + 1});
+ }
}
for (const [collKey, collElem] of Object.entries(state.collection)) {
if (collElem.cacheCards >= collElem.cards.length) {
collElem.reward.forEach(elem => {
dispatch('system/applyEffect', {type: elem.type, name: elem.name, multKey: `cardCollection_${ collKey }`, value: elem.value, trigger: false}, {root: true});
});
+ } else {
+ collElem.reward.forEach(elem => {
+ dispatch('system/resetEffect', {type: elem.type, name: elem.name, multKey: `cardCollection_${ collKey }`}, {root: true});
+ });
}
}
for (const [featKey] of Object.entries(state.feature)) {
@@ -197,9 +242,12 @@ export default {
activateCards({ state, commit, dispatch }, feature) {
state.feature[feature].cardEquipped.forEach(card => {
state.card[card].reward.forEach(eff => {
- dispatch('system/resetEffect', {type: eff.type, name: eff.name, multKey: `card_${card}`}, {root: true});
+ dispatch('system/resetEffect', {type: eff.type, name: eff.name, multKey: `card_${ card }`}, {root: true});
});
});
+ state.feature[feature].powerReward.forEach(elem => {
+ dispatch('system/resetEffect', {type: elem.type, name: elem.name, multKey: `cardPower_${ feature }`}, {root: true});
+ });
commit('updateKey', {type: 'feature', name: feature, key: 'cardEquipped', value: [...state.feature[feature].cardSelected]});
commit('updateKey', {type: 'feature', name: feature, key: 'cardSelected', value: []});
@@ -240,8 +288,10 @@ export default {
}
});
+ let cardPower = 0;
for (const [card, amount] of Object.entries(active)) {
let cardItem = state.card[card];
+ cardPower += (cardItem.power + (cardItem.foundShiny ? 1 : 0)) * amount;
cardItem.reward.forEach(elem => {
let value = elem.value;
if (['base', 'bonus'].includes(elem.type)) {
@@ -255,6 +305,11 @@ export default {
}
dispatch('system/applyEffect', {type: elem.type, name: elem.name, multKey: `card_${card}`, value, trigger: false}, {root: true});
});
+ if (cardPower > 0) {
+ state.feature[feature].powerReward.forEach(elem => {
+ dispatch('system/applyEffect', {type: elem.type, name: elem.name, multKey: `cardPower_${ feature }`, value: elem.value(cardPower), trigger: false}, {root: true});
+ });
+ }
}
},
applyFeatureEffects({ state, dispatch }, feature) {
@@ -262,7 +317,32 @@ export default {
state.feature[feature].reward.forEach(reward => {
dispatch('system/applyEffect', {type: reward.type, name: reward.name, multKey: `cards_${ feature }`, value: reward.value(state.feature[feature].cacheCards), trigger: true}, {root: true});
});
+ } else {
+ state.feature[feature].reward.forEach(reward => {
+ dispatch('system/resetEffect', {type: reward.type, name: reward.name, multKey: `cards_${ feature }`}, {root: true});
+ });
+ }
+ if (state.feature[feature].cacheShinyCards > 0) {
+ state.feature[feature].shinyReward.forEach(reward => {
+ dispatch('system/applyEffect', {type: reward.type, name: reward.name, multKey: `cardsShiny_${ feature }`, value: reward.value(state.feature[feature].cacheShinyCards), trigger: true}, {root: true});
+ });
+ } else {
+ state.feature[feature].shinyReward.forEach(reward => {
+ dispatch('system/resetEffect', {type: reward.type, name: reward.name, multKey: `cardsShiny_${ feature }`}, {root: true});
+ });
}
+ },
+ resetCards({ state, commit, dispatch }, feature) {
+ state.feature[feature].cardEquipped.forEach(card => {
+ state.card[card].reward.forEach(eff => {
+ dispatch('system/resetEffect', {type: eff.type, name: eff.name, multKey: `card_${card}`}, {root: true});
+ });
+ });
+ state.feature[feature].powerReward.forEach(elem => {
+ dispatch('system/resetEffect', {type: elem.type, name: elem.name, multKey: `cardPower_${ feature }`}, {root: true});
+ });
+ commit('updateKey', {type: 'feature', name: feature, key: 'cardEquipped', value: []});
+ commit('updateKey', {type: 'feature', name: feature, key: 'cardSelected', value: []});
}
}
}
diff --git a/src/store/cryolab.js b/src/store/cryolab.js
index 602ace0a..c294d862 100644
--- a/src/store/cryolab.js
+++ b/src/store/cryolab.js
@@ -26,7 +26,7 @@ export default {
for (const [, stat] of Object.entries(state[feature].data[subfeature])) {
const statValue = rootState.stat[stat].total;
if (statValue > 0) {
- const baseValue = stat === 'farm_bestPrestige' ? statValue : logBase(statValue, stat === 'horde_bestPrestige' ? 9 : 3);
+ const baseValue = stat === 'farm_bestPrestige' ? statValue : logBase(statValue, stat === 'horde_bestPrestige0' ? 9 : 3);
gain += baseValue * Math.pow(1.1, baseValue) * 40;
}
}
@@ -84,12 +84,13 @@ export default {
(o.effect ?? [[]]).forEach((effect, subfeature) => {
const activeMultName = `${ o.name }CryolabActive${ subfeature }`;
const passiveMultName = `${ o.name }CryolabPassive${ subfeature }`;
+ const featureMult = o.name === 'village' ? 0.4 : 1;
modifiedEffect.push([
- {name: activeMultName, type: 'base', value: lvl => lvl * 0.02},
- {name: passiveMultName, type: 'base', value: lvl => lvl * 0.01},
+ {name: activeMultName, type: 'base', value: lvl => lvl * featureMult * 0.02},
+ {name: passiveMultName, type: 'base', value: lvl => lvl * featureMult * 0.01},
...effect
]);
- commit('mult/init', {feature: 'cryolab', name: activeMultName, display: 'percent', baseValue: 0.25}, {root: true});
+ commit('mult/init', {feature: 'cryolab', name: activeMultName, display: 'percent', baseValue: 0.25 * featureMult}, {root: true});
commit('mult/init', {feature: 'cryolab', name: passiveMultName, display: 'percent'}, {root: true});
});
commit('init', {...o, effect: modifiedEffect});
@@ -123,6 +124,14 @@ export default {
value: eff.value(level)
}, {root: true});
});
+ } else {
+ state[o.feature].effect[o.subfeature].forEach(eff => {
+ dispatch('system/resetEffect', {
+ type: eff.type,
+ name: eff.name,
+ multKey: `cryolab_${ o.feature }_${ o.subfeature }`
+ }, {root: true});
+ });
}
},
}
diff --git a/src/store/currency.js b/src/store/currency.js
index 00156d6c..c44fcfcd 100644
--- a/src/store/currency.js
+++ b/src/store/currency.js
@@ -184,7 +184,7 @@ export default {
},
reset({ state, commit, dispatch }, o) {
for (const [key, elem] of Object.entries(state)) {
- if (elem.feature === o.feature && elem.type === o.type) {
+ if (elem.feature === o.feature && (o.type === undefined || elem.type === o.type)) {
commit('updateKey', {name: key, key: 'value', value: 0});
dispatch('updateCurrencyMult', key);
}
@@ -194,11 +194,11 @@ export default {
if (state[name].currencyMult) {
for (const [key, elem] of Object.entries(state[name].currencyMult)) {
const value = elem.value(getters.value(name));
- if (elem.type === 'mult' && value > 1) {
+ if (elem.type === 'mult' && value !== 1) {
dispatch('mult/setMult', {name: key, key: 'currencyMult_' + name, value}, {root: true});
- } else if (elem.type === 'base' && value > 0) {
+ } else if (elem.type === 'base' && value !== 0) {
dispatch('mult/setBase', {name: key, key: 'currencyMult_' + name, value}, {root: true});
- } else if (elem.type === 'bonus' && value > 0) {
+ } else if (elem.type === 'bonus' && value !== 0) {
dispatch('mult/setBonus', {name: key, key: 'currencyMult_' + name, value}, {root: true});
} else {
dispatch('mult/removeKey', {name: key, type: elem.type, key: 'currencyMult_' + name}, {root: true});
diff --git a/src/store/event.js b/src/store/event.js
index 925e926f..d253fe9e 100644
--- a/src/store/event.js
+++ b/src/store/event.js
@@ -167,7 +167,7 @@ export default {
if (elem.requirement() && elem.pool[pool]) {
const elemBase = {...elem, ...elem.pool[pool]};
if (elemBase.weight !== null && !(
- (elemBase.type === 'relic' && rootState.relic[elemBase.item].found) ||
+ (elemBase.type === 'relic' && rootState.relic.item[elemBase.item].found) ||
(elemBase.type === 'theme' && rootState.system.themes[elemBase.item].owned)
)) {
for (let i = 0; i < elem.times; i++) {
@@ -495,6 +495,7 @@ export default {
commit('nightHunt/updateKey', {key: 'performedRituals', value: []}, {root: true});
commit('nightHunt/updateKey', {key: 'ritualFamiliarity', value: {}}, {root: true});
commit('nightHunt/updateKey', {key: 'ritualHint', value: {}}, {root: true});
+ commit('nightHunt/updateKey', {key: 'favouriteIngredient', value: 'copy'}, {root: true});
for (const [key, elem] of Object.entries(rootState.nightHunt.potion)) {
commit('nightHunt/updatePotionKey', {name: key, key: 'recipe', value: null}, {root: true});
if (elem.level > 0) {
@@ -853,7 +854,7 @@ export default {
for (const [key, elem] of Object.entries(state.prize)) {
const elemBase = {...elem, ...elem.pool[pool]};
if (elem.requirement() && elem.pool[pool] && elemBase.weight === null && !(
- (elemBase.type === 'relic' && rootState.relic[elemBase.item].found) ||
+ (elemBase.type === 'relic' && rootState.relic.item[elemBase.item].found) ||
(elemBase.type === 'theme' && rootState.system.themes[elemBase.item].owned)
)) {
for (let i = 0; i < elemBase.times; i++) {
@@ -875,6 +876,10 @@ export default {
}
});
commit('updateKey', {key: pool === 'merchant' ? 'shop_merchant' : 'shop_big', value: [...chosen, ...randomPrizes]});
+ },
+ giveTokens({ commit, dispatch }, o) {
+ dispatch('currency/gain', {feature: 'event', name: o.event + 'Token', amount: o.amount}, {root: true});
+ commit('stat/add', {feature: 'event', name: o.event + 'Highscore', value: o.amount}, {root: true});
}
}
}
diff --git a/src/store/farm.js b/src/store/farm.js
index 00a6ed15..45d72301 100644
--- a/src/store/farm.js
+++ b/src/store/farm.js
@@ -1,6 +1,6 @@
import Vue from "vue"
import { capitalize } from "../js/utils/format";
-import { randomRound } from "../js/utils/random";
+import { chance, randomRound } from "../js/utils/random";
const fieldWidth = 7;
const fieldHeight = 7;
@@ -45,6 +45,8 @@ export default {
5: ['grow', 'overgrow', 'giant', 'grass'],
10: ['dna', 'gnome', 'lonely', 'fertile'],
15: ['mystery', 'conversion', 'prestige', 'rareDropChance'],
+ 20: ['lucky', 'finalize', 'selfless', 'unyielding'],
+ 25: ['teamwork', 'hunter', 'patient'],
},
fertilizer: {},
selectedCropName: null,
@@ -62,11 +64,14 @@ export default {
},
baseGoldChance: (state) => (name) => {
const crop = state.crop[name];
- return Math.pow(crop.grow, 0.5) * 0.008;
+ return (crop.grow >= 240 ? (Math.pow(crop.grow, 0.7) / Math.pow(240, 0.7)) : (Math.pow(crop.grow, 0.9) / Math.pow(240, 0.9))) * 0.08137;
},
- cropFertilizerCost: (state) => (name) => {
+ cropFertilizerCost: (state, getters, rootState, rootGetters) => (name) => {
const crop = state.crop[name];
- return Math.ceil(Math.pow(crop.grow, 0.4) * 0.12 + (crop.cost > 0 ? (Math.pow(crop.cost, 0.8) * 0.5) : 0));
+ const goldCost = crop.cost.farm_gold ?? 0;
+ const baseCost = Math.ceil(Math.pow(crop.grow, 0.4) * 0.12 + (goldCost > 0 ? (Math.pow(goldCost, 0.8) * 0.5) : 0));
+ const stats = getters.cropGeneStats(name);
+ return rootGetters['mult/get']('farmFertilizerCost', baseCost + stats.mult.farmFertilizerCost.baseValue, stats.mult.farmFertilizerCost.multValue);
},
currentPrestigeLevel: (state) => {
let totalPrestige = 0;
@@ -83,7 +88,7 @@ export default {
plantPrice: (state, getters, rootState, rootGetters) => (selectedCell = null, replace = false) => {
let fertilizerPrice = {};
let cells = [];
- let goldPrice = 0;
+ let plantPrice = {};
if (selectedCell) {
cells.push(selectedCell);
} else {
@@ -102,7 +107,13 @@ export default {
cells.forEach(coords => {
const cell = state.field[coords.y][coords.x];
const crop = replace ? cell.crop : state.selectedCropName;
- goldPrice += state.crop[crop].cost;
+ const costMult = rootGetters['mult/get']('farmCropCost', 1, getters.cropGeneStats(crop).mult.farmCropCost.multValue);
+ for (const [key, elem] of Object.entries(state.crop[crop].cost)) {
+ if (plantPrice[key] === undefined) {
+ plantPrice[key] = 0;
+ }
+ plantPrice[key] += elem * costMult;
+ }
const fertilizer = replace ? cell.fertilizer : state.selectedFertilizerName;
if (fertilizer !== null) {
const fertilizerName = 'farm_' + fertilizer;
@@ -114,11 +125,11 @@ export default {
});
let price = rootGetters['consumable/priceMultiple'](fertilizerPrice).price;
- if (goldPrice > 0) {
- if (price.farm_gold === undefined) {
- price.farm_gold = 0;
+ for (const [key, elem] of Object.entries(plantPrice)) {
+ if (price[key] === undefined) {
+ price[key] = 0;
}
- price.farm_gold += goldPrice;
+ price[key] += elem;
}
return price;
@@ -129,22 +140,20 @@ export default {
cropDnaGain: () => (level) => {
return level * 4 + 14;
},
- dnaRareDropChance: (state) => (name) => {
- const crop = state.crop[name];
- return (Math.pow(crop.grow / 10, 0.7) + Math.pow(crop.cost * 3, 0.65)) * 0.002 * Math.pow(crop.cost * 1.5 + 1, 0.6);
- },
cropGeneStats: (state, getters, rootState) => (name, fertilizer = null) => {
let stats = {
mult: {},
- rareDrop: {},
+ rareDrop: [],
tag: []
};
- ['farmCropGain', 'farmGoldChance', 'farmExperience', 'farmRareDropChance', 'farmGrow', 'farmOvergrow'].forEach(elem => {
+ ['farmCropGain', 'farmGoldChance', 'farmExperience', 'farmRareDropChance', 'farmGrow', 'farmOvergrow', 'farmCropCost', 'farmFertilizerCost', 'farmLuckyHarvestMult', 'farmHuntChance'].forEach(elem => {
stats.mult[elem] = {baseValue: 0, baseArray: [], multValue: 1, multArray: []};
});
const crop = state.crop[name];
+ const goldCost = crop.cost.farm_gold ?? 0;
const allGain = ['farmCropGain', 'farmGoldChance', 'farmExperience', 'farmRareDropChance'];
let active = {};
+ let cardPower = 0;
crop.cardEquipped.forEach(elem => {
if (active[elem]) {
active[elem]++;
@@ -154,6 +163,7 @@ export default {
});
for (const [card, amount] of Object.entries(active)) {
const cardItem = rootState.card.card[card];
+ cardPower += cardItem.power;
cardItem.reward.forEach(effect => {
let value = effect.value;
if (['base', 'bonus'].includes(effect.type)) {
@@ -167,10 +177,7 @@ export default {
}
switch (effect.type) {
case 'addRareDrop': {
- if (stats.rareDrop[effect.name] === undefined) {
- stats.rareDrop[effect.name] = 0;
- }
- stats.rareDrop[effect.name] += value;
+ stats.rareDrop.push({name: effect.name, amount: value, chance: effect.chance, mult: effect.mult ?? 1});
break;
}
case 'base': {
@@ -198,28 +205,52 @@ export default {
}
});
}
+ if (cardPower > 0) {
+ rootState.card.feature.farm.powerReward.forEach(effect => {
+ const value = effect.value(cardPower);
+ switch (effect.type) {
+ case 'base': {
+ if (stats.mult[effect.name]) {
+ stats.mult[effect.name].baseValue += value;
+ stats.mult[effect.name].baseArray.push({name: `cardPower_farm`, value: value});
+ }
+ break;
+ }
+ case 'mult': {
+ if (effect.name === 'farmAllGain') {
+ allGain.forEach(mult => {
+ stats.mult[mult].multValue *= value;
+ stats.mult[mult].multArray.push({name: `cardPower_farm`, value: value});
+ });
+ } else if (stats.mult[effect.name]) {
+ stats.mult[effect.name].multValue *= value;
+ stats.mult[effect.name].multArray.push({name: `cardPower_farm`, value: value});
+ }
+ break;
+ }
+ default:
+ console.warn(`Unknown card power effect ${ effect.type }`);
+ break;
+ }
+ });
+ }
crop.genes.forEach(elem => {
state.gene[elem].effect.forEach(effect => {
switch (effect.type) {
case 'text': {
stats.tag.push(effect.name);
if (effect.name === 'farmFertileBoost' && fertilizer !== null) {
- const fertilizerGrow = state.fertilizer[fertilizer].effect.farmGrow ?? 1;
- if (fertilizerGrow < 1) {
- const fertilizerBoost = (1 / fertilizerGrow - 1) * 0.3 + 1;
- allGain.forEach(mult => {
- stats.mult[mult].multValue *= fertilizerBoost;
- stats.mult[mult].multArray.push({name: `farmGene_${ elem }`, value: fertilizerBoost});
- });
+ const fertilizerPrice = rootState.consumable['farm_' + fertilizer].price;
+ if (fertilizerPrice !== null && fertilizerPrice.gem_sapphire > 0) {
+ const fertilizerBoost = fertilizerPrice.gem_sapphire * 0.3 + 1;
+ stats.mult.farmCropGain.multValue *= fertilizerBoost;
+ stats.mult.farmCropGain.multArray.push({name: `farmGene_${ elem }`, value: fertilizerBoost});
}
}
break;
}
case 'addRareDrop': {
- if (stats.rareDrop[effect.name] === undefined) {
- stats.rareDrop[effect.name] = 0;
- }
- stats.rareDrop[effect.name] = effect.value;
+ stats.rareDrop.push({name: effect.name, amount: effect.value, chance: effect.chance, mult: effect.mult ?? 1});
break;
}
case 'base': {
@@ -251,9 +282,11 @@ export default {
state.gene[key].upgrade.forEach(effect => {
switch (effect.type) {
case 'addRareDropAmount': {
- if (stats.rareDrop[effect.name] !== undefined) {
- stats.rareDrop[effect.name] += effect.value(elem);
- }
+ stats.rareDrop.forEach(rdrop => {
+ if (rdrop.name === effect.name) {
+ rdrop.amount += effect.value(elem);
+ }
+ });
break;
}
case 'base': {
@@ -281,6 +314,14 @@ export default {
}
});
}
+ stats.rareDrop.forEach(rdrop => {
+ rdrop.mult *= (Math.pow(crop.grow / 10, 0.7) + Math.pow(goldCost * 3, 0.65)) * 0.025 * Math.pow(goldCost * 1.5 + 1, 0.6);
+ });
+ if (stats.tag.includes('farmPatient') && crop.patientStacks > 0) {
+ const multValue = crop.patientStacks * 0.03 + 1;
+ stats.mult.farmCropGain.multValue *= multValue;
+ stats.mult.farmCropGain.multArray.push({name: `farmGene_patient`, value: multValue});
+ }
if (fertilizer) {
for (const [mult, value] of Object.entries(state.fertilizer[fertilizer].effect)) {
stats.mult[mult].multValue *= value;
@@ -301,12 +342,13 @@ export default {
}
},
initCrop(state, o) {
- const cost = o.cost ?? 0;
+ const cost = o.cost ?? {};
+ const goldCost = cost.farm_gold ?? 0;
const tier = o.tier ?? 0;
const rareDrop = o.rareDrop ? o.rareDrop.map(elem => {
- return {...elem, found: false};
+ return {...elem, mult: elem.mult ?? 1, found: false, hunter: 0};
}) : [];
- const baseExpMult = 1 / Math.pow(cost + 1, 0.6) / Math.pow(o.grow / 10, 0.7);
+ const baseExpMult = 1 / Math.pow(goldCost + 1, 0.6) / Math.pow(o.grow / 10, 0.7);
Vue.set(state.crop, o.name, {
found: o.found ?? false,
foundDefault: o.found ?? false,
@@ -314,7 +356,7 @@ export default {
color: o.color ?? 'green',
cost,
grow: o.grow ?? 60,
- yield: o.yield ?? ((Math.pow(o.grow / 10, 0.7) + Math.pow(cost * 3, 0.65)) * Math.pow(0.9, rareDrop.length) * 11 * Math.pow(1.05, tier) * Math.pow(cost * 1.5 + 1, 0.6)),
+ yield: o.yield ?? ((Math.pow(o.grow / 10, 0.7) + Math.pow(goldCost * 3, 0.65)) * Math.pow(0.9, rareDrop.length) * 11 * Math.pow(1.05, tier) * Math.pow(goldCost * 1.5 + 1, 0.6)),
rareDrop,
level: 0,
levelMax: 0,
@@ -325,9 +367,10 @@ export default {
cardEquipped: [],
upgrades: {},
exp: 0,
- baseExp: Math.pow(1.5, tier) * 60 * baseExpMult,
+ baseExp: Math.pow(1.6, tier) * 60 * baseExpMult,
baseExpMult,
- type: o.type
+ type: o.type,
+ patientStacks: 0
});
},
initBuilding(state, o) {
@@ -343,7 +386,8 @@ export default {
Vue.set(state.gene, o.name, {
icon: o.icon ?? 'mdi-dna',
effect: o.effect ?? (() => []),
- upgrade: o.upgrade ?? (() => [])
+ upgrade: o.upgrade ?? (() => []),
+ lockOnField: o.lockOnField ?? false
});
},
initFertilizer(state, o) {
@@ -404,6 +448,9 @@ export default {
},
findCropRareDrop(state, o) {
Vue.set(state.crop[o.name].rareDrop[o.index], 'found', true);
+ },
+ huntCropRareDrop(state, o) {
+ Vue.set(state.crop[o.name].rareDrop[o.index], 'hunter', o.value);
}
},
actions: {
@@ -427,26 +474,49 @@ export default {
commit('updateCropKey', {name: key, key: 'cardEquipped', value: []});
commit('updateCropKey', {name: key, key: 'upgrades', value: {}});
commit('updateCropKey', {name: key, key: 'found', value: elem.foundDefault});
+ commit('updateCropKey', {name: key, key: 'patientStacks', value: 0});
+ }
+
+ for (const [key] of Object.entries(state.building)) {
+ commit('updateBuildingKey', {name: key, key: 'max', value: 0});
+ commit('updateBuildingKey', {name: key, key: 'maxPremium', value: 0});
+ commit('updateBuildingKey', {name: key, key: 'cacheAmount', value: 0});
+ commit('updateBuildingKey', {name: key, key: 'cachePremium', value: 0});
}
},
plantCrop({ state, rootState, getters, rootGetters, commit, dispatch }, o) {
const field = state.field[o.y][o.x];
const crop = state.crop[o.crop];
- const price = crop.cost;
+ const costMult = rootGetters['mult/get']('farmCropCost', 1, getters.cropGeneStats(o.crop).mult.farmCropCost.multValue);
+ let price = {};
+ for (const [key, elem] of Object.entries(crop.cost)) {
+ price[key] = elem * costMult;
+ }
let fertilizerPrice = {};
+ let canAfford = true;
if (o.fertilizer !== null) {
fertilizerPrice['farm_' + o.fertilizer] = getters.cropFertilizerCost(o.crop);
+ for (const [key, elem] of Object.entries(rootGetters['consumable/priceMultiple'](fertilizerPrice).price)) {
+ if (price[key] === undefined) {
+ price[key] = 0;
+ }
+ price[key] += elem;
+ }
+ }
+ for (const [key, elem] of Object.entries(price)) {
+ if (rootGetters['currency/value'](key) < elem) {
+ canAfford = false;
+ }
}
- if (field !== null && field.type === null && (
- price <= 0 || rootGetters['currency/value']('farm_gold') >= price
- ) && (
+ if (field !== null && field.type === null && canAfford && (
o.fertilizer === null || (rootGetters['consumable/canAffordMultiple'](fertilizerPrice) && (state.fertilizer[o.fertilizer].type === 'all' || state.fertilizer[o.fertilizer].type === state.crop[o.crop].type))
)) {
if (o.fertilizer !== null) {
dispatch('consumable/useMultiple', fertilizerPrice, {root: true});
}
- if (price > 0) {
- dispatch('currency/spend', {feature: 'farm', name: 'gold', amount: price}, {root: true});
+ for (const [key, elem] of Object.entries(crop.cost)) {
+ const split = key.split('_');
+ dispatch('currency/spend', {feature: split[0], name: split[1], amount: elem * costMult}, {root: true});
}
commit('updateField', {x: o.x, y: o.y, value: {
type: 'crop',
@@ -473,7 +543,9 @@ export default {
const rngGen = rootGetters['system/getRngById'](`farmCrop_${ o.crop }`, field.rng);
const geneStats = getters.cropGeneStats(field.crop, field.fertilizer);
- const allGainBoost = 0.1 * (field.buildingEffect.gnomeBoost ?? 0) / field.time + 1;
+ const allGainBoost =
+ (0.04 * (field.buildingEffect.gnomeBoost ?? 0) / field.time + 1) *
+ ((geneStats.tag.includes('farmLuckyHarvest') && chance(0.01, rngGen())) ? rootGetters['mult/get']('farmLuckyHarvestMult', geneStats.mult.farmLuckyHarvestMult.baseValue) : 1);
// Gain currency based on crop type
const gainAmount = rootGetters['mult/get'](
@@ -481,12 +553,18 @@ export default {
crop.yield + geneStats.mult.farmCropGain.baseValue,
(((field.buildingEffect.flag ?? 0) / field.time) * 0.5 + 1) * geneStats.mult.farmCropGain.multValue
) * allGainBoost * field.grow;
+ dispatch('currency/gain', {feature: 'farm', name: crop.type, amount: gainAmount}, {root: true});
if (geneStats.tag.includes('farmYieldConversion')) {
- ['vegetable', 'fruit', 'grain', 'flower'].forEach(croptype => {
- dispatch('currency/gain', {feature: 'farm', name: croptype, amount: gainAmount * (crop.type === croptype ? 0.4 : 0.2)}, {root: true});
+ ['vegetable', 'berry', 'grain', 'flower'].forEach(croptype => {
+ if (crop.type !== croptype) {
+ const conversionAmount = rootGetters['mult/get'](
+ 'currencyFarm' + capitalize(croptype) + 'Gain',
+ crop.yield + geneStats.mult.farmCropGain.baseValue,
+ (((field.buildingEffect.flag ?? 0) / field.time) * 0.5 + 1) * geneStats.mult.farmCropGain.multValue
+ ) * allGainBoost * field.grow;
+ dispatch('currency/gain', {feature: 'farm', name: croptype, amount: conversionAmount * 0.05}, {root: true});
+ }
});
- } else {
- dispatch('currency/gain', {feature: 'farm', name: crop.type, amount: gainAmount}, {root: true});
}
// Chance to gain gold
@@ -503,21 +581,22 @@ export default {
}
// Chance to gain rare drops
- let geneDrops = [];
- for (const [name, elem] of Object.entries(geneStats.rareDrop)) {
- geneDrops.push({
- name,
+ let geneDrops = geneStats.rareDrop.map(elem => {
+ return {
+ name: elem.name,
type: 'currency',
- chance: getters.dnaRareDropChance(field.crop),
- value: elem,
+ chance: elem.chance,
+ mult: elem.mult,
+ value: elem.amount,
found: true
- });
- }
+ };
+ });
+ const pinwheelMult = (((field.buildingEffect.pinwheel ?? 0) / field.time) * 0.015) + 1;
[...crop.rareDrop, ...geneDrops].forEach((elem, index) => {
const times = randomRound(rootGetters['mult/get'](
'farmRareDropChance',
- elem.chance + (((field.buildingEffect.pinwheel ?? 0) / field.time) * 0.01) + geneStats.mult.farmRareDropChance.baseValue,
- geneStats.mult.farmRareDropChance.multValue
+ elem.chance + geneStats.mult.farmRareDropChance.baseValue,
+ geneStats.mult.farmRareDropChance.multValue * pinwheelMult * elem.mult
) * allGainBoost * field.grow, rngGen());
if (times > 0) {
switch (elem.type) {
@@ -540,18 +619,32 @@ export default {
}
});
+ // Chance to gain hunted rare drops
+ if (geneStats.tag.includes('farmHunter')) {
+ crop.rareDrop.forEach((elem, index) => {
+ const found = chance(rootGetters['mult/get'](
+ 'farmHuntChance',
+ elem.chance + geneStats.mult.farmRareDropChance.baseValue + geneStats.mult.farmHuntChance.baseValue - elem.hunter * 0.05,
+ geneStats.mult.farmRareDropChance.multValue * geneStats.mult.farmHuntChance.multValue * pinwheelMult * elem.mult
+ ) * allGainBoost * field.grow, rngGen());
+ if (found) {
+ commit('huntCropRareDrop', {name: field.crop, index, value: elem.hunter + 1});
+ dispatch('applyGeneEffects');
+ }
+ });
+ }
+
// Add exp if unlocked
if (rootState.unlock.farmCropExp.use) {
dispatch('getCropExp', {crop: field.crop, value: rootGetters['mult/get'](
'farmExperience',
- getters.baseGoldChance(field.crop) + geneStats.mult.farmExperience.baseValue,
+ geneStats.mult.farmExperience.baseValue,
(((field.buildingEffect.lectern ?? 0) / field.time) * 2 + 1) * geneStats.mult.farmExperience.multValue
) * allGainBoost * field.grow});
}
// Add stats
commit('stat/add', {feature: 'farm', name: 'harvests', value: 1}, {root: true});
- commit('stat/increaseTo', {feature: 'farm', name: 'maxOvergrow', value: field.grow}, {root: true});
// Unlock new notes
const note = notes[field.crop];
@@ -560,7 +653,14 @@ export default {
}
// Clear field
- commit('updateField', {x: o.x, y: o.y, value: {...emptyField, color: field.color}});
+ const freeReplant = geneStats.tag.includes('farmUnyielding') && chance(0.4, rngGen());
+ if (freeReplant) {
+ commit('updateFieldKey', {x: o.x, y: o.y, key: 'grow', value: 0});
+ commit('updateFieldKey', {x: o.x, y: o.y, key: 'rng', value: rootState.system.rng[`farmCrop_${ field.crop }`] ?? 0});
+ commit('system/nextRng', {name: `farmCrop_${ field.crop }`, amount: 1}, {root: true});
+ } else {
+ commit('updateField', {x: o.x, y: o.y, value: {...emptyField, color: field.color}});
+ }
dispatch('updateGrownHint');
if (!o.skipCache) {
@@ -717,6 +817,8 @@ export default {
applyCropPrestige({ getters, dispatch }) {
if (getters.currentPrestigeLevel > 0) {
dispatch('mult/setMult', {name: 'farmCropGain', key: 'prestige', value: getters.prestigeMult(getters.currentPrestigeLevel)}, {root: true});
+ } else {
+ dispatch('mult/removeKey', {name: 'farmCropGain', key: 'prestige', type: 'mult'}, {root: true});
}
},
updateCropGlobalLevel({ state, dispatch }) {
@@ -752,6 +854,7 @@ export default {
pickGene({ state, commit, dispatch }, o) {
commit('updateCropKey', {name: o.crop, key: 'genes', value: [...state.crop[o.crop].genes, o.gene] });
dispatch('updateFieldCaches');
+ dispatch('applyGeneEffects');
},
buyDnaUpgrade({ state, getters, commit, dispatch }, o) {
const crop = state.crop[o.crop];
@@ -865,7 +968,7 @@ export default {
flags.forEach(flag => {
if (
(crop.type === 'vegetable' && x < flag.x && y < flag.y) ||
- (crop.type === 'fruit' && x > flag.x && y < flag.y) ||
+ (crop.type === 'berry' && x > flag.x && y < flag.y) ||
(crop.type === 'grain' && x < flag.x && y > flag.y) ||
(crop.type === 'flower' && x > flag.x && y > flag.y)
) {
@@ -882,6 +985,50 @@ export default {
}
});
});
+ },
+ applyGeneEffects({ state, rootState, dispatch }) {
+ // Apply gene upgrades
+ let selflessAmount = 0
+ let teamworkActive = {
+ vegetable: false,
+ berry: false,
+ grain: false,
+ flower: false
+ };
+ for (const [, elem] of Object.entries(state.crop)) {
+ if (elem.genes.includes('selfless')) {
+ selflessAmount++;
+ }
+ if (elem.genes.includes('teamwork')) {
+ teamworkActive[elem.type] = true;
+ }
+ }
+ if (selflessAmount > 0) {
+ dispatch('mult/setMult', {name: 'farmCropGain', key: 'farmGene_selfless', value: selflessAmount * 0.05 + 1}, {root: true});
+ } else {
+ dispatch('mult/removeKey', {name: 'farmCropGain', key: 'farmGene_selfless', type: 'mult'}, {root: true});
+ }
+ if (teamworkActive.vegetable && teamworkActive.berry && teamworkActive.grain && teamworkActive.flower) {
+ dispatch('mult/setMult', {name: 'farmCropGain', key: 'farmGene_teamwork', value: 2}, {root: true});
+ } else {
+ dispatch('mult/removeKey', {name: 'farmCropGain', key: 'farmGene_teamwork', type: 'mult'}, {root: true});
+ }
+ let effect = {};
+ for (const [, elem] of Object.entries(state.crop)) {
+ elem.rareDrop.forEach(item => {
+ if (item.type === 'currency' && item.hunter > 0) {
+ if (effect[item.name] === undefined) {
+ effect[item.name] = 0;
+ }
+ effect[item.name] += item.hunter;
+ }
+ });
+ }
+ for (const [key, elem] of Object.entries(effect)) {
+ const split = key.split('_');
+ const capName = `currency${ capitalize(split[0]) + capitalize(split[1]) }Cap`;
+ dispatch('mult/setBase', {name: capName, key: 'farmGene_hunter', value: Math.round(rootState.mult.items[capName].baseValue / 10) * elem}, {root: true});
+ }
}
}
}
diff --git a/src/store/gallery.js b/src/store/gallery.js
index 18782176..470ca9bb 100644
--- a/src/store/gallery.js
+++ b/src/store/gallery.js
@@ -1,15 +1,22 @@
import Vue from "vue"
import { buildNum, capitalize } from "../js/utils/format";
import { logBase } from "../js/utils/math";
-import { randomRound } from "../js/utils/random";
+import { chance, randomElem, randomRound } from "../js/utils/random";
+import { GALLERY_CONVERTER_EXPONENT, GALLERY_MOTIVATION_BUY_AMOUNT, GALLERY_MOTIVATION_BUY_COST, GALLERY_REROLL_COST, GALLERY_SHAPES_GRID_HEIGHT, GALLERY_SHAPES_GRID_WIDTH } from "../js/constants";
+import { buildArray } from "../js/utils/array";
export default {
namespaced: true,
state: {
- color: ['red', 'orange', 'yellow', 'green', 'blue', 'purple', 'deep-orange', 'amber', 'light-green', 'teal', 'light-blue', 'pink'],
+ color: ['red', 'orange', 'yellow', 'green', 'blue', 'purple', 'deep-orange', 'amber', 'light-green', 'teal', 'light-blue', 'pink', 'brown', 'lime', 'pink-purple', 'grey'],
+ colorData: {},
inspirationTime: 0,
inspirationAmount: 0,
- idea: {}
+ idea: {},
+ shape: {},
+ shapeGrid: null,
+ hourglassCombo: 0,
+ canvasSpace: []
},
getters: {
availableColors: (state, getters, rootState) => {
@@ -21,33 +28,53 @@ export default {
return arr;
},
+ conversionColorPrice: (state) => (toColor) => {
+ const index = state.color.findIndex(c => c === toColor);
+ const fromColor = index < 1 ? 'beauty' : state.color[index - 1];
+ return {
+ name: `gallery_${fromColor}`,
+ amount: Math.pow(10, index) * 1000,
+ };
+ },
conversionPrice: (state) => (toColor) => {
const index = state.color.findIndex(c => c === toColor);
const fromColor = index < 1 ? 'beauty' : state.color[index - 1];
return {
[`gallery_${fromColor}`]: Math.pow(10, index) * 1000,
- gallery_converter: 1
+ gallery_converter: Math.pow(16, index) * 10
};
},
- maxAffordConversion: (state, getters, rootState, rootGetters) => (toColor) => {
- let maxAfford = Infinity;
- for (const [key, elem] of Object.entries(getters.conversionPrice(toColor))) {
- if (rootGetters['currency/value'](key) < elem) {
- maxAfford = 0;
- } else {
- maxAfford = Math.min(maxAfford, Math.floor(rootState.currency[key].value / elem));
- }
+ converterOverload: (state, getters, rootState) => (toColor) => {
+ const colorPrice = getters.conversionColorPrice(toColor);
+ const price = getters.conversionPrice(toColor);
+
+ const converterPercent = rootState.currency.gallery_converter.value / price.gallery_converter;
+ const colorPercent = rootState.currency[colorPrice.name].value / colorPrice.amount;
+ return Math.max(Math.pow(converterPercent / colorPercent, 0.25), 1);
+ },
+ conversionGain: (state, getters, rootState, rootGetters) => (toColor) => {
+ const colorPrice = getters.conversionColorPrice(toColor);
+ const price = getters.conversionPrice(toColor);
+
+ return Math.min(
+ rootState.currency.gallery_converter.value / price.gallery_converter,
+ rootState.currency[colorPrice.name].value / colorPrice.amount
+ ) * getters.converterOverload(toColor) * rootGetters['mult/get'](`gallery${ capitalize(toColor) }Conversion`);
+ },
+ prestigeGainBase: (state, getters, rootState) => {
+ if (rootState.stat.gallery_beauty.value < buildNum(1, 'T')) {
+ return 0;
}
- return maxAfford;
+ return Math.pow(10, Math.pow(logBase(rootState.stat.gallery_beauty.value / buildNum(100, 'B'), 8), 0.7));
},
prestigeGain: (state, getters, rootState, rootGetters) => {
if (rootState.stat.gallery_beauty.value < buildNum(1, 'T')) {
return 0;
}
- return Math.floor(rootGetters['mult/get']('currencyGalleryCashGain', Math.pow(10, Math.pow(logBase(rootState.stat.gallery_beauty.value / buildNum(100, 'B'), 10), 0.5))));
+ return Math.floor(rootGetters['mult/get']('currencyGalleryCashGain', getters.prestigeGainBase));
},
inspirationTimeNeeded: (state, getters, rootState, rootGetters) => (amount) => {
- return Math.pow(rootGetters['mult/get']('galleryInspirationIncrement') + 1, amount) * rootGetters['mult/get']('galleryInspirationBase');
+ return Math.ceil(Math.pow(rootGetters['mult/get']('galleryInspirationIncrement') + 1, amount) * rootGetters['mult/get']('galleryInspirationBase'));
},
inspirationTimeNeededCurrent: (state, getters) => {
return getters.inspirationTimeNeeded(state.inspirationAmount);
@@ -68,33 +95,112 @@ export default {
}
return previousTierCount >= (currentTierCount * 2);
+ },
+ shapeWeights: (state) => {
+ let arr = [];
+ for (const [key, elem] of Object.entries(state.shape)) {
+ if (!elem.isSpecial) {
+ arr.push(key);
+ if (elem.unlocked) {
+ arr.push(key);
+ }
+ }
+ }
+ return arr;
+ },
+ shapeSpecialWeights: (state) => {
+ let arr = [];
+ for (const [key, elem] of Object.entries(state.shape)) {
+ if (elem.isSpecial && elem.unlocked) {
+ arr.push(key);
+ }
+ }
+ return arr;
+ },
+ shapeHasHourglass: (state) => {
+ return state.shapeGrid.findIndex(row => row.findIndex(cell => cell === 'hourglass') !== -1) !== -1;
+ },
+ hourglassTime: (state) => {
+ return state.hourglassCombo * 13 + 300;
+ },
+ canvasDifficulty: (state) => (name, level) => {
+ const index = state.color.findIndex(c => c === name);
+ return Math.pow(3.25, index) * Math.pow(1.75, level) * buildNum(1, 'M');
}
},
mutations: {
updateKey(state, o) {
Vue.set(state, o.key, o.value);
},
+ updateColorDataKey(state, o) {
+ Vue.set(state.colorData[o.name], o.key, o.value);
+ },
updateIdeaKey(state, o) {
Vue.set(state.idea[o.name], o.key, o.value);
},
+ updateShapeKey(state, o) {
+ Vue.set(state.shape[o.name], o.key, o.value);
+ },
+ updateShapeCell(state, o) {
+ Vue.set(state.shapeGrid[o.y], o.x, o.value);
+ },
+ initColorData(state, o) {
+ Vue.set(state.colorData, o.name, {
+ progress: 0,
+ cacheSpace: 0
+ });
+ },
initIdea(state, o) {
Vue.set(state.idea, o.name, {
owned: o.owned ?? false,
+ ownedDefault: o.owned ?? false,
icon: o.icon ?? 'mdi-lightbulb',
color: o.color ?? 'primary',
tier: o.tier,
level: 0,
effect: o.effect ?? []
});
+ },
+ initShape(state, o) {
+ Vue.set(state.shape, o.name, {
+ unlocked: o.unlocked ?? false,
+ unlockedDefault: o.unlocked ?? false,
+ isSpecial: o.isSpecial ?? false,
+ icon: o.icon ?? 'mdi-shape',
+ color: o.color ?? 'primary'
+ });
+ },
+ initShapeGrid(state) {
+ Vue.set(state, 'shapeGrid', []);
+ let arr = ['circle'];
+ for (const [key, elem] of Object.entries(state.shape)) {
+ if (!elem.isSpecial) {
+ arr.push(key);
+ }
+ }
+ for (let y = 0; y < GALLERY_SHAPES_GRID_HEIGHT; y++) {
+ state.shapeGrid.push(buildArray(GALLERY_SHAPES_GRID_WIDTH).map(() => randomElem(arr)));
+ }
}
},
actions: {
cleanState({ state, commit }) {
commit('updateKey', {key: 'inspirationTime', value: 0});
commit('updateKey', {key: 'inspirationAmount', value: 0});
- for (const [key] of Object.entries(state.idea)) {
+ for (const [key, elem] of Object.entries(state.idea)) {
commit('updateIdeaKey', {name: key, key: 'level', value: 0});
+ commit('updateIdeaKey', {name: key, key: 'owned', value: elem.ownedDefault});
}
+ for (const [key, elem] of Object.entries(state.shape)) {
+ commit('updateShapeKey', {name: key, key: 'unlocked', value: elem.unlockedDefault});
+ }
+ for (const [key] of Object.entries(state.colorData)) {
+ commit('updateColorDataKey', {name: key, key: 'progress', value: 0});
+ commit('updateColorDataKey', {name: key, key: 'cacheSpace', value: 0});
+ }
+ commit('updateKey', {key: 'shapeGrid', value: null});
+ commit('updateKey', {key: 'hourglassCombo', value: 0});
+ commit('updateKey', {key: 'canvasSpace', value: []});
},
prestige({ state, getters, rootGetters, commit, dispatch }) {
commit('stat/increaseTo', {feature: 'gallery', name: 'bestPrestige', value: getters.prestigeGain}, {root: true});
@@ -109,6 +215,10 @@ export default {
dispatch('applyIdeaReset', key);
}
}
+ commit('updateKey', {key: 'canvasSpace', value: []});
+ for (const [key] of Object.entries(state.colorData)) {
+ commit('updateColorDataKey', {name: key, key: 'cacheSpace', value: 0});
+ }
dispatch('upgrade/reset', {feature: 'gallery', type: 'regular'}, {root: true});
dispatch('currency/reset', {feature: 'gallery', type: 'regular'}, {root: true});
@@ -121,17 +231,21 @@ export default {
}
},
convertColor({ getters, rootGetters, dispatch }, o) {
- const amount = o.max ? getters.maxAffordConversion(o.toColor) : 1;
-
- for (const [key, elem] of Object.entries(getters.conversionPrice(o.toColor))) {
- dispatch('currency/spend', {feature: key.split('_')[0], name: key.split('_')[1], amount: elem * amount}, {root: true});
+ const price = getters.conversionPrice(o.toColor);
+ if (rootGetters['currency/canAfford'](price)) {
+ dispatch('currency/gain', {
+ feature: 'gallery',
+ name: o.toColor,
+ amount: getters.conversionGain(o.toColor)
+ }, {root: true});
+ for (const [key, elem] of Object.entries(price)) {
+ if (key === 'gallery_converter') {
+ dispatch('currency/spendAll', {feature: key.split('_')[0], name: key.split('_')[1]}, {root: true});
+ } else {
+ dispatch('currency/spend', {feature: key.split('_')[0], name: key.split('_')[1], amount: elem}, {root: true});
+ }
+ }
}
-
- dispatch('currency/gain', {
- feature: 'gallery',
- name: o.toColor,
- amount: amount * rootGetters['mult/get'](`gallery${ capitalize(o.toColor) }Conversion`)
- }, {root: true});
},
applyIdea({ state, dispatch }, o) {
let trigger = o.onBuy ?? false;
@@ -156,18 +270,332 @@ export default {
const amount = Math.floor(rootState.currency.gallery_package.value);
if (amount > 0) {
let rngGen = rootGetters['system/getRng']('gallery_package');
- [...state.color].reverse().forEach(color => {
- const drumChance = rootGetters['mult/get'](`gallery${ capitalize(color) }DrumChance`);
- if (drumChance > 0) {
- const drums = randomRound(drumChance * amount, rngGen());
- if (drums > 0) {
- dispatch('currency/gain', {feature: 'gallery', name: color + 'Drum', amount: drums}, {root: true});
- }
+ let num = amount;
+ [...state.color].map(color => {
+ num = randomRound(rootGetters['mult/get'](`gallery${ capitalize(color) }DrumChance`) * num, rngGen());
+ return {color, amount: num};
+ }).reverse().forEach(obj => {
+ if (obj.amount > 0) {
+ dispatch('currency/gain', {feature: 'gallery', name: obj.color + 'Drum', amount: obj.amount}, {root: true});
}
});
commit('system/nextRng', {name: 'gallery_package', amount: 1}, {root: true});
dispatch('currency/spend', {feature: 'gallery', name: 'package', amount}, {root: true});
}
+ },
+ switchShape({ state, rootGetters, commit, dispatch }, o) {
+ const fromTile = state.shapeGrid[o.fromY][o.fromX];
+ const toTile = state.shapeGrid[o.toY][o.toX];
+ if (rootGetters['currency/canAfford']({gallery_motivation: 1})) {
+ commit('updateShapeCell', {x: o.fromX, y: o.fromY, value: toTile});
+ commit('updateShapeCell', {x: o.toX, y: o.toY, value: fromTile});
+ dispatch('currency/spend', {feature: 'gallery', name: 'motivation', amount: 1}, {root: true});
+ }
+ },
+ clickShape({ state, rootState, getters, rootGetters, commit, dispatch }, o) {
+ if (rootGetters['currency/canAfford']({gallery_motivation: 1})) {
+ const shapeName = state.shapeGrid[o.y][o.x];
+ if (state.shape[shapeName].isSpecial) {
+ switch (shapeName) {
+ case 'bomb': {
+ let connectedGrid = [];
+ for (let y = 0; y < GALLERY_SHAPES_GRID_HEIGHT; y++) {
+ connectedGrid.push(buildArray(GALLERY_SHAPES_GRID_WIDTH).map(x => x === o.x || y === o.y));
+ }
+ connectedGrid.forEach((row, y) => {
+ row.forEach((cell, x) => {
+ const cellName = state.shapeGrid[y][x];
+ if (cell && state.shape[cellName].unlocked && !state.shape[cellName].isSpecial) {
+ dispatch('currency/gain', {feature: 'gallery', name: cellName, gainMult: true, amount: rootGetters['mult/get']('gallerySpecialShapeMult')}, {root: true});
+ commit('stat/add', {feature: 'gallery', name: 'shapeComboTotal', value: 1}, {root: true});
+ }
+ });
+ });
+ dispatch('rerollShapes', connectedGrid);
+ break;
+ }
+ case 'dice': {
+ const selectedCell = state.shapeGrid[o.y <= 0 ? (o.y + 1) : (o.y - 1)][o.x];
+ const connectedGrid = state.shapeGrid.map(row => row.map(cell => cell !== selectedCell));
+ dispatch('rerollShapes', connectedGrid);
+ break;
+ }
+ case 'accelerator': {
+ let connectedGrid = [];
+ for (let y = 0; y < GALLERY_SHAPES_GRID_HEIGHT; y++) {
+ connectedGrid.push(buildArray(GALLERY_SHAPES_GRID_WIDTH).map(x => Math.abs(x - o.x) <= 1 && Math.abs(y - o.y) <= 1));
+ }
+ const targetShape = (o.x > 0 && o.y > 0) ? state.shapeGrid[o.y - 1][o.x - 1] : null;
+ let sameAmount = 0;
+ connectedGrid.forEach((row, y) => {
+ row.forEach((cell, x) => {
+ const cellName = state.shapeGrid[y][x];
+ if (cell && state.shape[cellName].unlocked && !state.shape[cellName].isSpecial) {
+ if (cellName === targetShape) {
+ sameAmount++;
+ }
+ dispatch('currency/gain', {feature: 'gallery', name: cellName, gainMult: true, amount: rootGetters['mult/get']('gallerySpecialShapeMult')}, {root: true});
+ commit('stat/add', {feature: 'gallery', name: 'shapeComboTotal', value: 1}, {root: true});
+ }
+ });
+ });
+ if (sameAmount >= 8) {
+ const motivation = Math.floor(rootState.currency.gallery_motivation.value);
+ dispatch('currency/gain', {feature: 'gallery', name: targetShape, gainMult: true, amount: (motivation / 5 + 1) * rootGetters['mult/get']('gallerySpecialShapeMult')}, {root: true});
+ dispatch('currency/spend', {feature: 'gallery', name: 'motivation', amount: motivation}, {root: true});
+ }
+ dispatch('rerollShapes', connectedGrid);
+ break;
+ }
+ case 'sparkles': {
+ let coords = [];
+ if (o.x > 0) {
+ coords.push({x: o.x - 1, y: o.y});
+ }
+ if (o.y > 0) {
+ coords.push({x: o.x, y: o.y - 1});
+ }
+ if (o.x < (GALLERY_SHAPES_GRID_WIDTH - 1)) {
+ coords.push({x: o.x + 1, y: o.y});
+ }
+ if (o.y < (GALLERY_SHAPES_GRID_HEIGHT - 1)) {
+ coords.push({x: o.x, y: o.y + 1});
+ }
+ let combinedGrid = [];
+ for (let y = 0; y < GALLERY_SHAPES_GRID_HEIGHT; y++) {
+ combinedGrid.push(buildArray(GALLERY_SHAPES_GRID_WIDTH).map(x => x === o.x && y === o.y));
+ }
+ coords.forEach(coord => {
+ let connectedGrid = [];
+ for (let y = 0; y < GALLERY_SHAPES_GRID_HEIGHT; y++) {
+ connectedGrid.push(buildArray(GALLERY_SHAPES_GRID_WIDTH).map(x => x === coord.x && y === coord.y));
+ }
+ let changed = true;
+ while (changed) {
+ changed = false;
+ connectedGrid.forEach((row, y) => {
+ row.forEach((cell, x) => {
+ if (!cell) {
+ if (
+ (x > 0 && connectedGrid[y][x - 1] && state.shapeGrid[y][x] === state.shapeGrid[y][x - 1]) ||
+ (y > 0 && connectedGrid[y - 1][x] && state.shapeGrid[y][x] === state.shapeGrid[y - 1][x]) ||
+ (x < (GALLERY_SHAPES_GRID_WIDTH - 1) && connectedGrid[y][x + 1] && state.shapeGrid[y][x] === state.shapeGrid[y][x + 1]) ||
+ (y < (GALLERY_SHAPES_GRID_HEIGHT - 1) && connectedGrid[y + 1][x] && state.shapeGrid[y][x] === state.shapeGrid[y + 1][x])
+ ) {
+ connectedGrid[y][x] = true;
+ changed = true;
+ }
+ }
+ });
+ });
+ }
+ const amount = connectedGrid.reduce((a, b) => a + b.reduce((c, d) => c + (d ? 1 : 0), 0), 0);
+ if (amount >= 5) {
+ connectedGrid.forEach((row, y) => {
+ row.forEach((cell, x) => {
+ if (cell) {
+ combinedGrid[y][x] = true;
+ }
+ });
+ });
+ }
+ });
+ const totalAmount = combinedGrid.reduce((a, b) => a + b.reduce((c, d) => c + (d ? 1 : 0), 0), 0) - 1;
+ combinedGrid.forEach((row, y) => {
+ row.forEach((cell, x) => {
+ if (cell) {
+ const thisShapeName = state.shapeGrid[y][x];
+ if (state.shape[thisShapeName].unlocked && !state.shape[thisShapeName].isSpecial) {
+ dispatch('currency/gain', {feature: 'gallery', name: thisShapeName, gainMult: true, amount: totalAmount}, {root: true});
+ }
+ }
+ });
+ });
+ commit('stat/increaseTo', {feature: 'gallery', name: 'shapeComboHighest', value: totalAmount}, {root: true});
+ commit('stat/add', {feature: 'gallery', name: 'shapeComboTotal', value: totalAmount}, {root: true});
+ dispatch('rerollShapes', combinedGrid);
+ break;
+ }
+ case 'hourglass': {
+ commit('stat/increaseTo', {feature: 'gallery', name: 'hourglassHighest', value: getters.hourglassTime}, {root: true});
+ dispatch('packageAndConverterTick', getters.hourglassTime);
+ commit('updateKey', {key: 'hourglassCombo', value: 0});
+ let connectedGrid = [];
+ for (let y = 0; y < GALLERY_SHAPES_GRID_HEIGHT; y++) {
+ connectedGrid.push(buildArray(GALLERY_SHAPES_GRID_WIDTH).map(x => o.x === x && o.y === y));
+ }
+ dispatch('rerollShapes', connectedGrid);
+ break;
+ }
+ case 'chest': {
+ let connectedGrid = [];
+ for (let y = 0; y < GALLERY_SHAPES_GRID_HEIGHT; y++) {
+ connectedGrid.push(buildArray(GALLERY_SHAPES_GRID_WIDTH).map(x => (Math.abs(x - o.x) <= 1 && Math.abs(y - o.y) <= 1) || (Math.abs(x - o.x) === 2 && Math.abs(y - o.y) === 0)));
+ }
+ let shapeList = [];
+ connectedGrid.forEach((row, y) => {
+ row.forEach((cell, x) => {
+ const cellName = state.shapeGrid[y][x];
+ if (cell && !state.shape[cellName].isSpecial) {
+ if (!shapeList.includes(cellName)) {
+ shapeList.push(cellName);
+ }
+ if (state.shape[cellName].unlocked) {
+ dispatch('currency/gain', {feature: 'gallery', name: cellName, gainMult: true, amount: rootGetters['mult/get']('gallerySpecialShapeMult')}, {root: true});
+ commit('stat/add', {feature: 'gallery', name: 'shapeComboTotal', value: 1}, {root: true});
+ }
+ }
+ });
+ });
+ if (shapeList.length >= 10) {
+ dispatch('currency/gain', {feature: 'gallery', name: 'mysteryShape', amount: 1}, {root: true});
+ }
+ dispatch('rerollShapes', connectedGrid);
+ break;
+ }
+ default:
+ console.warn(`Unknown shape: ${ shapeName }`);
+ break;
+ }
+ if (rootGetters['currency/canAfford']({gallery_motivation: 1})) {
+ dispatch('currency/spend', {feature: 'gallery', name: 'motivation', amount: 1}, {root: true});
+ }
+ } else {
+ let connectedGrid = [];
+ for (let y = 0; y < GALLERY_SHAPES_GRID_HEIGHT; y++) {
+ connectedGrid.push(buildArray(GALLERY_SHAPES_GRID_WIDTH).map(x => x === o.x && y === o.y));
+ }
+ let changed = true;
+ while (changed) {
+ changed = false;
+ connectedGrid.forEach((row, y) => {
+ row.forEach((cell, x) => {
+ if (!cell) {
+ if (
+ (x > 0 && connectedGrid[y][x - 1] && state.shapeGrid[y][x] === state.shapeGrid[y][x - 1]) ||
+ (y > 0 && connectedGrid[y - 1][x] && state.shapeGrid[y][x] === state.shapeGrid[y - 1][x]) ||
+ (x < (GALLERY_SHAPES_GRID_WIDTH - 1) && connectedGrid[y][x + 1] && state.shapeGrid[y][x] === state.shapeGrid[y][x + 1]) ||
+ (y < (GALLERY_SHAPES_GRID_HEIGHT - 1) && connectedGrid[y + 1][x] && state.shapeGrid[y][x] === state.shapeGrid[y + 1][x])
+ ) {
+ connectedGrid[y][x] = true;
+ changed = true;
+ }
+ }
+ });
+ });
+ }
+ const amount = connectedGrid.reduce((a, b) => a + b.reduce((c, d) => c + (d ? 1 : 0), 0), 0);
+ if (amount >= 5) {
+ if (state.shape[shapeName].unlocked && !state.shape[shapeName].isSpecial) {
+ dispatch('currency/gain', {feature: 'gallery', name: shapeName, gainMult: true, amount: Math.pow(amount, 2)}, {root: true});
+ commit('stat/increaseTo', {feature: 'gallery', name: 'shapeComboHighest', value: amount}, {root: true});
+ commit('stat/add', {feature: 'gallery', name: 'shapeComboTotal', value: amount}, {root: true});
+ }
+ dispatch('currency/spend', {feature: 'gallery', name: 'motivation', amount: 1}, {root: true});
+ if (getters.shapeHasHourglass) {
+ commit('updateKey', {key: 'hourglassCombo', value: state.hourglassCombo + amount});
+ }
+ dispatch('rerollShapes', connectedGrid);
+ }
+ }
+ }
+ },
+ buyShapeReroll({ rootGetters, dispatch }) {
+ if (rootGetters['currency/canAfford']({gallery_motivation: GALLERY_REROLL_COST})) {
+ let connectedGrid = [];
+ for (let y = 0; y < GALLERY_SHAPES_GRID_HEIGHT; y++) {
+ connectedGrid.push(buildArray(GALLERY_SHAPES_GRID_WIDTH).map(() => true));
+ }
+ dispatch('rerollShapes', connectedGrid);
+ dispatch('currency/spend', {feature: 'gallery', name: 'motivation', amount: GALLERY_REROLL_COST}, {root: true});
+ }
+ },
+ rerollShapes({ state, getters, rootGetters, commit }, grid) {
+ const weights = getters.shapeWeights;
+ const specialWeights = getters.shapeSpecialWeights;
+ let hasSpecial = specialWeights.length > 0 && state.shapeGrid.reduce((a, b) => a + b.reduce((c, d) => c + (state.shape[d].isSpecial ? 1 : 0), 0), 0) <= 0;
+ const specialChance = rootGetters['mult/get']('gallerySpecialShapeChance');
+ grid.forEach((row, y) => {
+ row.forEach((cell, x) => {
+ if (cell) {
+ if (hasSpecial && chance(specialChance)) {
+ commit('updateShapeCell', {x, y, value: randomElem(specialWeights)});
+ hasSpecial = false;
+ } else {
+ commit('updateShapeCell', {x, y, value: randomElem(weights)});
+ }
+ }
+ });
+ });
+ },
+ packageAndConverterTick({ rootState, rootGetters, dispatch }, seconds) {
+ if (rootState.unlock.galleryConversion.use) {
+ let secondsLeft = seconds;
+ const baseGain = rootGetters['mult/get']('currencyGalleryConverterGain');
+ const amount = rootGetters['currency/value']('gallery_converter');
+ const cap = rootState.currency.gallery_converter.cap;
+ let gain = amount;
+ while (secondsLeft > 0) {
+ const nextGain = gain * Math.pow(1 + GALLERY_CONVERTER_EXPONENT, 100) + baseGain * 100 + (baseGain * 50) * 0.268999110;
+ if (secondsLeft < 100 || nextGain >= cap) {
+ break;
+ }
+ gain = nextGain;
+ secondsLeft -= 100;
+ }
+ while (secondsLeft > 0) {
+ if (gain > cap) {
+ gain += secondsLeft * (baseGain + cap * GALLERY_CONVERTER_EXPONENT);
+ secondsLeft = 0;
+ } else {
+ gain += baseGain + Math.min(gain, cap) * GALLERY_CONVERTER_EXPONENT;
+ secondsLeft--;
+ }
+ }
+ if (gain > amount) {
+ dispatch('currency/gain', {feature: 'gallery', name: 'converter', amount: gain - amount}, {root: true});
+ }
+ }
+ if (rootState.unlock.galleryDrums.use) {
+ dispatch('currency/gain', {feature: 'gallery', name: 'package', amount: seconds * rootGetters['mult/get']('currencyGalleryPackageGain')}, {root: true});
+ }
+ },
+ addCanvasSpace({ state, rootGetters, commit }, name) {
+ if (state.canvasSpace.length < rootGetters['mult/get']('galleryCanvasSize')) {
+ commit('updateKey', {key: 'canvasSpace', value: [...state.canvasSpace, name]});
+ commit('updateColorDataKey', {name, key: 'cacheSpace', value: state.colorData[name].cacheSpace + 1});
+ }
+ },
+ removeCanvasSpace({ state, commit }, name) {
+ if (state.colorData[name].cacheSpace > 0) {
+ let arr = [...state.canvasSpace].reverse();
+ const colorIndex = arr.findIndex(elem => elem === name);
+ if (colorIndex !== -1) {
+ arr.splice(colorIndex, 1);
+ commit('updateKey', {key: 'canvasSpace', value: arr.reverse()});
+ }
+ commit('updateColorDataKey', {name, key: 'cacheSpace', value: state.colorData[name].cacheSpace - 1});
+ }
+ },
+ applyCanvasLevel({ state, dispatch }, o) {
+ let trigger = o.onLevel ?? false;
+ const level = Math.floor(state.colorData[o.name].progress);
+ if (level > 0) {
+ dispatch('system/applyEffect', {type: 'mult', name: `currencyGallery${ capitalize(o.name) }Gain`, multKey: `galleryCanvas_${o.name}`, value: Math.pow(2, level), trigger}, {root: true});
+ dispatch('system/applyEffect', {type: 'mult', name: `gallery${ capitalize(o.name) }Conversion`, multKey: `galleryCanvas_${o.name}`, value: Math.pow(2, level), trigger}, {root: true});
+ dispatch('system/applyEffect', {type: 'base', name: `currencyGallery${ capitalize(o.name) }DrumCap`, multKey: `galleryCanvas_${o.name}`, value: 25 * level, trigger}, {root: true});
+ } else {
+ dispatch('system/resetEffect', {type: 'mult', name: `currencyGallery${ capitalize(o.name) }Gain`, multKey: `galleryCanvas_${o.name}`}, {root: true});
+ dispatch('system/resetEffect', {type: 'mult', name: `gallery${ capitalize(o.name) }Conversion`, multKey: `galleryCanvas_${o.name}`}, {root: true});
+ dispatch('system/resetEffect', {type: 'base', name: `currencyGallery${ capitalize(o.name) }DrumCap`, multKey: `galleryCanvas_${o.name}`}, {root: true});
+ }
+ },
+ buyMotivation({ rootGetters, commit, dispatch }) {
+ if (rootGetters['currency/value']('gem_sapphire') >= GALLERY_MOTIVATION_BUY_COST) {
+ commit('currency/add', {feature: 'gallery', name: 'motivation', amount: GALLERY_MOTIVATION_BUY_AMOUNT}, {root: true});
+ commit('stat/add', {feature: 'gallery', name: 'motivation', value: GALLERY_MOTIVATION_BUY_AMOUNT}, {root: true});
+ dispatch('currency/spend', {feature: 'gem', name: 'sapphire', amount: GALLERY_MOTIVATION_BUY_COST}, {root: true});
+ }
}
}
}
diff --git a/src/store/horde.js b/src/store/horde.js
index ff38d373..a7f5b235 100644
--- a/src/store/horde.js
+++ b/src/store/horde.js
@@ -1,7 +1,7 @@
import Vue from "vue";
-import { HORDE_COMBO_ATTACK, HORDE_COMBO_BONE, HORDE_COMBO_HEALTH, HORDE_ENEMY_RESPAWN_MAX, HORDE_ENEMY_RESPAWN_TIME, HORDE_HEIRLOOM_MIN_ZONE, HORDE_HEIRLOOM_TOWER_FLOORS, HORDE_KEYS_PER_TOWER, HORDE_MASTERY_MINIBOSS_MULT, HORDE_MINIBOSS_MIN_ZONE, HORDE_SHARD_INCREMENT, HORDE_SHARD_PER_EQUIP } from "../js/constants";
-import { buildNum, capitalize } from "../js/utils/format";
-import { chance, randomElem, randomInt } from "../js/utils/random";
+import { HORDE_COMBO_ATTACK, HORDE_COMBO_BONE, HORDE_COMBO_HEALTH, HORDE_ENEMY_RESPAWN_MAX, HORDE_ENEMY_RESPAWN_TIME, HORDE_HEIRLOOM_MIN_ZONE, HORDE_HEIRLOOM_TOWER_FLOORS, HORDE_KEYS_PER_TOWER, HORDE_LEVEL_MIN_SECONDS, HORDE_MASTERY_MINIBOSS_MULT, HORDE_MINIBOSS_MIN_ZONE, HORDE_SHARD_INCREMENT, HORDE_SHARD_PER_EQUIP } from "../js/constants";
+import { buildNum, capitalize, decapitalize } from "../js/utils/format";
+import { chance, randomElem, randomInt, randomRound, weightSelect } from "../js/utils/random";
import { logBase } from "../js/utils/math";
const notes = {
@@ -36,6 +36,10 @@ const notes = {
107: 'horde_30',
};
+const BATTLE_PASS_COMBAT_REWARD = 1.5;
+const BATTLE_PASS_LOOT_REWARD = 1.3;
+const BATTLE_PASS_PRESTIGE_REWARD = 1.4;
+
export default {
namespaced: true,
state: {
@@ -65,13 +69,53 @@ export default {
tower: {},
currentTower: null,
towerFloor: 0,
- taunt: false
+ taunt: false,
+ fighterClass: {},
+ selectedClass: 'adventurer',
+ nextClass: 'adventurer',
+ area: {},
+ selectedArea: null,
+ cachePlayerStats: null,
+ cacheEnemyStats: null,
+ playerBuff: {},
+ expLevel: 0,
+ skillPoints: 0,
+ skillLevel: {},
+ skillActive: {},
+ trinket: {},
+ battlePassEffect: {},
+ enemyType: {},
+ areaBoss: {},
+ autocast: [],
+ activeTimer: 0,
+ trinketAmountNeeded: [1, 8, 36, 150, 600, 2350, 9000, 33000, 115000, 380000],
+ trinketDrop: null,
+ bossStage: 0,
+ bossBonusDifficulty: 0,
+ sacrificeLevel: 0,
+ nextSacrificeLevel: 0,
},
getters: {
- enemyStats: () => (zone, combo = 0) => {
+ playerBaseStats: (state, getters, rootState) => {
+ const subfeature = rootState.system.features.horde.currentSubfeature;
+ switch (subfeature) {
+ case 0:
+ return {
+ attack: 5,
+ health: 500
+ };
+ case 1:
+ return state.fighterClass[state.selectedClass].baseStats;
+ default:
+ return {};
+ }
+ },
+ enemyStats: (state, getters, rootState) => (difficulty, combo = 0, baseAttack = 2, baseHealth = 50) => {
+ const subfeature = rootState.system.features.horde.currentSubfeature;
+ const statMult = subfeature === 1 ? 2000 : 1;
return {
- attack: Math.pow(2.1, zone) * Math.pow(HORDE_COMBO_ATTACK, combo) * 2,
- health: Math.pow(2.1, zone) * Math.pow(HORDE_COMBO_HEALTH, combo) * 50,
+ attack: Math.pow(2.1, difficulty) * Math.pow(HORDE_COMBO_ATTACK, combo) * statMult * baseAttack,
+ health: Math.pow(2.1, difficulty) * Math.pow(HORDE_COMBO_HEALTH, combo) * statMult * baseHealth,
critChance: 0,
critMult: 0.5,
revive: 0,
@@ -80,6 +124,8 @@ export default {
cutting: 0,
divisionShield: 0,
stunResist: 0,
+ defense: 0,
+ execute: 0,
// Damage type specifics
physicConversion: 1,
@@ -99,40 +145,59 @@ export default {
enemyBone: () => (zone, combo = 0) => {
return Math.pow(1.6, zone) * (combo * HORDE_COMBO_BONE + 1) * 90;
},
+ enemyBlood: () => (difficulty, combo = 0) => {
+ return Math.pow(1.5, difficulty) * (combo * HORDE_COMBO_BONE + 1) * 2;
+ },
enemyMonsterPart: () => (zone) => {
return Math.pow(1.1, zone - 10) * 0.2;
},
enemyCorruption: (state, getters, rootState, rootGetters) => (zone) => {
return rootGetters['mult/get']('hordeCorruption', getters.enemyCorruptionBase(zone));
},
- enemyCorruptionBase: () => (zone) => {
- return Math.max(0, (zone - 40) * 0.1);
+ enemyCorruptionBase: (state, getters, rootState) => (zone) => {
+ const subfeature = rootState.system.features.horde.currentSubfeature;
+ const baseValue = subfeature === 1 ? 2.5 : -4;
+ return Math.max(0, zone * 0.1 + baseValue);
},
currentBone: (state, getters) => {
return getters.enemyBone(state.zone, state.combo);
},
+ currentBlood: (state, getters) => {
+ if (state.selectedArea === null) {
+ return 0;
+ }
+ return getters.enemyBlood(state.area[state.selectedArea].zones[state.zone].difficulty, state.combo);
+ },
currentMonsterPart: (state, getters) => {
return getters.enemyMonsterPart(state.zone);
},
- currentCorruption: (state, getters) => {
- return getters.enemyCorruption(state.zone);
+ currentCorruption: (state, getters, rootState) => {
+ const subfeature = rootState.system.features.horde.currentSubfeature;
+ const tower = state.currentTower !== null ? state.tower[state.currentTower] : null;
+ return getters.enemyCorruption(tower ? tower.statBase : (subfeature === 1 ? state.area[state.selectedArea].zones[state.zone].difficulty : state.zone));
},
- currentCorruptionBase: (state, getters) => {
- return getters.enemyCorruptionBase(state.zone);
+ currentCorruptionBase: (state, getters, rootState) => {
+ const subfeature = rootState.system.features.horde.currentSubfeature;
+ const tower = state.currentTower !== null ? state.tower[state.currentTower] : null;
+ return getters.enemyCorruptionBase(tower ? tower.statBase : (subfeature === 1 ? state.area[state.selectedArea].zones[state.zone].difficulty : state.zone));
},
- currentCorruptionStats: (state, getters) => {
+ currentCorruptionStats: (state, getters, rootState) => {
const corruption = getters.currentCorruption;
+ const subfeature = rootState.system.features.horde.currentSubfeature;
let stats = {};
if (corruption > 0) {
stats.power = 1.2 * Math.pow(0.005 * corruption + 1.01, corruption * 100);
}
- if (corruption >= 0.5) {
+ if (corruption >= 0.5 && subfeature === 0) {
stats.sigil = Math.floor(corruption * 2);
}
if (corruption >= 1.25) {
stats.revive = Math.floor(corruption / 1.25);
}
+ if (corruption >= 10) {
+ stats.execute = 0.9 - Math.pow(14 / 15, corruption / 2 - 4) * 0.75;
+ }
return stats;
},
@@ -167,6 +232,15 @@ export default {
}
return i;
},
+ trinketsEquipped: (state) => {
+ let i = 0;
+ for (const [, elem] of Object.entries(state.trinket)) {
+ if (elem.equipped) {
+ i++;
+ }
+ }
+ return i;
+ },
itemsActiveList: (state) => {
let obj = {};
for (const [key, elem] of Object.entries(state.items)) {
@@ -190,16 +264,10 @@ export default {
return Math.pow(10, lvl) * Math.pow(1.04, item.findZone) * (item.unlock === 'hordeChessItems' ? buildNum(20, 'K') : 500);
},
baseRespawnTime: (state) => {
- return state.zone * 3 + 12;
- },
- maxMysticalShards: (state) => {
- let i = 0;
- for (const [, elem] of Object.entries(state.items)) {
- if (elem.equipped && elem.masteryLevel >= 5) {
- i += (elem.masteryLevel - 5) * HORDE_SHARD_INCREMENT + HORDE_SHARD_PER_EQUIP;
- }
+ if (state.selectedArea !== null) {
+ return state.area[state.selectedArea].zones[state.zone].difficulty + 912;
}
- return i;
+ return state.zone * 3 + 12;
},
canSpawnMiniboss: (state, getters, rootState) => {
return rootState.stat.horde_maxZone.value >= HORDE_MINIBOSS_MIN_ZONE;
@@ -209,7 +277,68 @@ export default {
},
masteryBaseGain: (state) => (name) => {
return state.zone - state.items[name].findZone - 24;
- }
+ },
+ expIncrement: (state, getters, rootState, rootGetters) => (className) => {
+ const incLowerLimit = className === 'scholar' ? 1.12 : 1.15;
+ return rootGetters['mult/get']('hordeExpIncrement', state.fighterClass[className].exp.increment - incLowerLimit) + incLowerLimit;
+ },
+ expDifficulty: (state, getters, rootState, rootGetters) => (lvl) => {
+ return Math.max(HORDE_LEVEL_MIN_SECONDS, Math.pow(getters.expIncrement(state.selectedClass), lvl) * rootGetters['mult/get']('hordeExpBase', state.fighterClass[state.selectedClass].exp.base));
+ },
+ classLevelEffect: () => (lvl) => {
+ return [
+ {name: 'currencyHordeCourageGain', type: 'base', value: lvl >= 10 ? ((lvl - 8) * 2 * Math.pow(1.175, lvl - 10)) : 0},
+ {name: 'currencyHordeBloodGain', type: 'mult', value: Math.pow(1.175, lvl)},
+ {name: 'currencyHordeBloodCap', type: 'mult', value: Math.pow(1.5, lvl)},
+ ];
+ },
+ battlePassEffectAtLevel: (state) => (lvl) => {
+ if (lvl <= 0) {
+ return null;
+ } else if (state.battlePassEffect[lvl] !== undefined) {
+ return {...state.battlePassEffect[lvl], isSpecial: true};
+ } else {
+ const finalLevel = lvl - Object.keys(state.battlePassEffect).filter(elem => lvl > parseInt(elem)).length - 1;
+ const rewardLevel = Math.floor(finalLevel / 3) + 1;
+ switch (finalLevel % 3) {
+ case 0:
+ return {icon: 'mdi-sword-cross', color: 'grey', effect: [
+ {name: 'hordeAttack', type: 'mult', before: Math.pow(BATTLE_PASS_COMBAT_REWARD, rewardLevel - 1), value: Math.pow(BATTLE_PASS_COMBAT_REWARD, rewardLevel)},
+ {name: 'hordeHealth', type: 'mult', before: Math.pow(BATTLE_PASS_COMBAT_REWARD, rewardLevel - 1), value: Math.pow(BATTLE_PASS_COMBAT_REWARD, rewardLevel)},
+ ], isSpecial: false};
+ case 1:
+ return {icon: 'mdi-bone', color: 'grey', effect: [
+ {name: 'currencyHordeBoneGain', type: 'mult', before: Math.pow(BATTLE_PASS_LOOT_REWARD, rewardLevel - 1), value: Math.pow(BATTLE_PASS_LOOT_REWARD, rewardLevel)},
+ {name: 'currencyHordeBloodGain', type: 'mult', before: Math.pow(BATTLE_PASS_LOOT_REWARD, rewardLevel - 1), value: Math.pow(BATTLE_PASS_LOOT_REWARD, rewardLevel)},
+ ], isSpecial: false};
+ case 2:
+ return {icon: 'mdi-ghost', color: 'grey', effect: [
+ {name: 'currencyHordeSoulCorruptedGain', type: 'mult', before: Math.pow(BATTLE_PASS_PRESTIGE_REWARD, rewardLevel - 1), value: Math.pow(BATTLE_PASS_PRESTIGE_REWARD, rewardLevel)},
+ {name: 'currencyHordeCourageGain', type: 'mult', before: Math.pow(BATTLE_PASS_PRESTIGE_REWARD, rewardLevel - 1), value: Math.pow(BATTLE_PASS_PRESTIGE_REWARD, rewardLevel)},
+ ], isSpecial: false};
+ default:
+ return null;
+ }
+ }
+ },
+ battlePassCurrentLevel: (state) => {
+ let lvl = 0;
+ for (const [, elem] of Object.entries(state.fighterClass)) {
+ for (const [, qelem] of Object.entries(elem.questsCompleted)) {
+ lvl += qelem;
+ }
+ }
+ return lvl;
+ },
+ sacrificeEffectAtLevel: () => (lvl) => {
+ return [
+ {name: 'hordeAttack', type: 'mult', value: Math.pow(5, lvl)},
+ {name: 'hordeHealth', type: 'mult', value: Math.pow(5, lvl)},
+ {name: 'hordeCorruption', type: 'mult', value: 1 / (0.25 * lvl + 1)},
+ {name: 'hordeItemMasteryGain', type: 'mult', value: Math.pow(0.5, lvl)},
+ {name: 'hordeMaxItems', type: 'bonus', value: lvl * -1},
+ ];
+ },
},
mutations: {
updateKey(state, o) {
@@ -253,6 +382,7 @@ export default {
stats: o.stats ?? (() => { return {}; }),
active: o.active ?? (() => []),
activeType: o.activeType ?? 'combat',
+ activeCost: o.activeCost ?? (() => { return {}; }),
cooldown: o.cooldown,
cooldownLeft: 0,
usableInStun: o.usableInStun ?? false,
@@ -298,6 +428,75 @@ export default {
highest: 0
});
},
+ initFighterClass(state, o) {
+ Vue.set(state.fighterClass, o.name, {
+ unlock: o.unlock ?? null,
+ icon: o.icon ?? 'mdi-circle',
+ baseStats: o.baseStats,
+ courageMult: o.courageMult ?? 1,
+ exp: o.exp,
+ skills: o.skills,
+ skillTree: o.skillTree,
+ quests: o.quests,
+ questsCompleted: {stat: 0, zone: 0, level: 0, boss: 0}
+ });
+ },
+ initArea(state, o) {
+ let zones = {};
+ for (const [key, elem] of Object.entries(o.zones)) {
+ zones[key] = {
+ unlocked: elem.unlockedBy === null,
+ enemyAmount: elem.type === 'regular' ? 100 : null,
+ ...elem,
+ unlockedBy: elem.unlockedBy ? (Array.isArray(elem.unlockedBy) ? elem.unlockedBy : [elem.unlockedBy]) : null,
+ };
+ }
+ Vue.set(state.area, o.name, {
+ unlock: o.unlock ?? null,
+ icon: o.icon ?? 'mdi-nature',
+ color: o.color ?? 'grey',
+ zones: zones,
+ decoration: o.decoration
+ });
+ },
+ initTrinket(state, o) {
+ Vue.set(state.trinket, o.name, {
+ amount: 0,
+ level: 0,
+ rarity: o.rarity ?? 0,
+ icon: o.icon ?? 'mdi-circle',
+ color: o.color ?? 'grey',
+ isTimeless: o.isTimeless ?? false,
+ needsEnergy: o.needsEnergy ?? false,
+ needsMana: o.needsMana ?? false,
+ usableInStun: o.usableInStun ?? false,
+ uniqueToBoss: o.uniqueToBoss ?? null,
+ effect: o.effect ?? [],
+ active: o.active ?? (() => []),
+ activeType: o.activeType ?? null,
+ activeCost: o.activeCost ?? (() => { return {}; }),
+ cooldown: o.cooldown ?? (() => 60),
+ equipped: false,
+ isActive: false
+ });
+ },
+ initEnemyType(state, o) {
+ Vue.set(state.enemyType, o.name, {
+ attack: o.attack,
+ health: o.health,
+ sigil: o.sigil ?? {},
+ stats: o.stats ?? {}
+ });
+ },
+ initAreaBoss(state, o) {
+ Vue.set(state.areaBoss, o.name, {
+ attack: o.attack,
+ health: o.health,
+ textShadow: o.textShadow ?? null,
+ sigil: o.sigil ?? {},
+ stats: o.stats ?? {}
+ });
+ },
addSigilZone(state, value) {
state.sigilZones.push(value);
},
@@ -311,6 +510,15 @@ export default {
updateLoadoutKey(state, o) {
Vue.set(state.loadout[o.id], o.key, o.value);
},
+ updateClassQuestKey(state, o) {
+ Vue.set(state.fighterClass[o.name].questsCompleted, o.key, o.value);
+ },
+ updateAreaZoneKey(state, o) {
+ Vue.set(state.area[o.name].zones[o.zone], o.key, o.value);
+ },
+ updateTrinketKey(state, o) {
+ Vue.set(state.trinket[o.name], o.key, o.value);
+ },
deleteLoadout(state, index) {
state.loadout.splice(index, 1);
}
@@ -337,9 +545,27 @@ export default {
commit('updateKey', {key: 'currentTower', value: null});
commit('updateKey', {key: 'towerFloor', value: 0});
commit('updateKey', {key: 'taunt', value: false});
+ commit('updateKey', {key: 'selectedClass', value: 'adventurer'});
+ commit('updateKey', {key: 'nextClass', value: 'adventurer'});
+ commit('updateKey', {key: 'selectedArea', value: null});
commit('updateKey', {key: 'player', value: {}});
- commit('updateKey', {key: 'enemy', value: {}});
+ commit('updateKey', {key: 'enemy', value: null});
+ commit('updateKey', {key: 'enemyActive', value: {}});
+ commit('updateKey', {key: 'cachePlayerStats', value: null});
+ commit('updateKey', {key: 'cacheEnemyStats', value: null});
+ commit('updateKey', {key: 'playerBuff', value: {}});
+ commit('updateKey', {key: 'expLevel', value: 0});
+ commit('updateKey', {key: 'skillPoints', value: 0});
+ commit('updateKey', {key: 'skillLevel', value: {}});
+ commit('updateKey', {key: 'skillActive', value: {}});
+ commit('updateKey', {key: 'autocast', value: []});
+ commit('updateKey', {key: 'activeTimer', value: 0});
+ commit('updateKey', {key: 'trinketDrop', value: null});
+ commit('updateKey', {key: 'bossStage', value: 0});
+ commit('updateKey', {key: 'bossBonusDifficulty', value: 0});
+ commit('updateKey', {key: 'sacrificeLevel', value: 0});
+ commit('updateKey', {key: 'nextSacrificeLevel', value: 0});
for (const [key, elem] of Object.entries(state.items)) {
commit('updateItemKey', {name: key, key: 'level', value: 1});
@@ -355,36 +581,87 @@ export default {
for (const [key] of Object.entries(state.heirloom)) {
commit('updateHeirloomKey', {name: key, key: 'amount', value: 0});
}
+ for (const [key, elem] of Object.entries(state.area)) {
+ for (const [subkey, subelem] of Object.entries(elem.zones)) {
+ commit('updateAreaZoneKey', {name: key, zone: subkey, key: 'unlocked', value: subelem.unlockedBy === null});
+ }
+ }
+ for (const [key] of Object.entries(state.trinket)) {
+ commit('updateTrinketKey', {name: key, key: 'amount', value: 0});
+ commit('updateTrinketKey', {name: key, key: 'level', value: 0});
+ commit('updateTrinketKey', {name: key, key: 'equipped', value: false});
+ commit('updateTrinketKey', {name: key, key: 'isActive', value: false});
+ }
+ for (const [key] of Object.entries(state.tower)) {
+ commit('updateTowerKey', {name: key, key: 'highest', value: 0});
+ }
+ for (const [name, elem] of Object.entries(state.fighterClass)) {
+ for (const [key] of Object.entries(elem.questsCompleted)) {
+ commit('updateClassQuestKey', {name, key, value: 0});
+ }
+ }
},
initHeirloom({ commit }, o) {
commit('initHeirloom', o);
commit('mult/init', {feature: 'horde', name: `${ o.name }HeirloomEffect`, type: 'heirloomEffect'}, {root: true});
},
- updatePlayerStats({ rootGetters, commit }) {
- commit('updatePlayerKey', {key: 'health', value: rootGetters['mult/get']('hordeHealth')});
- commit('updatePlayerKey', {key: 'revive', value: rootGetters['mult/get']('hordeRevive')});
- commit('updatePlayerKey', {key: 'divisionShield', value: rootGetters['mult/get']('hordeDivisionShield')});
- commit('updatePlayerKey', {key: 'silence', value: 0});
- commit('updatePlayerKey', {key: 'stun', value: 0});
- commit('updatePlayerKey', {key: 'poison', value: 0});
- commit('updatePlayerKey', {key: 'hits', value: 0});
- commit('updatePlayerKey', {key: 'spells', value: 0});
+ updatePlayerStats({ state, rootState, getters, rootGetters, commit }) {
+ const baseStats = getters.playerBaseStats;
+ let newPlayerStats = {
+ health: rootGetters['mult/get']('hordeHealth', baseStats.health),
+ revive: rootGetters['mult/get']('hordeRevive'),
+ divisionShield: rootGetters['mult/get']('hordeDivisionShield'),
+ silence: 0,
+ stun: 0,
+ poison: 0,
+ hits: 0,
+ spells: 0,
+ };
+
+ // Preserve energy and mana, they are NOT reset on player death / combat change
+ if (rootState.system.features.horde.currentSubfeature === 1) {
+ if (state.player.energy !== undefined) {
+ newPlayerStats.energy = state.player.energy;
+ }
+ if (state.player.mana !== undefined) {
+ newPlayerStats.mana = state.player.mana;
+ }
+ }
+
+ commit('updateKey', {key: 'player', value: newPlayerStats});
},
- checkPlayerHealth({ state, rootGetters, commit }) {
- const maxHealth = rootGetters['mult/get']('hordeHealth');
+ checkPlayerHealth({ state, getters, rootGetters, commit }) {
+ const maxHealth = rootGetters['mult/get']('hordeHealth', getters.playerBaseStats.health);
if (state.respawn <= 0 && state.player.health > maxHealth) {
commit('updatePlayerKey', {key: 'health', value: maxHealth});
}
},
- updateEnemyStats({ state, rootState, getters, rootGetters, commit }) {
+ updateEnemyStats({ state, rootState, getters, rootGetters, commit, dispatch }) {
+ const subfeature = rootState.system.features.horde.currentSubfeature;
if (state.respawn <= 0) {
const inTower = state.currentTower !== null;
- if (!inTower && state.minibossTimer >= 1 && state.bossFight === 0) {
+ let enemyName = null;
+ let currentArea = null;
+ if (subfeature === 1) {
+ currentArea = state.area[state.selectedArea].zones[state.zone];
+ enemyName = currentArea.type === 'boss' ? currentArea.boss[state.bossStage] : randomElem(currentArea.enemyType);
+ }
+ if (state.bossFight === 0 && !inTower && state.minibossTimer >= 1) {
commit('updateKey', {key: 'bossFight', value: 1});
+ } else if (state.bossFight === 0 && currentArea !== null && currentArea.type === 'boss') {
+ commit('updateKey', {key: 'bossFight', value: 2});
}
- const canSpawn = inTower || state.enemyTimer >= HORDE_ENEMY_RESPAWN_TIME || state.bossFight > 0;
- if (canSpawn || (state.zone === rootState.stat.horde_maxZone.value && !state.bossAvailable && state.taunt)) {
- let stats = getters.enemyStats(getters.currentBaseZone, inTower ? 0 : state.combo);
+ const canSpawn = !(subfeature === 1 && state.selectedArea === null) &&
+ (inTower || state.enemyTimer >= HORDE_ENEMY_RESPAWN_TIME || state.bossFight > 0);
+ if (canSpawn || (subfeature === 0 && state.zone === rootState.stat.horde_maxZone.value && !state.bossAvailable && state.taunt)) {
+ const enemyData = enemyName !== null ? (currentArea.type === 'boss' ? state.areaBoss[enemyName] : state.enemyType[enemyName]) : null;
+ const bonusDifficulty = (enemyName !== null && currentArea.type === 'boss' && rootState.unlock[currentArea.reward].use) ? state.bossBonusDifficulty : 0;
+ let stats = getters.enemyStats(
+ subfeature === 1 ? (currentArea.difficulty + bonusDifficulty) : getters.currentBaseZone,
+ inTower ? 0 : state.combo,
+ enemyName ? enemyData.attack : undefined,
+ enemyName ? enemyData.health : undefined
+ );
const corruptionStats = inTower ? {} : getters.currentCorruptionStats;
if (corruptionStats.power !== undefined) {
@@ -394,9 +671,17 @@ export default {
if (corruptionStats.revive !== undefined) {
stats.revive += corruptionStats.revive;
}
+ if (corruptionStats.execute !== undefined) {
+ stats.execute += corruptionStats.execute;
+ }
+
+ if (subfeature === 1) {
+ stats.attack *= buildNum(100, 'K');
+ stats.health *= buildNum(100, 'K');
+ }
// update sigil zones
- if (!inTower) {
+ if (subfeature === 0 && !inTower) {
while (state.sigilZones.length < state.zone) {
let sigils = [];
let sigilsAvailable = [];
@@ -422,32 +707,45 @@ export default {
let amt = getters.currentSigils + (corruptionStats.sigil ?? 0);
let sigil = {};
- let sigilSource = inTower ? [...state.tower[state.currentTower].sigils] : [...state.sigilZones[state.zone - 1]];
- let rngGen = state.bossFight === 0 ? null : rootGetters['system/getRng']('horde_sigil' + (state.bossFight === 2 ? 'Boss' : 'Miniboss'));
- while (amt > 0) {
- let chosen = null;
- if (sigilSource.length > 0) {
- if (state.bossFight === 0) {
- chosen = randomElem(sigilSource);
+ if (enemyName) {
+ for (const [stat, amount] of Object.entries(enemyData.stats)) {
+ const split = stat.split('_');
+ if (split[1] === 'mult') {
+ stats[split[0]] *= amount;
} else {
- chosen = randomElem(sigilSource, rngGen());
+ stats[split[0]] += amount;
}
- } else {
- chosen = 'generic';
}
- if (!sigil[chosen]) {
- sigil[chosen] = 0;
- }
- sigil[chosen]++;
- if (state.sigil[chosen].cap !== null && sigil[chosen] >= state.sigil[chosen].cap) {
- sigilSource.splice(sigilSource.findIndex(elem => elem === chosen), 1);
+ sigil = {...enemyData.sigil};
+ } else if (subfeature === 0) {
+ let sigilSource = inTower ? [...state.tower[state.currentTower].sigils] : [...state.sigilZones[state.zone - 1]];
+ let rngGen = state.bossFight === 0 ? null : rootGetters['system/getRng']('horde_sigil' + (state.bossFight === 2 ? 'Boss' : 'Miniboss'));
+ while (amt > 0) {
+ let chosen = null;
+ if (sigilSource.length > 0) {
+ if (state.bossFight === 0) {
+ chosen = randomElem(sigilSource);
+ } else {
+ chosen = randomElem(sigilSource, rngGen());
+ }
+ } else {
+ chosen = 'generic';
+ }
+ if (!sigil[chosen]) {
+ sigil[chosen] = 0;
+ }
+ sigil[chosen]++;
+ if (state.sigil[chosen].cap !== null && sigil[chosen] >= state.sigil[chosen].cap) {
+ sigilSource.splice(sigilSource.findIndex(elem => elem === chosen), 1);
+ }
+ amt--;
}
- amt--;
}
if (state.bossFight >= 1) {
stats.attack *= state.bossFight === 2 ? 15 : 1.5;
stats.health *= state.bossFight === 2 ? 15 : 2.5;
+ stats.magicTaken *= state.bossFight === 2 ? 1.35 : 1.1;
stats.bioTaken /= state.bossFight === 2 ? 10 : 2;
stats.stunResist += state.bossFight;
}
@@ -456,11 +754,13 @@ export default {
const cooldownStart = rootGetters['mult/get']('hordeEnemyActiveStart');
for (const [key, elem] of Object.entries(sigil)) {
- for (const [stat, obj] of Object.entries(state.sigil[key].stats(elem, state.bossFight))) {
- if (obj.type === 'mult') {
- stats[stat] *= obj.amount;
- } else {
- stats[stat] += obj.amount;
+ if (subfeature !== 1) {
+ for (const [stat, obj] of Object.entries(state.sigil[key].stats(elem, state.bossFight))) {
+ if (obj.type === 'mult') {
+ stats[stat] *= obj.amount;
+ } else {
+ stats[stat] += obj.amount;
+ }
}
}
if (state.sigil[key].active) {
@@ -490,8 +790,27 @@ export default {
commit('updateEnemyKey', {key: 'sigil', value: sigil});
commit('updateEnemyKey', {key: 'active', value: active});
+ commit('updateEnemyKey', {key: 'name', value: enemyName});
+
commit('updateKey', {key: 'fightTime', value: 0});
commit('updateKey', {key: 'fightRampage', value: 0});
+
+ // Reset after x time effects
+ dispatch('system/resetEffect', {
+ type: 'mult',
+ name: 'hordeAttack',
+ multKey: `hordeTime`
+ }, {root: true});
+ dispatch('system/resetEffect', {
+ type: 'base',
+ name: 'hordeStrength',
+ multKey: `hordeTime`
+ }, {root: true});
+ dispatch('system/resetEffect', {
+ type: 'base',
+ name: 'hordeIntelligence',
+ multKey: `hordeTime`
+ }, {root: true});
} else {
commit('updateKey', {key: 'enemy', value: null});
}
@@ -513,10 +832,20 @@ export default {
dispatch('resetStats');
},
+ updateAreaZone({ state, commit, dispatch }, o) {
+ commit('updateKey', {key: 'selectedArea', value: o.area});
+ commit('updateKey', {key: 'zone', value: o.zone});
+
+ commit('updateKey', {key: 'bossStage', value: 0});
+ commit('updateKey', {key: 'bossFight', value: state.area[o.area].zones[o.zone].type === 'boss' ? 2 : 0});
+
+ dispatch('resetStats');
+ },
equipItem({ state, getters, rootGetters, commit, dispatch }, name) {
if (state.items[name] && !state.items[name].equipped && state.items[name].found && getters.itemsEquipped < rootGetters['mult/get']('hordeMaxItems')) {
commit('updateItemKey', {name, key: 'equipped', value: true});
dispatch('applyItemEffects', name);
+ dispatch('updateMysticalShardCap');
dispatch('resetStats');
commit('stat/increaseTo', {feature: 'horde', name: 'maxItems', value: getters.itemsEquipped}, {root: true});
}
@@ -526,13 +855,23 @@ export default {
commit('updateItemKey', {name, key: 'equipped', value: false});
state.items[name].stats(state.items[name].level).forEach(elem => {
- dispatch('mult/removeKey', {name: elem.name, key: 'item_' + name, type: elem.type}, {root: true});
+ if (elem.type === 'tag') {
+ commit('tag/reset', {name: elem.name, key: 'item_' + name}, {root: true});
+ } else {
+ dispatch('mult/removeKey', {name: elem.name, key: 'item_' + name, type: elem.type}, {root: true});
+ }
});
+ if (state.chosenActive === name) {
+ commit('updateKey', {key: 'chosenActive', value: null});
+ }
+ commit('updateKey', {key: 'autocast', value: state.autocast.filter(el => el !== name)});
+
+ dispatch('updateMysticalShardCap');
dispatch('resetStats');
}
},
- applyItemEffects({ state, dispatch }, name) {
+ applyItemEffects({ state, commit, dispatch }, name) {
state.items[name].stats(state.items[name].level).forEach(elem => {
let value = elem.value;
if (state.items[name].passive && elem.isPositive) {
@@ -544,13 +883,20 @@ export default {
}
} else if (elem.type === 'mult' && elem.value > 0) {
value = Math.pow(value, masteryMult);
+ } else if (elem.type === 'tag') {
+ value = value.map(el => el * masteryMult);
}
}
- dispatch('mult/set' + capitalize(elem.type), {name: elem.name, key: 'item_' + name, value}, {root: true});
+ if (elem.type === 'tag') {
+ commit('tag/set', {name: elem.name, key: 'item_' + name, value}, {root: true});
+ } else {
+ dispatch('mult/set' + capitalize(elem.type), {name: elem.name, key: 'item_' + name, value}, {root: true});
+ }
});
},
resetStats({ commit, dispatch }) {
commit('updateKey', {key: 'combo', value: 0});
+ commit('updateKey', {key: 'playerBuff', value: {}});
dispatch('updatePlayerStats');
dispatch('updateEnemyStats');
},
@@ -589,6 +935,14 @@ export default {
commit('unlock/unlock', 'hordeIceTower', {root: true});
dispatch('currency/gain', {feature: 'horde', name: 'towerKey', amount: HORDE_KEYS_PER_TOWER}, {root: true});
}
+ if (!rootState.unlock.hordeDangerTower.use && maxZoneTotal >= 245) {
+ commit('unlock/unlock', 'hordeDangerTower', {root: true});
+ dispatch('currency/gain', {feature: 'horde', name: 'towerKey', amount: HORDE_KEYS_PER_TOWER}, {root: true});
+ }
+ if (!rootState.unlock.hordeToxicTower.use && maxZoneTotal >= 290) {
+ commit('unlock/unlock', 'hordeToxicTower', {root: true});
+ dispatch('currency/gain', {feature: 'horde', name: 'towerKey', amount: HORDE_KEYS_PER_TOWER}, {root: true});
+ }
// Raise miniboss rewards
if (maxZoneTotal >= HORDE_MINIBOSS_MIN_ZONE) {
@@ -634,10 +988,18 @@ export default {
}
},
killEnemy({ state, rootState, getters, rootGetters, commit, dispatch }) {
- if (state.bossFight === 0 && state.currentTower === null) {
+ const subfeature = rootState.system.features.horde.currentSubfeature;
+ if (subfeature === 0 && state.bossFight === 0 && state.currentTower === null) {
dispatch('currency/gain', {feature: 'horde', name: 'bone', amount: rootGetters['mult/get']('currencyHordeBoneGain', getters.currentBone, state.enemy.loot)}, {root: true});
dispatch('findItems', 1);
}
+ if (subfeature === 1 && state.bossFight === 0) {
+ dispatch('currency/gain', {feature: 'horde', name: 'blood', amount: rootGetters['mult/get']('currencyHordeBloodGain', getters.currentBlood)}, {root: true});
+ }
+
+ if (state.currentTower === null && getters.currentCorruption > 0) {
+ commit('stat/increaseTo', {feature: 'horde', name: 'maxCorruptionKill', value: getters.currentCorruption}, {root: true});
+ }
// Reset some stats
commit('updatePlayerKey', {key: 'divisionShield', value: rootGetters['mult/get']('hordeDivisionShield')});
@@ -645,10 +1007,16 @@ export default {
commit('updatePlayerKey', {key: 'silence', value: 0});
commit('updatePlayerKey', {key: 'stun', value: 0});
- const recovery = rootGetters['mult/get']('hordeRecovery');
- const missingHealth = rootGetters['mult/get']('hordeHealth') - state.player.health;
+ const recovery = state.cachePlayerStats.recovery;
+ const maxHealth = state.cachePlayerStats.health;
+ const missingHealth = maxHealth - state.player.health;
if (recovery > 0 && missingHealth > 0) {
- commit('updatePlayerKey', {key: 'health', value: Math.min(rootGetters['mult/get']('hordeHealth'), state.player.health + missingHealth * recovery)});
+ commit('updatePlayerKey', {key: 'health', value: Math.min(maxHealth, state.player.health + missingHealth * recovery * state.cachePlayerStats.healing)});
+ }
+
+ const manasteal = rootGetters['tag/values']('hordeManasteal')[0];
+ if (state.player.mana !== undefined && state.player.mana < state.cachePlayerStats.mana && manasteal > 0) {
+ dispatch('updateMana', Math.min(state.player.mana + manasteal, state.cachePlayerStats.mana));
}
if (state.currentTower !== null) {
@@ -672,37 +1040,123 @@ export default {
commit('updateKey', {key: 'bossFight', value: 0});
commit('system/nextRng', {name: 'horde_sigilMiniboss', amount: 1}, {root: true});
} else if (state.bossFight === 2) {
- // Find notes based on depth
- const note = notes[rootState.stat.horde_maxZone.value];
- if (note !== undefined) {
- dispatch('note/find', note, {root: true});
- }
+ if (subfeature === 0) {
+ // Find notes based on depth
+ const note = notes[rootState.stat.horde_maxZone.value];
+ if (note !== undefined) {
+ dispatch('note/find', note, {root: true});
+ }
- commit('updateKey', {key: 'bossFight', value: 0});
- commit('system/nextRng', {name: 'horde_sigilBoss', amount: 1}, {root: true});
- commit('updateKey', {key: 'bossAvailable', value: false});
- commit('updateKey', {key: 'enemyTimer', value: HORDE_ENEMY_RESPAWN_TIME * HORDE_ENEMY_RESPAWN_MAX});
- commit('stat/increaseTo', {feature: 'horde', name: 'maxZone', value: rootState.stat.horde_maxZone.value + 1}, {root: true});
- commit('updateKey', {key: 'zone', value: state.zone + 1});
- // Speedrun stat
- if (rootState.stat.horde_timeSpent.value <= 1800) {
- commit('stat/increaseTo', {feature: 'horde', name: 'maxZoneSpeedrun', value: rootState.stat.horde_maxZone.value}, {root: true});
- }
- if (state.zone >= 75) {
- // Add item mastery
- dispatch('gainMastery', 1);
- }
- dispatch('updatePlayerStats');
- dispatch('checkZoneUnlocks');
+ commit('system/nextRng', {name: 'horde_sigilBoss', amount: 1}, {root: true});
+ commit('updateKey', {key: 'bossAvailable', value: false});
+ commit('updateKey', {key: 'enemyTimer', value: HORDE_ENEMY_RESPAWN_TIME * HORDE_ENEMY_RESPAWN_MAX});
+ commit('stat/increaseTo', {feature: 'horde', name: 'maxZone', value: rootState.stat.horde_maxZone.value + 1}, {root: true});
+ commit('updateKey', {key: 'zone', value: state.zone + 1});
+ // Speedrun stat
+ if (rootState.stat.horde_timeSpent.value <= 1800) {
+ commit('stat/increaseTo', {feature: 'horde', name: 'maxZoneSpeedrun', value: rootState.stat.horde_maxZone.value}, {root: true});
+ }
+ if (state.zone >= 75) {
+ // Add item mastery
+ dispatch('gainMastery', 1);
+ }
+ dispatch('checkZoneUnlocks');
+ commit('updateKey', {key: 'bossFight', value: 0});
+ dispatch('updatePlayerStats');
+ } else if (subfeature === 1) {
+ const bossData = state.area[state.selectedArea].zones[state.zone];
+ const bossName = bossData.boss[bossData.boss.length - 1];
+ if ((state.bossStage + 1) >= bossData.boss.length) {
+ // Check if one of the conditions is met to give trinkets
+ let hasTrinket = false;
+ let difficulty = bossData.difficulty;
+ const classObj = state.fighterClass[state.selectedClass];
+ const questObj = classObj.questsCompleted.boss < classObj.quests.boss.length ? classObj.quests.boss[classObj.questsCompleted.boss] : null;
+ if (!rootState.unlock[bossData.reward].use) {
+ commit('unlock/unlock', bossData.reward, {root: true});
+ hasTrinket = true;
+ } else if (questObj !== null && questObj.boss === bossName && questObj.difficulty === state.bossBonusDifficulty) {
+ commit('updateClassQuestKey', {name: state.selectedClass, key: 'boss', value: classObj.questsCompleted.boss + 1});
+ dispatch('applyBattlePassEffects');
+ difficulty += state.bossBonusDifficulty;
+ hasTrinket = true;
+ } else if (state.selectedClass === 'pirate' && rootGetters['currency/value']('horde_lockpick') >= 1) {
+ dispatch('currency/spend', {feature: 'horde', name: 'lockpick', amount: 1}, {root: true});
+ difficulty += state.bossBonusDifficulty;
+ hasTrinket = true;
+ }
+
+ if (hasTrinket) {
+ // Get a random trinket
+ let trinkets = [];
+ let eligible = [];
+ for (const [key, elem] of Object.entries(state.trinket)) {
+ const diff = rootGetters['mult/get']('hordeTrinketQuality', difficulty) - elem.rarity;
+ if (diff >= 0 && (elem.uniqueToBoss === null || elem.uniqueToBoss === bossName) && (!elem.isTimeless || elem.level <= 0)) {
+ eligible.push({name: key, weight: (diff * 0.1 + 1) * (elem.isTimeless ? 0.05 : 1), maxAmount: elem.isTimeless ? 1 : Math.floor(rootGetters['mult/get']('hordeTrinketGain', Math.pow(diff, 1.5) * 0.01) + 1)});
+ }
+ }
+ let rngGen = rootGetters['system/getRng']('horde_trinket');
+ for (let i = 0; i < 3; i++) {
+ if (eligible.length > 0) {
+ const chosenId = weightSelect(eligible.map(el => el.weight), rngGen());
+ if (chosenId !== -1) {
+ const chosenObj = eligible[chosenId];
+ trinkets.push({name: chosenObj.name, amount: randomInt(1, chosenObj.maxAmount, rngGen())});
+ eligible.splice(chosenId, 1);
+ }
+ }
+ }
+ commit('system/nextRng', {name: 'horde_trinket', amount: 1}, {root: true});
+ commit('updateKey', {key: 'trinketDrop', value: trinkets});
+ }
+
+ // Go back to last zone
+ commit('updateKey', {key: 'zone', value: bossData.unlockedBy[0]});
+ commit('updateKey', {key: 'bossFight', value: 0});
+ dispatch('updatePlayerStats');
+ } else {
+ commit('updateKey', {key: 'bossStage', value: state.bossStage + 1});
+ }
+ }
} else {
commit('updateKey', {key: 'combo', value: state.combo + 1});
if (state.enemy.loot > 0) {
commit('updateKey', {key: 'enemyTimer', value: state.enemyTimer - HORDE_ENEMY_RESPAWN_TIME});
}
+
+ // Reset zone in classes subfeature
+ if (rootState.system.features.horde.currentSubfeature === 1) {
+ const maxAmount = state.area[state.selectedArea].zones[state.zone].enemyAmount;
+ if (maxAmount !== null && state.combo >= maxAmount) {
+ commit('stat/increaseTo', {feature: 'horde', name: 'maxDifficulty', value: state.area[state.selectedArea].zones[state.zone].difficulty}, {root: true});
+ commit('updateKey', {key: 'combo', value: 0});
+ dispatch('resetStats');
+ dispatch('updateMaxDifficulty');
+
+ // Unlock new zones
+ for (const [key, elem] of Object.entries(state.area[state.selectedArea].zones)) {
+ if (!elem.unlocked && elem.unlockedBy !== null && elem.unlockedBy.includes(state.zone)) {
+ commit('updateAreaZoneKey', {name: state.selectedArea, zone: key, key: 'unlocked', value: true});
+ }
+ }
+
+ // Complete zone quest
+ const classObj = state.fighterClass[state.selectedClass];
+ if (
+ classObj.questsCompleted.zone < classObj.quests.zone.length &&
+ classObj.quests.zone[classObj.questsCompleted.zone].area === state.selectedArea &&
+ classObj.quests.zone[classObj.questsCompleted.zone].zone === state.zone
+ ) {
+ commit('updateClassQuestKey', {name: state.selectedClass, key: 'zone', value: classObj.questsCompleted.zone + 1});
+ dispatch('applyBattlePassEffects');
+ }
+ }
+ }
}
let skipStats = false;
- if (state.zone === rootState.stat.horde_maxZone.value && !state.bossAvailable && state.combo >= getters.comboRequired) {
+ if (subfeature === 0 && state.zone === rootState.stat.horde_maxZone.value && !state.bossAvailable && state.combo >= getters.comboRequired) {
commit('updateKey', {key: 'bossAvailable', value: true});
if (rootState.system.settings.automation.items.fightHordeBoss.value) {
skipStats = true;
@@ -732,6 +1186,8 @@ export default {
// Current cooldown gets halved
commit('updateItemKey', {name: key, key: 'cooldownLeft', value: Math.ceil(elem.cooldownLeft / 2)});
}
+ } else if (state.items[key].masteryLevel >= 5 && elem.equipped) {
+ dispatch('updateMysticalShardCap');
}
}
}
@@ -765,25 +1221,65 @@ export default {
}
},
useActive({ state, rootState, getters, commit, dispatch }, name) {
- const item = state.items[name];
- if (item.equipped && item.cooldownLeft <= 0) {
+ const subfeature = rootState.system.features.horde.currentSubfeature;
+ let item = null;
+ if (subfeature === 0) {
+ item = state.items[name];
+ } else if (subfeature === 1) {
+ const split = name.split('_');
+ if (split[0] === 'skill') {
+ item = state.fighterClass[state.selectedClass].skills[split[1]];
+ } else if (split[0] === 'trinket') {
+ item = state.trinket[split[1]];
+ }
+ }
+ const cooldownLeft = subfeature === 1 ? state.skillActive[name] : item.cooldownLeft;
+ const level = subfeature === 1 ? (state.skillLevel[name.split('_')[1]] ?? 0) : item.level;
+ const activeCost = item.activeCost !== undefined ? item.activeCost(level) : {};
+ if (
+ item &&
+ (subfeature !== 0 || item.equipped) &&
+ cooldownLeft <= 0 &&
+ (activeCost.energy === undefined || state.player.energy >= activeCost.energy) &&
+ (activeCost.mana === undefined || state.player.mana >= activeCost.mana)
+ ) {
if (item.activeType === 'utility') {
- const cooldown = Math.ceil(item.cooldown(item.level) / (item.masteryLevel >= 4 ? 2 : 1));
- const charges = Math.floor(logBase(2 - (item.cooldownLeft / cooldown), 2));
+ const cooldown = Math.ceil(item.cooldown(level) / ((subfeature === 0 && item.masteryLevel >= 4) ? 2 : 1));
+ const charges = Math.floor(logBase(2 - (cooldownLeft / cooldown), 2));
- item.active(item.level).forEach(elem => {
+ item.active(level).forEach(elem => {
+ let value = 0;
+ let critEffect = elem.canCrit ?? 0;
+ for (let i = 0; i < charges; i++) {
+ value += elem.value * (critEffect > 0 ? Math.pow((state.cachePlayerStats.critMult - 1) * critEffect + 1, randomRound(state.cachePlayerStats.critChance)) : 1);
+ }
if (elem.type === 'bone') {
- dispatch('currency/gain', {feature: 'horde', name: 'bone', gainMult: true, amount: elem.value * charges * getters.enemyBone(rootState.stat.horde_maxZone.value, 0)}, {root: true});
+ dispatch('currency/gain', {feature: 'horde', name: 'bone', gainMult: true, amount: value * getters.enemyBone(rootState.stat.horde_maxZone.value, 0)}, {root: true});
+ } else if (elem.type === 'blood') {
+ dispatch('currency/gain', {feature: 'horde', name: 'blood', gainMult: true, amount: value * getters.enemyBlood(rootState.stat.horde_maxDifficulty.value, 0)}, {root: true});
} else if (elem.type === 'monsterPart') {
- dispatch('currency/gain', {feature: 'horde', name: 'monsterPart', gainMult: true, amount: elem.value * charges * getters.enemyMonsterPart(rootState.stat.horde_maxZone.value, 0)}, {root: true});
+ dispatch('currency/gain', {feature: 'horde', name: 'monsterPart', gainMult: true, amount: value * getters.enemyMonsterPart(rootState.stat.horde_maxZone.value, 0)}, {root: true});
} else if (elem.type === 'permanentStat') {
- const value = (state.itemStatMult[elem.stat] ?? 0) + elem.value * charges;
- commit('updateSubkey', {name: 'itemStatMult', key: elem.stat, value});
- dispatch('system/applyEffect', {type: 'mult', name: elem.stat, multKey: `hordeItemPermanent`, value: value + 1}, {root: true});
+ const statValue = (state.itemStatMult[elem.stat] ?? 0) + value;
+ const split = elem.stat.split('_');
+ commit('updateSubkey', {name: 'itemStatMult', key: elem.stat, value: statValue});
+ dispatch('system/applyEffect', {type: split[1], name: split[0], multKey: `hordeItemPermanent`, value: statValue + (split[1] === 'mult' ? 1 : 0)}, {root: true});
}
});
- commit('updateItemKey', {name, key: 'cooldownLeft', value: Math.ceil(cooldown * ((item.cooldownLeft / cooldown) - (2 - Math.pow(2, charges + 1))) / Math.pow(2, charges))});
+ if (activeCost.energy !== undefined) {
+ dispatch('updateEnergy', state.player.energy - activeCost.energy);
+ }
+ if (activeCost.mana !== undefined) {
+ dispatch('updateMana', state.player.mana - activeCost.mana);
+ }
+
+ const newCooldown = Math.ceil(cooldown * ((cooldownLeft / cooldown) - (2 - Math.pow(2, charges + 1))) / Math.pow(2, charges));
+ if (subfeature === 0) {
+ commit('updateItemKey', {name, key: 'cooldownLeft', value: newCooldown});
+ } else if (subfeature === 1) {
+ commit('updateSubkey', {name: 'skillActive', key: name, value: newCooldown});
+ }
} else {
commit('updateKey', {key: 'chosenActive', value: name === state.chosenActive ? null : name});
}
@@ -799,11 +1295,12 @@ export default {
}
}
},
- prestige({ state, rootState, commit, dispatch }) {
- const prestigeGain = rootState.currency.horde_soulCorrupted.value;
- commit('stat/increaseTo', {feature: 'horde', name: 'bestPrestige', value: prestigeGain}, {root: true});
+ prestige({ state, rootState, getters, rootGetters, commit, dispatch }, subfeature) {
+ const currentSubfeature = rootState.system.features.horde.currentSubfeature;
+ const prestigeGain = [rootState.currency.horde_soulCorrupted.value, rootGetters['mult/get']('currencyHordeCourageGain')][currentSubfeature];
+ commit('stat/increaseTo', {feature: 'horde', name: 'bestPrestige' + currentSubfeature, value: prestigeGain}, {root: true});
commit('stat/add', {feature: 'horde', name: 'prestigeCount', value: 1}, {root: true});
- dispatch('currency/gain', {feature: 'horde', name: 'soulEmpowered', amount: prestigeGain}, {root: true});
+ dispatch('currency/gain', {feature: 'horde', name: ['soulEmpowered', 'courage'][currentSubfeature], amount: prestigeGain}, {root: true});
for (const [key, elem] of Object.entries(state.items)) {
if (elem.equipped) {
@@ -820,18 +1317,21 @@ export default {
// Reset per-run item effects
for (const [key] of Object.entries(state.itemStatMult)) {
- dispatch('system/resetEffect', {type: 'mult', name: key, multKey: `hordeItemPermanent`}, {root: true});
+ const split = key.split('_');
+ dispatch('system/resetEffect', {type: split[1], name: split[0], multKey: `hordeItemPermanent`}, {root: true});
}
commit('updateKey', {key: 'itemStatMult', value: {}});
- dispatch('upgrade/reset', {feature: 'horde', type: 'regular'}, {root: true});
+ dispatch('upgrade/reset', {feature: 'horde', subfeature, type: 'regular'}, {root: true});
dispatch('currency/reset', {feature: 'horde', type: 'regular'}, {root: true});
dispatch('stat/reset', {feature: 'horde', type: 'regular'}, {root: true});
dispatch('mult/removeKey', {name: 'currencyHordeSoulCorruptedGain', type: 'base', key: 'zoneCleared'}, {root: true});
dispatch('mult/removeKey', {name: 'hordeHeirloomChance', type: 'base', key: 'zoneCleared'}, {root: true});
- commit('updateKey', {key: 'zone', value: 1});
+ commit('system/updateSubfeature', {key: 'horde', value: subfeature}, {root: true});
+
+ commit('updateKey', {key: 'zone', value: subfeature === 1 ? '1' : 1});
commit('updateKey', {key: 'combo', value: 0});
commit('updateKey', {key: 'respawn', value: 0});
commit('updateKey', {key: 'maxRespawn', value: 1});
@@ -844,34 +1344,103 @@ export default {
commit('updateKey', {key: 'nostalgiaLost', value: 0});
commit('updateKey', {key: 'currentTower', value: null});
commit('updateKey', {key: 'towerFloor', value: 0});
+ commit('updateKey', {key: 'selectedArea', value: subfeature === 1 ? 'warzone' : null});
+ commit('updateKey', {key: 'playerBuff', value: {}});
+ commit('updateKey', {key: 'expLevel', value: 0});
+ commit('updateKey', {key: 'skillPoints', value: 0});
+ commit('updateKey', {key: 'autocast', value: []});
+ commit('updateKey', {key: 'bossStage', value: 0});
+ dispatch('updateActiveTimer', 0);
dispatch('updateNostalgia');
+ // Apply sacrifice level
+ commit('updateKey', {key: 'sacrificeLevel', value: subfeature === 0 ? state.nextSacrificeLevel : 0});
+ dispatch('updateSacrifice');
+
+ // Reset all heirloom effects in case of subfeature switch
+ for (const [key] of Object.entries(state.heirloom)) {
+ dispatch('applyHeirloomEffects', key);
+ }
+
+ for (const [key] of Object.entries(state.skillLevel)) {
+ commit('updateSubkey', {name: 'skillLevel', key, value: 0});
+ dispatch('applySkillEffects', key);
+ }
+ commit('updateKey', {key: 'skillLevel', value: {}});
+ commit('updateKey', {key: 'skillActive', value: {}});
+ for (const [key, elem] of Object.entries(state.trinket)) {
+ if (elem.isActive) {
+ commit('updateTrinketKey', {name: key, key: 'isActive', value: false});
+ dispatch('removeTrinketEffects', key);
+ }
+ if (subfeature === 1 && elem.equipped) {
+ const fighterStats = state.fighterClass[state.nextClass].baseStats;
+ if ((!elem.needsEnergy || fighterStats.energy !== undefined) && (!elem.needsMana || fighterStats.mana !== undefined)) {
+ commit('updateTrinketKey', {name: key, key: 'isActive', value: true});
+ dispatch('applyTrinketEffects', key);
+ }
+ }
+ }
+
+ // Switch classes
+ if (subfeature === 1) {
+ commit('updateKey', {key: 'selectedClass', value: state.nextClass});
+
+ const skillInnate = state.fighterClass[state.nextClass].skillTree[0];
+ if (skillInnate.isInnate) {
+ skillInnate.items.forEach(key => {
+ commit('updateSubkey', {name: 'skillLevel', key, value: 1});
+ dispatch('applySkillEffects', key);
+ });
+ }
+ }
+
+ dispatch('applyClassEffects');
+ dispatch('applyClassLevelEffects');
+
dispatch('card/activateCards', 'horde', {root: true});
dispatch('updatePlayerStats');
dispatch('updateEnemyStats');
+ dispatch('updatePlayerCache');
+
+ const baseStats = getters.playerBaseStats;
+ if (baseStats.energy !== undefined) {
+ dispatch('updateEnergy', rootGetters['mult/get']('hordeEnergy', baseStats.energy));
+ } else {
+ dispatch('updateEnergy');
+ }
+ if (baseStats.mana !== undefined) {
+ dispatch('updateMana', rootGetters['mult/get']('hordeMana', baseStats.mana));
+ } else {
+ dispatch('updateMana');
+ }
},
findHeirloom({ state, rootGetters, commit, dispatch }, o) {
- let eligibleHeirlooms = o.heirlooms ? [...o.heirlooms] : [];
+ let eligibleHeirlooms = [];
let lowestItem = null;
let lowestAmount = Infinity;
- for (const [key, elem] of Object.entries(state.heirloom)) {
- if (o.zone >= elem.minZone) {
- eligibleHeirlooms.push(key);
+ if (o.heirlooms) {
+ eligibleHeirlooms = o.heirlooms;
+ } else {
+ for (const [key, elem] of Object.entries(state.heirloom)) {
+ if (o.zone >= elem.minZone) {
+ eligibleHeirlooms.push(key);
- if (elem.amount < lowestAmount) {
- lowestItem = key;
- lowestAmount = elem.amount;
- } else if (elem.amount === lowestAmount) {
- lowestItem = null;
+ if (elem.amount < lowestAmount) {
+ lowestItem = key;
+ lowestAmount = elem.amount;
+ } else if (elem.amount === lowestAmount) {
+ lowestItem = null;
+ }
}
}
- }
- // The heirloom with the lowest amount is added to the list twice
- // (but only if no other heirloom has the same amount)
- if (lowestItem !== null) {
- eligibleHeirlooms.push(lowestItem);
+ // The heirloom with the lowest amount is added to the list twice
+ // (but only if no other heirloom has the same amount)
+ if (lowestItem !== null) {
+ eligibleHeirlooms.push(lowestItem);
+ }
}
let rngGen = rootGetters['system/getRng']('horde_heirloomType');
@@ -888,15 +1457,24 @@ export default {
found[chosen] += amount;
commit('updateKey', {key: 'heirloomsFound', value: found});
},
- applyHeirloomEffects({ state, rootGetters, dispatch }, name) {
+ applyHeirloomEffects({ state, rootState, rootGetters, dispatch }, name) {
+ const subfeature = rootState.system.features.horde.currentSubfeature;
if (state.heirloom[name].amount > 0) {
state.heirloom[name].effect.forEach(eff => {
- dispatch('system/applyEffect', {
- type: eff.type,
- name: eff.name,
- multKey: `hordeHeirloom_${name}`,
- value: eff.value(rootGetters['mult/get'](`${ name }HeirloomEffect`, state.heirloom[name].amount))
- }, {root: true});
+ if (subfeature === 0) {
+ dispatch('system/applyEffect', {
+ type: eff.type,
+ name: eff.name,
+ multKey: `hordeHeirloom_${name}`,
+ value: eff.value(rootGetters['mult/get'](`${ name }HeirloomEffect`, state.heirloom[name].amount))
+ }, {root: true});
+ } else {
+ dispatch('system/resetEffect', {
+ type: eff.type,
+ name: eff.name,
+ multKey: `hordeHeirloom_${name}`
+ }, {root: true});
+ }
});
}
},
@@ -909,7 +1487,8 @@ export default {
},
applyPermanentEffects({ state, dispatch }) {
for (const [key, elem] of Object.entries(state.itemStatMult)) {
- dispatch('system/applyEffect', {type: 'mult', name: key, multKey: `hordeItemPermanent`, value: elem + 1}, {root: true});
+ const split = key.split('_');
+ dispatch('system/applyEffect', {type: split[1], name: split[0], multKey: `hordeItemPermanent`, value: elem + (split[1] === 'mult' ? 1 : 0)}, {root: true});
}
},
applyTowerEffects({ state, dispatch }) {
@@ -965,6 +1544,389 @@ export default {
commit('updateKey', {key: 'towerFloor', value: 0});
dispatch('resetStats');
}
+ },
+ updatePlayerCache({ state, rootState, getters, rootGetters, commit, dispatch }) {
+ const subfeature = rootState.system.features.horde.currentSubfeature;
+
+ let stats = [
+ // Offense
+ 'attack', 'critChance', 'critMult', 'toxic', 'firstStrike', 'spellblade', 'cutting', 'shieldbreak', 'execute',
+
+ // Defense
+ 'health', 'revive', 'divisionShield', 'stunResist', 'recovery', 'defense', 'healing',
+
+ // Damage types
+ 'physicConversion', 'magicConversion', 'bioConversion', 'physicAttack', 'magicAttack', 'bioAttack', 'physicTaken', 'magicTaken', 'bioTaken',
+
+ // Horde 2 stuff
+ 'strength', 'intelligence', 'haste',
+ ];
+ if (subfeature === 1) {
+ stats.push('mana', 'manaRegen', 'energy', 'energyRegen');
+ }
+
+ // Convert stats to cache object
+ let cache = {};
+ let cacheObj = {};
+ stats.forEach(name => {
+ cache[name] = {name: `horde${ capitalize(name) }`, base: 0, mult: 1, bonus: 0};
+ });
+ for (const [name, value] of Object.entries(getters.playerBaseStats)) {
+ cache[name].base += value;
+ }
+ cache.critMult.bonus = 1;
+
+ // Apply buffs
+ for (const [, buff] of Object.entries(state.playerBuff)) {
+ buff.effect.forEach(effect => {
+ const name = decapitalize(effect.name.slice(5));
+ if (effect.type === 'mult') {
+ cache[name].mult *= effect.value;
+ } else {
+ cache[name][effect.type] += effect.value;
+ }
+ });
+ }
+
+ // Calculate caches
+ for (const [name, elem] of Object.entries(cache)) {
+ cacheObj[name] = rootGetters['mult/get'](elem.name, elem.base, elem.mult, elem.bonus);
+ }
+
+ // Turn conversion values into percentages
+ const conversionTotal = cacheObj.physicConversion + cacheObj.magicConversion + cacheObj.bioConversion;
+ cacheObj.physicConversion /= conversionTotal;
+ cacheObj.magicConversion /= conversionTotal;
+ cacheObj.bioConversion /= conversionTotal;
+
+ commit('updateKey', {key: 'cachePlayerStats', value: cacheObj});
+
+ // Check quests
+ if (subfeature === 1) {
+ const classObj = state.fighterClass[state.selectedClass];
+ const questObj = classObj.quests.stat[classObj.questsCompleted.stat];
+ if (classObj.questsCompleted.stat < classObj.quests.stat.length) {
+ let current = 0;
+ switch (questObj.type) {
+ case 'base':
+ current = (cache[decapitalize(questObj.stat.slice(5))].base ?? 0) + (rootState.mult.items[questObj.stat].baseCache ?? 0);
+ break;
+ case 'total':
+ current = cacheObj[decapitalize(questObj.stat.slice(5))] ?? 0;
+ break;
+ }
+
+ if (current >= questObj.value) {
+ commit('updateClassQuestKey', {name: state.selectedClass, key: 'stat', value: classObj.questsCompleted.stat + 1});
+ dispatch('applyBattlePassEffects');
+ }
+ }
+ }
+ },
+ updateEnemyCache({ commit }) {
+ let cache = {};
+ commit('updateKey', {key: 'cacheEnemyStats', value: cache});
+ },
+ addBuff({ commit, dispatch }, o) {
+ commit('updateSubkey', {name: 'playerBuff', key: o.name, value: {time: o.time, maxTime: o.time, positive: o.positive ?? false, effect: o.effect}});
+ dispatch('updatePlayerCache');
+ },
+ applySkillEffects({ state, commit, dispatch }, name) {
+ const skill = state.fighterClass[state.selectedClass].skills[name];
+ const skillLevel = state.skillLevel[name] ?? 0;
+ if (skill.type === 'active') {
+ if (skillLevel > 0 && state.skillActive[name] === undefined) {
+ commit('updateSubkey', {name: 'skillActive', key: `skill_${ name }`, value: 0});
+ }
+ } else {
+ skill.effect.forEach(eff => {
+ if (skillLevel > 0) {
+ dispatch('system/applyEffect', {
+ type: eff.type,
+ name: eff.name,
+ multKey: `hordeSkill_${name}`,
+ value: eff.value(skillLevel)
+ }, {root: true});
+ } else {
+ dispatch('system/resetEffect', {
+ type: eff.type,
+ name: eff.name,
+ multKey: `hordeSkill_${name}`
+ }, {root: true});
+ }
+ });
+ }
+ },
+ upgradeSkill({ state, commit, dispatch }, name) {
+ const skill = state.fighterClass[state.selectedClass].skills[name];
+ const skillLevel = state.skillLevel[name] ?? 0;
+ if (skillLevel < skill.max && state.skillPoints >= skill.cost) {
+ commit('updateKey', {key: 'skillPoints', value: state.skillPoints - skill.cost});
+ commit('updateSubkey', {name: 'skillLevel', key: name, value: skillLevel + 1});
+ dispatch('applySkillEffects', name);
+ }
+ },
+ applyClassEffects({ state, dispatch }) {
+ const value = state.fighterClass[state.selectedClass].courageMult;
+ if (value !== 1) {
+ dispatch('system/applyEffect', {
+ type: 'mult',
+ name: 'currencyHordeCourageGain',
+ multKey: `hordeClassMult`,
+ value: value
+ }, {root: true});
+ } else {
+ dispatch('system/resetEffect', {
+ type: 'mult',
+ name: 'currencyHordeCourageGain',
+ multKey: `hordeClassMult`
+ }, {root: true});
+ }
+ },
+ applyClassLevelEffects({ state, getters, dispatch }) {
+ const level = Math.floor(state.expLevel);
+ getters.classLevelEffect(level).forEach(effect => {
+ if (level > 0) {
+ dispatch('system/applyEffect', {
+ type: effect.type,
+ name: effect.name,
+ multKey: `hordeClassLevel`,
+ value: effect.value
+ }, {root: true});
+ } else {
+ dispatch('system/resetEffect', {
+ type: effect.type,
+ name: effect.name,
+ multKey: `hordeClassLevel`
+ }, {root: true});
+ }
+ });
+ },
+ applyBattlePassEffects({ state, getters, dispatch }) {
+ const level = getters.battlePassCurrentLevel;
+ if (level > 0) {
+ dispatch('meta/globalLevelPart', {key: 'horde_1', amount: level}, {root: true});
+ }
+ for (const [key, elem] of Object.entries(state.battlePassEffect)) {
+ if (level >= parseInt(key)) {
+ elem.effect.forEach(effect => {
+ dispatch('system/applyEffect', {
+ type: effect.type,
+ name: effect.name,
+ multKey: `hordeBattlePass_${ key }`,
+ value: effect.value
+ }, {root: true});
+ });
+ }
+ }
+ const finalLevel = level - Object.keys(state.battlePassEffect).filter(elem => level >= parseInt(elem)).length;
+ if (finalLevel >= 1) {
+ dispatch('system/applyEffect', {
+ type: 'mult',
+ name: 'hordeAttack',
+ multKey: `hordeBattlePass`,
+ value: Math.pow(BATTLE_PASS_COMBAT_REWARD, Math.floor((finalLevel + 2) / 3))
+ }, {root: true});
+ dispatch('system/applyEffect', {
+ type: 'mult',
+ name: 'hordeHealth',
+ multKey: `hordeBattlePass`,
+ value: Math.pow(BATTLE_PASS_COMBAT_REWARD, Math.floor((finalLevel + 2) / 3))
+ }, {root: true});
+ }
+ if (finalLevel >= 2) {
+ dispatch('system/applyEffect', {
+ type: 'mult',
+ name: 'currencyHordeBoneGain',
+ multKey: `hordeBattlePass`,
+ value: Math.pow(BATTLE_PASS_LOOT_REWARD, Math.floor((finalLevel + 1) / 3))
+ }, {root: true});
+ dispatch('system/applyEffect', {
+ type: 'mult',
+ name: 'currencyHordeBloodGain',
+ multKey: `hordeBattlePass`,
+ value: Math.pow(BATTLE_PASS_LOOT_REWARD, Math.floor((finalLevel + 1) / 3))
+ }, {root: true});
+ }
+ if (finalLevel >= 3) {
+ dispatch('system/applyEffect', {
+ type: 'mult',
+ name: 'currencyHordeSoulCorruptedGain',
+ multKey: `hordeBattlePass`,
+ value: Math.pow(BATTLE_PASS_PRESTIGE_REWARD, Math.floor(finalLevel / 3))
+ }, {root: true});
+ dispatch('system/applyEffect', {
+ type: 'mult',
+ name: 'currencyHordeCourageGain',
+ multKey: `hordeBattlePass`,
+ value: Math.pow(BATTLE_PASS_PRESTIGE_REWARD, Math.floor(finalLevel / 3))
+ }, {root: true});
+ }
+ },
+ updateEnergy({ state, rootGetters, commit, dispatch }, amount = null) {
+ if (amount !== null) {
+ commit('updatePlayerKey', {key: 'energy', value: amount});
+ } else {
+ amount = state.player.energy;
+ }
+ if (amount === null || amount === undefined) {
+ amount = 0;
+ }
+ const value = amount * rootGetters['tag/values']('hordeEnergyToStr')[0];
+ if (value > 0) {
+ dispatch('system/applyEffect', {
+ type: 'base',
+ name: 'hordeStrength',
+ multKey: `hordeEnergy`,
+ value
+ }, {root: true});
+ } else {
+ dispatch('system/resetEffect', {
+ type: 'base',
+ name: 'hordeStrength',
+ multKey: `hordeEnergy`
+ }, {root: true});
+ }
+ const value2 = (state.cachePlayerStats.energy - amount) * rootGetters['tag/values']('hordeEnergyToEnergyReg')[0];
+ if (value2 > 0) {
+ dispatch('system/applyEffect', {
+ type: 'base',
+ name: 'hordeEnergyRegen',
+ multKey: `hordeEnergy`,
+ value: value2
+ }, {root: true});
+ } else {
+ dispatch('system/resetEffect', {
+ type: 'base',
+ name: 'hordeEnergyRegen',
+ multKey: `hordeEnergy`
+ }, {root: true});
+ }
+ },
+ updateMana({ state, commit }, amount = null) {
+ if (amount !== null) {
+ commit('updatePlayerKey', {key: 'mana', value: amount});
+ } else {
+ amount = state.player.mana;
+ }
+ },
+ updateActiveTimer({ rootGetters, commit, dispatch }, amount) {
+ commit('updateKey', {key: 'activeTimer', value: amount});
+
+ const values = rootGetters['tag/values']('hordeManaRest');
+ if (amount >= values[0] && values[1] > 0) {
+ dispatch('system/applyEffect', {
+ type: 'base',
+ name: 'hordeManaRegen',
+ multKey: `hordeRest`,
+ value: values[1]
+ }, {root: true});
+ } else {
+ dispatch('system/resetEffect', {
+ type: 'base',
+ name: 'hordeManaRegen',
+ multKey: `hordeRest`
+ }, {root: true});
+ }
+ },
+ updateMaxDifficulty({ rootState, dispatch }) {
+ const level = rootState.stat.horde_maxDifficulty.value;
+ if (level > 0) {
+ dispatch('system/applyEffect', {
+ type: 'mult',
+ name: 'currencyHordeCourageGain',
+ multKey: `hordeMaxDifficulty`,
+ value: Math.pow(1.125, level)
+ }, {root: true});
+ } else {
+ dispatch('system/resetEffect', {
+ type: 'mult',
+ name: 'currencyHordeCourageGain',
+ multKey: `hordeMaxDifficulty`
+ }, {root: true});
+ }
+ },
+ updateMysticalShardCap({ state, dispatch }) {
+ let value = 0;
+ for (const [, elem] of Object.entries(state.items)) {
+ if (elem.equipped && elem.masteryLevel >= 5) {
+ value += (elem.masteryLevel - 5) * HORDE_SHARD_INCREMENT + HORDE_SHARD_PER_EQUIP;
+ }
+ }
+ if (value > 0) {
+ dispatch('system/applyEffect', {
+ type: 'base',
+ name: 'currencyHordeMysticalShardCap',
+ multKey: `hordeMastery`,
+ value
+ }, {root: true});
+ } else {
+ dispatch('system/resetEffect', {
+ type: 'base',
+ name: 'currencyHordeMysticalShardCap',
+ multKey: `hordeMastery`
+ }, {root: true});
+ }
+ },
+ updateSacrifice({ state, getters, dispatch }) {
+ const stats = getters.sacrificeEffectAtLevel(state.sacrificeLevel);
+ if (state.sacrificeLevel > 0) {
+ stats.forEach(elem => {
+ dispatch('system/applyEffect', {
+ type: elem.type,
+ name: elem.name,
+ multKey: `hordeSacrifice`,
+ value: elem.value
+ }, {root: true});
+ });
+ } else {
+ stats.forEach(elem => {
+ dispatch('system/resetEffect', {
+ type: elem.type,
+ name: elem.name,
+ multKey: `hordeSacrifice`
+ }, {root: true});
+ });
+ }
+ },
+ toggleAutocast({ state, rootGetters, commit }, name) {
+ if (state.autocast.includes(name)) {
+ commit('updateKey', {key: 'autocast', value: state.autocast.filter(el => el !== name)});
+ } else if (state.autocast.length < rootGetters['mult/get']('hordeAutocast')) {
+ commit('updateKey', {key: 'autocast', value: [...state.autocast, name]});
+ }
+ },
+ findTrinket({ state, commit }, index) {
+ const chosen = state.trinketDrop[index];
+ if (chosen) {
+ const chosenTrinket = state.trinket[chosen.name];
+ const newAmount = chosenTrinket.amount + chosen.amount;
+ commit('updateTrinketKey', {name: chosen.name, key: 'amount', value: newAmount});
+ const newLevel = state.trinketAmountNeeded.filter(el => newAmount >= el).length;
+ if (newLevel > chosenTrinket.level) {
+ commit('updateTrinketKey', {name: chosen.name, key: 'level', value: newLevel});
+ }
+ }
+ commit('updateKey', {key: 'trinketDrop', value: null});
+ },
+ applyTrinketEffects({ state, commit, dispatch }, name) {
+ state.trinket[name].effect.forEach(elem => {
+ dispatch('mult/set' + capitalize(elem.type), {name: elem.name, key: 'trinket_' + name, value: elem.value(state.trinket[name].level)}, {root: true});
+ });
+ if (state.trinket[name].activeType !== null) {
+ commit('updateSubkey', {name: 'skillActive', key: `trinket_${ name }`, value: 0});
+ }
+ },
+ removeTrinketEffects({ state, dispatch }, name) {
+ state.trinket[name].effect.forEach(elem => {
+ dispatch('mult/removeKey', {name: elem.name, key: 'trinket_' + name, type: elem.type}, {root: true});
+ });
+ },
+ useManaPotion({ state, rootGetters, dispatch }) {
+ if (rootGetters['consumable/canAfford']('horde_manaPotion')) {
+ dispatch('updateMana', Math.min(state.player.mana + state.cachePlayerStats.mana * 0.5, state.cachePlayerStats.mana));
+ dispatch('consumable/use', 'horde_manaPotion', {root: true});
+ }
}
}
}
diff --git a/src/store/index.js b/src/store/index.js
index 8f8c6801..f24dc1bc 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -29,6 +29,7 @@ import note from './note';
import treasure from './treasure';
import cryolab from './cryolab';
import consumable from './consumable';
+import tag from './tag';
// store modules
@@ -64,6 +65,7 @@ export default new Vuex.Store({
note,
treasure,
cryolab,
- consumable
+ consumable,
+ tag
}
})
diff --git a/src/store/meta.js b/src/store/meta.js
index 926e0724..caa266a1 100644
--- a/src/store/meta.js
+++ b/src/store/meta.js
@@ -22,9 +22,10 @@ export default {
cryolabFeature: 290,
galleryFeature: 360,
schoolArtSubfeature: 440,
- // generalOrladeeSubfeature: 500,
miningGasSubfeature: 625,
- // villageCraftingSubfeature: 800,
+ villageCraftingSubfeature: 800,
+ // generalOrladeeSubfeature: 1000,
+ hordeClassesSubfeature: 1100,
},
globalLevelNotes: {
meta_0: 5,
@@ -52,7 +53,7 @@ export default {
cryolab_0: 290,
gallery_0: 360,
},
- globalLevelList: ['mining_0', 'mining_1', 'village_0', 'horde_0', 'farm_0', 'gallery_0']
+ globalLevelList: ['mining_0', 'mining_1', 'village_0', 'village_1', 'horde_0', 'horde_1', 'farm_0', 'gallery_0']
},
getters: {
globalEventLevel: (state) => {
@@ -120,12 +121,22 @@ export default {
}}, {root: true});
commit('unlock/unlock', key, {root: true});
- // Start current event if events just got unlocked
- if (key === 'eventFeature') {
+ // Gain various gems on feature unlock to let new players experience the feature right away
+ if (key === 'gemFeature') {
+ dispatch('currency/gain', {feature: 'gem', name: 'ruby', amount: 50}, {root: true});
+ dispatch('currency/gain', {feature: 'gem', name: 'amethyst', amount: 800}, {root: true});
+ } else if (key === 'cardFeature') {
+ dispatch('currency/gain', {feature: 'gem', name: 'emerald', amount: 100}, {root: true});
+ } else if (key === 'eventFeature') {
+ dispatch('currency/gain', {feature: 'gem', name: 'topaz', amount: 500}, {root: true});
+
+ // Start current event if events just got unlocked
const currentEvent = rootGetters['event/currentEvent'];
if (currentEvent !== null) {
dispatch('event/start', currentEvent, {root: true});
}
+ } else if (key === 'treasureFeature') {
+ dispatch('currency/gain', {feature: 'gem', name: 'emerald', amount: 300}, {root: true});
}
}
}
@@ -138,7 +149,7 @@ export default {
}
// Get a relic at global level 40 (when relics unlock)
- if (state.globalLevel >= 40 && !rootState.relic.friendlyBat.found) {
+ if (state.globalLevel >= 40 && !rootState.relic.item.friendlyBat.found) {
dispatch('relic/find', 'friendlyBat', {root: true});
}
}
diff --git a/src/store/mining.js b/src/store/mining.js
index 6d96d780..67fddf17 100644
--- a/src/store/mining.js
+++ b/src/store/mining.js
@@ -1,7 +1,7 @@
import Vue from "vue";
-import { MINING_COAL_DEPTH, MINING_CRAFTING_COMPRESSION, MINING_DWELLER_OVERFLOW, MINING_ENHANCEMENT_BARS, MINING_ENHANCEMENT_FINAL, MINING_GRANITE_DEPTH, MINING_NITER_DEPTH, MINING_OBSIDIAN_DEPTH, MINING_SALT_DEPTH, MINING_SMELTERY_TEMPERATURE_SPEED, MINING_SULFUR_DEPTH } from "../js/constants";
+import { MINING_COAL_DEPTH, MINING_CRAFTING_COMPRESSION, MINING_DEEPROCK_DEPTH, MINING_DWELLER_OVERFLOW, MINING_ENHANCEMENT_BARS, MINING_ENHANCEMENT_FINAL, MINING_GLOWSHARD_DEPTH, MINING_GRANITE_DEPTH, MINING_NITER_DEPTH, MINING_OBSIDIAN_DEPTH, MINING_SALT_DEPTH, MINING_SMELTERY_TEMPERATURE_SPEED, MINING_SULFUR_DEPTH, SECONDS_PER_HOUR } from "../js/constants";
import { buildNum, capitalize } from "../js/utils/format";
-import { deltaLinear, logBase } from "../js/utils/math";
+import { deltaLinear, digitSum, logBase } from "../js/utils/math";
import { randomFloat } from "../js/utils/random";
export default {
@@ -17,15 +17,19 @@ export default {
neon: 41,
argon: 91,
krypton: 151,
- xenon: 221,
- radon: 301,
+ xenon: 301,
+ radon: 601,
},
breaks: [],
ingredientList: [],
resin: 0,
enhancement: {},
enhancementBars: 0,
- enhancementIngredient: null
+ enhancementIngredient: null,
+ glowshardLimit: 0,
+ beacon: {},
+ beaconPlaced: {},
+ beaconCooldown: 0,
},
getters: {
damage: (state, getters, rootState, rootGetters) => {
@@ -37,13 +41,14 @@ export default {
return Math.ceil(Math.pow(incrementValue, depth) * Math.pow(depth * 0.1 + 1, 2) * baseValue);
},
depthBaseToughness: (state, getters, rootState) => (depth) => {
- return (depth < 10 || rootState.system.features.mining.currentSubfeature === 1) ? 0 : (Math.pow(1.82, depth) * (depth * 0.01 - 0.09) * 0.25 * Math.pow(depth * 0.1 + 1, 2) * (depth > 250 ? Math.pow(depth * 0.02 - 4, depth - 250) : 1));
+ return Math.min(buildNum(1, 'C'), (depth < 10 || rootState.system.features.mining.currentSubfeature === 1) ? 0 : (Math.pow(1.82, depth) * (depth * 0.01 - 0.09) * 0.25 * Math.pow(depth * 0.1 + 1, 2) * (depth > 150 ? Math.pow(depth * 0.002 + 0.7, depth - 150) : 1) * ((depth >= 300 && (depth % 10 === 0) ? 100 : 1))));
},
depthToughness: (state, getters, rootState, rootGetters) => (depth) => {
return rootGetters['mult/get']('miningToughness', (getters.depthBaseToughness(depth)));
},
- depthBaseScrap: () => (depth) => {
- return Math.ceil(Math.pow(1.2, depth) * Math.pow(depth * 0.2 + 1.2, 2) * 2);
+ depthBaseScrap: (state, getters, rootState) => (depth) => {
+ const subfeature = rootState.system.features.mining.currentSubfeature;
+ return Math.ceil(Math.pow(1.2, depth) * Math.pow(depth * 0.2 + 1.2, 2) * (subfeature === 1 ? 0.1 : 2));
},
depthScrap: (state, getters, rootState, rootGetters) => (depth) => {
return rootGetters['mult/get']('currencyMiningScrapGain', getters.depthBaseScrap(depth));
@@ -82,6 +87,12 @@ export default {
case 'obsidian':
amount = Math.pow(1.05, state.depth - MINING_OBSIDIAN_DEPTH);
break;
+ case 'deeprock':
+ amount = Math.pow(1.05, state.depth - MINING_DEEPROCK_DEPTH) * Math.pow(1.5, digitSum(state.depth) - 14);
+ break;
+ case 'glowshard':
+ amount = 10;
+ break;
}
return amount;
},
@@ -111,6 +122,12 @@ export default {
if (state.depth >= MINING_OBSIDIAN_DEPTH && getters.enhancementLevel <= 0) {
obj.obsidian = getters.rareDropFinal('obsidian');
}
+ if (state.depth >= MINING_DEEPROCK_DEPTH && digitSum(state.depth) >= 14) {
+ obj.deeprock = getters.rareDropFinal('deeprock');
+ }
+ if (state.depth >= (MINING_GLOWSHARD_DEPTH + state.glowshardLimit)) {
+ obj.glowshard = getters.rareDropFinal('glowshard');
+ }
return obj;
},
graniteBreaksMult: (state, getters) => {
@@ -250,23 +267,35 @@ export default {
dwellerLimit: (state, getters, rootState, rootGetters) => {
return rootState.stat[`mining_maxDepth${rootState.system.features.mining.currentSubfeature}`].value * rootGetters['mult/get']('miningDepthDwellerMax');
},
- dwellerGreenCrystal: (state, getters, rootState) => {
- const baseValue = Math.floor(rootState.stat.mining_depthDweller0.value * 2);
- const capValue = Math.floor(rootState.stat.mining_depthDwellerCap0.value * 2);
- const bonusPercent = capValue > 0 ? (baseValue / capValue) : 1;
- return getters.dwellerGain(capValue, 0) * bonusPercent;
+ dwellerStats: (state, getters, rootState) => (subfeature) => {
+ const baseValue = Math.floor(rootState.stat[`mining_depthDweller${ subfeature }`].value * 2);
+ const capValue = Math.floor(rootState.stat[`mining_depthDwellerCap${ subfeature }`].value * 2);
+ return {cap: capValue, bonus: capValue > 0 ? (baseValue / capValue) : 1};
},
- dwellerYellowCrystal: (state, getters, rootState) => {
- const baseValue = Math.floor(rootState.stat.mining_depthDweller1.value * 2);
- const capValue = Math.floor(rootState.stat.mining_depthDwellerCap1.value * 2);
- const bonusPercent = capValue > 0 ? (baseValue / capValue) : 1;
- return getters.dwellerGain(capValue, 1) * bonusPercent;
+ dwellerBaseGreenCrystal: (state, getters) => {
+ const stats = getters.dwellerStats(0);
+ return getters.dwellerBaseGain(stats.cap) * stats.bonus;
+ },
+ dwellerGreenCrystal: (state, getters) => {
+ const stats = getters.dwellerStats(0);
+ return getters.dwellerGain(stats.cap, 0) * stats.bonus;
+ },
+ dwellerBaseYellowCrystal: (state, getters) => {
+ const stats = getters.dwellerStats(1);
+ return getters.dwellerBaseGain(stats.cap) * stats.bonus;
+ },
+ dwellerYellowCrystal: (state, getters) => {
+ const stats = getters.dwellerStats(1);
+ return getters.dwellerGain(stats.cap, 1) * stats.bonus;
},
crystalColor: () => (subfeature) => {
return ['Green', 'Yellow'][subfeature];
},
+ dwellerBaseGain: () => (steps) => {
+ return Math.pow(1.15, steps / 2) * steps * 7;
+ },
dwellerGain: (state, getters, rootState, rootGetters) => (steps, subfeature) => {
- return rootGetters['mult/get'](`currencyMiningCrystal${ getters.crystalColor(subfeature) }Gain`, Math.pow(1.15, steps / 2) * steps * 7);
+ return rootGetters['mult/get'](`currencyMiningCrystal${ getters.crystalColor(subfeature) }Gain`, getters.dwellerBaseGain(steps));
},
currentBreaks: (state) => {
return state.breaks.length >= state.depth ? state.breaks[state.depth - 1] : 0;
@@ -316,6 +345,33 @@ export default {
}
const dwellerSpeed = rootGetters['mult/get']('miningDepthDwellerSpeed') / dwellerLimit;
return logBase((amount - MINING_DWELLER_OVERFLOW - dwellerLimit) / -(MINING_DWELLER_OVERFLOW + dwellerLimit - rootState.stat[`mining_depthDwellerCap${rootState.system.features.mining.currentSubfeature}`].value), 1 - dwellerSpeed);
+ },
+ depthBeacon: (state, getters, rootState) => (depth) => {
+ if (rootState.system.features.mining.currentSubfeature !== 0) {
+ return null;
+ }
+ let beacon = null;
+ let beaconLevel = 0;
+ for (const [key, elem] of Object.entries(state.beaconPlaced)) {
+ const level = parseInt(key);
+ if ((depth >= level && depth <= (level + state.beacon[elem].range - 1)) && level > beaconLevel) {
+ beacon = elem;
+ beaconLevel = level;
+ }
+ }
+ return beacon;
+ },
+ currentDepthBeacon: (state, getters) => {
+ return getters.depthBeacon(state.depth);
+ },
+ beaconOwned: (state, getters, rootState, rootGetters) => (name) => {
+ let amount = rootGetters['mult/get'](state.beacon[name].ownedMult);
+ for (const [, elem] of Object.entries(state.beaconPlaced)) {
+ if (elem === name) {
+ amount--;
+ }
+ }
+ return amount;
}
},
mutations: {
@@ -349,9 +405,21 @@ export default {
effect: o.effect ?? []
});
},
+ initBeacon(state, o) {
+ Vue.set(state.beacon, o.name, {
+ ownedMult: o.ownedMult,
+ range: o.range ?? 1,
+ color: o.color ?? 'grey',
+ level: 0,
+ effect: o.effect ?? []
+ });
+ },
updateKey(state, o) {
Vue.set(state, o.key, o.value);
},
+ updateSubkey(state, o) {
+ Vue.set(state[o.name], o.key, o.value);
+ },
updateSmelteryKey(state, o) {
Vue.set(state.smeltery[o.name], o.key, o.value);
},
@@ -361,6 +429,9 @@ export default {
updateIngredientKey(state, o) {
Vue.set(state.ingredientList[o.index], o.key, o.value);
},
+ updateBeaconKey(state, o) {
+ Vue.set(state.beacon[o.name], o.key, o.value);
+ },
addIngredient(state, name) {
state.ingredientList.push({name, compress: 0});
},
@@ -393,6 +464,8 @@ export default {
for (const [key] of Object.entries(state.enhancement)) {
commit('updateEnhancementKey', {name: key, key: 'level', value: 0});
}
+ commit('updateKey', {key: 'beaconPlaced', value: {}});
+ commit('updateKey', {key: 'beaconCooldown', value: 0});
},
craftPickaxe({ state, rootState, getters, commit, dispatch, rootGetters }, consumables = {}) {
const subfeature = rootState.system.features.mining.currentSubfeature;
@@ -451,7 +524,7 @@ export default {
prestige({ state, rootState, getters, rootGetters, commit, dispatch }, subfeature) {
const currentSubfeature = rootState.system.features.mining.currentSubfeature;
const prestigeGain = [getters.dwellerGreenCrystal, getters.dwellerYellowCrystal][currentSubfeature];
- const emberGain = rootGetters['mult/get']('currencyMiningEmberGain');
+ const emberGain = Math.floor(rootGetters['mult/get']('currencyMiningEmberGain') * rootState.stat[`mining_depthDweller${ currentSubfeature }`].value);
if (prestigeGain > 0) {
commit('stat/increaseTo', {feature: 'mining', name: 'bestPrestige' + currentSubfeature, value: prestigeGain}, {root: true});
commit('stat/add', {feature: 'mining', name: 'prestigeCount', value: 1}, {root: true});
@@ -487,6 +560,7 @@ export default {
if (state.resin > rootGetters['mult/get']('miningResinMax')) {
commit('updateKey', {key: 'resin', value: rootGetters['mult/get']('miningResinMax')});
}
+ dispatch('applyBeaconEffects');
},
addToSmeltery({ state, getters, commit, dispatch }, o) {
const smeltery = state.smeltery[o.name];
@@ -551,6 +625,45 @@ export default {
rootState.stat[`mining_depthDweller${ subfeature }`].value,
getters.dwellerLimit
)}, {root: true});
+ },
+ placeBeacon({ state, getters, commit, dispatch }, o) {
+ if (state.beaconPlaced[o.depth] === undefined && getters.beaconOwned(o.beacon) >= 1) {
+ commit('updateSubkey', {name: 'beaconPlaced', key: o.depth, value: o.beacon});
+ dispatch('applyBeaconEffects');
+ }
+ },
+ removeBeacon({ state, commit, dispatch }, depth) {
+ if (state.beaconCooldown <= 0) {
+ let newObj = {};
+ for (const [key, elem] of Object.entries(state.beaconPlaced)) {
+ if (parseInt(key) !== depth) {
+ newObj[key] = elem;
+ }
+ }
+ commit('updateKey', {key: 'beaconCooldown', value: SECONDS_PER_HOUR * 20});
+ commit('updateKey', {key: 'beaconPlaced', value: newObj});
+ dispatch('applyBeaconEffects');
+ }
+ },
+ applyBeaconEffects({ state, getters, dispatch }) {
+ // Reset effects first
+ let effects = [];
+ for (const [key, elem] of Object.entries(state.beacon)) {
+ effects.push(...elem.effect.map(el => {
+ return {...el, key};
+ }));
+ }
+ effects.forEach(effect => {
+ dispatch('system/resetEffect', {type: effect.type, name: effect.name, multKey: `miningBeacon_${ effect.key }`}, {root: true});
+ });
+
+ // Then apply current one (if it exists)
+ const beacon = getters.currentDepthBeacon;
+ if (beacon) {
+ state.beacon[beacon].effect.forEach(effect => {
+ dispatch('system/applyEffect', {type: effect.type, name: effect.name, multKey: `miningBeacon_${ beacon }`, value: effect.value(state.beacon[beacon].level), trigger: false}, {root: true});
+ });
+ }
}
}
}
diff --git a/src/store/mult.js b/src/store/mult.js
index 8a57e246..1a28d945 100644
--- a/src/store/mult.js
+++ b/src/store/mult.js
@@ -197,6 +197,7 @@ export default {
case 'currencyGain': {
for (const [key, elem] of Object.entries(rootState.currency)) {
if (elem.feature === o.feature && !blacklist.includes(key) &&
+ (o.type === undefined || elem.type === o.type) &&
(o.subtype === undefined || elem.subtype === o.subtype)
) {
group.push(rootGetters['currency/gainMultName'](...key.split('_')));
@@ -308,6 +309,8 @@ export default {
} else {
dispatch('removeKey', {name: 'hordeHeirloomChance', type: 'base', key: 'hordeNostalgia'});
}
+ } else if (name.slice(0, 5) === 'horde') {
+ dispatch('horde/updatePlayerCache', null, {root: true});
}
},
updateTriggerCaches({ getters, dispatch }, o) {
diff --git a/src/store/nightHunt.js b/src/store/nightHunt.js
index d58b3de6..651a49e5 100644
--- a/src/store/nightHunt.js
+++ b/src/store/nightHunt.js
@@ -13,7 +13,8 @@ export default {
potion: {},
performedRituals: [],
ritualFamiliarity: {},
- ritualHint: {}
+ ritualHint: {},
+ favouriteIngredient: 'copy',
},
getters: {
ritualCost: (state, getters) => {
@@ -188,16 +189,22 @@ export default {
commit('updateKey', {key: 'performedRituals', value: []});
commit('updateKey', {key: 'ritualFamiliarity', value: {}});
commit('updateKey', {key: 'ritualHint', value: {}});
+ commit('updateKey', {key: 'favouriteIngredient', value: 'copy'});
for (const [key] of Object.entries(state.potion)) {
commit('updatePotionKey', {name: key, key: 'recipe', value: null});
commit('updatePotionKey', {name: key, key: 'level', value: 0});
}
},
- addChangedCurrency({ state, rootState, rootGetters, commit }, amount = 1) {
+ addChangedCurrency({ state, rootState, rootGetters, commit }, o) {
const currencyList = Object.keys(state.ingredientStat).slice(0, rootGetters['mult/get']('nightHuntFindableIngredients'));
let targetList = Object.keys(rootState.currency).filter(key => key.split('_')[0] !== 'event' && state.changedCurrency[key] === undefined && rootState.stat[key].total > 0);
- for (let i = 0; i < amount && targetList.length > 0; i++) {
+ for (let i = 0; i < o.sack && targetList.length > 0; i++) {
+ const targetIndex = randomInt(0, targetList.length - 1);
+ commit('updateSubkey', {key: 'changedCurrency', subkey: targetList[targetIndex], value: 'sack'});
+ targetList.splice(targetIndex, 1);
+ }
+ for (let i = 0; i < o.random && targetList.length > 0; i++) {
const targetIndex = randomInt(0, targetList.length - 1);
commit('updateSubkey', {key: 'changedCurrency', subkey: targetList[targetIndex], value: randomElem(currencyList)});
targetList.splice(targetIndex, 1);
@@ -206,7 +213,31 @@ export default {
claimChangedCurrency({ state, rootGetters, commit, dispatch }, name) {
const claimedName = state.changedCurrency[name];
if (claimedName !== undefined) {
- dispatch('currency/gain', {feature: 'event', name: claimedName, amount: rootGetters['mult/get']('nightHuntIngredientSize')}, {root: true});
+ if (claimedName === 'sack') {
+ const currencyList = Object.keys(state.ingredientStat).slice(0, rootGetters['mult/get']('nightHuntFindableIngredients'));
+ let amount = rootGetters['mult/get']('nightHuntIngredientSize') * 10;
+ if (state.favouriteIngredient === 'copy') {
+ amount += rootGetters['mult/get']('nightHuntFavouriteIngredientSize') * 10;
+ }
+ const amountPerIngredient = Math.floor(amount / currencyList.length);
+ const amountLeft = amount - amountPerIngredient;
+ if (amountPerIngredient > 0) {
+ currencyList.forEach(elem => {
+ dispatch('currency/gain', {feature: 'event', name: elem, amount: amountPerIngredient}, {root: true});
+ });
+ }
+ shuffleArray(currencyList).slice(0, amountLeft).forEach(elem => {
+ dispatch('currency/gain', {feature: 'event', name: elem, amount: 1}, {root: true});
+ });
+ if (state.favouriteIngredient !== 'copy' && rootGetters['mult/get']('nightHuntFavouriteIngredientSize') > 0) {
+ dispatch('currency/gain', {feature: 'event', name: state.favouriteIngredient, amount: rootGetters['mult/get']('nightHuntFavouriteIngredientSize') * 10}, {root: true});
+ }
+ } else {
+ dispatch('currency/gain', {feature: 'event', name: claimedName, amount: rootGetters['mult/get']('nightHuntIngredientSize')}, {root: true});
+ if (rootGetters['mult/get']('nightHuntFavouriteIngredientSize') > 0) {
+ dispatch('currency/gain', {feature: 'event', name: state.favouriteIngredient === 'copy' ? claimedName : state.favouriteIngredient, amount: rootGetters['mult/get']('nightHuntFavouriteIngredientSize')}, {root: true});
+ }
+ }
let newObj = {};
for (const [key, elem] of Object.entries(state.changedCurrency)) {
if (key !== name) {
@@ -223,8 +254,9 @@ export default {
const potionRecipe = getters.ritualRecipe;
const ritualKey = state.ritualIngredients.join(',');
const tier = state.ritualIngredients.length;
- let rngGen = rootGetters['system/getRng']('nightHunt_ritual');
- commit('system/nextRng', {name: 'nightHunt_ritual', amount: 1}, {root: true});
+ const rngSeed = `nightHunt_ritual${ potionRecipe ? ('_' + potionRecipe) : '' }`;
+ let rngGen = rootGetters['system/getRng'](rngSeed);
+ commit('system/nextRng', {name: rngSeed, amount: 1}, {root: true});
const stabilityChance = rngGen();
// Do not lose base resources if the ritual is really stable (100% - 200%)
@@ -247,7 +279,7 @@ export default {
if (chance(stats.nightHuntRitualSuccessChance, rngGen())) {
if (!getters.ritualPerformed) {
if (!potionRecipe) {
- dispatch('currency/gain', {feature: 'event', name: 'nightHuntToken', amount: 1}, {root: true});
+ dispatch('event/giveTokens', {event: 'nightHunt', amount: 1}, {root: true});
dispatch('note/find', 'event_29', {root: true});
canAddHint = true;
}
@@ -257,7 +289,7 @@ export default {
if (potionRecipe) {
commit('updatePotionKey', {name: potionRecipe, key: 'level', value: state.potion[potionRecipe].level + 1});
dispatch('applyPotionEffects', potionRecipe);
- dispatch('currency/gain', {feature: 'event', name: 'nightHuntToken', amount: tier * 2}, {root: true});
+ dispatch('event/giveTokens', {event: 'nightHunt', amount: tier * 2}, {root: true});
dispatch('note/find', 'event_28', {root: true});
// Remove the hint if you found the recipe
diff --git a/src/store/relic.js b/src/store/relic.js
index 616e397d..a1b3f12a 100644
--- a/src/store/relic.js
+++ b/src/store/relic.js
@@ -2,12 +2,15 @@ import Vue from "vue"
export default {
namespaced: true,
- state: {},
+ state: {
+ item: {},
+ glyph: {}
+ },
getters: {
owned: (state) => {
let arr = [];
- for (const [key, elem] of Object.entries(state)) {
+ for (const [key, elem] of Object.entries(state.item)) {
if (elem.found) {
arr.push(key);
}
@@ -18,35 +21,54 @@ export default {
},
mutations: {
init(state, o) {
- Vue.set(state, o.name, {
+ Vue.set(state.item, o.name, {
found: false,
feature: o.feature ?? [],
icon: o.icon ?? 'mdi-sack',
- color: o.color ?? 'amber',
+ color: o.color ?? 'grey',
+ effect: o.effect ?? []
+ });
+ },
+ initGlyph(state, o) {
+ Vue.set(state.glyph, o.name, {
+ level: 0,
+ progress: 0,
+ icon: o.icon ?? 'mdi-sack',
+ color: o.color ?? 'grey',
effect: o.effect ?? []
});
},
updateKey(state, o) {
- Vue.set(state[o.name], o.key, o.value);
+ Vue.set(state.item[o.name], o.key, o.value);
}
},
actions: {
cleanState({ state, commit }) {
- for (const [key] of Object.entries(state)) {
+ for (const [key] of Object.entries(state.item)) {
commit('updateKey', {name: key, key: 'found', value: false});
}
},
apply({ state, dispatch }, o) {
let trigger = o.onFind ?? false;
- state[o.name].effect.forEach(eff => {
+ state.item[o.name].effect.forEach(eff => {
dispatch('system/applyEffect', {type: eff.type, name: eff.name, multKey: `relic_${o.name}`, value: eff.value, trigger}, {root: true});
});
},
find({ state, commit, dispatch }, name) {
- if (!state[name].found) {
+ if (!state.item[name].found) {
commit('updateKey', {name, key: 'found', value: true});
dispatch('apply', {name, onFind: true});
}
+ },
+ reset({ state, commit, dispatch }, feature) {
+ for (const [key, elem] of Object.entries(state.item)) {
+ if (elem.found && elem.feature.length === 1 && elem.feature[0] === feature) {
+ elem.effect.forEach(eff => {
+ dispatch('system/resetEffect', {type: eff.type, name: eff.name, multKey: `relic_${ key }`}, {root: true});
+ });
+ commit('updateKey', {name: key, key: 'found', value: false});
+ }
+ }
}
}
}
diff --git a/src/store/school.js b/src/store/school.js
index 44e64225..2e84264b 100644
--- a/src/store/school.js
+++ b/src/store/school.js
@@ -22,6 +22,9 @@ export default {
if (dustBase > 1000) {
dustBase = Math.pow((dustBase - 900) / 100, 0.8) * 100 + 900;
}
+ if (dustBase > 2000) {
+ dustBase = Math.pow((dustBase - 1900) / 100, 0.2) * 100 + 1900;
+ }
return Math.round(dustBase * getters.dustMult);
}
},
diff --git a/src/store/snowdown.js b/src/store/snowdown.js
index eaaa0a21..025fb9fa 100644
--- a/src/store/snowdown.js
+++ b/src/store/snowdown.js
@@ -475,7 +475,7 @@ export default {
}
// Get currency rewards
dispatch('currency/gain', {feature: 'event', name: 'snowball', amount: Math.round(rootGetters['mult/get']('snowdownLootRating', 3, 3))}, {root: true});
- dispatch('currency/gain', {feature: 'event', name: 'snowdownToken', amount: Math.floor(rootGetters['mult/get']('snowdownLootRating', state.fight * 3.5 + 50, 0.05))}, {root: true});
+ dispatch('event/giveTokens', {event: 'snowdown', amount: Math.floor(rootGetters['mult/get']('snowdownLootRating', state.fight * 3.5 + 50, 0.05))}, {root: true});
commit('updateKey', {key: 'fight', value: state.fight + 1});
commit('updateKey', {key: 'rewardProducer', value: true});
diff --git a/src/store/stat.js b/src/store/stat.js
index 882258c5..89bf0530 100644
--- a/src/store/stat.js
+++ b/src/store/stat.js
@@ -12,7 +12,8 @@ export default {
display: o.display ?? 'number',
default: o.value ?? 0,
value: o.value ?? 0,
- total: o.value ?? 0
+ total: o.value ?? 0,
+ showInStatistics: o.showInStatistics ?? false
});
},
add(state, o) {
@@ -46,6 +47,14 @@ export default {
commit('updateKey', {name: key, key: 'value', value: elem.default});
}
}
+ },
+ resetAll({ state, commit }, feature) {
+ for (const [key, elem] of Object.entries(state)) {
+ if (elem.feature === feature) {
+ commit('updateKey', {name: key, key: 'value', value: elem.default});
+ commit('updateKey', {name: key, key: 'total', value: elem.default});
+ }
+ }
}
}
}
diff --git a/src/store/summerFestival.js b/src/store/summerFestival.js
index 094af3c1..04a64154 100644
--- a/src/store/summerFestival.js
+++ b/src/store/summerFestival.js
@@ -629,7 +629,7 @@ export default {
dispatch('currency/spend', {feature: split[0], name: split[1], amount: elem.amount}, {root: true});
}
});
- dispatch('currency/gain', {feature: 'event', name: 'summerFestivalToken', amount: getters.questTokenGain}, {root: true});
+ dispatch('event/giveTokens', {event: 'summerFestival', amount: getters.questTokenGain}, {root: true});
commit('updateKey', {key: 'questsCompleted', value: state.questsCompleted + 1});
if (state.questsCompleted <= 50 && state.questsCompleted % 5 === 0) {
commit('updateKey', {key: 'freeExpansion', value: state.freeExpansion + 1});
diff --git a/src/store/system.js b/src/store/system.js
index 7f43c6e5..4ff983a8 100644
--- a/src/store/system.js
+++ b/src/store/system.js
@@ -1,13 +1,16 @@
import Vue from "vue";
import { tick } from "../js/tick";
-import { getDay } from "../js/utils/date";
import { randomHex } from "../js/utils/random";
import seedrandom from "seedrandom";
+import { LOCAL_STORAGE_NAME } from "../js/constants";
export default {
namespaced: true,
state: {
- version: '1.4.1',
+ version: '1.5.3',
+ cheaterSelfMark: 0,
+ cheatDetected: {},
+ lastPlayedDays: [],
patchnote: {},
timestamp: null,
screen: 'newGame',
@@ -17,6 +20,7 @@ export default {
unlock: null,
subfeatures: ['miningGasSubfeature'],
currentSubfeature: 0,
+ nextSubfeature: 0,
icon: 'mdi-pickaxe',
offlineStat: ['mining_maxDepth0', 'mining_maxDepth1', 'mining_depthDwellerCap0', 'mining_depthDwellerCap1'],
main: true
@@ -25,14 +29,16 @@ export default {
unlock: 'villageFeature',
subfeatures: ['villageCraftingSubfeature'],
currentSubfeature: 0,
+ nextSubfeature: 0,
icon: 'mdi-home-group',
offlineStat: ['village_maxBuilding'],
main: true
},
horde: {
unlock: 'hordeFeature',
- subfeatures: [],
+ subfeatures: ['hordeClassesSubfeature'],
currentSubfeature: 0,
+ nextSubfeature: 0,
icon: 'mdi-account-group',
offlineStat: ['horde_maxZone', 'horde_totalMastery'],
main: true
@@ -41,6 +47,7 @@ export default {
unlock: 'farmFeature',
subfeatures: [],
currentSubfeature: 0,
+ nextSubfeature: 0,
icon: 'mdi-barn',
offlineStat: [],
main: true
@@ -49,6 +56,7 @@ export default {
unlock: 'galleryFeature',
subfeatures: [],
currentSubfeature: 0,
+ nextSubfeature: 0,
icon: 'mdi-image-frame',
offlineStat: [],
main: true
@@ -184,6 +192,13 @@ export default {
value: false,
defaultValue: false
},
+ useLegacyFarmSelect: {
+ unlock: 'farmFeature',
+ hasDescription: true,
+ type: 'switch',
+ value: false,
+ defaultValue: false
+ },
}
},
automation: {
@@ -368,6 +383,66 @@ export default {
defaultValue: false
}
}
+ },
+ mods_qol: {
+ unlock: null,
+ items: {
+ progressNiterMiningSound: {
+ unlock: null,
+ hasDescription: false,
+ type: 'number',
+ min: 1,
+ max: 1000000,
+ step: 1,
+ suffix: 'times',
+ value: null,
+ defaultValue: null,
+ clearable: true
+ },
+ progressNiterMiningActiveSound: {
+ unlock: null,
+ hasDescription: false,
+ type: 'switch',
+ value: false,
+ defaultValue: false
+ }
+ }
+ },
+ mods_automation: {
+ unlock: null,
+ items: {
+ progressNiterMining: {
+ unlock: null,
+ hasDescription: false,
+ type: 'number',
+ min: 1,
+ max: 1000000,
+ step: 1,
+ suffix: 'times',
+ value: null,
+ defaultValue: null,
+ clearable: true
+ },
+ progressNiterMiningActive: {
+ unlock: null,
+ hasDescription: false,
+ type: 'switch',
+ value: false,
+ defaultValue: false
+ }
+ }
+ },
+ mods_cheats: {
+ unlock: null,
+ items: {
+ cheatsGo: {
+ unlock: null,
+ hasDescription: false,
+ type: 'switch',
+ value: false,
+ defaultValue: false
+ }
+ }
}
},
keybinds: {
@@ -396,7 +471,8 @@ export default {
farmHint: false,
tutorial: {},
cachePage: {},
- playerId: null
+ playerId: null,
+ playerName: null,
},
getters: {
mainFeatures: (state, getters, rootState) => {
@@ -452,23 +528,35 @@ export default {
case 'mining': {
switch (state.features.mining.currentSubfeature) {
case 0:
- return rootState.stat.mining_maxDepth0.total > 300;
+ return rootState.stat.mining_maxDepth0.total > 475;
case 1:
return rootState.stat.mining_maxDepth1.total > 160;
}
break;
}
case 'village': {
- return rootState.upgrade.item.village_windTurbine.highestLevel > 0;
+ switch (state.features.village.currentSubfeature) {
+ case 0:
+ return rootState.upgrade.item.village_windTurbine.highestLevel > 0;
+ case 1:
+ return rootState.upgrade.item.village_marbleBin.highestLevel > 0;
+ }
+ break;
}
case 'horde': {
- return rootState.stat.horde_maxZone.total > 200;
+ switch (state.features.horde.currentSubfeature) {
+ case 0:
+ return rootState.stat.horde_maxZone.total > 300;
+ case 1:
+ return rootState.unlock.hordeEndOfContent.use;
+ }
+ break;
}
case 'farm': {
- return rootState.upgrade.item.farm_seedBox.highestLevel >= 19;
+ return rootState.upgrade.item.farm_seedBox.highestLevel >= 24;
}
case 'gallery': {
- return rootState.stat["gallery_deep-orange"].total > 0;
+ return rootState.stat.gallery_brown.total > 0;
}
default:
return false;
@@ -484,6 +572,28 @@ export default {
}
}
return null;
+ },
+ cheetahState: (state) => {
+ let highest = 0;
+ for (const [, elem] of Object.entries(state.cheatDetected)) {
+ if (elem.severity > highest) {
+ highest = elem.severity;
+ }
+ }
+ return highest;
+ },
+ cheetahBreakdown: (state) => {
+ let obj = {};
+ for (const [key, elem] of Object.entries(state.cheatDetected)) {
+ const feature = key.split('_')[1];
+ if (obj[feature] === undefined) {
+ obj[feature] = 0;
+ }
+ if (elem.severity > obj[feature]) {
+ obj[feature] = elem.severity;
+ }
+ }
+ return obj;
}
},
mutations: {
@@ -543,6 +653,9 @@ export default {
updateSubfeature(state, o) {
Vue.set(state.features[o.key], 'currentSubfeature', o.value);
},
+ updateNextSubfeature(state, o) {
+ Vue.set(state.features[o.key], 'nextSubfeature', o.value);
+ },
updateKeybind(state, o) {
Vue.set(state.keybinds, o.name, o.value);
},
@@ -575,10 +688,34 @@ export default {
if (state.playerId === null) {
state.playerId = randomHex(16);
}
+ },
+ registerCheat(state, o) {
+ const key = (o.modid ?? 'gooboo') + '_' + (o.feature ?? 'meta') + '_' + o.name;
+ const severity = o.severity ?? 200;
+ if (state.cheatDetected[key] === undefined) {
+ console.warn(`Cheat detected: ${ key } - severity ${ severity }`);
+ Vue.set(state.cheatDetected, key, {version: state.version, severity});
+ }
+ if (state.cheatDetected[key] !== undefined && state.cheatDetected[key].severity < severity) {
+ console.warn(`Cheat severity increased: ${ key } - severity ${ severity }`);
+ Vue.set(state.cheatDetected[key], 'severity', severity);
+ }
+ },
+ reformFeature(state, feature) {
+ let newCheatObj = {};
+ for (const [key, elem] of Object.entries(state.cheatDetected)) {
+ if (key.split('_')[1] !== feature) {
+ newCheatObj[key] = elem;
+ }
+ }
+ Vue.set(state, 'cheatDetected', newCheatObj);
}
},
actions: {
cleanState({ state, commit }) {
+ commit('updateKey', {key: 'cheaterSelfMark', value: 0});
+ commit('updateKey', {key: 'cheatDetected', value: {}});
+ commit('updateKey', {key: 'lastPlayedDays', value: []});
commit('updateKey', {key: 'notification', value: []});
commit('updateKey', {key: 'keybindCurrent', value: null});
commit('updateKey', {key: 'autosaveTimer', value: null});
@@ -595,6 +732,7 @@ export default {
commit('updateKey', {key: 'rng', value: {}});
commit('updateKey', {key: 'cachePage', value: {}});
commit('updateKey', {key: 'playerId', value: null});
+ commit('updateKey', {key: 'playerName', value: null});
for (const [key, elem] of Object.entries(state.features)) {
if (elem.currentSubfeature !== undefined) {
@@ -642,6 +780,11 @@ export default {
}
}
break;
+ case 'tag':
+ if (o.value !== null) {
+ commit('tag/set', {name: o.name, key: o.multKey, value: o.value}, {root: true});
+ }
+ break;
case 'keepUpgrade':
if (o.value) {
dispatch('upgrade/makePersistent', o.name, {root: true});
@@ -655,6 +798,11 @@ export default {
case 'villageJob':
commit('village/updateJobKey', {name: o.name, key: 'max', value: o.value}, {root: true});
break;
+ case 'villageCraft':
+ if (o.value) {
+ commit('village/updateSubkey', {key: 'crafting', name: o.name, subkey: 'unlocked', value: true}, {root: true});
+ }
+ break;
case 'farmSeed':
if (o.value) {
commit('farm/updateCropKey', {name: o.name, key: 'found', value: true}, {root: true});
@@ -674,6 +822,11 @@ export default {
commit('gallery/updateIdeaKey', {name: o.name, key: 'owned', value: true}, {root: true});
}
break;
+ case 'galleryShape':
+ if (o.value) {
+ commit('gallery/updateShapeKey', {name: o.name, key: 'unlocked', value: true}, {root: true});
+ }
+ break;
default:
break;
}
@@ -692,9 +845,15 @@ export default {
case 'unlock':
commit('unlock/reset', o.name, {root: true});
break;
+ case 'tag':
+ commit('tag/reset', {name: o.name, key: o.multKey}, {root: true});
+ break;
case 'villageJob':
commit('village/updateJobKey', {name: o.name, key: 'max', value: 0}, {root: true});
break;
+ case 'villageCraft':
+ commit('village/updateSubkey', {key: 'crafting', name: o.name, subkey: 'unlocked', value: false}, {root: true});
+ break;
default:
break;
}
@@ -774,14 +933,6 @@ export default {
dispatch('farm/updateGrownHint', null, {root: true});
}
},
- updateCurrentDay({ state, rootState, commit, dispatch }) {
- const oldDay = state.currentDay;
- const newDay = getDay();
- commit('updateKey', {key: 'currentDay', value: newDay});
- if (rootState.unlock.eventFeature.see && oldDay !== null && oldDay !== newDay) {
- dispatch('event/dayChange', {start: oldDay, end: newDay}, {root: true});
- }
- },
buyTheme({ state, rootGetters, commit, dispatch }, name) {
const theme = state.themes[name];
if (!theme.owned && theme.price !== null && rootGetters['currency/value']('gem_amethyst') >= theme.price) {
@@ -789,6 +940,160 @@ export default {
dispatch('currency/spend', {feature: 'gem', name: 'amethyst', amount: theme.price}, {root: true});
}
},
+ resetFeatureProgress({ state, rootState, commit, dispatch }, o) {
+ if (o.feature !== 'school') {
+ commit('system/updateSubfeature', {key: o.feature, value: 0}, {root: true});
+ for (let i = 0, n = state.features[o.feature].subfeatures.length + 1; i < n; i++) {
+ dispatch('upgrade/resetAll', {feature: o.feature, subfeature: i, type: 'regular'}, {root: true});
+ if (o.feature === 'village' && i === 0) {
+ dispatch('upgrade/resetAll', {feature: o.feature, subfeature: i, type: 'building'}, {root: true});
+ }
+ if (o.feature === 'gallery' && i === 0) {
+ dispatch('upgrade/resetAll', {feature: o.feature, subfeature: i, type: 'shape'}, {root: true});
+ }
+ if (o.feature !== 'farm') {
+ dispatch('upgrade/resetAll', {feature: o.feature, subfeature: i, type: 'prestige'}, {root: true});
+ }
+ }
+ dispatch('currency/reset', {feature: o.feature}, {root: true});
+ dispatch('card/resetCards', o.feature, {root: true});
+ dispatch('stat/resetAll', o.feature, {root: true});
+ }
+
+ // Feature specific effects before state wipe
+ if (o.feature === 'mining') {
+ for (const [key, elem] of Object.entries(rootState.mining.enhancement)) {
+ if (elem.level > 0) {
+ commit('mining/updateEnhancementKey', {name: key, key: 'level', value: 0}, {root: true});
+ dispatch('mining/resetEnhancement', key, {root: true});
+ }
+ }
+ }
+ if (o.feature === 'horde') {
+ for (const [key, elem] of Object.entries(rootState.horde.items)) {
+ if (elem.equipped) {
+ dispatch('horde/unequipItem', key, {root: true});
+ }
+ }
+ for (const [key] of Object.entries(rootState.horde.itemStatMult)) {
+ const split = key.split('_');
+ dispatch('system/resetEffect', {type: split[1], name: split[0], multKey: `hordeItemPermanent`}, {root: true});
+ }
+ for (const [key, elem] of Object.entries(rootState.horde.heirloom)) {
+ elem.effect.forEach(eff => {
+ dispatch('system/resetEffect', {type: eff.type, name: eff.name, multKey: `hordeHeirloom_${ key }`}, {root: true});
+ });
+ }
+ for (const [name, skill] of Object.entries(rootState.horde.fighterClass[rootState.horde.selectedClass].skills)) {
+ if (skill.type !== 'active') {
+ skill.effect.forEach(eff => {
+ dispatch('system/resetEffect', {
+ type: eff.type,
+ name: eff.name,
+ multKey: `hordeSkill_${name}`
+ }, {root: true});
+ });
+ }
+ }
+ }
+
+ // Clean state
+ dispatch(`${ o.feature }/cleanState`, null, {root: true});
+
+ // Clear cheater status
+ commit('reformFeature', o.feature);
+
+ // Feature specific effects after state wipe
+ if (o.feature === 'mining') {
+ dispatch('mining/applyBeaconEffects', null, {root: true});
+ }
+ if (o.feature === 'village') {
+ for (const [key] of Object.entries(rootState.village.job)) {
+ dispatch('village/applyJobEffect', key, {root: true});
+ }
+ for (const [key] of Object.entries(rootState.village.policy)) {
+ dispatch('village/applyPolicyEffect', key, {root: true});
+ }
+ for (const [key, elem] of Object.entries(rootState.village.crafting)) {
+ if (elem.isSpecial) {
+ elem.effect.forEach(reward => {
+ dispatch('system/resetEffect', {type: reward.type, name: reward.name, multKey: `villageSpecialCraft_${ key }`}, {root: true});
+ });
+ }
+ }
+ dispatch('village/applyOfferingEffect', null, {root: true});
+ dispatch('upgrade/updateVillageStats', null, {root: true});
+ }
+ if (o.feature === 'horde') {
+ dispatch('horde/resetStats', null, {root: true});
+ dispatch('horde/updateNostalgia', null, {root: true});
+ dispatch('horde/applyClassEffects', null, {root: true});
+ dispatch('horde/applyClassLevelEffects', null, {root: true});
+ dispatch('mult/updateExternalCaches', 'hordeNostalgia', {root: true});
+
+ for (const [key] of Object.entries(rootState.horde.trinket)) {
+ dispatch('horde/removeTrinketEffects', key, {root: true})
+ }
+
+ // Reset tower rewards
+ for (const [name, tower] of Object.entries(rootState.horde.tower)) {
+ for (const [floor, reward] of Object.entries(tower.reward)) {
+ dispatch('system/resetEffect', {type: reward.type, name: reward.name, multKey: `hordeTower_${ name }_${ floor }`}, {root: true});
+ }
+ }
+
+ // Reset battle pass rewards
+ dispatch('system/resetEffect', {type: 'mult', name: 'hordeAttack', multKey: `hordeBattlePass`}, {root: true});
+ dispatch('system/resetEffect', {type: 'mult', name: 'hordeHealth', multKey: `hordeBattlePass`}, {root: true});
+ dispatch('system/resetEffect', {type: 'mult', name: 'currencyHordeBoneGain', multKey: `hordeBattlePass`}, {root: true});
+ dispatch('system/resetEffect', {type: 'mult', name: 'currencyHordeBloodGain', multKey: `hordeBattlePass`}, {root: true});
+ dispatch('system/resetEffect', {type: 'mult', name: 'currencyHordeSoulCorruptedGain', multKey: `hordeBattlePass`}, {root: true});
+ dispatch('system/resetEffect', {type: 'mult', name: 'currencyHordeCourageGain', multKey: `hordeBattlePass`}, {root: true});
+ for (const [key, elem] of Object.entries(rootState.horde.battlePassEffect)) {
+ elem.effect.forEach(effect => {
+ dispatch('system/resetEffect', {
+ type: effect.type,
+ name: effect.name,
+ multKey: `hordeBattlePass_${ key }`
+ }, {root: true});
+ });
+ }
+
+ dispatch('horde/updateEnergy', null, {root: true});
+ dispatch('horde/updateMana', null, {root: true});
+ dispatch('horde/updateActiveTimer', 0, {root: true});
+ dispatch('horde/updateMaxDifficulty', null, {root: true});
+ dispatch('horde/updateMysticalShardCap', null, {root: true});
+ dispatch('horde/updateSacrifice', null, {root: true});
+ }
+ if (o.feature === 'farm') {
+ commit('farm/initField', null, {root: true});
+ dispatch('farm/applyEarlyGameBuff', null, {root: true});
+ dispatch('farm/applyCropPrestige', null, {root: true});
+ dispatch('farm/applyGeneEffects', null, {root: true});
+ }
+ if (o.feature === 'gallery') {
+ for (const [key] of Object.entries(rootState.gallery.idea)) {
+ dispatch('gallery/applyIdeaReset', key, {root: true});
+ }
+ for (const [key] of Object.entries(rootState.gallery.colorData)) {
+ dispatch('gallery/applyCanvasLevel', {name: key}, {root: true});
+ }
+ commit('gallery/initShapeGrid', null, {root: true});
+ }
+
+ // Make sure premium buildings and relics get applied correctly
+ for (const [key, elem] of Object.entries(rootState.upgrade.item)) {
+ if (elem.feature === o.feature && elem.type === 'premium') {
+ dispatch('upgrade/apply', {name: key}, {root: true});
+ }
+ }
+ for (const [key, elem] of Object.entries(rootState.relic.item)) {
+ if (elem.feature.includes(o.feature) && elem.found) {
+ dispatch('relic/apply', {name: key, onFind: true}, {root: true});
+ }
+ }
+ },
confirmAction({ state, dispatch }) {
switch (state.confirm.type) {
case 'prestige': {
@@ -830,6 +1135,10 @@ export default {
}
break;
}
+ case 'galleryMotivation': {
+ dispatch('gallery/buyMotivation', null, {root: true});
+ break;
+ }
case 'schoolExamPass': {
dispatch('school/buyPass', null, {root: true});
break;
@@ -868,6 +1177,14 @@ export default {
dispatch('mining/craftPickaxe', state.confirm.consumable, {root: true});
break;
}
+ case 'openIngredientBox': {
+ dispatch('village/openIngredientBox', null, {root: true});
+ break;
+ }
+ case 'useManaPotion': {
+ dispatch('horde/useManaPotion', null, {root: true});
+ break;
+ }
case 'fastPrestige': {
dispatch('gem/fastPrestige', state.confirm.prestige, {root: true});
break;
@@ -875,6 +1192,15 @@ export default {
}
break;
}
+ case 'reset': {
+ dispatch('resetFeatureProgress', state.confirm);
+ break;
+ }
+ case 'resetAll': {
+ localStorage.removeItem(LOCAL_STORAGE_NAME);
+ location.reload();
+ break;
+ }
}
}
}
diff --git a/src/store/tag.js b/src/store/tag.js
new file mode 100644
index 00000000..214f28b6
--- /dev/null
+++ b/src/store/tag.js
@@ -0,0 +1,58 @@
+import Vue from "vue"
+
+export default {
+ namespaced: true,
+ state: {},
+ getters: {
+ isActive: (state) => (name) => {
+ return Object.keys(state[name].values).length > 0;
+ },
+ values: (state) => (name) => {
+ let values = state[name].params.map(() => 0);
+ const stacking = state[name].stacking;
+ for (const [, arr] of Object.entries(state[name].values)) {
+ arr.forEach((elem, index) => {
+ if (stacking === 'add') {
+ values[index] += elem;
+ } else if (stacking === 'max') {
+ if (elem > values[index]) {
+ values[index] = elem;
+ }
+ }
+ });
+ }
+ return values;
+ }
+ },
+ mutations: {
+ init(state, o) {
+ Vue.set(state, o.name, {
+ params: o.params ?? [],
+ stacking: o.stacking ?? 'add',
+ values: {}
+ });
+ },
+ set(state, o) {
+ Vue.set(state[o.name].values, o.key, o.value);
+ },
+ reset(state, o) {
+ let newObj = {};
+ for (const [key, elem] of Object.entries(state[o.name].values)) {
+ if (key !== o.key) {
+ newObj[key] = elem;
+ }
+ }
+ Vue.set(state[o.name], 'values', newObj);
+ },
+ fullReset(state, name) {
+ Vue.set(state[name], 'values', {});
+ }
+ },
+ actions: {
+ cleanState({ state, commit }) {
+ for (const [key] of Object.entries(state)) {
+ commit('fullReset', key);
+ }
+ }
+ }
+}
diff --git a/src/store/treasure.js b/src/store/treasure.js
index 4425a239..d6733063 100644
--- a/src/store/treasure.js
+++ b/src/store/treasure.js
@@ -179,6 +179,7 @@ export default {
Vue.set(state.effect[feature], o.name, {
unlock: o.unlock ?? null,
type: o.type ?? 'regular',
+ icon: o.icon ?? 'mdi-circle',
unique: o.unique ?? false,
value: o.value ?? 0
});
diff --git a/src/store/upgrade.js b/src/store/upgrade.js
index c64ad17e..6ba882d7 100644
--- a/src/store/upgrade.js
+++ b/src/store/upgrade.js
@@ -122,9 +122,11 @@ export default {
timeNeeded: o.timeNeeded ?? (() => 1),
timeProgress: 0,
persistent: o.persistent ?? false,
+ alwaysActive: o.alwaysActive ?? false,
collapse: false,
note: o.note ?? null,
- hideCap: o.hideCap ?? false
+ hideCap: o.hideCap ?? false,
+ onBuy: o.onBuy ?? (() => {})
});
// init queue if needed
@@ -190,6 +192,7 @@ export default {
for (const [key] of Object.entries(state.queue)) {
commit('updateQueue', {key, value: []});
}
+ commit('initCache');
},
init({ getters, rootGetters, commit }, o) {
let cap = o.cap ?? null;
@@ -206,17 +209,8 @@ export default {
state.item[o.name].effect.forEach(eff => {
dispatch('system/applyEffect', {type: eff.type, name: eff.name, multKey: `upgrade_${o.name}`, value: eff.value(state.item[o.name].level), trigger}, {root: true});
});
- if (trigger && o.name === 'mining_crystalDrill') {
- dispatch('mining/updateDwellerStat', null, {root: true});
- }
- if (trigger && ['horde_mysticalBag', 'horde_collector'].includes(o.name)) {
- dispatch('horde/checkPlayerHealth', null, {root: true});
- }
- if (trigger && o.name === 'farm_gardenGnome') {
- dispatch('farm/applyEarlyGameBuff', null, {root: true});
- }
- if (trigger && ['farm_overgrowth', 'farm_groundSeeds'].includes(o.name)) {
- dispatch('farm/updateFieldCaches', null, {root: true});
+ if (trigger) {
+ state.item[o.name].onBuy();
}
},
applyReset({ state, dispatch }, name) {
@@ -285,7 +279,7 @@ export default {
// Reset upgrades first
for (const [key, elem] of Object.entries(state.item)) {
- if (elem.feature === o.feature && elem.type === o.type && elem.bought > 0 && (elem.subfeature !== subfeature || !elem.persistent)) {
+ if (elem.feature === o.feature && elem.type === o.type && elem.bought > 0 && (elem.subfeature !== subfeature || !elem.persistent) && !elem.alwaysActive) {
commit('updateKey', {name: key, key: 'level', value: 0});
commit('updateKey', {name: key, key: 'bought', value: 0});
commit('updateKey', {name: key, key: 'timeProgress', value: 0});
@@ -309,6 +303,29 @@ export default {
commit('updateQueue', {key: queueKey, value: state.queue[queueKey].filter(elem => state.item[elem].persistent)});
}
},
+ resetAll({ state, commit, dispatch }, o) {
+ const subfeature = o.subfeature ?? 0;
+
+ // Reset upgrades first
+ for (const [key, elem] of Object.entries(state.item)) {
+ if (elem.feature === o.feature && elem.type === o.type && (elem.bought > 0 || elem.highestLevel > 0) && elem.subfeature === subfeature) {
+ commit('updateKey', {name: key, key: 'level', value: 0});
+ commit('updateKey', {name: key, key: 'bought', value: 0});
+ commit('updateKey', {name: key, key: 'highestLevel', value: 0});
+ commit('updateKey', {name: key, key: 'timeProgress', value: 0});
+ dispatch('applyReset', key);
+ }
+ }
+
+ // Reset cache
+ commit('updateCacheKey', {...o, subfeature});
+
+ // Cleanup queue
+ const queueKey = `${o.feature}_${o.type}`;
+ if (state.queue[queueKey] !== undefined) {
+ commit('updateQueue', {key: queueKey, value: []});
+ }
+ },
raiseLevel({ state, commit, dispatch }, name) {
const upgrade = state.item[name];
diff --git a/src/store/village.js b/src/store/village.js
index efba6651..ac22bbdf 100644
--- a/src/store/village.js
+++ b/src/store/village.js
@@ -10,19 +10,36 @@ export default {
job: {},
offering: {},
policy: {},
+ crafting: {},
explorerProgress: 0,
offeringGen: 0
},
getters: {
employed: (state) => {
let worker = 0;
-
for (const [, elem] of Object.entries(state.job)) {
worker += elem.amount * elem.needed;
}
-
return worker;
},
+ artisansActive: (state) => {
+ let active = 0;
+ for (const [, elem] of Object.entries(state.crafting)) {
+ if (elem.isCrafting) {
+ active++;
+ }
+ }
+ return active;
+ },
+ countersActive: (state) => {
+ let active = 0;
+ for (const [, elem] of Object.entries(state.crafting)) {
+ if (elem.isSelling) {
+ active++;
+ }
+ }
+ return active;
+ },
unemployed: (state, getters, rootState, rootGetters) => {
return rootGetters['mult/get']('villageWorker') - getters.employed;
},
@@ -52,6 +69,10 @@ export default {
},
offeringPerSecond: (state, getters, rootState) => {
return rootState.stat.village_offeringAmount.value * 0.01 / SECONDS_PER_HOUR;
+ },
+ sharesGain: (state, getters, rootState, rootGetters) => {
+ const val = rootState.currency.village_copperCoin.value / 1000;
+ return val >= 10 ? rootGetters['mult/get']('currencyVillageSharesGain', val) : 0;
}
},
mutations: {
@@ -82,9 +103,35 @@ export default {
effect: o.effect ?? []
});
},
+ initCrafting(state, o) {
+ Vue.set(state.crafting, o.name, {
+ icon: o.icon ?? 'mdi-square',
+ color: o.color ?? 'grey',
+ price: o.price ?? {},
+ baseValue: o.value ?? 10,
+ value: o.value ?? 10,
+ baseTimeNeeded: o.timeNeeded ?? 60,
+ timeNeeded: o.timeNeeded ?? 60,
+ milestone: o.milestone ?? {},
+ prio: o.prio ?? 0,
+ isSpecial: o.isSpecial ?? false,
+ effect: o.effect ?? [],
+ unlocked: false,
+ isCrafting: false,
+ isSelling: false,
+ sellPrice: o.value ?? 10,
+ cacheSellChance: 0,
+ progress: 0,
+ owned: 0,
+ crafted: 0
+ });
+ },
updateKey(state, o) {
Vue.set(state, o.key, o.value);
},
+ updateSubkey(state, o) {
+ Vue.set(state[o.key][o.name], o.subkey, o.value);
+ },
updateJobKey(state, o) {
Vue.set(state.job[o.name], o.key, o.value);
},
@@ -107,6 +154,18 @@ export default {
for (const [key] of Object.entries(state.policy)) {
commit('updatePolicyKey', {name: key, key: 'value', value: 0});
}
+ for (const [key, elem] of Object.entries(state.crafting)) {
+ commit('updateSubkey', {key: 'crafting', name: key, subkey: 'value', value: elem.baseValue});
+ commit('updateSubkey', {key: 'crafting', name: key, subkey: 'timeNeeded', value: elem.baseTimeNeeded});
+ commit('updateSubkey', {key: 'crafting', name: key, subkey: 'unlocked', value: false});
+ commit('updateSubkey', {key: 'crafting', name: key, subkey: 'isCrafting', value: false});
+ commit('updateSubkey', {key: 'crafting', name: key, subkey: 'isSelling', value: false});
+ commit('updateSubkey', {key: 'crafting', name: key, subkey: 'sellPrice', value: elem.baseValue});
+ commit('updateSubkey', {key: 'crafting', name: key, subkey: 'cacheSellChance', value: 0});
+ commit('updateSubkey', {key: 'crafting', name: key, subkey: 'progress', value: 0});
+ commit('updateSubkey', {key: 'crafting', name: key, subkey: 'owned', value: 0});
+ commit('updateSubkey', {key: 'crafting', name: key, subkey: 'crafted', value: 0});
+ }
commit('updateKey', {key: 'explorerProgress', value: 0});
commit('updateKey', {key: 'offeringGen', value: 0});
},
@@ -141,11 +200,12 @@ export default {
// Update mults
dispatch('applyJobEffect', o.name);
},
- prestige({ state, rootState, commit, dispatch }, subfeature) {
- const prestigeGain = rootState.currency.village_faith.value;
- commit('stat/increaseTo', {feature: 'village', name: 'bestPrestige', value: prestigeGain}, {root: true});
+ prestige({ state, getters, rootState, commit, dispatch }, subfeature) {
+ const currentSubfeature = rootState.system.features.village.currentSubfeature;
+ const prestigeGain = [rootState.currency.village_faith.value, getters.sharesGain][currentSubfeature];
+ commit('stat/increaseTo', {feature: 'village', name: 'bestPrestige' + currentSubfeature, value: prestigeGain}, {root: true});
commit('stat/add', {feature: 'village', name: 'prestigeCount', value: 1}, {root: true});
- dispatch('currency/gain', {feature: 'village', name: 'blessing', amount: prestigeGain}, {root: true});
+ dispatch('currency/gain', {feature: 'village', name: ['blessing', 'shares'][currentSubfeature], amount: prestigeGain}, {root: true});
// Unassign all workers
for (const [key] of Object.entries(state.job)) {
@@ -165,6 +225,17 @@ export default {
}
}
+ // Reset all crafts
+ for (const [key, elem] of Object.entries(state.crafting)) {
+ commit('updateSubkey', {key: 'crafting', name: key, subkey: 'isCrafting', value: false});
+ commit('updateSubkey', {key: 'crafting', name: key, subkey: 'isSelling', value: false});
+ commit('updateSubkey', {key: 'crafting', name: key, subkey: 'cacheSellChance', value: 0});
+ if (!elem.isSpecial) {
+ commit('updateSubkey', {key: 'crafting', name: key, subkey: 'progress', value: 0});
+ commit('updateSubkey', {key: 'crafting', name: key, subkey: 'owned', value: 0});
+ }
+ }
+
commit('system/updateSubfeature', {key: 'village', value: subfeature}, {root: true});
dispatch('upgrade/reset', {feature: 'village', subfeature, type: 'regular'}, {root: true});
dispatch('upgrade/reset', {feature: 'village', subfeature, type: 'building'}, {root: true});
@@ -297,6 +368,50 @@ export default {
for (let i = 0; i < amount; i++) {
dispatch('currency/gain', {feature: 'village', name: 'loot' + weightSelect(weights), amount: 1}, {root: true});
}
+ },
+ applyMilestoneEffects({ state, commit, dispatch }, name) {
+ const craft = state.crafting[name];
+ commit('updateSubkey', {key: 'crafting', name, subkey: 'value', value: craft.baseValue});
+ commit('updateSubkey', {key: 'crafting', name, subkey: 'timeNeeded', value: craft.baseTimeNeeded});
+ for (const [crafts, reward] of Object.entries(craft.milestone)) {
+ if (craft.crafted >= parseInt(crafts)) {
+ if (reward.type === 'changeStat') {
+ commit('updateSubkey', {key: 'crafting', name, subkey: reward.name, value: reward.value});
+ } else {
+ dispatch('system/applyEffect', {type: reward.type, name: reward.name, multKey: `villageMilestone_${ name }_${ crafts }`, value: reward.value, trigger: true}, {root: true});
+ }
+ }
+ }
+ commit('updateSubkey', {key: 'crafting', name, subkey: 'cacheSellChance', value: 0.01 * Math.pow(craft.value / craft.sellPrice, 2)});
+ },
+ applyMilestoneGlobalLevel({ state, dispatch }) {
+ let totalMilestones = 0;
+ for (const [, elem] of Object.entries(state.crafting)) {
+ for (const [crafts] of Object.entries(elem.milestone)) {
+ if (elem.crafted >= parseInt(crafts)) {
+ totalMilestones++;
+ }
+ }
+ }
+ dispatch('meta/globalLevelPart', {key: 'village_1', amount: totalMilestones}, {root: true});
+ },
+ applySpecialCraftEffects({ state, dispatch }, name) {
+ const craft = state.crafting[name];
+ craft.effect.forEach(reward => {
+ dispatch('system/applyEffect', {type: reward.type, name: reward.name, multKey: `villageSpecialCraft_${ name }`, value: reward.value(craft.owned), trigger: true}, {root: true});
+ });
+ },
+ openIngredientBox({ rootGetters, commit, dispatch }) {
+ if (rootGetters['consumable/canAfford']('village_ingredientBox')) {
+ let rngGen = rootGetters['system/getRng']('village_ingredientBox');
+ const ingredients = ['acidVial', 'snowflake', 'chiliBundle', 'gears'];
+ const weights = [20, 14, 11, 9].slice(0, rootGetters['mult/get']('villageIngredientCount'));
+ for (let i = 0, n = rootGetters['mult/get']('villageIngredientBoxAmount'); i < n; i++) {
+ dispatch('currency/gain', {feature: 'village', name: ingredients[weightSelect(weights, rngGen())], amount: 1}, {root: true});
+ }
+ commit('system/nextRng', {name: 'village_ingredientBox', amount: 1}, {root: true});
+ dispatch('consumable/use', 'village_ingredientBox', {root: true});
+ }
}
}
}
diff --git a/src/store/weatherChaos.js b/src/store/weatherChaos.js
index 4eb4625f..ffdae61b 100644
--- a/src/store/weatherChaos.js
+++ b/src/store/weatherChaos.js
@@ -200,7 +200,7 @@ export default {
dispatch('currency/gain', {feature: 'event', name: 'slime', gainMult: true, amount: size}, {root: true});
if (state.fish[name].catchRecord === null || state.fish[name].catchRecord < size) {
- dispatch('currency/gain', {feature: 'event', name: 'weatherChaosToken', amount: size - (state.fish[name].catchRecord ?? 0)}, {root: true});
+ dispatch('event/giveTokens', {event: 'weatherChaos', amount: size - (state.fish[name].catchRecord ?? 0)}, {root: true});
commit('updateSubkey', {name: 'fish', key: name, subkey: 'catchRecord', value: size});
dispatch('note/find', 'event_18', {root: true});
}
diff --git a/test.js b/test.js
new file mode 100644
index 00000000..4a15a45d
--- /dev/null
+++ b/test.js
@@ -0,0 +1,4 @@
+setInterval(() => {
+ const randomNumber = Math.random();
+ console.log(randomNumber);
+}, 1000);
diff --git a/test/unit/setup.test.js b/test/unit/setup.test.js
index 37aef5dc..07a2835c 100644
--- a/test/unit/setup.test.js
+++ b/test/unit/setup.test.js
@@ -11,7 +11,7 @@ test('game sets up everything correctly', () => {
const mults = Object.keys(store.state.mult.items).length;
const currencies = Object.keys(store.state.currency).length;
const upgrades = Object.keys(store.state.upgrade.item).length;
- const relics = Object.keys(store.state.relic).length;
+ const relics = Object.keys(store.state.relic.item).length;
const achievements = Object.keys(store.state.achievement).length;
// Specific systems
diff --git a/test2.js b/test2.js
new file mode 100644
index 00000000..f584ca15
--- /dev/null
+++ b/test2.js
@@ -0,0 +1,4 @@
+setInterval(() => {
+ const randomNumber = Math.random();
+ console.log("test2: " + randomNumber);
+}, 1000);
diff --git a/test3.js b/test3.js
new file mode 100644
index 00000000..788dca24
--- /dev/null
+++ b/test3.js
@@ -0,0 +1,113 @@
+var store = document.getElementById("app").__vue__.$store
+var ritualNr = store.state.system.rng.nightHunt_ritual
+var names = ["power", "rage", "calming", "sorrow", "energy", "hysteria", "insanity", "transformation"]
+var ingres = [[ "lavender" ], [ "charredSkull", "mapleLeaf" ], [ "fourLeafClover", "mapleLeaf" ], [ "charredSkull", "charredSkull" ], [ "mapleLeaf", "mapleLeaf" ], [ "mysticalWater", "fourLeafClover", "mysticalWater" ], [ "mysticalWater", "lavender", "fourLeafClover" ], [ "cheese", "cheese", "mapleLeaf" ]]
+store.state.nightHunt.ritualIngredients = [ "charredSkull" ]
+store.state.currency.event_charredSkull.value = 1000000000000
+
+function gg(){
+ growTheThing(20)
+}
+
+async function growTheThing(loop){
+ let result = await freegg()
+ if (result === "") {
+ result = await costgg()
+ }
+ ritualNr ++
+ console.log(result)
+ if (loop < 0){
+ return;
+ }
+ loop --
+ growTheThing(loop)
+}
+
+async function costgg(){
+ let useNummer = ritualNr
+ store.state.nightHunt.bonusIngredients = []
+ let resultString = useNummer + " "
+
+ for (let i = 0; names.length > i ; i++){
+ setValuesForCurrency()
+ store.state.system.rng.nightHunt_ritual = useNummer
+ let levelOfCurrent = store.state.nightHunt.potion[names[i]].level
+ store.state.nightHunt.ritualIngredients = ingres[i]
+ await new Promise(r => setTimeout(r, 1));
+ document.getElementsByClassName("ma-1 v-btn v-btn--is-elevated v-btn--has-bg")[0].click()
+ if (levelOfCurrent != store.state.nightHunt.potion[names[i]].level) {
+ resultString += names[i] + ", "
+ }
+ store.state.nightHunt.potion[names[i]].level = levelOfCurrent
+ }
+
+ store.state.system.rng.nightHunt_ritual = useNummer
+ let currToken = store.state.currency.event_nightHuntToken.value
+ store.state.nightHunt.ritualIngredients = [ "cheese", "cheese", "cheese" ]
+ store.state.nightHunt.performedRituals = store.state.nightHunt.performedRituals.filter(item => item !== "cheese,cheese,cheese");
+ await new Promise(r => setTimeout(r, 1));
+ document.getElementsByClassName("ma-1 v-btn v-btn--is-elevated v-btn--has-bg")[0].click()
+ if (currToken != store.state.currency.event_nightHuntToken.value) {
+ resultString += " Random 3 Long"
+ }
+ store.state.system.rng.nightHunt_ritual = useNummer
+ return resultString
+}
+
+async function freegg(){
+ let found = false
+ let useNummer = ritualNr
+ store.state.nightHunt.bonusIngredients = [{"name":"charredSkull","amount":4}]
+ let resultString = useNummer + " Free: "
+
+ for (let i = 0; names.length > i ; i++){
+ setValuesForCurrency()
+ store.state.system.rng.nightHunt_ritual = useNummer
+ let levelOfCurrent = store.state.nightHunt.potion[names[i]].level
+ store.state.nightHunt.ritualIngredients = ingres[i]
+ await new Promise(r => setTimeout(r, 1));
+ document.getElementsByClassName("ma-1 v-btn v-btn--is-elevated v-btn--has-bg")[0].click()
+ let totalValue = store.state.currency.event_lavender.value + store.state.currency.event_mapleLeaf.value + store.state.currency.event_fourLeafClover.value + store.state.currency.event_charredSkull.value + store.state.currency.event_mysticalWater.value + store.state.currency.event_cheese.value
+ if (levelOfCurrent != store.state.nightHunt.potion[names[i]].level && totalValue === 60000) {
+ resultString += names[i] + ", "
+ found = true
+ }
+ store.state.nightHunt.potion[names[i]].level = levelOfCurrent
+ }
+
+ store.state.system.rng.nightHunt_ritual = useNummer
+ let currToken = store.state.currency.event_nightHuntToken.value
+ store.state.nightHunt.ritualIngredients = [ "cheese", "cheese", "cheese" ]
+ store.state.nightHunt.performedRituals = store.state.nightHunt.performedRituals.filter(item => item !== "cheese,cheese,cheese");
+ await new Promise(r => setTimeout(r, 1));
+ document.getElementsByClassName("ma-1 v-btn v-btn--is-elevated v-btn--has-bg")[0].click()
+ let totalValueRandom = store.state.currency.event_lavender.value + store.state.currency.event_mapleLeaf.value + store.state.currency.event_fourLeafClover.value + store.state.currency.event_charredSkull.value + store.state.currency.event_mysticalWater.value + store.state.currency.event_cheese.value
+ if (currToken != store.state.currency.event_nightHuntToken.value && totalValueRandom === 60000) {
+ resultString += " Random 3 Long"
+ found = true
+ }
+ store.state.system.rng.nightHunt_ritual = useNummer
+ if (found){
+ return resultString
+ } else {
+ return "";
+ }
+}
+
+function setValuesForCurrency(){
+ store.state.currency.event_lavender.value = 10000
+ store.state.currency.event_mapleLeaf.value = 10000
+ store.state.currency.event_fourLeafClover.value = 10000
+ store.state.currency.event_charredSkull.value = 10000
+ store.state.currency.event_mysticalWater.value = 10000
+ store.state.currency.event_cheese.value = 10000
+}
+
+
+async function wololololo(){
+ await new Promise(r => setTimeout(r, 1));
+ await new Promise(r => setTimeout(r, 1));
+ gg()
+}
+
+wololololo()