├── .editorconfig
├── .github
└── workflows
│ └── gh-pages-deploy.yml
├── .gitignore
├── LICENSE
├── README.md
├── babel.config.js
├── cypress.config.js
├── cypress
├── e2e
│ ├── achievement.cy.js
│ ├── card.cy.js
│ ├── event.cy.js
│ ├── farm.cy.js
│ ├── gallery.cy.js
│ ├── gem.cy.js
│ ├── general.cy.js
│ ├── horde.cy.js
│ ├── mining.cy.js
│ ├── note.cy.js
│ ├── relic.cy.js
│ ├── treasure.cy.js
│ └── village.cy.js
├── fixtures
│ └── example.json
├── plugins
│ └── index.js
└── support
│ ├── commands.js
│ └── e2e.js
├── debug.json
├── forge.config.js
├── jsconfig.json
├── main.js
├── package-lock.json
├── package.json
├── public
├── android-chrome-192x192.png
├── android-chrome-512x512.png
├── apple-touch-icon.png
├── favicon-16x16.png
├── favicon-32x32.png
├── favicon.ico
├── img
│ └── note.png
├── index.html
├── site.webmanifest
├── theme
│ └── sky
│ │ └── navbar.png
└── version.txt
├── scripts
└── gh-pages-deploy.mjs
├── src
├── App.vue
├── components
│ ├── partial
│ │ ├── achievement
│ │ │ └── Item.vue
│ │ ├── card
│ │ │ ├── CardItem.vue
│ │ │ ├── CardOverview.vue
│ │ │ ├── CardPack.vue
│ │ │ ├── CardSelect.vue
│ │ │ └── CardSelectDisplay.vue
│ │ ├── cryolab
│ │ │ └── LabFeature.vue
│ │ ├── debug
│ │ │ └── AutoplayGraph.vue
│ │ ├── event
│ │ │ ├── Bank.vue
│ │ │ ├── Bingo.vue
│ │ │ ├── BingoCell.vue
│ │ │ ├── BloomBreeder.vue
│ │ │ ├── BloomBuyFlower.vue
│ │ │ ├── BloomFlower.vue
│ │ │ ├── BloomInventory.vue
│ │ │ ├── BloomInventorySlot.vue
│ │ │ ├── Casino.vue
│ │ │ ├── CindersCandle.vue
│ │ │ ├── CindersInventory.vue
│ │ │ ├── EventCalendar.vue
│ │ │ ├── NightHuntFavouritableDisplay.vue
│ │ │ ├── NightHuntIngredient.vue
│ │ │ ├── NightHuntInventory.vue
│ │ │ ├── NightHuntPotion.vue
│ │ │ ├── NightHuntPotionList.vue
│ │ │ ├── Prize.vue
│ │ │ ├── Shop.vue
│ │ │ ├── ShopList.vue
│ │ │ ├── SnowballFight.vue
│ │ │ ├── SnowdownFighter.vue
│ │ │ ├── SnowdownInventory.vue
│ │ │ ├── SnowdownItem.vue
│ │ │ ├── SnowdownItemList.vue
│ │ │ ├── SummerFestivalBuildingCard.vue
│ │ │ ├── SummerFestivalInventory.vue
│ │ │ ├── SummerFestivalIsland.vue
│ │ │ ├── WeatherChaosFish.vue
│ │ │ ├── WeatherChaosInventory.vue
│ │ │ ├── WeatherChaosStatus.vue
│ │ │ └── WheelOfFortune.vue
│ │ ├── farm
│ │ │ ├── Building.vue
│ │ │ ├── BuildingCard.vue
│ │ │ ├── Crop.vue
│ │ │ ├── CropCard.vue
│ │ │ ├── CropRareDrop.vue
│ │ │ ├── CropUpgrade.vue
│ │ │ ├── FertilizerCard.vue
│ │ │ ├── Field.vue
│ │ │ ├── FieldBar.vue
│ │ │ ├── GeneIcon.vue
│ │ │ ├── GeneUpgrade.vue
│ │ │ ├── Inventory.vue
│ │ │ └── PlaceableSelectDisplay.vue
│ │ ├── gallery
│ │ │ ├── Color.vue
│ │ │ ├── IdeaItem.vue
│ │ │ ├── IdeaList.vue
│ │ │ ├── Inventory.vue
│ │ │ ├── PrestigeInventory.vue
│ │ │ ├── PrestigeStatus.vue
│ │ │ └── ShapeMinigame.vue
│ │ ├── gem
│ │ │ └── GemList.vue
│ │ ├── general
│ │ │ └── QuestTask.vue
│ │ ├── horde
│ │ │ ├── Active.vue
│ │ │ ├── ActiveCost.vue
│ │ │ ├── ActiveTooltip.vue
│ │ │ ├── AreaMap.vue
│ │ │ ├── BattlePass.vue
│ │ │ ├── EnemyActive.vue
│ │ │ ├── EnemyActiveTooltip.vue
│ │ │ ├── EnemyStatus.vue
│ │ │ ├── EntityStatus.vue
│ │ │ ├── EquipDisplay.vue
│ │ │ ├── EquipLoadout.vue
│ │ │ ├── FighterPrestigeStats.vue
│ │ │ ├── HeirloomItem.vue
│ │ │ ├── HeirloomList.vue
│ │ │ ├── Item.vue
│ │ │ ├── ItemList.vue
│ │ │ ├── PlayerStatus.vue
│ │ │ ├── PrestigeInventory.vue
│ │ │ ├── PrestigeStatus.vue
│ │ │ ├── Sigil.vue
│ │ │ ├── SkillButton.vue
│ │ │ ├── SkillTree.vue
│ │ │ ├── Status.vue
│ │ │ ├── TowerTile.vue
│ │ │ ├── TrinketItem.vue
│ │ │ └── TrinketList.vue
│ │ ├── main
│ │ │ ├── FeatureTile.vue
│ │ │ └── NextTile.vue
│ │ ├── mining
│ │ │ ├── BeaconSector.vue
│ │ │ ├── Ingredient.vue
│ │ │ ├── Inventory.vue
│ │ │ ├── PrestigeInventory.vue
│ │ │ ├── PrestigeStatus.vue
│ │ │ ├── Smeltery.vue
│ │ │ ├── SmelteryStation.vue
│ │ │ └── Status.vue
│ │ ├── note
│ │ │ ├── NoteList.vue
│ │ │ └── ShowButton.vue
│ │ ├── patchnote
│ │ │ ├── PatchnoteContent.vue
│ │ │ └── PatchnoteItem.vue
│ │ ├── prestige
│ │ │ ├── InventoryTemplate.vue
│ │ │ └── StatusTemplate.vue
│ │ ├── relic
│ │ │ ├── Item.vue
│ │ │ ├── Mini.vue
│ │ │ ├── MuseumTab.vue
│ │ │ └── RelicList.vue
│ │ ├── render
│ │ │ ├── AlertText.vue
│ │ │ ├── CurrencyTooltip.vue
│ │ │ ├── GoobooTooltip.vue
│ │ │ ├── MultStat.vue
│ │ │ ├── StatRow.vue
│ │ │ └── TabIconText.vue
│ │ ├── school
│ │ │ ├── ArtMinigame.vue
│ │ │ ├── BookUpgrades.vue
│ │ │ ├── HistoryMinigame.vue
│ │ │ ├── LiteratureMinigame.vue
│ │ │ ├── MathMinigame.vue
│ │ │ ├── Subject.vue
│ │ │ └── SubjectList.vue
│ │ ├── settings
│ │ │ ├── Item.vue
│ │ │ ├── Keybind.vue
│ │ │ └── ThemeItem.vue
│ │ ├── snackbar
│ │ │ ├── AchievementMessage.vue
│ │ │ ├── CardPackInstantEffect.vue
│ │ │ ├── CardPackMessage.vue
│ │ │ ├── ErrorMessage.vue
│ │ │ ├── FeatureMessage.vue
│ │ │ ├── HeirloomMessage.vue
│ │ │ ├── ImportMessage.vue
│ │ │ ├── NoteMessage.vue
│ │ │ ├── PrizeMessage.vue
│ │ │ ├── SaveMessage.vue
│ │ │ ├── SchoolMessage.vue
│ │ │ └── UpdateMessage.vue
│ │ ├── treasure
│ │ │ ├── BuyItem.vue
│ │ │ ├── ChanceList.vue
│ │ │ ├── ItemSlot.vue
│ │ │ └── StatList.vue
│ │ ├── upgrade
│ │ │ └── DisplayRow.vue
│ │ └── village
│ │ │ ├── BuildingStatBar.vue
│ │ │ ├── CraftingItem.vue
│ │ │ ├── CraftingList.vue
│ │ │ ├── Job.vue
│ │ │ ├── JobList.vue
│ │ │ ├── OfferingInventory.vue
│ │ │ ├── OfferingItem.vue
│ │ │ ├── OfferingList.vue
│ │ │ ├── PolicyItem.vue
│ │ │ ├── PolicyList.vue
│ │ │ ├── PrestigeInventory.vue
│ │ │ ├── PrestigeStatus.vue
│ │ │ └── Resources.vue
│ ├── render
│ │ ├── Consumable.vue
│ │ ├── Currency.vue
│ │ ├── CurrencyIcon.vue
│ │ ├── CurrentConfirm.vue
│ │ ├── CurrentNote.vue
│ │ ├── GoldenDustMenu.vue
│ │ ├── MultName.vue
│ │ ├── NoteSimple.vue
│ │ ├── NoteSystem.vue
│ │ ├── OfflineFeature.vue
│ │ ├── ParticleSpawner.vue
│ │ ├── PriceTag.vue
│ │ ├── StatBreakdown.vue
│ │ ├── Upgrade.vue
│ │ ├── UpgradeList.vue
│ │ └── UpgradeQueue.vue
│ └── view
│ │ ├── Achievement.vue
│ │ ├── Card.vue
│ │ ├── Cryolab.vue
│ │ ├── Debug.vue
│ │ ├── Event.vue
│ │ ├── Farm.vue
│ │ ├── Gallery.vue
│ │ ├── Gem.vue
│ │ ├── General.vue
│ │ ├── Horde.vue
│ │ ├── Info.vue
│ │ ├── Mining.vue
│ │ ├── NewGame.vue
│ │ ├── Note.vue
│ │ ├── OfflineSummary.vue
│ │ ├── Patchnote.vue
│ │ ├── Relic.vue
│ │ ├── ResetProgress.vue
│ │ ├── School.vue
│ │ ├── Settings.vue
│ │ ├── StatOverview.vue
│ │ ├── TabDuplicate.vue
│ │ ├── Treasure.vue
│ │ └── Village.vue
├── gbPlugin.js
├── js
│ ├── autoplay.js
│ ├── constants.js
│ ├── init.js
│ ├── modules
│ │ ├── achievement.js
│ │ ├── card.js
│ │ ├── cryolab.js
│ │ ├── event.js
│ │ ├── event
│ │ │ ├── bank
│ │ │ │ └── project.js
│ │ │ ├── big.js
│ │ │ ├── bloom
│ │ │ │ ├── prize.js
│ │ │ │ ├── tick.js
│ │ │ │ └── upgrade.js
│ │ │ ├── card.js
│ │ │ ├── cardList.js
│ │ │ ├── cinders
│ │ │ │ ├── prize.js
│ │ │ │ ├── producer.js
│ │ │ │ ├── tick.js
│ │ │ │ └── upgrade.js
│ │ │ ├── nightHunt
│ │ │ │ ├── ingredientStat.js
│ │ │ │ ├── potion.js
│ │ │ │ ├── prize.js
│ │ │ │ ├── tick.js
│ │ │ │ └── upgrade.js
│ │ │ ├── prize.js
│ │ │ ├── relic.js
│ │ │ ├── snowdown
│ │ │ │ ├── item.js
│ │ │ │ ├── prize.js
│ │ │ │ ├── tick.js
│ │ │ │ └── upgrade.js
│ │ │ ├── summerFestival
│ │ │ │ ├── building.js
│ │ │ │ ├── prize.js
│ │ │ │ ├── quest.js
│ │ │ │ ├── tick.js
│ │ │ │ └── upgrade.js
│ │ │ └── weatherChaos
│ │ │ │ ├── bait.js
│ │ │ │ ├── fish.js
│ │ │ │ ├── fishingRod.js
│ │ │ │ ├── location.js
│ │ │ │ ├── prize.js
│ │ │ │ ├── tick.js
│ │ │ │ ├── upgrade.js
│ │ │ │ └── weather.js
│ │ ├── farm.js
│ │ ├── farm
│ │ │ ├── achievement.js
│ │ │ ├── building.js
│ │ │ ├── card.js
│ │ │ ├── cardList.js
│ │ │ ├── crop.js
│ │ │ ├── fertilizer.js
│ │ │ ├── gene.js
│ │ │ ├── relic.js
│ │ │ ├── upgrade.js
│ │ │ └── upgradePremium.js
│ │ ├── gallery.js
│ │ ├── gallery
│ │ │ ├── achievement.js
│ │ │ ├── card.js
│ │ │ ├── cardList.js
│ │ │ ├── idea.js
│ │ │ ├── relic.js
│ │ │ ├── shape.js
│ │ │ ├── upgrade.js
│ │ │ ├── upgradePremium.js
│ │ │ ├── upgradePrestige.js
│ │ │ └── upgradeShape.js
│ │ ├── gem.js
│ │ ├── gem
│ │ │ ├── card.js
│ │ │ └── cardList.js
│ │ ├── general.js
│ │ ├── general
│ │ │ ├── grobodal.js
│ │ │ └── orladee.js
│ │ ├── horde.js
│ │ ├── horde
│ │ │ ├── achievement.js
│ │ │ ├── area
│ │ │ │ ├── loveIsland.js
│ │ │ │ ├── monkeyJungle.js
│ │ │ │ └── warzone.js
│ │ │ ├── battlePass.js
│ │ │ ├── boss.js
│ │ │ ├── card.js
│ │ │ ├── cardList.js
│ │ │ ├── enemyType.js
│ │ │ ├── equipment.js
│ │ │ ├── fighterClass
│ │ │ │ ├── adventurer.js
│ │ │ │ ├── archer.js
│ │ │ │ ├── assassin.js
│ │ │ │ ├── cultist.js
│ │ │ │ ├── knight.js
│ │ │ │ ├── mage.js
│ │ │ │ ├── pirate.js
│ │ │ │ ├── scholar.js
│ │ │ │ ├── shaman.js
│ │ │ │ └── undead.js
│ │ │ ├── heirloom.js
│ │ │ ├── relic.js
│ │ │ ├── sigil.js
│ │ │ ├── sigil_boss.js
│ │ │ ├── tower.js
│ │ │ ├── trinket.js
│ │ │ ├── upgrade.js
│ │ │ ├── upgrade2.js
│ │ │ ├── upgradePremium.js
│ │ │ └── upgradePrestige.js
│ │ ├── meta.js
│ │ ├── migration
│ │ │ ├── helper.js
│ │ │ ├── v1_1_0.js
│ │ │ ├── v1_1_2.js
│ │ │ ├── v1_3_0.js
│ │ │ ├── v1_3_4.js
│ │ │ ├── v1_3_5.js
│ │ │ ├── v1_4_0.js
│ │ │ ├── v1_4_1.js
│ │ │ ├── v1_5_0.js
│ │ │ ├── v1_5_1.js
│ │ │ ├── v1_5_3.js
│ │ │ ├── v1_5_4.js
│ │ │ └── v1_5_6.js
│ │ ├── mining.js
│ │ ├── mining
│ │ │ ├── achievement.js
│ │ │ ├── beacon.js
│ │ │ ├── card.js
│ │ │ ├── cardList.js
│ │ │ ├── enhancement.js
│ │ │ ├── ore.js
│ │ │ ├── relic.js
│ │ │ ├── smeltery.js
│ │ │ ├── upgrade.js
│ │ │ ├── upgrade2.js
│ │ │ ├── upgradePremium.js
│ │ │ └── upgradePrestige.js
│ │ ├── patchnote
│ │ │ ├── v1_0_0.js
│ │ │ ├── v1_0_1.js
│ │ │ ├── v1_1_0.js
│ │ │ ├── v1_1_1.js
│ │ │ ├── v1_1_2.js
│ │ │ ├── v1_2_0.js
│ │ │ ├── v1_3_0.js
│ │ │ ├── v1_3_1.js
│ │ │ ├── v1_3_2.js
│ │ │ ├── v1_3_3.js
│ │ │ ├── v1_3_4.js
│ │ │ ├── v1_3_5.js
│ │ │ ├── v1_3_6.js
│ │ │ ├── v1_4_0.js
│ │ │ ├── v1_4_1.js
│ │ │ ├── v1_4_2.js
│ │ │ ├── v1_5_0.js
│ │ │ ├── v1_5_1.js
│ │ │ ├── v1_5_2.js
│ │ │ ├── v1_5_3.js
│ │ │ ├── v1_5_4.js
│ │ │ ├── v1_5_5.js
│ │ │ ├── v1_5_6.js
│ │ │ ├── v1_5_7.js
│ │ │ └── v1_5_8.js
│ │ ├── relic.js
│ │ ├── relic
│ │ │ └── glyph.js
│ │ ├── school.js
│ │ ├── school
│ │ │ ├── bookFarm.js
│ │ │ ├── bookGallery.js
│ │ │ ├── bookHorde.js
│ │ │ ├── bookMining.js
│ │ │ ├── bookVillage.js
│ │ │ └── upgradePremium.js
│ │ ├── treasure.js
│ │ ├── treasure
│ │ │ ├── effect.js
│ │ │ └── upgradePremium.js
│ │ ├── village.js
│ │ └── village
│ │ │ ├── achievement.js
│ │ │ ├── building.js
│ │ │ ├── card.js
│ │ │ ├── cardList.js
│ │ │ ├── craftingRecipe.js
│ │ │ ├── job.js
│ │ │ ├── offering.js
│ │ │ ├── policy.js
│ │ │ ├── relic.js
│ │ │ ├── upgrade.js
│ │ │ ├── upgrade2.js
│ │ │ ├── upgradePremium.js
│ │ │ └── upgradePrestige.js
│ ├── savefile.js
│ ├── theme
│ │ ├── autumnForest.js
│ │ ├── brown.js
│ │ ├── candlelight.js
│ │ ├── cherry.js
│ │ ├── colorful.js
│ │ ├── colors.js
│ │ ├── cyan.js
│ │ ├── default.js
│ │ ├── factory.js
│ │ ├── forest.js
│ │ ├── frozen.js
│ │ ├── green.js
│ │ ├── grey.js
│ │ ├── orange.js
│ │ ├── pink.js
│ │ ├── polar.js
│ │ ├── prismatic.js
│ │ ├── purple.js
│ │ ├── rain.js
│ │ ├── red.js
│ │ ├── sepia.js
│ │ ├── shades.js
│ │ ├── sky.js
│ │ ├── themes.js
│ │ ├── waves.js
│ │ └── yellow.js
│ ├── tick.js
│ └── utils
│ │ ├── array.js
│ │ ├── color.js
│ │ ├── date.js
│ │ ├── file.js
│ │ ├── format.js
│ │ ├── math.js
│ │ ├── random.js
│ │ └── words.js
├── lang
│ ├── de.js
│ ├── de
│ │ ├── card.js
│ │ ├── consumable.js
│ │ ├── currency.js
│ │ ├── mult.js
│ │ ├── note.js
│ │ ├── patchnote.js
│ │ ├── relic.js
│ │ ├── stat.js
│ │ ├── tag.js
│ │ ├── unlock.js
│ │ └── upgrade.js
│ ├── en.js
│ └── en
│ │ ├── card.js
│ │ ├── consumable.js
│ │ ├── currency.js
│ │ ├── mult.js
│ │ ├── note.js
│ │ ├── patchnote.js
│ │ ├── relic.js
│ │ ├── stat.js
│ │ ├── tag.js
│ │ ├── unlock.js
│ │ └── upgrade.js
├── main.js
├── plugins
│ └── vuetify.js
└── store
│ ├── achievement.js
│ ├── bloom.js
│ ├── card.js
│ ├── cinders.js
│ ├── consumable.js
│ ├── cryolab.js
│ ├── currency.js
│ ├── event.js
│ ├── farm.js
│ ├── gallery.js
│ ├── gem.js
│ ├── general.js
│ ├── horde.js
│ ├── index.js
│ ├── meta.js
│ ├── mining.js
│ ├── mult.js
│ ├── nightHunt.js
│ ├── note.js
│ ├── relic.js
│ ├── school.js
│ ├── snowdown.js
│ ├── stat.js
│ ├── summerFestival.js
│ ├── system.js
│ ├── tag.js
│ ├── treasure.js
│ ├── unlock.js
│ ├── upgrade.js
│ ├── village.js
│ └── weatherChaos.js
├── test
└── unit
│ ├── autoplay.test.js
│ ├── currency.test.js
│ ├── event.test.js
│ ├── mult.test.js
│ ├── setup.test.js
│ ├── stat.test.js
│ ├── treasure.test.js
│ ├── unlock.test.js
│ ├── upgrade.test.js
│ └── utils.test.js
├── vue.config.js
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*.{js,vue}]
4 | insert_final_newline = true
5 | charset = utf-8
6 | indent_style = space
7 | trim_trailing_whitespace = true
8 |
9 | [*.vue]
10 | indent_size = 2
11 |
12 | [*.js]
13 | indent_size = 4
14 |
15 | [src/lang/**.js]
16 | indent_size = 2
17 |
--------------------------------------------------------------------------------
/.github/workflows/gh-pages-deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy to Github Pages
2 | on:
3 | push:
4 | branches:
5 | - main
6 | jobs:
7 | gh-pages-deploy:
8 | name: Deploying to Github Pages
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v2
12 | with:
13 | token: ${{ secrets.PAGES_TOKEN }}
14 | - uses: actions/setup-node@v2
15 | with:
16 | node-version: '16'
17 | - name: Install packages
18 | run: npm i
19 | - name: Set Creds
20 | run: git config user.name "Tendsty" && git config user.email "137620092+Tendsty@users.noreply.github.com"
21 | - name: Deploy
22 | run: npm run deploy
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /dist
2 | /node_modules
3 | /coverage
4 | /out
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # gooboo
2 |
3 | ## Project setup
4 | Install dependencies
5 | ```
6 | yarn install
7 | ```
8 |
9 | ### Compiles and hot-reloads for development
10 | ```
11 | yarn serve
12 | ```
13 |
14 | ### Lints and fixes files
15 | ```
16 | yarn lint
17 | ```
18 |
19 | ### Debug mode
20 | To enable debug mode, import the debug.json file as savefile or edit your savefile to include the feature debugFeature.
21 | Then you can access tools for debugging and developing by navigating to the debug feature.
22 | Please note that the debug feature does not support translations and may break on small screens.
23 |
24 | ## Testing
25 |
26 | ### Unit tests
27 | Run all tests
28 | ```
29 | yarn test:unit
30 | ```
31 |
32 | Run tests without parameters. This allows to run only selected tests by passing a name as argument
33 | ```
34 | yarn test:unit-custom
35 | ```
36 |
37 | ### E2E tests
38 | Open cypress
39 | ```
40 | yarn test:e2e
41 | ```
42 |
43 | ## Building for production
44 |
45 | Don't forget to set the desired APP_ENV in constants.js before building!
46 |
47 | ### Build for use on a webserver
48 | ```
49 | yarn build
50 | ```
51 |
52 | ### Preview electron app
53 | ```
54 | yarn forge:start
55 | ```
56 |
57 | ### Create electron app
58 | ```
59 | yarn forge:make
60 | ```
61 |
62 | ## Compatibility
63 |
64 | ### Devices
65 | Supports desktop, tablet, and mobile with a screen width of 375px or higher
66 |
67 | ### Browsers
68 | Supports firefox, electron and chromium-based browsers
69 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/cypress.config.js:
--------------------------------------------------------------------------------
1 | const { defineConfig } = require('cypress')
2 |
3 | module.exports = defineConfig({
4 | e2e: {
5 | // We've imported your old cypress plugins here.
6 | // You may want to clean this up later by importing these.
7 | setupNodeEvents(on, config) {
8 | return require('./cypress/plugins/index.js')(on, config)
9 | },
10 | experimentalRunAllSpecs: true
11 | },
12 | })
13 |
--------------------------------------------------------------------------------
/cypress/e2e/achievement.cy.js:
--------------------------------------------------------------------------------
1 | describe('Achievements load properly', () => {
2 | it('achievements show their categories and stats', () => {
3 | cy.toFeature('Debug');
4 | cy.giveUnlock('achievementFeature');
5 | cy.contains('1m').click();
6 |
7 | cy.toFeature('Achievements');
8 | cy.contains('Game');
9 | cy.contains('Mining').click();
10 | cy.contains('This is deep');
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/cypress/e2e/card.cy.js:
--------------------------------------------------------------------------------
1 | describe('Cards load properly', () => {
2 | it('card packs can be bought and give cards', () => {
3 | cy.toFeature('Debug');
4 | cy.giveUnlock('cardFeature');
5 | cy.giveCurrency('gem_emerald', 25);
6 |
7 | cy.toFeature('Cards');
8 | cy.get('[data-cy=card-pack-selector]').vselect('Into darkness');
9 | cy.contains('Buy').click();
10 | cy.get('[data-cy=confirm-action-confirm]').click();
11 | cy.contains('Card pack content');
12 | cy.contains('NEW!');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/cypress/e2e/event.cy.js:
--------------------------------------------------------------------------------
1 | describe('Events load properly', () => {
2 | it('event calendar shows', () => {
3 | cy.toFeature('Debug');
4 | cy.giveUnlock('eventFeature');
5 |
6 | cy.toFeature('Event');
7 | cy.contains('Calendar');
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/cypress/e2e/farm.cy.js:
--------------------------------------------------------------------------------
1 | describe('Farm feature loads properly', () => {
2 | it('crops can be planted and harvested', () => {
3 | cy.toFeature('Debug');
4 | cy.giveUnlock('farmFeature');
5 |
6 | cy.toFeature('Farm');
7 | cy.get('[data-cy=farm-crop-carrot]').click();
8 | cy.get('[data-cy=farm-plant-all]').click();
9 |
10 | cy.toFeature('Debug');
11 | cy.contains('10m').click();
12 |
13 | cy.toFeature('Farm');
14 | cy.get('[data-cy=farm-harvest-all]').click();
15 | cy.contains('41');
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/cypress/e2e/gallery.cy.js:
--------------------------------------------------------------------------------
1 | describe('Gallery feature loads properly', () => {
2 | it('beauty is generated on its own', () => {
3 | cy.toFeature('Debug');
4 | cy.giveUnlock('galleryFeature');
5 | cy.contains('1m').click();
6 |
7 | cy.toFeature('Gallery');
8 | cy.contains('60');
9 | });
10 |
11 | it('prestige option can be unlocked', () => {
12 | cy.toFeature('Debug');
13 | cy.giveUnlock('galleryFeature');
14 | cy.giveUnlock('galleryAuction');
15 |
16 | cy.toFeature('Gallery');
17 | cy.contains('Auction').click();
18 | cy.contains('Prestige');
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/cypress/e2e/gem.cy.js:
--------------------------------------------------------------------------------
1 | describe('Gems load properly', () => {
2 | it('gems generate passively', () => {
3 | cy.toFeature('Debug');
4 | cy.giveUnlock('gemFeature');
5 | cy.contains('1d').click();
6 |
7 | cy.toFeature('Gems');
8 | cy.contains('24');
9 | });
10 |
11 | it('achievements show accelerated gem gain', () => {
12 | cy.toFeature('Debug');
13 | cy.giveUnlock('gemFeature');
14 | cy.giveUnlock('achievementFeature');
15 |
16 | cy.toFeature('Gems');
17 | cy.contains('+0%');
18 | });
19 |
20 | it('new gem upgrades show with event feature', () => {
21 | cy.toFeature('Debug');
22 | cy.giveUnlock('gemFeature');
23 | cy.giveUnlock('eventFeature');
24 |
25 | cy.toFeature('Gems');
26 | cy.get('[data-cy=gem-upgrade-feature]').vselect('Gems');
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/cypress/e2e/general.cy.js:
--------------------------------------------------------------------------------
1 | describe('Generals load properly', () => {
2 | it('generals are shown with quests', () => {
3 | cy.toFeature('Debug');
4 | cy.giveUnlock('generalFeature');
5 |
6 | cy.toFeature('Generals');
7 | cy.contains('Grobodal');
8 | cy.contains('1 / 5');
9 |
10 | cy.contains('Digging deeper').click();
11 | cy.contains('Completion reward');
12 | cy.contains('Time spent at most 30m 00s');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/cypress/e2e/horde.cy.js:
--------------------------------------------------------------------------------
1 | describe('Horde feature loads properly', () => {
2 | it('horde fights passively and loots bones', () => {
3 | cy.toFeature('Debug');
4 | cy.giveUnlock('hordeFeature');
5 | cy.contains('1m').click();
6 |
7 | cy.toFeature('Horde');
8 | cy.contains('5.000M');
9 | });
10 |
11 | it('prestige option can be unlocked', () => {
12 | cy.toFeature('Debug');
13 | cy.giveUnlock('hordeFeature');
14 | cy.giveUnlock('hordePrestige');
15 |
16 | cy.toFeature('Horde');
17 | cy.contains('Souls').click();
18 | cy.contains('Prestige');
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/cypress/e2e/mining.cy.js:
--------------------------------------------------------------------------------
1 | describe('Mining feature loads properly', () => {
2 | it('scrap can be gained over time', () => {
3 | cy.toFeature('Debug');
4 | cy.contains('1m').click();
5 |
6 | cy.toFeature('Mining');
7 | cy.contains('10.00K');
8 | });
9 |
10 | it('crafting unlock shows craft button', () => {
11 | cy.toFeature('Debug');
12 | cy.giveUnlock('miningPickaxeCrafting');
13 |
14 | cy.toFeature('Mining');
15 | cy.contains('Craft');
16 | });
17 |
18 | it('depth dweller offers prestige option', () => {
19 | cy.toFeature('Debug');
20 | cy.giveUnlock('miningDepthDweller');
21 |
22 | cy.toFeature('Mining');
23 | cy.contains('Depth dweller').click();
24 | cy.contains('Prestige');
25 | });
26 |
27 | it('smeltery unlocks access to temperature', () => {
28 | cy.toFeature('Debug');
29 | cy.giveUnlock('miningSmeltery');
30 |
31 | cy.toFeature('Mining');
32 | cy.contains('100°C');
33 | cy.contains('275°C');
34 | });
35 |
36 | it('resin can be used in crafting', () => {
37 | cy.toFeature('Debug');
38 | cy.giveUnlock('miningPickaxeCrafting');
39 | cy.giveUnlock('miningResin');
40 |
41 | cy.toFeature('Mining');
42 | cy.get('[data-cy=mining-resin-input]');
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/cypress/e2e/note.cy.js:
--------------------------------------------------------------------------------
1 | describe('Notes load properly', () => {
2 | it('notes can be viewed', () => {
3 | cy.toFeature('Debug');
4 | cy.contains('1m').click();
5 |
6 | cy.contains('Read').click();
7 | cy.contains('Use pickaxe');
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/cypress/e2e/relic.cy.js:
--------------------------------------------------------------------------------
1 | describe('Relics load properly', () => {
2 | it('relics can be gained and show in the list', () => {
3 | cy.get('[data-cy=settings-button]').click();
4 | cy.contains('Automation').click();
5 | cy.get('[data-cy=setting-automation-progressMining]').type('90');
6 |
7 | cy.toFeature('Debug');
8 | cy.giveUnlock('relicFeature');
9 | cy.changeMult('miningDamage', 'mult', 1000000000000);
10 | cy.contains('1h').click();
11 |
12 | cy.contains('Features').click();
13 | cy.contains('Relics').click();
14 | cy.contains('Friendly bat');
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/cypress/e2e/treasure.cy.js:
--------------------------------------------------------------------------------
1 | describe('Treasures load properly', () => {
2 | it('treasure can be bought, upgraded and deleted', () => {
3 | cy.toFeature('Debug');
4 | cy.giveUnlock('treasureFeature');
5 | cy.giveCurrency('gem_emerald', 130);
6 |
7 | cy.toFeature('Treasure');
8 | cy.get('[data-cy=treasure-buy-regular]').click();
9 | cy.get('[data-cy=confirm-action-confirm]').click();
10 | cy.get('[data-cy=treasure-slot-0]').click();
11 |
12 | cy.get('[data-cy=treasure-buy-fragment]').click();
13 | cy.get('[data-cy=confirm-action-confirm]').click();
14 |
15 | cy.get('[data-cy=treasure-upgrade-button]').click();
16 | cy.get('[data-cy=treasure-slot-0]').click();
17 | cy.contains('22');
18 | cy.contains('+1');
19 |
20 | cy.get('[data-cy=treasure-slot-0]').click();
21 | cy.get('[data-cy=treasure-slot-0]').click();
22 | cy.contains('+3');
23 |
24 | cy.get('[data-cy=treasure-delete-button]').click();
25 | cy.get('[data-cy=treasure-slot-0]').click();
26 | cy.get('[data-cy=confirm-action-confirm]').click();
27 | cy.contains('40');
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/cypress/e2e/village.cy.js:
--------------------------------------------------------------------------------
1 | describe('Village feature loads properly', () => {
2 | it('basic resources can be gained over time and used to buy buildings', () => {
3 | cy.toFeature('Debug');
4 | cy.giveUnlock('villageFeature');
5 |
6 | cy.toFeature('Village');
7 | cy.get('[data-cy=village-job-collector-add]').click();
8 |
9 | cy.toFeature('Debug');
10 | cy.contains('1m').click();
11 |
12 | cy.toFeature('Village');
13 | cy.contains('2000');
14 |
15 | cy.get('[data-cy=upgrade-village_campfire-buy]').click();
16 |
17 | cy.toFeature('Debug');
18 | cy.contains('1m').click();
19 |
20 | cy.toFeature('Village');
21 | cy.contains('Hut');
22 | });
23 |
24 | it('praying offers prestige option', () => {
25 | cy.toFeature('Debug');
26 | cy.giveUnlock('villageFeature');
27 | cy.changeMult('currencyVillageFaithGain', 'base', 1);
28 | cy.contains('1m').click();
29 |
30 | cy.toFeature('Village');
31 | cy.contains('Pray').click();
32 | cy.contains('Prestige');
33 | });
34 |
35 | it('offerings unlocks new tab', () => {
36 | cy.toFeature('Debug');
37 | cy.giveUnlock('villageFeature');
38 | cy.giveUnlock('villageOffering1');
39 |
40 | cy.toFeature('Village');
41 | cy.contains('Offerings').click();
42 | cy.contains('Sacrifice');
43 | });
44 |
45 | it('policies are shown in a new tab', () => {
46 | cy.toFeature('Debug');
47 | cy.giveUnlock('villageFeature');
48 | cy.changeMult('villagePolicyTaxes', 'base', 1);
49 |
50 | cy.toFeature('Village');
51 | cy.contains('Policies').click();
52 | cy.contains('0 / 1');
53 | });
54 | });
55 |
--------------------------------------------------------------------------------
/cypress/fixtures/example.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Using fixtures to represent data",
3 | "email": "hello@cypress.io",
4 | "body": "Fixtures are a great way to mock data for responses to routes"
5 | }
6 |
--------------------------------------------------------------------------------
/cypress/plugins/index.js:
--------------------------------------------------------------------------------
1 | ///
2 | // ***********************************************************
3 | // This example plugins/index.js can be used to load plugins
4 | //
5 | // You can change the location of this file or turn off loading
6 | // the plugins file with the 'pluginsFile' configuration option.
7 | //
8 | // You can read more here:
9 | // https://on.cypress.io/plugins-guide
10 | // ***********************************************************
11 |
12 | // This function is called when a project is opened or re-opened (e.g. due to
13 | // the project's config changing)
14 |
15 | /**
16 | * @type {Cypress.PluginConfig}
17 | */
18 | // eslint-disable-next-line no-unused-vars
19 | module.exports = (on, config) => {
20 | // `on` is used to hook into various events Cypress emits
21 | // `config` is the resolved Cypress config
22 | }
23 |
--------------------------------------------------------------------------------
/cypress/support/commands.js:
--------------------------------------------------------------------------------
1 | Cypress.Commands.add('vselect', { prevSubject: 'element' }, (subject, option) => {
2 | subject.click();
3 | cy.get('.v-menu__content.menuable__content__active').contains(option).click();
4 | });
5 |
6 | Cypress.Commands.add('toFeature', name => {
7 | cy.contains('Features').click();
8 | cy.get('[data-cy=feature-list]').contains(name).click();
9 | });
10 |
11 | Cypress.Commands.add('giveUnlock', name => {
12 | cy.get('[data-cy=debug-unlock-input]').type(name.slice(0, -1));
13 | cy.contains(name).click();
14 | cy.get('[data-cy=debug-unlock-unlock]').click();
15 | });
16 |
17 | Cypress.Commands.add('changeMult', (name, type = 'base', amount = 1) => {
18 | cy.get('[data-cy=debug-mult-input]').type(name.slice(0, -1));
19 | cy.contains(name).click();
20 | cy.get('[data-cy=debug-mult-amount]').type('{backspace}' + amount);
21 | cy.get('[data-cy=debug-mult-type]').vselect(type);
22 | cy.get('[data-cy=debug-mult-apply]').click();
23 | });
24 |
25 | Cypress.Commands.add('giveCurrency', (name, amount = 1)=> {
26 | cy.get('[data-cy=debug-currency-input]').type(name.slice(0, -1));
27 | cy.contains(name).click();
28 | cy.get('[data-cy=debug-currency-amount]').type('{backspace}' + amount);
29 | cy.get('[data-cy=debug-currency-gain]').click();
30 | });
31 |
--------------------------------------------------------------------------------
/cypress/support/e2e.js:
--------------------------------------------------------------------------------
1 | import './commands'
2 |
3 | beforeEach(() => {
4 | cy.viewport(1920, 1080);
5 | cy.visit('http://localhost:8080');
6 | cy.get('input[type=file]').selectFile('debug.json', {force: true});
7 | });
8 |
--------------------------------------------------------------------------------
/debug.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.3.4",
3 | "timestamp": 0,
4 | "theme": "default",
5 | "unlock": {
6 | "debugFeature": true
7 | },
8 | "settings": {
9 | "general": {
10 | "pause": true,
11 | "autosaveTimer": null
12 | }
13 | },
14 | "subfeature": {},
15 | "currency": {},
16 | "stat": {},
17 | "upgrade": {},
18 | "upgradeQueue": {},
19 | "relic": [],
20 | "globalLevel": {},
21 | "keybinds": {},
22 | "note": [],
23 | "consumable": {},
24 | "rng": {},
25 | "cachePage": {}
26 | }
27 |
--------------------------------------------------------------------------------
/forge.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | packagerConfig: {
3 | asar: true,
4 | icon: 'dist/favicon'
5 | },
6 | rebuildConfig: {},
7 | makers: [
8 | {
9 | name: '@electron-forge/maker-squirrel',
10 | config: {},
11 | },
12 | {
13 | name: '@electron-forge/maker-zip',
14 | platforms: ['darwin'],
15 | },
16 | {
17 | name: '@electron-forge/maker-deb',
18 | config: {},
19 | },
20 | {
21 | name: '@electron-forge/maker-rpm',
22 | config: {},
23 | },
24 | ],
25 | plugins: [
26 | {
27 | name: '@electron-forge/plugin-auto-unpack-natives',
28 | config: {},
29 | },
30 | ],
31 | };
32 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [
3 | "./src/**/*"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | const { app, BrowserWindow, shell } = require('electron')
2 |
3 | const createWindow = () => {
4 | const win = new BrowserWindow({
5 | width: 1080,
6 | height: 720,
7 | icon: 'dist/favicon.ico'
8 | })
9 |
10 | win.loadFile('dist/index.html')
11 | win.removeMenu()
12 | win.webContents.setWindowOpenHandler(({ url }) => {
13 | shell.openExternal(url);
14 | return { action: 'deny' };
15 | });
16 | }
17 |
18 | app.whenReady().then(() => {
19 | createWindow()
20 |
21 | app.on('activate', () => {
22 | if (BrowserWindow.getAllWindows().length === 0) {
23 | createWindow()
24 | }
25 | })
26 | })
27 |
28 | app.on('window-all-closed', () => {
29 | if (process.platform !== 'darwin') {
30 | app.quit()
31 | }
32 | })
33 |
--------------------------------------------------------------------------------
/public/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tendsty/gooboo/e6d91028c7cdba4e913c5278111ff98834dd986d/public/android-chrome-192x192.png
--------------------------------------------------------------------------------
/public/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tendsty/gooboo/e6d91028c7cdba4e913c5278111ff98834dd986d/public/android-chrome-512x512.png
--------------------------------------------------------------------------------
/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tendsty/gooboo/e6d91028c7cdba4e913c5278111ff98834dd986d/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/public/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tendsty/gooboo/e6d91028c7cdba4e913c5278111ff98834dd986d/public/favicon-16x16.png
--------------------------------------------------------------------------------
/public/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tendsty/gooboo/e6d91028c7cdba4e913c5278111ff98834dd986d/public/favicon-32x32.png
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tendsty/gooboo/e6d91028c7cdba4e913c5278111ff98834dd986d/public/favicon.ico
--------------------------------------------------------------------------------
/public/img/note.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tendsty/gooboo/e6d91028c7cdba4e913c5278111ff98834dd986d/public/img/note.png
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Gooboo
13 |
14 |
15 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/public/site.webmanifest:
--------------------------------------------------------------------------------
1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
--------------------------------------------------------------------------------
/public/theme/sky/navbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tendsty/gooboo/e6d91028c7cdba4e913c5278111ff98834dd986d/public/theme/sky/navbar.png
--------------------------------------------------------------------------------
/public/version.txt:
--------------------------------------------------------------------------------
1 | 1.5.8
2 |
--------------------------------------------------------------------------------
/scripts/gh-pages-deploy.mjs:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | import { execa } from "execa";
3 | (async () => {
4 | try {
5 | await execa("git", ["checkout", "--orphan", "gh-pages"]);
6 | // eslint-disable-next-line no-console
7 | console.log("Building started...");
8 | await execa("npm", ["run", "build"]);
9 | const folderName = "dist";
10 | await execa("git", ["--work-tree", folderName, "add", "--all"]);
11 | await execa("git", ["--work-tree", folderName, "commit", "-m", "gh-pages"]);
12 | console.log("Pushing to gh-pages...");
13 | await execa("git", ["push", "origin", "HEAD:gh-pages", "--force"]);
14 | await execa("rm", ["-r", folderName]);
15 | await execa("git", ["checkout", "-f", "main"]);
16 | await execa("git", ["branch", "-D", "gh-pages"]);
17 | console.log("Successfully deployed, check your settings");
18 | } catch (e) {
19 | // eslint-disable-next-line no-console
20 | console.log(e.message);
21 | process.exit(1);
22 | }
23 | })();
24 |
--------------------------------------------------------------------------------
/src/components/partial/card/CardPack.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ $vuetify.lang.t(`$vuetify.card.pack.${ item.name }`) }}
4 |
{{ featureIcon }}{{ $vuetify.lang.t(`$vuetify.feature.${ item.feature }`) }}
5 |
mdi-cards{{ item.amount }}
6 |
7 |
8 |
9 |
10 |
28 |
--------------------------------------------------------------------------------
/src/components/partial/event/BingoCell.vue:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | {{ cell.value }}
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
46 |
--------------------------------------------------------------------------------
/src/components/partial/event/BloomBuyFlower.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ flower.icon }}
4 |
5 |
{{ $vuetify.lang.t('$vuetify.gooboo.buy') }}
6 |
7 |
8 |
9 |
42 |
--------------------------------------------------------------------------------
/src/components/partial/event/BloomInventorySlot.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
33 |
--------------------------------------------------------------------------------
/src/components/partial/event/Casino.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
20 |
--------------------------------------------------------------------------------
/src/components/partial/event/EventCalendar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | mdi-chevron-left
5 |
6 | {{ monthAndYear }}
7 |
8 | mdi-chevron-right
9 |
10 |
11 | {{ $vuetify.lang.t(`$vuetify.event.${event.name}.name`) }}
12 |
13 |
14 |
15 |
16 |
39 |
40 |
--------------------------------------------------------------------------------
/src/components/partial/event/NightHuntFavouritableDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 | {{ $vuetify.lang.t(`$vuetify.event.nightHunt.favouriteIngredient.copy`) }}
3 |
4 |
{{ ingredient.icon }}
5 |
{{ $vuetify.lang.t(`$vuetify.currency.event_${ name }.name`) }}
6 |
7 |
8 |
9 |
33 |
--------------------------------------------------------------------------------
/src/components/partial/event/NightHuntPotion.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ $vuetify.lang.t(`$vuetify.event.nightHunt.potion.${name}`) }}
4 | {{ $vuetify.lang.t('$vuetify.gooboo.level') }} {{ potion.level }}
5 |
6 |
11 |
12 |
13 |
14 |
15 |
16 |
45 |
--------------------------------------------------------------------------------
/src/components/partial/event/Prize.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
mdi-close{{ amount }}
6 |
7 |
8 |
mdi-cards
9 |
{{ $vuetify.lang.t(`$vuetify.card.pack.${ prize.item }`) }}
10 |
mdi-cards{{ cardPackAmount * amount }}
11 |
12 |
13 |
14 |
15 |
16 |
17 |
50 |
--------------------------------------------------------------------------------
/src/components/partial/event/SnowdownInventory.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | mdi-chevron-double-right
14 | {{ $vuetify.lang.t(`$vuetify.gooboo.boost`) }}
15 |
16 |
17 |
18 | {{ $vuetify.lang.t('$vuetify.event.snowdown.boost') }}
19 |
20 |
21 |
22 |
23 |
24 |
25 |
55 |
--------------------------------------------------------------------------------
/src/components/partial/event/WeatherChaosInventory.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
19 |
--------------------------------------------------------------------------------
/src/components/partial/farm/Building.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ building.icon }}
6 |
7 |
8 | {{ $vuetify.lang.t(`$vuetify.farm.building.${ name }.description${ isPremium ? 'Premium' : '' }`) }}
9 |
10 |
11 |
12 |
40 |
--------------------------------------------------------------------------------
/src/components/partial/farm/BuildingCard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ $vuetify.lang.t(`$vuetify.farm.building.${ name }.name`) }}
4 | {{ $vuetify.lang.t(`$vuetify.farm.building.premiumOwned`, premium) }}
5 | {{ $vuetify.lang.t(`$vuetify.farm.building.owned`, owned) }}
6 | {{ $vuetify.lang.t(`$vuetify.farm.building.${ name }.description${ premium > 0 ? 'Premium' : '' }`) }}
7 |
8 |
9 |
10 |
31 |
--------------------------------------------------------------------------------
/src/components/partial/farm/CropUpgrade.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ icons[upgrade] }}
7 |
8 |
9 |
10 | {{ $vuetify.lang.t(`$vuetify.farm.cropUpgrade.${ upgrade }`) }}
11 |
12 |
13 |
14 |
39 |
--------------------------------------------------------------------------------
/src/components/partial/farm/FertilizerCard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ $vuetify.lang.t(`$vuetify.farm.fertilizerCannotBeBought`) }}
4 |
{{ $vuetify.lang.t(`$vuetify.farm.fertilizerEffect.${fertilizer.type}`) }}
5 |
{{ $vuetify.lang.t(`$vuetify.mult.${key}`) }} {{ (item > 0 && item < 1) ? ('/' + $formatNum(1 / item, true)) : ('x' + $formatNum(item, true)) }}
11 |
12 |
13 |
14 |
35 |
--------------------------------------------------------------------------------
/src/components/partial/gallery/IdeaItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{ idea.icon }}
8 |
9 |
10 |
11 |
12 | {{ $vuetify.lang.t(`$vuetify.gallery.idea.tier`, idea.tier) }}
13 |
14 |
15 |
16 |
17 |
60 |
--------------------------------------------------------------------------------
/src/components/partial/gallery/Inventory.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ $vuetify.lang.t(`$vuetify.gallery.openPackage`) }}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
40 |
--------------------------------------------------------------------------------
/src/components/partial/gallery/PrestigeInventory.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
28 |
--------------------------------------------------------------------------------
/src/components/partial/gallery/PrestigeStatus.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
26 |
--------------------------------------------------------------------------------
/src/components/partial/gem/GemList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
--------------------------------------------------------------------------------
/src/components/partial/horde/ActiveCost.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | mdi-timer
4 | {{ $formatTime(Math.ceil(cooldown)) }}
5 | ({{ $formatTime(Math.ceil(cooldownLeft)) }})
6 | ({{ $formatTime(Math.round(nextChargeTime)) }})
7 |
8 | mdi-circle-small
9 | mdi-heart
10 | {{ $formatNum(cost.health, true) }}%
11 |
12 |
13 | mdi-circle-small
14 | mdi-lightning-bolt
15 | {{ $formatNum(cost.energy) }}
16 |
17 |
18 | mdi-circle-small
19 | mdi-water
20 | {{ $formatNum(cost.mana) }}
21 |
22 |
23 | mdi-circle-small
24 | mdi-billiards-rack
25 | {{ $formatNum(cost.mysticalShard) }}
26 |
27 |
28 |
29 |
30 |
55 |
--------------------------------------------------------------------------------
/src/components/partial/horde/EquipDisplay.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
{{ item.icon }}
11 |
12 |
{{ $vuetify.lang.t(`$vuetify.horde.items.${ name }`) }}
13 |
14 | mdi-timer
15 | {{ $formatTime(cooldown) }}
16 | ({{ $formatTime(Math.ceil(item.cooldownLeft)) }})
17 |
18 |
19 |
20 | {{ item.activeIcon }}
21 |
22 |
23 |
24 |
25 |
43 |
--------------------------------------------------------------------------------
/src/components/partial/horde/HeirloomList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
27 |
--------------------------------------------------------------------------------
/src/components/partial/horde/PrestigeInventory.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
34 |
--------------------------------------------------------------------------------
/src/components/partial/horde/TrinketList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ trinketsEquipped }} / {{ maxTrinkets }} {{ $vuetify.lang.t(`$vuetify.horde.trinket.equipped`) }}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
45 |
--------------------------------------------------------------------------------
/src/components/partial/main/NextTile.vue:
--------------------------------------------------------------------------------
1 |
26 |
27 |
28 |
29 |
30 |
mdi-lock
31 |
mdi-octagram
32 |
33 | {{ level }}
34 |
35 |
36 |
37 |
38 |
39 |
49 |
--------------------------------------------------------------------------------
/src/components/partial/mining/PrestigeInventory.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
31 |
--------------------------------------------------------------------------------
/src/components/partial/note/NoteList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ featureIcon }}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
47 |
--------------------------------------------------------------------------------
/src/components/partial/note/ShowButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | #{{ id }}
12 |
13 |
14 |
15 |
70 |
--------------------------------------------------------------------------------
/src/components/partial/relic/Mini.vue:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 | {{ relic.icon }}
17 |
18 |
19 |
20 | {{ $vuetify.lang.t(`$vuetify.achievement.relicReward`) }}
21 |
22 |
23 |
24 |
53 |
--------------------------------------------------------------------------------
/src/components/partial/relic/MuseumTab.vue:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
{{ glyph.level }}
16 |
10{{ $formatNum(glyph.progress * 100) }}% ({{ $formatTime(80000) }})
17 |
18 | {{ glyph.icon }}
19 |
20 |
21 |
22 |
23 |
24 |
25 |
36 |
--------------------------------------------------------------------------------
/src/components/partial/relic/RelicList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
20 |
--------------------------------------------------------------------------------
/src/components/partial/render/AlertText.vue:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 |
19 |
{{ icon }}
20 |
21 |
22 |
23 |
24 |
54 |
--------------------------------------------------------------------------------
/src/components/partial/render/GoobooTooltip.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ titleText }}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
44 |
--------------------------------------------------------------------------------
/src/components/partial/render/TabIconText.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ finalIcon }}
4 | {{ finalText }}
5 |
6 |
7 |
8 |
70 |
--------------------------------------------------------------------------------
/src/components/partial/school/BookUpgrades.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ $vuetify.lang.t(`$vuetify.feature.${ item.name }`) }}
5 | {{ $vuetify.lang.t(`$vuetify.feature.${ item.name }`) }}
6 |
7 |
8 |
9 |
10 |
11 |
27 |
--------------------------------------------------------------------------------
/src/components/partial/settings/Keybind.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ $vuetify.lang.t(`$vuetify.settings.keybinds.${name}.name`) }}
4 |
5 |
6 |
CTRL
7 |
ALT
8 |
SHIFT
9 |
{{ keybindCode }}
10 |
11 | mdi-close
12 | mdi-keyboard
13 |
14 |
15 |
16 |
47 |
--------------------------------------------------------------------------------
/src/components/partial/snackbar/AchievementMessage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | mdi-trophy
5 | {{ $vuetify.lang.t(`$vuetify.message.achievement.get`) }}
6 |
7 |
8 |
9 | {{ $vuetify.lang.t(`$vuetify.stat.${ message.name }.achievement`) }}
10 | #{{ message.value }}
11 | ({{ message.value - message.oldValue }} {{ $vuetify.lang.t(`$vuetify.message.achievement.gained`) }})
12 |
13 |
14 | {{ $vuetify.lang.t(`$vuetify.message.achievement.relicGained`) }}:
15 | {{ $vuetify.lang.t(`$vuetify.relic.${ relic.name }`) }}
16 | {{ relic.icon }}
17 |
18 |
19 |
20 |
21 |
22 |
52 |
--------------------------------------------------------------------------------
/src/components/partial/snackbar/CardPackInstantEffect.vue:
--------------------------------------------------------------------------------
1 |
2 | +{{ $formatNum(value) }} {{ $vuetify.lang.t(`$vuetify.currency.${effectName}.name`) }}
3 | +{{ $formatNum(value) }} {{ $vuetify.lang.t(`$vuetify.consumable.${effectName}.name`) }}
4 |
5 |
6 |
28 |
--------------------------------------------------------------------------------
/src/components/partial/snackbar/CardPackMessage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ $vuetify.lang.t(`$vuetify.message.card.get`) }}
4 |
5 |
6 | {{ item.amount }}x {{ key }}: {{ $vuetify.lang.t(`$vuetify.card.card.${key}`) }}
7 | ({{ $vuetify.lang.t(`$vuetify.message.card.new`) }})
8 | (
9 | ,
10 |
11 | )
12 |
13 |
14 |
15 |
16 |
17 |
30 |
--------------------------------------------------------------------------------
/src/components/partial/snackbar/ErrorMessage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ $vuetify.lang.t(`$vuetify.error.title`, $vuetify.lang.t(`$vuetify.error.tech.${ message.tech }`)) }}
4 |
5 | {{ message.message }}
6 | {{ $vuetify.lang.t(`$vuetify.error.source`, message.source) }}
7 | {{ $vuetify.lang.t(`$vuetify.error.position`, message.line, message.column) }}
8 |
9 |
10 | {{ $vuetify.lang.t(`$vuetify.error.reportBug`) }}
11 |
12 |
13 |
14 |
15 |
25 |
--------------------------------------------------------------------------------
/src/components/partial/snackbar/FeatureMessage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ $vuetify.lang.t(`$vuetify.message.feature.${ subfeature }`) }}
5 | {{ $vuetify.lang.t(`$vuetify.message.feature.feature`) }}
6 |
7 |
8 | {{ feature.icon }}
9 | {{ $vuetify.lang.t(`$vuetify.feature.${ message.subfeature }`) }} ({{ $vuetify.lang.t(`$vuetify.feature.${ message.name }`) }})
10 | {{ $vuetify.lang.t(`$vuetify.feature.${ message.name }`) }}
11 |
12 |
13 |
14 |
15 |
33 |
--------------------------------------------------------------------------------
/src/components/partial/snackbar/HeirloomMessage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ $vuetify.lang.t(`$vuetify.message.heirloom.get`) }}
4 |
5 | {{ item }}x {{ $vuetify.lang.t(`$vuetify.horde.heirloom.${key}`) }}
6 |
7 |
8 |
9 |
10 |
20 |
--------------------------------------------------------------------------------
/src/components/partial/snackbar/ImportMessage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | mdi-alert
5 | {{ $vuetify.lang.t(`$vuetify.message.import.message`) }}
6 |
7 |
8 | {{ $vuetify.lang.t(`$vuetify.message.import.${ message.error }`, messageVersion, version) }}
9 |
10 |
11 |
12 |
13 |
33 |
--------------------------------------------------------------------------------
/src/components/partial/snackbar/NoteMessage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ $vuetify.lang.t(`$vuetify.message.note.get`, noteNumber) }}
4 |
5 | {{ $vuetify.lang.t(`$vuetify.message.note.read`) }}
6 |
7 |
8 |
9 |
10 |
31 |
--------------------------------------------------------------------------------
/src/components/partial/snackbar/PrizeMessage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ $vuetify.lang.t(`$vuetify.message.prize.get`) }}
4 | {{ $vuetify.lang.t(`$vuetify.message.prize.bingo${ bingoTier }`) }}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
29 |
--------------------------------------------------------------------------------
/src/components/partial/snackbar/SaveMessage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | mdi-alert
6 | {{ $vuetify.lang.t(`$vuetify.message.save.error`) }}
7 |
8 | {{ message.error.message }}
9 |
10 | {{ $vuetify.lang.t(`$vuetify.message.save.success`) }}
11 |
12 |
13 |
14 |
24 |
--------------------------------------------------------------------------------
/src/components/partial/snackbar/SchoolMessage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ $vuetify.lang.t(`$vuetify.message.school.${ message.isExam ? 'getExam' : 'get' }`) }}
4 |
5 |
6 | {{ $vuetify.lang.t(`$vuetify.message.school.score`, Math.floor(message.score)) }}
7 | {{ $vuetify.lang.t(`$vuetify.message.school.perfectScore`) }}
8 |
9 | {{ $vuetify.lang.t(`$vuetify.message.school.gradePlus`) }}
10 |
11 | +
12 | {{ $vuetify.lang.t(`$vuetify.message.school.grade`, $formatNum(message.grade * 100)) }}
13 |
14 | {{ $vuetify.lang.t(`$vuetify.message.school.dust`, $formatNum(message.dust)) }}
15 |
16 |
17 |
18 |
19 |
29 |
--------------------------------------------------------------------------------
/src/components/partial/snackbar/UpdateMessage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ $vuetify.lang.t(`$vuetify.message.update.get`) }}
4 |
5 | {{ $vuetify.lang.t(`$vuetify.message.update.apply`) }}
6 |
7 |
8 |
9 |
10 |
25 |
--------------------------------------------------------------------------------
/src/components/partial/treasure/BuyItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ typeObj.icon ? typeObj.icon : 'mdi-help' }}
6 |
7 | {{ $vuetify.lang.t(`$vuetify.treasure.buyTreasure`) }}
8 |
9 |
10 | {{ $vuetify.lang.t(`$vuetify.gooboo.buy`) }}
11 |
12 |
13 |
14 |
55 |
--------------------------------------------------------------------------------
/src/components/partial/treasure/StatList.vue:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
{{ $vuetify.lang.t(`$vuetify.treasure.effectSummary`) }}
10 |
11 |
{{ features[key].icon }}{{ $vuetify.lang.t(`$vuetify.feature.${key}`) }}
12 |
13 |
14 |
15 |
16 |
17 |
47 |
--------------------------------------------------------------------------------
/src/components/partial/village/CraftingItem.vue:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | {{ crafting.icon }}
13 | {{ $formatNum(crafting.owned) }}
14 |
15 |
16 | mdi-star
17 |
18 |
19 |
20 | mdi-hammer
21 |
22 |
23 |
24 | mdi-currency-usd
25 |
26 |
27 |
28 |
29 |
44 |
--------------------------------------------------------------------------------
/src/components/partial/village/OfferingInventory.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | -
9 | {{ $formatTime(timeLeft) }}
10 |
11 |
12 |
13 |
14 |
15 |
32 |
--------------------------------------------------------------------------------
/src/components/partial/village/OfferingList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
38 |
--------------------------------------------------------------------------------
/src/components/partial/village/PolicyList.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
29 |
--------------------------------------------------------------------------------
/src/components/partial/village/PrestigeInventory.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
31 |
--------------------------------------------------------------------------------
/src/components/partial/village/PrestigeStatus.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
38 |
--------------------------------------------------------------------------------
/src/components/render/CurrencyIcon.vue:
--------------------------------------------------------------------------------
1 |
2 | {{ currency.icon }}
3 |
4 |
5 |
25 |
--------------------------------------------------------------------------------
/src/components/render/CurrentNote.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
45 |
--------------------------------------------------------------------------------
/src/components/render/MultName.vue:
--------------------------------------------------------------------------------
1 |
2 | ???
3 | {{ $vuetify.lang.t(`$vuetify.upgrade.${upgradeName}`) }} {{ $vuetify.lang.t(`$vuetify.gooboo.maxLevel`) }}
4 | {{ $vuetify.lang.t(`$vuetify.gooboo.multCapacity`, $vuetify.lang.t(`$vuetify.currency.${currencyName}.name`)) }}
5 | {{ $vuetify.lang.t(`$vuetify.gooboo.multGain`, $vuetify.lang.t(`$vuetify.currency.${currencyGainName}.name`)) }}
6 | {{ $vuetify.lang.t(`$vuetify.mult.${name}`) }}
7 |
8 |
9 |
52 |
--------------------------------------------------------------------------------
/src/components/render/NoteSimple.vue:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
17 | {{ $vuetify.lang.t(`$vuetify.note.text.${ name }`) }}
18 | ~ {{ $vuetify.lang.t(`$vuetify.note.author.${ author }`) }}
19 |
20 |
21 |
22 |
40 |
--------------------------------------------------------------------------------
/src/components/view/Achievement.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
39 |
--------------------------------------------------------------------------------
/src/components/view/Cryolab.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ $vuetify.lang.t('$vuetify.cryolab.frozen', currentFrozen, maxFrozen) }}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
45 |
--------------------------------------------------------------------------------
/src/components/view/Patchnote.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
41 |
--------------------------------------------------------------------------------
/src/components/view/Relic.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
29 |
--------------------------------------------------------------------------------
/src/components/view/TabDuplicate.vue:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
{{ $vuetify.lang.t('$vuetify.duplicateTab.title') }}
21 |
{{ $vuetify.lang.t('$vuetify.duplicateTab.description') }}
22 |
23 |
24 |
25 |
34 |
--------------------------------------------------------------------------------
/src/gbPlugin.js:
--------------------------------------------------------------------------------
1 | const { formatNum, formatTime, formatRoman, formatInt } = require("./js/utils/format");
2 |
3 | export default {
4 | install: function(Vue) {
5 | Vue.prototype.$formatNum = formatNum;
6 | Vue.prototype.$formatTime = formatTime;
7 | Vue.prototype.$formatRoman = formatRoman;
8 | Vue.prototype.$formatInt = formatInt;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/js/modules/event/bank/project.js:
--------------------------------------------------------------------------------
1 | import { getSequence } from "../../../utils/math";
2 |
3 | export default {
4 | expandVault: {
5 | price: lvl => getSequence(2, lvl) * 500 + 2000,
6 | effect: [
7 | {name: 'currencyGemTopazCap', type: 'base', value: lvl => lvl * 300}
8 | ]
9 | },
10 | persuadeInvestors: {
11 | price: lvl => getSequence(2, lvl) * 500 + 2000,
12 | effect: [
13 | {name: 'currencySchoolGoldenDustCap', type: 'base', value: lvl => lvl * 4000}
14 | ]
15 | },
16 | improveCreditScore: {
17 | price: lvl => getSequence(2, lvl) * 500 + 2000,
18 | effect: [
19 | {name: 'bankInvestmentSize', type: 'base', value: lvl => lvl * 200},
20 | {name: 'bankLoanSize', type: 'base', value: lvl => lvl * 200}
21 | ]
22 | },
23 | businessMarketing: {
24 | price: lvl => getSequence(2, lvl) * 500 + 2000,
25 | effect: [
26 | {name: 'merchantOffers', type: 'base', value: lvl => lvl}
27 | ]
28 | },
29 | cardTournament: {
30 | price: lvl => getSequence(2, lvl) * 500 + 2000,
31 | effect: [
32 | {name: 'bankCardPackChance', type: 'base', value: lvl => 0.5 - Math.pow(0.8, lvl) * 0.5}
33 | ]
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/js/modules/event/big.js:
--------------------------------------------------------------------------------
1 | export default {
2 | cinders: {
3 | // 20 days
4 | start: '01-15',
5 | end: '02-03',
6 | color: 'amber',
7 | currency: 'wax',
8 | token: 'cindersToken'
9 | },
10 | bloom: {
11 | // 23 days
12 | start: '03-09',
13 | end: '03-31',
14 | color: 'light-green',
15 | currency: 'humus',
16 | token: 'bloomToken'
17 | },
18 | weatherChaos: {
19 | // 18 days
20 | start: '05-22',
21 | end: '06-08',
22 | color: 'grey',
23 | currency: 'cloud',
24 | token: 'weatherChaosToken'
25 | },
26 | summerFestival: {
27 | // 28 days
28 | start: '07-26',
29 | end: '08-22',
30 | color: 'orange-red',
31 | currency: 'cocktail',
32 | token: 'summerFestivalToken'
33 | },
34 | nightHunt: {
35 | // 16 days
36 | start: '10-04',
37 | end: '10-19',
38 | color: 'deep-purple',
39 | currency: 'magic',
40 | token: 'nightHuntToken'
41 | },
42 | snowdown: {
43 | // 21 days
44 | start: '11-25',
45 | end: '12-15',
46 | color: 'skyblue',
47 | currency: 'snowball',
48 | token: 'snowdownToken'
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/js/modules/event/bloom/prize.js:
--------------------------------------------------------------------------------
1 | import store from "../../../../store";
2 |
3 | export default {
4 | theme_colorful: {
5 | type: 'theme',
6 | item: 'colorful',
7 | pool: {
8 | bloom: {price: {event_bloomToken: 180}}
9 | }
10 | },
11 | relic_colorfulFlower: {
12 | type: 'relic',
13 | item: 'colorfulFlower',
14 | requirement() {
15 | return store.state.unlock.farmFeature.see;
16 | },
17 | pool: {
18 | bloom: {price: {event_bloomToken: 170}}
19 | }
20 | },
21 | relic_heatingBulb: {
22 | type: 'relic',
23 | item: 'heatingBulb',
24 | requirement() {
25 | return store.state.unlock.galleryInspiration.see;
26 | },
27 | pool: {
28 | bloom: {price: {event_bloomToken: 200}}
29 | }
30 | },
31 | cardPack_greenThumb: {
32 | type: 'cardPack',
33 | item: 'greenThumb',
34 | pool: {
35 | bloom: {price: {event_bloomToken: 30}}
36 | }
37 | },
38 | farm_superFlower: {
39 | type: 'consumable',
40 | item: 'farm_superFlower',
41 | amount: 20,
42 | requirement() {
43 | return store.state.unlock.farmFertilizer.see;
44 | },
45 | pool: {
46 | bloom: {price: {event_bloomToken: 1}}
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/js/modules/event/cinders/prize.js:
--------------------------------------------------------------------------------
1 | import store from "../../../../store";
2 |
3 | export default {
4 | theme_candlelight: {
5 | type: 'theme',
6 | item: 'candlelight',
7 | pool: {
8 | cinders: {price: {event_cindersToken: 170}}
9 | }
10 | },
11 | relic_geode: {
12 | type: 'relic',
13 | item: 'geode',
14 | pool: {
15 | cinders: {price: {event_cindersToken: 140}}
16 | }
17 | },
18 | relic_birthdayCake: {
19 | type: 'relic',
20 | item: 'birthdayCake',
21 | requirement() {
22 | return store.state.unlock.treasureFeature.see;
23 | },
24 | pool: {
25 | cinders: {price: {event_cindersToken: 180}}
26 | }
27 | },
28 | cardPack_sparksOfJoy: {
29 | type: 'cardPack',
30 | item: 'sparksOfJoy',
31 | pool: {
32 | cinders: {price: {event_cindersToken: 30}}
33 | }
34 | },
35 | farm_sunshine: {
36 | type: 'consumable',
37 | item: 'farm_sunshine',
38 | amount: 20,
39 | requirement() {
40 | return store.state.unlock.farmFertilizer.see;
41 | },
42 | pool: {
43 | cinders: {price: {event_cindersToken: 1}}
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/js/modules/event/cinders/tick.js:
--------------------------------------------------------------------------------
1 | import store from "../../../../store";
2 | import { buildNum } from "../../../utils/format";
3 | import { logBase } from "../../../utils/math";
4 |
5 | export default function(seconds) {
6 | const candleDuration = store.state.cinders.activeCandle ? store.state.cinders.activeCandle.duration : 0
7 | const candleTime = Math.min(candleDuration, seconds);
8 | const lightGain = store.getters['cinders/totalProduction'] * Math.pow(1.015, store.getters['meta/globalEventLevel']);
9 |
10 | let totalLight = lightGain * (seconds - candleTime);
11 | if (candleTime > 0) {
12 | totalLight += lightGain * store.getters['mult/get']('cindersCandlePower', store.state.cinders.candle[store.state.cinders.activeCandle.name].lightMult - 1, 1, 1) * candleTime;
13 | const newCandleDuration = candleDuration - candleTime;
14 | if (newCandleDuration > 0) {
15 | store.commit('cinders/updateCandleKey', {key: 'duration', value: newCandleDuration});
16 | } else {
17 | store.dispatch('currency/gain', {feature: 'event', name: 'soot', gainMult: true, amount: store.state.cinders.candle[store.state.cinders.activeCandle.name].soot});
18 | store.commit('cinders/updateKey', {key: 'activeCandle', value: null});
19 | }
20 | }
21 | if (lightGain > 0) {
22 | store.dispatch('currency/gain', {
23 | feature: 'event',
24 | name: 'light',
25 | gainMult: true,
26 | amount: totalLight
27 | });
28 | store.dispatch('note/find', 'event_8');
29 |
30 | const lightGained = store.state.stat.event_light.value;
31 | const totalTokens = Math.floor(store.getters['mult/get']('currencyEventCindersTokenGain', logBase(lightGained / buildNum(10, 'K'), 1.2)));
32 | const collectedTokens = store.state.stat.event_cindersToken.value;
33 | if (totalTokens > collectedTokens) {
34 | store.dispatch('event/giveTokens', {event: 'cinders', amount: totalTokens - collectedTokens});
35 | store.dispatch('note/find', 'event_10');
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/js/modules/event/nightHunt/prize.js:
--------------------------------------------------------------------------------
1 | import store from "../../../../store";
2 |
3 | export default {
4 | theme_autumnForest: {
5 | type: 'theme',
6 | item: 'autumnForest',
7 | pool: {
8 | nightHunt: {price: {event_nightHuntToken: 200}}
9 | }
10 | },
11 | relic_massiveGrain: {
12 | type: 'relic',
13 | item: 'massiveGrain',
14 | requirement() {
15 | return store.state.unlock.farmFeature.see;
16 | },
17 | pool: {
18 | nightHunt: {price: {event_nightHuntToken: 170}}
19 | }
20 | },
21 | relic_enchantedBottle: {
22 | type: 'relic',
23 | item: 'enchantedBottle',
24 | requirement() {
25 | return store.state.unlock.miningResin.see;
26 | },
27 | pool: {
28 | nightHunt: {price: {event_nightHuntToken: 175}}
29 | }
30 | },
31 | cardPack_midnightAnomaly: {
32 | type: 'cardPack',
33 | item: 'midnightAnomaly',
34 | pool: {
35 | nightHunt: {price: {event_nightHuntToken: 30}}
36 | }
37 | },
38 | farm_fieldBlessing: {
39 | type: 'consumable',
40 | item: 'farm_fieldBlessing',
41 | amount: 20,
42 | requirement() {
43 | return store.state.unlock.farmFertilizer.see;
44 | },
45 | pool: {
46 | nightHunt: {price: {event_nightHuntToken: 1}}
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/js/modules/event/nightHunt/tick.js:
--------------------------------------------------------------------------------
1 | import store from "../../../../store";
2 | import { NIGHT_HUNT_GL_BOOST } from "../../../constants";
3 | import { chance } from "../../../utils/random";
4 |
5 | export default function(seconds) {
6 | let magicValue = store.state.currency.event_magic.value / 10;
7 | let addAmount = 0;
8 | let sackAmount = 0;
9 | let secondsLeft = seconds;
10 | while (secondsLeft > 0) {
11 | const changeAmount = Math.min(20, Math.floor(Math.sqrt(magicValue))) - Object.keys(store.state.nightHunt.changedCurrency).length - addAmount - sackAmount;
12 | const percent = 0.002 * changeAmount;
13 | const sackPercent = 0.002 * magicValue - 0.2;
14 | const secondsNeeded = percent > 0 ? Math.ceil(1 / percent) : Infinity;
15 | if (changeAmount <= 0) {
16 | secondsLeft = 0;
17 | } else if (secondsLeft >= secondsNeeded) {
18 | if (chance(sackPercent)) {
19 | sackAmount++;
20 | magicValue -= 10;
21 | } else {
22 | addAmount++;
23 | magicValue--;
24 | }
25 | secondsLeft -= secondsNeeded;
26 | } else {
27 | if (chance(percent)) {
28 | if (chance(sackPercent)) {
29 | sackAmount++;
30 | } else {
31 | addAmount++;
32 | }
33 | }
34 | secondsLeft = 0;
35 | }
36 | }
37 | if (addAmount > 0 || sackAmount > 0) {
38 | store.dispatch('nightHunt/addChangedCurrency', {random: addAmount, sack: sackAmount});
39 | store.dispatch('currency/spend', {feature: 'event', name: 'magic', amount: addAmount * 10 + sackAmount * 100});
40 | }
41 |
42 | const essenceGain = store.getters['mult/get']('currencyEventEssenceGain') * Math.pow(NIGHT_HUNT_GL_BOOST, store.getters['meta/globalEventLevel']);
43 | if (essenceGain > 0) {
44 | store.dispatch('currency/gain', {feature: 'event', name: 'essence', amount: essenceGain * seconds});
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/js/modules/event/snowdown/prize.js:
--------------------------------------------------------------------------------
1 | import store from "../../../../store";
2 |
3 | export default {
4 | theme_frozen: {
5 | type: 'theme',
6 | item: 'frozen',
7 | pool: {
8 | snowdown: {price: {event_snowdownToken: 225}}
9 | }
10 | },
11 | relic_moneyGift: {
12 | type: 'relic',
13 | item: 'moneyGift',
14 | requirement() {
15 | return store.state.unlock.villageFeature.see;
16 | },
17 | pool: {
18 | snowdown: {price: {event_snowdownToken: 155}}
19 | }
20 | },
21 | relic_frozenCarrot: {
22 | type: 'relic',
23 | item: 'frozenCarrot',
24 | requirement() {
25 | return store.state.unlock.farmFeature.see;
26 | },
27 | pool: {
28 | snowdown: {price: {event_snowdownToken: 170}}
29 | }
30 | },
31 | cardPack_icyWonderland: {
32 | type: 'cardPack',
33 | item: 'icyWonderland',
34 | pool: {
35 | snowdown: {price: {event_snowdownToken: 30}}
36 | }
37 | },
38 | farm_cinnamonBag: {
39 | type: 'consumable',
40 | item: 'farm_cinnamonBag',
41 | amount: 20,
42 | requirement() {
43 | return store.state.unlock.farmFertilizer.see;
44 | },
45 | pool: {
46 | snowdown: {price: {event_snowdownToken: 1}}
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/js/modules/event/snowdown/tick.js:
--------------------------------------------------------------------------------
1 | import store from "../../../../store";
2 |
3 | export default function(seconds) {
4 | ['sapling', 'yarn', 'dough', 'snow'].forEach(name => {
5 | const gain = store.getters['mult/get'](store.getters['currency/gainMultName']('event', name));
6 | if (gain > 0) {
7 | store.dispatch('currency/gain', {feature: 'event', name, amount: gain * seconds});
8 | }
9 | });
10 | }
11 |
--------------------------------------------------------------------------------
/src/js/modules/event/snowdown/upgrade.js:
--------------------------------------------------------------------------------
1 | export default {
2 | pineTrees: {type: 'snowdown', price(lvl) {
3 | return {event_sapling: 250 * Math.pow(lvl * 0.5 + 1, 2) * Math.pow(2, lvl)};
4 | }, effect: [
5 | {name: 'snowdownAllAttack', type: 'mult', value: lvl => Math.pow(1.02, lvl) * (lvl * 0.05 + 1)}
6 | ]},
7 | woolHat: {type: 'snowdown', price(lvl) {
8 | return {event_yarn: 250 * Math.pow(lvl * 0.5 + 1, 2) * Math.pow(2, lvl)};
9 | }, effect: [
10 | {name: 'snowdownAllHealth', type: 'mult', value: lvl => Math.pow(1.02, lvl) * (lvl * 0.05 + 1)},
11 | {name: 'snowdownAllDefense', type: 'mult', value: lvl => Math.pow(1.02, lvl) * (lvl * 0.05 + 1)},
12 | ]},
13 | cookies: {type: 'snowdown', price(lvl) {
14 | return {event_dough: 250 * Math.pow(lvl * 0.5 + 1, 2) * Math.pow(2, lvl)};
15 | }, effect: [
16 | {name: 'snowdownRevengeStats', type: 'base', value: lvl => lvl * 0.0005},
17 | {name: 'snowdownRevengeCrit', type: 'base', value: lvl => lvl * 0.06},
18 | {name: 'snowdownRevengeBlock', type: 'base', value: lvl => lvl * 0.04},
19 | ]},
20 |
21 | // topaz upgrades
22 | attackBoost: {type: 'snowdown', price(lvl) {
23 | return {gem_topaz: lvl * 50 + 150};
24 | }, effect: [
25 | {name: 'snowdownAllAttack', type: 'mult', value: lvl => lvl * 0.5 + 1}
26 | ]},
27 | healthBoost: {type: 'snowdown', price(lvl) {
28 | return {gem_topaz: lvl * 40 + 100};
29 | }, effect: [
30 | {name: 'snowdownAllHealth', type: 'mult', value: lvl => lvl * 0.5 + 1},
31 | {name: 'snowdownAllDefense', type: 'mult', value: lvl => lvl * 0.5 + 1},
32 | ]},
33 | }
34 |
--------------------------------------------------------------------------------
/src/js/modules/event/summerFestival/prize.js:
--------------------------------------------------------------------------------
1 | import store from "../../../../store";
2 |
3 | export default {
4 | theme_waves: {
5 | type: 'theme',
6 | item: 'waves',
7 | pool: {
8 | summerFestival: {price: {event_summerFestivalToken: 240}}
9 | }
10 | },
11 | relic_tropicalTent: {
12 | type: 'relic',
13 | item: 'tropicalTent',
14 | requirement() {
15 | return store.state.unlock.villageFeature.see;
16 | },
17 | pool: {
18 | summerFestival: {price: {event_summerFestivalToken: 150}}
19 | }
20 | },
21 | relic_fruitBasket: {
22 | type: 'relic',
23 | item: 'fruitBasket',
24 | requirement() {
25 | return store.state.unlock.farmFeature.see;
26 | },
27 | pool: {
28 | summerFestival: {price: {event_summerFestivalToken: 170}}
29 | }
30 | },
31 | cardPack_charmingShip: {
32 | type: 'cardPack',
33 | item: 'charmingShip',
34 | pool: {
35 | summerFestival: {price: {event_summerFestivalToken: 30}}
36 | }
37 | },
38 | farm_tropicalWater: {
39 | type: 'consumable',
40 | item: 'farm_tropicalWater',
41 | amount: 20,
42 | requirement() {
43 | return store.state.unlock.farmFertilizer.see;
44 | },
45 | pool: {
46 | summerFestival: {price: {event_summerFestivalToken: 1}}
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/js/modules/event/summerFestival/upgrade.js:
--------------------------------------------------------------------------------
1 | export default {
2 | extraBuildingSlot: {type: 'summerFestival', cap: 3, price(lvl) {
3 | return {gem_topaz: Math.pow(2, lvl) * 250};
4 | }, effect: [
5 | {name: 'summerFestivalBuildQueueSlots', type: 'base', value: lvl => lvl * 2}
6 | ]},
7 | doubleTime: {type: 'summerFestival', cap: 5, price(lvl) {
8 | return {gem_topaz: lvl * 100 + 200};
9 | }, effect: [
10 | {name: 'summerFestivalBuildQueueSpeed', type: 'mult', value: lvl => lvl + 1}
11 | ]},
12 | tropicalBlessing: {type: 'summerFestival', cap: 8, price(lvl) {
13 | return {gem_topaz: lvl * 50 + 100};
14 | }, effect: [
15 | {name: 'summerFestivalMaterialGain', type: 'mult', value: lvl => lvl * 0.25 + 1},
16 | {name: 'summerFestivalMaterialStackCap', type: 'base', value: lvl => lvl * 5}
17 | ]},
18 | }
19 |
--------------------------------------------------------------------------------
/src/js/modules/event/weatherChaos/bait.js:
--------------------------------------------------------------------------------
1 | export default {
2 | juicyBait: {
3 | icon: 'mdi-fruit-grapes',
4 | stackSize: 10,
5 | effect: [
6 | {name: 'weatherChaosFishingTime', type: 'mult', value: 0.1},
7 | {name: 'weatherChaosFishChance', type: 'base', value: 1},
8 | {name: 'weatherChaosFishDoubleChance', type: 'base', value: 0.35},
9 | {name: 'weatherChaosTreasureChance', type: 'mult', value: 0.1},
10 | ],
11 | },
12 | rainbowBait: {
13 | icon: 'mdi-looks',
14 | stackSize: 3,
15 | effect: [
16 | {name: 'weatherChaosFishChance', type: 'base', value: 1},
17 | {name: 'weatherChaosIgnoreWeather', type: 'base', value: 0.25},
18 | {name: 'weatherChaosFishSizeMax', type: 'mult', value: 1 / 1.1},
19 | {name: 'weatherChaosFishSizeAverage', type: 'mult', value: 0.8},
20 | ],
21 | },
22 | trashNet: {
23 | icon: 'mdi-spider-web',
24 | stackSize: 10,
25 | effect: [
26 | {name: 'weatherChaosFishingTime', type: 'mult', value: 0.1},
27 | {name: 'weatherChaosFishChance', type: 'base', value: -1},
28 | {name: 'weatherChaosTrashGain', type: 'mult', value: 3},
29 | {name: 'weatherChaosTreasureChance', type: 'mult', value: 0.1},
30 | ],
31 | },
32 | magnet: {
33 | icon: 'mdi-magnet',
34 | effect: [
35 | {name: 'weatherChaosTreasureChance', type: 'base', value: 1},
36 | ],
37 | },
38 | }
39 |
--------------------------------------------------------------------------------
/src/js/modules/event/weatherChaos/location.js:
--------------------------------------------------------------------------------
1 | export default {
2 | pond: {
3 | owned: true,
4 | next: {minPower: 40, name: 'lake'},
5 | },
6 | lake: {
7 | next: {minPower: 100, name: 'river'},
8 | effect: [
9 | {name: 'weatherChaosFishSizeAverage', type: 'mult', value: 1.2},
10 | {name: 'weatherChaosAlgaeWeight', type: 'mult', value: 3},
11 | {name: 'currencyEventAlgaeGain', type: 'mult', value: 2},
12 | ],
13 | },
14 | river: {
15 | next: {minPower: 250, name: 'ocean'},
16 | effect: [
17 | {name: 'weatherChaosFishSizeAverage', type: 'mult', value: 1.4},
18 | {name: 'weatherChaosDriftwoodWeight', type: 'mult', value: 3},
19 | {name: 'currencyEventDriftwoodGain', type: 'mult', value: 2},
20 | ],
21 | },
22 | ocean: {
23 | next: {minPower: 500, name: 'mountain'},
24 | effect: [
25 | {name: 'weatherChaosFishSizeAverage', type: 'mult', value: 1.6},
26 | {name: 'weatherChaosPlasticWeight', type: 'mult', value: 3},
27 | {name: 'currencyEventPlasticGain', type: 'mult', value: 2},
28 | ],
29 | },
30 | mountain: {
31 | next: {minPower: 1000, name: 'cave'},
32 | effect: [
33 | {name: 'weatherChaosFishSizeAverage', type: 'mult', value: 1.8},
34 | {name: 'currencyEventAlgaeGain', type: 'mult', value: 1.5},
35 | {name: 'currencyEventDriftwoodGain', type: 'mult', value: 1.5},
36 | {name: 'currencyEventPlasticGain', type: 'mult', value: 1.5},
37 | ],
38 | },
39 | cave: {
40 | effect: [
41 | {name: 'weatherChaosFishSizeAverage', type: 'mult', value: 2},
42 | {name: 'weatherChaosTreasureChance', type: 'mult', value: 1.5},
43 | ],
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/js/modules/event/weatherChaos/prize.js:
--------------------------------------------------------------------------------
1 | import store from "../../../../store";
2 |
3 | export default {
4 | theme_rain: {
5 | type: 'theme',
6 | item: 'rain',
7 | pool: {
8 | weatherChaos: {price: {event_weatherChaosToken: 260}}
9 | }
10 | },
11 | relic_trashCan: {
12 | type: 'relic',
13 | item: 'trashCan',
14 | pool: {
15 | weatherChaos: {price: {event_weatherChaosToken: 130}}
16 | }
17 | },
18 | relic_suitcase: {
19 | type: 'relic',
20 | item: 'suitcase',
21 | requirement() {
22 | return store.state.unlock.hordeHeirlooms.see;
23 | },
24 | pool: {
25 | weatherChaos: {price: {event_weatherChaosToken: 155}}
26 | }
27 | },
28 | cardPack_fishingForFun: {
29 | type: 'cardPack',
30 | item: 'fishingForFun',
31 | pool: {
32 | weatherChaos: {price: {event_weatherChaosToken: 30}}
33 | }
34 | },
35 | farm_smellyMud: {
36 | type: 'consumable',
37 | item: 'farm_smellyMud',
38 | amount: 20,
39 | requirement() {
40 | return store.state.unlock.farmFertilizer.see;
41 | },
42 | pool: {
43 | weatherChaos: {price: {event_weatherChaosToken: 1}}
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/js/modules/event/weatherChaos/upgrade.js:
--------------------------------------------------------------------------------
1 | import { getSequence } from "../../../utils/math";
2 |
3 | export default {
4 | juicyBait: {type: 'weatherChaos', price(lvl) {
5 | return {event_algae: Math.pow(1.35 + 0.08 * lvl, lvl) * 500};
6 | }, effect: [
7 | {name: 'weatherChaosFishSizeMax', type: 'base', value: lvl => lvl * 0.1},
8 | {name: 'weatherChaosFishSizeMax', type: 'mult', value: lvl => lvl * 0.1 + 1}
9 | ]},
10 | incubator: {type: 'weatherChaos', price(lvl) {
11 | return {event_driftwood: Math.pow(1.25 + 0.065 * lvl, lvl) * 250};
12 | }, effect: [
13 | {name: 'weatherChaosFishSizeAverage', type: 'base', value: lvl => lvl * 0.2},
14 | {name: 'weatherChaosFishSizeAverage', type: 'mult', value: lvl => lvl * 0.05 + 1}
15 | ]},
16 | fishWhistle: {type: 'weatherChaos', price(lvl) {
17 | return {event_plastic: Math.pow(1.15 + 0.015 * lvl, lvl) * 100};
18 | }, effect: [
19 | {name: 'weatherChaosFishingPower', type: 'base', value: lvl => getSequence(1, lvl) * 0.1 + lvl}
20 | ]},
21 | pollution: {type: 'weatherChaos', price(lvl) {
22 | return {event_slime: Math.pow(1.35, lvl) * 100};
23 | }, effect: [
24 | {name: 'weatherChaosTrashGain', type: 'mult', value: lvl => lvl * 0.1 + 1}
25 | ]},
26 | goldenHook: {type: 'weatherChaos', cap: 4, price(lvl) {
27 | return {gem_topaz: lvl * 250 + 500};
28 | }, effect: [
29 | {name: 'weatherChaosFishingTime', type: 'mult', value: lvl => 1 / (lvl * 0.25 + 1)}
30 | ]},
31 | }
32 |
--------------------------------------------------------------------------------
/src/js/modules/farm/achievement.js:
--------------------------------------------------------------------------------
1 | import store from "../../../store";
2 | import { getSequence } from "../../utils/math";
3 |
4 | export default {
5 | harvests: {value: () => store.state.stat.farm_harvests.total, milestones: lvl => Math.round(Math.pow(lvl + 1, 2) * Math.pow(1.5, lvl) * 10)},
6 | maxOvergrow: {value: () => store.state.stat.farm_maxOvergrow.total, display: 'percent', milestones: lvl => getSequence(1, lvl + 1), relic: {2: 'trellis', 4: 'brickWall'}},
7 | bestPrestige: {value: () => store.state.stat.farm_bestPrestige.total, milestones: lvl => lvl * 2 + 4},
8 | vegetable: {value: () => store.state.stat.farm_vegetable.total, milestones: lvl => Math.pow(81, lvl) * 250, relic: {2: 'goldenCarrot'}},
9 | berry: {value: () => store.state.stat.farm_berry.total, milestones: lvl => Math.pow(81, lvl) * 750, relic: {3: 'goldenApple'}},
10 | grain: {value: () => store.state.stat.farm_grain.total, milestones: lvl => Math.pow(81, lvl) * 2250, relic: {4: 'popcorn'}},
11 | flower: {value: () => store.state.stat.farm_flower.total, milestones: lvl => Math.pow(81, lvl) * 6750, relic: {5: 'roseQuartz'}},
12 | 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'}}
13 | }
14 |
--------------------------------------------------------------------------------
/src/js/modules/farm/building.js:
--------------------------------------------------------------------------------
1 | export default {
2 | gardenGnome: {
3 | icon: 'mdi-human-child'
4 | },
5 | sprinkler: {
6 | icon: 'mdi-sprinkler-variant'
7 | },
8 | lectern: {
9 | icon: 'mdi-book-open-page-variant'
10 | },
11 | pinwheel: {
12 | icon: 'mdi-pinwheel'
13 | },
14 | flag: {
15 | icon: 'mdi-flag'
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/js/modules/farm/relic.js:
--------------------------------------------------------------------------------
1 | export default {
2 | goldenCarrot: {icon: 'mdi-carrot', color: 'amber', effect: [
3 | {name: 'currencyFarmVegetableGain', type: 'mult', value: 1.4}
4 | ]},
5 | goldenApple: {icon: 'mdi-food-apple', color: 'amber', effect: [
6 | {name: 'currencyFarmBerryGain', type: 'mult', value: 1.4}
7 | ]},
8 | popcorn: {icon: 'mdi-popcorn', color: 'pale-yellow', effect: [
9 | {name: 'currencyFarmGrainGain', type: 'mult', value: 1.4}
10 | ]},
11 | roseQuartz: {icon: 'mdi-crystal-ball', color: 'pale-pink', effect: [
12 | {name: 'currencyFarmFlowerGain', type: 'mult', value: 1.4}
13 | ]},
14 | goldenSeed: {icon: 'mdi-seed', color: 'amber', effect: [
15 | {name: 'goldenRose', type: 'farmSeed', value: true}
16 | ]},
17 | trellis: {icon: 'mdi-fence', color: 'brown', effect: [
18 | {name: 'farmOvergrow', type: 'base', value: 0.05}
19 | ]},
20 | brickWall: {icon: 'mdi-wall', color: 'cherry', effect: [
21 | {name: 'farmOvergrow', type: 'base', value: 0.05}
22 | ]},
23 | }
24 |
--------------------------------------------------------------------------------
/src/js/modules/gallery/card.js:
--------------------------------------------------------------------------------
1 | import cardList from "./cardList";
2 |
3 | export default {
4 | feature: {
5 | prefix: 'GA',
6 | reward: [{name: 'currencyGalleryBeautyGain', type: 'mult', value: lvl => lvl * 0.075 + 1}],
7 | shinyReward: [{name: 'currencyGalleryCashGain', type: 'mult', value: lvl => lvl * 0.05 + 1}],
8 | powerReward: [
9 | {name: 'currencyGalleryBeautyGain', type: 'mult', value: lvl => Math.pow(1.1, lvl)},
10 | {name: 'currencyGalleryCashGain', type: 'mult', value: lvl => Math.pow(1.05, lvl)},
11 | ],
12 | unlock: 'galleryFeature'
13 | },
14 | collection: {
15 | artDisplay: {reward: [
16 | {name: 'galleryCardCap', type: 'base', value: 1},
17 | {name: 'currencyGalleryBeautyGain', type: 'mult', value: 2}
18 | ]},
19 | deliveryService: {reward: [
20 | {name: 'currencyGalleryConverterGain', type: 'mult', value: 1.25},
21 | {name: 'currencyGalleryPackageGain', type: 'mult', value: 1.25}
22 | ]},
23 | },
24 | pack: {
25 | newArtist: {unlock: 'galleryAuction', amount: 3, price: 55, content: {
26 | 'GA-0001': 1.2, 'GA-0002': 1, 'GA-0003': 0.8, 'GA-0004': 0.6,
27 | '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,
28 | 'GA-0012': 1.24, 'GA-0013': 1.5, 'GA-0014': 1.18,
29 | 'GA-0015': 1.4, 'GA-0016': 1.32, 'GA-0017': 1.12, 'GA-0018': 1.03,
30 | }},
31 | inspiringCreations: {unlock: 'galleryAuction', amount: 3, price: 120, content: {
32 | 'GA-0012': 1.24, 'GA-0013': 2.25, 'GA-0014': 1.18,
33 | 'GA-0015': 1.4, 'GA-0016': 1.32, 'GA-0017': 1.12, 'GA-0018': 1.03,
34 | 'GA-0019': 1.6, 'GA-0020': 0.77, 'GA-0021': 0.92, 'GA-0022': 0.85, 'GA-0023': 1.08,
35 | }},
36 | },
37 | card: cardList
38 | }
39 |
--------------------------------------------------------------------------------
/src/js/modules/gallery/shape.js:
--------------------------------------------------------------------------------
1 | export default {
2 | // Shapes
3 | circle: {unlocked: true, icon: 'mdi-circle', color: 'orange'},
4 | rectangle: {icon: 'mdi-rectangle', color: 'indigo'},
5 | triangle: {icon: 'mdi-triangle', color: 'light-green'},
6 | star: {icon: 'mdi-star', color: 'amber'},
7 | ellipse: {icon: 'mdi-ellipse', color: 'purple'},
8 | heart: {icon: 'mdi-heart', color: 'red'},
9 | square: {icon: 'mdi-square', color: 'light-blue'},
10 | octagon: {icon: 'mdi-octagon', color: 'babypink'},
11 | pentagon: {icon: 'mdi-pentagon', color: 'aqua'},
12 | hexagon: {icon: 'mdi-hexagon', color: 'brown'},
13 |
14 | // Special
15 | bomb: {isSpecial: true, icon: 'mdi-bomb', color: 'pale-red'},
16 | dice: {isSpecial: true, icon: 'mdi-dice-multiple', color: 'pale-pink'},
17 | accelerator: {isSpecial: true, icon: 'mdi-rotate-orbit', color: 'pale-purple'},
18 | sparkles: {isSpecial: true, icon: 'mdi-shimmer', color: 'pale-green'},
19 | hourglass: {isSpecial: true, icon: 'mdi-timer-sand', color: 'pale-yellow'},
20 | chest: {isSpecial: true, icon: 'mdi-treasure-chest', color: 'pale-blue'},
21 | }
22 |
--------------------------------------------------------------------------------
/src/js/modules/gem/card.js:
--------------------------------------------------------------------------------
1 | import cardList from "./cardList";
2 |
3 | export default {
4 | feature: {
5 | prefix: 'GE',
6 | reward: [{name: 'currencyGemTopazCap', type: 'base', value: lvl => lvl * 20}],
7 | shinyReward: [{name: 'currencyGemTopazCap', type: 'base', value: lvl => lvl * 20}],
8 | unlock: 'gemFeature'
9 | },
10 | collection: {
11 | preciousJewelry: {reward: [
12 | {name: 'currencyGemTopazCap', type: 'base', value: 160}
13 | ]},
14 | },
15 | pack: {},
16 | card: cardList
17 | }
18 |
--------------------------------------------------------------------------------
/src/js/modules/general/orladee.js:
--------------------------------------------------------------------------------
1 | export default {
2 | unlock: 'generalOrladeeSubfeature',
3 | quests: {
4 | beautyOfThisWorld: {
5 | reward: 'chessboard',
6 | stages: [
7 | {note: 'general_32', tasks: [
8 | {type: 'stat', subtype: 'current', name: 'farm_bugMax', operator: '>=', value: 250},
9 | {type: 'stat', subtype: 'current', name: 'farm_ladybugMax', operator: '>=', value: 250},
10 | {type: 'stat', subtype: 'current', name: 'farm_butterflyMax', operator: '>=', value: 50}
11 | ]},
12 | {note: 'general_33', tasks: [
13 | {type: 'stat', subtype: 'current', name: 'gallery_redDrumMax', operator: '>=', value: 1200}
14 | ]},
15 | ]
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/js/modules/horde/achievement.js:
--------------------------------------------------------------------------------
1 | import store from "../../../store";
2 | import { buildNum } from "../../utils/format";
3 | import { getSequence } from "../../utils/math";
4 |
5 | export default {
6 | maxZone: {value: () => store.state.stat.horde_maxZone.total, default: 1, cap: 30, milestones: lvl => lvl * 10 + 10, relic: {7: 'ultimateGuide', 11: 'crackedSafe'}},
7 | maxZoneSpeedrun: {value: () => store.state.stat.horde_maxZoneSpeedrun.total, default: 1, cap: 10, milestones: lvl => lvl * 5 + 10, relic: {8: 'dumbbell'}},
8 | totalDamage: {value: () => store.state.stat.horde_totalDamage.total, milestones: lvl => Math.pow(lvl * 250 + 7500, lvl) * buildNum(10, 'K'), relic: {6: 'newBackpack'}},
9 | maxDamage: {value: () => store.state.stat.horde_maxDamage.total, milestones: lvl => Math.pow(lvl * 250 + 7500, lvl) * 10, relic: {3: 'burningSkull'}},
10 | bone: {value: () => store.state.stat.horde_bone.total, milestones: lvl => Math.pow(2, getSequence(10, lvl) - 10) * buildNum(1, 'M'), relic: {2: 'forgottenShield'}},
11 | monsterPart: {value: () => store.state.stat.horde_monsterPart.total, milestones: lvl => Math.pow(16, lvl) * 50, relic: {3: 'energyDrink', 5: 'bandage'}},
12 | soulCorrupted: {value: () => store.state.stat.horde_soulCorrupted.total, milestones: lvl => Math.pow(7 + lvl, lvl) * 1000, relic: {4: 'luckyDice'}},
13 | maxCorruptionKill: {value: () => store.state.stat.horde_maxCorruptionKill.total, display: 'percent', milestones: lvl => lvl + 1},
14 | maxMastery: {value: () => store.state.stat.horde_maxMastery.total, milestones: lvl => lvl + 1},
15 | totalMastery: {value: () => store.state.stat.horde_totalMastery.total, milestones: lvl => Math.round((lvl + 1) * 25 * (lvl * 0.2 + 1))},
16 | unlucky: {value: () => store.state.stat.horde_unlucky.total, secret: true, display: 'boolean', cap: 1, milestones: () => 1},
17 | }
18 |
--------------------------------------------------------------------------------
/src/js/modules/horde/battlePass.js:
--------------------------------------------------------------------------------
1 | const newUpgrade = {icon: 'mdi-arrow-up-thin', color: 'light-blue', effect: [{name: 'hordeBattlePassUpgrade', type: 'text', value: true}]};
2 | const newPrestigeUpgrade = {icon: 'mdi-arrow-up-bold', color: 'orange', effect: [{name: 'hordeBattlePassPrestigeUpgrade', type: 'text', value: true}]};
3 |
4 | export default {
5 | 1: newUpgrade,
6 | 2: {icon: 'mdi-bow-arrow', color: 'light-green', effect: [{name: 'hordeClassArcher', type: 'unlock', value: true}]},
7 | 3: newUpgrade,
8 | 5: {icon: 'mdi-wizard-hat', color: 'deep-purple', effect: [{name: 'hordeClassMage', type: 'unlock', value: true}]},
9 | 7: newPrestigeUpgrade,
10 | 8: newUpgrade,
11 | 10: newPrestigeUpgrade,
12 | 12: newPrestigeUpgrade,
13 | 14: newUpgrade,
14 | 15: {icon: 'mdi-shield', color: 'blue-grey', effect: [{name: 'hordeClassKnight', type: 'unlock', value: true}]},
15 | 16: newPrestigeUpgrade,
16 | 18: newUpgrade,
17 | 20: newPrestigeUpgrade,
18 | 24: newUpgrade,
19 | 25: {icon: 'mdi-cached', color: 'pink', effect: [{name: 'hordeAutocast', type: 'base', value: 1}]},
20 | 27: newPrestigeUpgrade,
21 | 30: {icon: 'mdi-necklace', color: 'cyan', effect: [{name: 'hordeHeirloomAmount', type: 'mult', value: 2}]},
22 | 31: newUpgrade,
23 | 33: newPrestigeUpgrade,
24 | 35: {icon: 'mdi-pirate', color: 'orange', effect: [{name: 'hordeClassPirate', type: 'unlock', value: true}]},
25 | 40: {icon: 'mdi-star', color: 'light-blue', effect: [{name: 'hordeSkillPointsPerLevel', type: 'base', value: 1}]},
26 | 42: newUpgrade,
27 | 45: newPrestigeUpgrade,
28 | 50: {icon: 'mdi-treasure-chest', color: 'red', effect: [{name: 'hordeMaxTrinkets', type: 'base', value: 1}]},
29 | 55: newUpgrade,
30 | 60: {icon: 'mdi-billiards-rack', color: 'teal', effect: [{name: 'hordeShardChance', type: 'mult', value: 3}]},
31 | 65: newPrestigeUpgrade,
32 | 70: newUpgrade,
33 | 75: {icon: 'mdi-treasure-chest', color: 'wooden', effect: [{name: 'hordeMaxItems', type: 'base', value: 1}]},
34 | 80: {icon: 'mdi-star', color: 'light-blue', effect: [{name: 'hordeSkillPointsPerLevel', type: 'base', value: 1}]},
35 | }
36 |
--------------------------------------------------------------------------------
/src/js/modules/horde/boss.js:
--------------------------------------------------------------------------------
1 | export default {
2 | ohilio_guard1: {
3 | attack: 0.15,
4 | health: 150,
5 | textShadow: '1px 1px 2px palevioletred, 0 0 25px lightpink, 0 0 5px pink',
6 | sigil: {
7 | shotgun_gun: 3,
8 | war_bandage: 3,
9 | },
10 | stats: {}
11 | },
12 | ohilio_guard2: {
13 | attack: 0.6125,
14 | health: 45,
15 | textShadow: '1px 1px 2px palevioletred, 0 0 25px lightpink, 0 0 5px pink',
16 | sigil: {
17 | rifle_gun: 3,
18 | war_grenade: 2,
19 | },
20 | stats: {}
21 | },
22 | ohilio: {
23 | attack: 0.01,
24 | health: 0.01,
25 | textShadow: '1px 1px 2px palevioletred, 0 0 25px lightpink, 0 0 5px pink',
26 | sigil: {
27 | ohilio_megagun: 1,
28 | },
29 | stats: {}
30 | },
31 | mina: {
32 | attack: 0.5,
33 | health: 87.5,
34 | textShadow: '1px 1px 2px palevioletred, 0 0 25px lightpink, 0 0 5px pink',
35 | sigil: {
36 | mina_charm: 1,
37 | },
38 | stats: {
39 | toxic_base: 0.03,
40 | execute_base: 0.2
41 | }
42 | },
43 | chriz1: {
44 | attack: 0.375,
45 | health: 42.5,
46 | textShadow: '1px 1px 2px blue',
47 | sigil: {
48 | chriz_magicMissile: 1,
49 | chriz_fireball: 1,
50 | chriz_iceBlast: 1,
51 | chriz_lightningStrike: 1,
52 | chriz_heal: 1,
53 | },
54 | stats: {
55 | magicConversion_base: 4,
56 | physicTaken_mult: 0.01,
57 | magicTaken_mult: 1.75,
58 | }
59 | },
60 | chriz2: {
61 | attack: 0.5,
62 | health: 50,
63 | textShadow: '1px 1px 2px red',
64 | sigil: {},
65 | stats: {
66 | critChance_base: 0.35,
67 | critMult_base: 3,
68 | physicTaken_mult: 1.75,
69 | magicTaken_mult: 0.01,
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/js/modules/horde/fighterClass/assassin.js:
--------------------------------------------------------------------------------
1 | export default {
2 | unlock: 'hordeClassAssassin',
3 | icon: 'mdi-robber',
4 | baseStats: {
5 | attack: 8.5,
6 | health: 220,
7 | mana: 90
8 | },
9 | exp: {
10 | base: 2700,
11 | increment: 1.5
12 | },
13 | skills: {},
14 | skillTree: [
15 | {isInnate: true, level: 0, items: []},
16 | ],
17 | quests: {
18 | stat: [],
19 | zone: [],
20 | level: [],
21 | boss: []
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/js/modules/horde/fighterClass/cultist.js:
--------------------------------------------------------------------------------
1 | export default {
2 | unlock: 'hordeClassCultist',
3 | icon: 'mdi-pentagram',
4 | baseStats: {
5 | attack: 3.3,
6 | health: 700
7 | },
8 | exp: {
9 | base: 12600,
10 | increment: 1.875
11 | },
12 | skills: {},
13 | skillTree: [
14 | {isInnate: true, level: 0, items: []},
15 | ],
16 | quests: {
17 | stat: [],
18 | zone: [],
19 | level: [],
20 | boss: []
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/js/modules/horde/fighterClass/scholar.js:
--------------------------------------------------------------------------------
1 | export default {
2 | unlock: 'hordeClassScholar',
3 | icon: 'mdi-school',
4 | baseStats: {
5 | attack: 2,
6 | health: 250
7 | },
8 | exp: {
9 | base: 18000,
10 | increment: 2.1
11 | },
12 | skills: {},
13 | skillTree: [
14 | {isInnate: true, level: 0, items: []},
15 | ],
16 | quests: {
17 | stat: [],
18 | zone: [],
19 | level: [],
20 | boss: []
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/js/modules/horde/fighterClass/shaman.js:
--------------------------------------------------------------------------------
1 | export default {
2 | unlock: 'hordeClassShaman',
3 | icon: 'mdi-tree',
4 | baseStats: {
5 | attack: 4.4,
6 | health: 575,
7 | mana: 150
8 | },
9 | exp: {
10 | base: 4200,
11 | increment: 1.425
12 | },
13 | skills: {},
14 | skillTree: [
15 | {isInnate: true, level: 0, items: []},
16 | ],
17 | quests: {
18 | stat: [],
19 | zone: [],
20 | level: [],
21 | boss: []
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/js/modules/horde/fighterClass/undead.js:
--------------------------------------------------------------------------------
1 | export default {
2 | unlock: 'hordeClassUndead',
3 | icon: 'mdi-emoticon-dead',
4 | baseStats: {
5 | attack: 1.8,
6 | health: 60
7 | },
8 | exp: {
9 | base: 8400,
10 | increment: 1.7
11 | },
12 | skills: {},
13 | skillTree: [
14 | {isInnate: true, level: 0, items: []},
15 | ],
16 | quests: {
17 | stat: [],
18 | zone: [],
19 | level: [],
20 | boss: []
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/js/modules/horde/relic.js:
--------------------------------------------------------------------------------
1 | export default {
2 | forgottenShield: {icon: 'mdi-shield-sun', color: 'pale-light-blue', effect: [
3 | {name: 'horde_resilience', type: 'keepUpgrade', value: true},
4 | {name: 'horde_rest', type: 'keepUpgrade', value: true}
5 | ]},
6 | burningSkull: {icon: 'mdi-skull', color: 'orange-red', effect: [
7 | {name: 'horde_boneBag', type: 'keepUpgrade', value: true},
8 | {name: 'horde_anger', type: 'keepUpgrade', value: true}
9 | ]},
10 | energyDrink: {icon: 'mdi-bottle-soda', color: 'yellow', effect: [
11 | {name: 'currencyHordeMonsterPartGain', type: 'base', value: 0.5},
12 | {name: 'horde_monsterSoup', type: 'keepUpgrade', value: true}
13 | ]},
14 | luckyDice: {icon: 'mdi-dice-6', color: 'light-green', effect: [
15 | {name: 'horde_luckyStrike', type: 'keepUpgrade', value: true}
16 | ]},
17 | dumbbell: {icon: 'mdi-dumbbell', color: 'indigo', effect: [
18 | {name: 'horde_training', type: 'keepUpgrade', value: true}
19 | ]},
20 | bandage: {icon: 'mdi-bandage', color: 'pale-pink', effect: [
21 | {name: 'horde_thickSkin', type: 'keepUpgrade', value: true}
22 | ]},
23 | newBackpack: {icon: 'mdi-bag-personal', color: 'pale-orange', effect: [
24 | {name: 'horde_hoarding', type: 'keepUpgrade', value: true},
25 | {name: 'horde_plunderSecret', type: 'keepUpgrade', value: true}
26 | ]},
27 | ultimateGuide: {icon: 'mdi-book-multiple', color: 'brown', effect: [
28 | {name: 'horde_stabbingGuide', type: 'keepUpgrade', value: true},
29 | {name: 'horde_dodgingGuide', type: 'keepUpgrade', value: true}
30 | ]},
31 | crackedSafe: {icon: 'mdi-safe-square', color: 'darker-grey', effect: [
32 | {name: 'horde_looting', type: 'keepUpgrade', value: true}
33 | ]},
34 | }
35 |
--------------------------------------------------------------------------------
/src/js/modules/migration/v1_1_0.js:
--------------------------------------------------------------------------------
1 | import { addCurrencyToSave } from "./helper";
2 |
3 | export default function(save) {
4 | // Convert old grades to new ones
5 | if (save.school) {
6 | for (const [key, elem] of Object.entries(save.school)) {
7 | const oldGradeBase = Math.max(elem.elo, elem.grade) * 0.6;
8 | const newGrade = Math.floor(oldGradeBase / 100);
9 | save.school[key] = {
10 | grade: newGrade,
11 | currentGrade: newGrade,
12 | progress: oldGradeBase / 100 - newGrade
13 | };
14 | }
15 | }
16 |
17 | // Adjust know-it-all achievement
18 | if (save.stat?.school_highestGrade) {
19 | save.stat.school_highestGrade.value = Math.floor(save.stat.school_highestGrade.value * 0.006);
20 | save.stat.school_highestGrade.total = Math.floor(save.stat.school_highestGrade.total * 0.006);
21 | }
22 |
23 | // Award lost exam passes
24 | if (save.globalLevel) {
25 | let totalLevel = 0;
26 | for (const [, elem] of Object.entries(save.globalLevel)) {
27 | totalLevel += elem;
28 | }
29 | if (totalLevel >= 25) {
30 | save = addCurrencyToSave(save, 'school_examPass', Math.floor(totalLevel / 10));
31 | }
32 | }
33 |
34 | return save;
35 | }
36 |
--------------------------------------------------------------------------------
/src/js/modules/migration/v1_1_2.js:
--------------------------------------------------------------------------------
1 | import { raiseUpgradeLevel } from "./helper";
2 |
3 | export default function(save) {
4 | save = raiseUpgradeLevel(save, 'mining_moreDamage', 2);
5 | save = raiseUpgradeLevel(save, 'mining_moreScrap', 2);
6 | save = raiseUpgradeLevel(save, 'village_overtime', 1);
7 | save = raiseUpgradeLevel(save, 'village_goldenThrone', 1);
8 | save = raiseUpgradeLevel(save, 'school_student', 4);
9 |
10 | return save;
11 | }
12 |
--------------------------------------------------------------------------------
/src/js/modules/migration/v1_3_4.js:
--------------------------------------------------------------------------------
1 | export default function(save) {
2 | // Delete all rng prerolls because of the new seeded rng
3 | save.rng = {};
4 |
5 | // New unlock format
6 | for (const [key, elem] of Object.entries(save.unlock)) {
7 | save.unlock[key] = elem.use;
8 | }
9 |
10 | // New stat format
11 | for (const [key, elem] of Object.entries(save.stat)) {
12 | save.stat[key] = [elem.value, elem.total];
13 | }
14 |
15 | // New upgrade format
16 | for (const [key, elem] of Object.entries(save.upgrade)) {
17 | save.upgrade[key] = elem.bought === undefined ? [elem.collapse, elem.level, elem.highestLevel] : [elem.collapse, elem.level, elem.highestLevel, elem.bought, elem.timeProgress];
18 | }
19 |
20 | return save;
21 | }
22 |
--------------------------------------------------------------------------------
/src/js/modules/migration/v1_3_5.js:
--------------------------------------------------------------------------------
1 | export default function(save) {
2 | if (save.horde && save.horde.loadout) {
3 | save.horde.loadout = save.horde.loadout.map(elem => {
4 | return {name: encodeURIComponent(elem.name), content: elem.content};
5 | });
6 | }
7 | return save;
8 | }
9 |
--------------------------------------------------------------------------------
/src/js/modules/migration/v1_4_0.js:
--------------------------------------------------------------------------------
1 | import { deltaLinear } from "../../utils/math";
2 |
3 | export default function(save) {
4 | if (save.farm?.field) {
5 | let newField = {};
6 | save.farm.field.forEach(cell => {
7 | let content = {...cell.content};
8 | if (content.type === 'crop') {
9 | content.grow = 0;
10 | content.time = 0;
11 | content.buildingEffect = {};
12 | }
13 | newField[cell.y * 7 + cell.x] = content;
14 | });
15 | save.farm.field = newField;
16 | }
17 |
18 | if (save.farm?.crop) {
19 | for (const [, elem] of Object.entries(save.farm.crop)) {
20 | elem.dna = deltaLinear(14, 4, elem.level);
21 | elem.genes = [];
22 | elem.genesBlocked = [];
23 | elem.cardSelected = [];
24 | elem.cardEquipped = [];
25 | elem.upgrades = {};
26 | }
27 | }
28 |
29 | // Update dweller cap stats
30 | if (save.stat.mining_depthDweller0) {
31 | save.stat.mining_depthDwellerCap0 = save.stat.mining_depthDweller0;
32 | }
33 | if (save.stat.mining_depthDweller1) {
34 | save.stat.mining_depthDwellerCap1 = save.stat.mining_depthDweller1;
35 | }
36 | if (save.achievement?.mining_depthDweller0) {
37 | save.achievement.mining_depthDwellerCap0 = save.achievement.mining_depthDweller0;
38 | }
39 | if (save.achievement?.mining_depthDweller1) {
40 | save.achievement.mining_depthDwellerCap1 = save.achievement.mining_depthDweller1;
41 | }
42 |
43 | return save;
44 | }
45 |
--------------------------------------------------------------------------------
/src/js/modules/migration/v1_4_1.js:
--------------------------------------------------------------------------------
1 | export default function(save) {
2 | // Update offering stats
3 | if (save.stat.village_offering) {
4 | save.stat.village_offeringAmount = save.stat.village_offering;
5 | }
6 | return save;
7 | }
8 |
--------------------------------------------------------------------------------
/src/js/modules/migration/v1_5_1.js:
--------------------------------------------------------------------------------
1 | export default function(save) {
2 | // Use new school subject format
3 | if (save.school) {
4 | for (const [key, elem] of Object.entries(save.school)) {
5 | save.school[key] = [elem.grade, elem.currentGrade, elem.progress];
6 | }
7 | }
8 |
9 | // Use new smeltery format
10 | if (save.mining && save.mining.smeltery) {
11 | for (const [key, elem] of Object.entries(save.mining.smeltery)) {
12 | save.mining.smeltery[key] = [elem.progress, elem.stored, elem.total];
13 | }
14 | }
15 |
16 | // Use new offering format
17 | if (save.village && save.village.offering) {
18 | for (const [key, elem] of Object.entries(save.village.offering)) {
19 | save.village.offering[key] = [elem.offeringBought, elem.upgradeBought];
20 | }
21 | }
22 |
23 | return save;
24 | }
25 |
--------------------------------------------------------------------------------
/src/js/modules/migration/v1_5_4.js:
--------------------------------------------------------------------------------
1 | export default function(save) {
2 | // Remove snowballs to prevent old version players from getting a massive advantage
3 | if (save.currency.event_snowball !== undefined) {
4 | delete save.currency.event_snowball;
5 | }
6 |
7 | if (save.event) {
8 | // Convert tokens from the old to the new formula
9 | let tokensExpected = 0;
10 | const fights = save.event.snowdown_fight ?? 0;
11 | for (let i = 0; i < fights; i++) {
12 | tokensExpected += Math.floor(Math.pow(i * 0.35 + 1, 0.75) + 3);
13 | }
14 | if (save.stat.event_snowdownToken && save.currency.event_snowdownToken !== undefined) {
15 | const tokenDiff = tokensExpected - save.stat.event_snowdownToken[0];
16 | if (tokenDiff !== 0) {
17 | save.currency.event_snowdownToken += tokenDiff;
18 | if (tokenDiff > 0) {
19 | save.stat.event_snowdownToken = [save.stat.event_snowdownToken[0] + tokenDiff, save.stat.event_snowdownToken[1] + tokenDiff];
20 | }
21 | }
22 | }
23 |
24 | // Convert removed producers
25 | if (save.event.snowdown_item !== undefined) {
26 | if (save.event.snowdown_item.spiceJar) {
27 | save.event.snowdown_item.shepherd = (save.event.snowdown_item.shepherd ?? 0) + save.event.snowdown_item.spiceJar;
28 | delete save.event.snowdown_item.spiceJar;
29 | }
30 | if (save.event.snowdown_item.tap) {
31 | save.event.snowdown_item.forest = (save.event.snowdown_item.forest ?? 0) + save.event.snowdown_item.tap;
32 | delete save.event.snowdown_item.tap;
33 | }
34 | }
35 | }
36 |
37 | // Convert levels of the well drawn ellipse upgrade
38 | if (save.upgrade.gallery_wellDrawnEllipse) {
39 | const newLvl = Math.ceil(save.upgrade.gallery_wellDrawnEllipse[1] / 2);
40 | save.upgrade.gallery_wellDrawnEllipse[1] = newLvl;
41 | save.upgrade.gallery_wellDrawnEllipse[2] = newLvl;
42 | }
43 |
44 | return save;
45 | }
46 |
--------------------------------------------------------------------------------
/src/js/modules/migration/v1_5_6.js:
--------------------------------------------------------------------------------
1 | export default function(save) {
2 | // Fix event token values
3 | if (save.stat.event_bloomToken !== undefined) {
4 | save.stat.event_bloomToken[0] = 0;
5 | }
6 | if (save.stat.event_weatherChaosToken !== undefined) {
7 | save.stat.event_weatherChaosToken[0] = 0;
8 | }
9 | if (save.stat.event_summerFestivalToken !== undefined) {
10 | save.stat.event_summerFestivalToken[0] = 0;
11 | }
12 | if (save.stat.event_nightHuntToken !== undefined) {
13 | save.stat.event_nightHuntToken[0] = 0;
14 | }
15 | if (save.stat.event_snowdownToken !== undefined) {
16 | save.stat.event_snowdownToken[0] = 0;
17 | }
18 |
19 | // Give missing cinders tokens
20 | if (save.stat.event_cindersToken !== undefined && save.stat.event_cindersHighscore !== undefined && save.stat.event_cindersHighscore[1] > save.stat.event_cindersHighscore[0]) {
21 | const missingTokens = save.stat.event_cindersToken[1] - save.stat.event_cindersHighscore[0];
22 | if (missingTokens > 0) {
23 | save.stat.event_cindersToken[0] -= missingTokens;
24 | }
25 | }
26 |
27 | return save;
28 | }
29 |
--------------------------------------------------------------------------------
/src/js/modules/mining/beacon.js:
--------------------------------------------------------------------------------
1 | export default {
2 | piercing: {
3 | color: 'purple',
4 | ownedMult: 'miningBeaconPiercing',
5 | effect: [
6 | {name: 'miningToughness', type: 'mult', value: lvl => 1 / (lvl * 0.25 + 5)}
7 | ]
8 | },
9 | rich: {
10 | color: 'orange',
11 | ownedMult: 'miningBeaconRich',
12 | effect: [
13 | {name: 'miningOreGain', type: 'mult', value: lvl => lvl * 0.05 + 2}
14 | ]
15 | },
16 | wonder: {
17 | color: 'blue',
18 | ownedMult: 'miningBeaconWonder',
19 | effect: [
20 | {name: 'miningRareEarthGain', type: 'mult', value: lvl => lvl * 0.04 + 1.6}
21 | ]
22 | },
23 | hope: {
24 | color: 'green',
25 | ownedMult: 'miningBeaconHope',
26 | range: 5,
27 | effect: [
28 | {name: 'miningDamage', type: 'mult', value: lvl => lvl * 0.01 + 1.1},
29 | {name: 'currencyMiningScrapGain', type: 'mult', value: lvl => lvl * 0.015 + 1.2}
30 | ]
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/js/modules/mining/enhancement.js:
--------------------------------------------------------------------------------
1 | import { getSequence } from "../../utils/math";
2 |
3 | export default {
4 | barAluminium: {
5 | effect: [
6 | {name: 'miningPickaxeCraftingQuality', type: 'mult', value: lvl => lvl * 0.5 + 1},
7 | {name: 'miningOreQuality', type: 'mult', value: lvl => Math.pow(2, lvl)}
8 | ]
9 | },
10 | barBronze: {
11 | effect: [
12 | {name: 'miningOreGain', type: 'mult', value: lvl => Math.pow(1.5, lvl)},
13 | {name: 'miningRareEarthGain', type: 'mult', value: lvl => Math.pow(1.25, lvl)}
14 | ]
15 | },
16 | barSteel: {
17 | effect: [
18 | {name: 'miningDamage', type: 'mult', value: lvl => lvl * 0.35 + 1},
19 | {name: 'miningToughness', type: 'mult', value: lvl => Math.pow(1 / 1.5, lvl)}
20 | ]
21 | },
22 | barTitanium: {
23 | effect: [
24 | {name: 'currencyMiningScrapGain', type: 'mult', value: lvl => getSequence(2, lvl) + 1}
25 | ]
26 | },
27 | barShiny: {
28 | effect: [
29 | {name: 'miningDepthDwellerSpeed', type: 'mult', value: lvl => Math.pow(1.35, lvl)},
30 | {name: 'currencyMiningCrystalGreenGain', type: 'mult', value: lvl => lvl * 0.2 + 1}
31 | ]
32 | },
33 | barIridium: {
34 | effect: [
35 | {name: 'currencyMiningEmberGain', type: 'mult', value: lvl => lvl + 1}
36 | ]
37 | },
38 | barDarkIron: {
39 | effect: [
40 | {name: 'currencyMiningScrapCap', type: 'mult', value: lvl => getSequence(2, lvl) * 0.5 + 1}
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/js/modules/mining/ore.js:
--------------------------------------------------------------------------------
1 | import { buildNum } from "../../utils/format";
2 |
3 | export default {
4 | oreAluminium: {
5 | power: 15,
6 | impurity: 1.5,
7 | minDepth: 15,
8 | maxDepth: 45,
9 | modulo: 3,
10 | baseAmount: 0.02,
11 | amountMult: 1.05
12 | },
13 | oreCopper: {
14 | power: 50,
15 | impurity: 2,
16 | minDepth: 30,
17 | maxDepth: 68,
18 | modulo: 4,
19 | baseAmount: 0.004,
20 | amountMult: 1.05
21 | },
22 | oreTin: {
23 | power: 240,
24 | impurity: 2.5,
25 | minDepth: 50,
26 | maxDepth: 100,
27 | modulo: 5,
28 | baseAmount: 0.0008,
29 | amountMult: 1.05
30 | },
31 | oreIron: {
32 | power: 1300,
33 | impurity: 3,
34 | minDepth: 80,
35 | maxDepth: 140,
36 | modulo: 7,
37 | baseAmount: 0.00016,
38 | amountMult: 1.05
39 | },
40 | oreTitanium: {
41 | power: 7000,
42 | impurity: 3.5,
43 | minDepth: 120,
44 | maxDepth: 200,
45 | modulo: 11,
46 | baseAmount: 0.000032,
47 | amountMult: 1.05
48 | },
49 | orePlatinum: {
50 | power: buildNum(40, 'K'),
51 | impurity: 4,
52 | minDepth: 175,
53 | maxDepth: 295,
54 | modulo: 13,
55 | baseAmount: 0.0000064,
56 | amountMult: 1.05
57 | },
58 | oreIridium: {
59 | power: buildNum(250, 'K'),
60 | impurity: 5,
61 | minDepth: 260,
62 | maxDepth: 420,
63 | modulo: 17,
64 | baseAmount: 0.00000128,
65 | amountMult: 1.05
66 | },
67 | oreOsmium: {
68 | power: buildNum(1.75, 'M'),
69 | impurity: 6,
70 | minDepth: 350,
71 | maxDepth: 525,
72 | modulo: 23,
73 | baseAmount: 0.000000256,
74 | amountMult: 1.05
75 | },
76 | oreLead: {
77 | power: buildNum(12.5, 'M'),
78 | impurity: 7.5,
79 | minDepth: 450,
80 | maxDepth: 650,
81 | modulo: 29,
82 | baseAmount: 0.0000000512,
83 | amountMult: 1.05
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/js/modules/patchnote/v1_0_1.js:
--------------------------------------------------------------------------------
1 | export default {
2 | day: '2023-09-26',
3 | content: {
4 | meta: [
5 | {
6 | type: 'qol',
7 | text: '6',
8 | }
9 | ],
10 | mining: [
11 | {
12 | type: 'balance',
13 | text: '0',
14 | },
15 | {
16 | type: 'clarity',
17 | text: '1',
18 | },
19 | {
20 | unlock: 'miningDepthDweller',
21 | type: 'clarity',
22 | text: '8',
23 | }
24 | ],
25 | village: [
26 | {
27 | type: 'clarity',
28 | text: '2',
29 | },
30 | {
31 | type: 'clarity',
32 | text: '3',
33 | }
34 | ],
35 | achievement: [
36 | {
37 | type: 'clarity',
38 | text: '9',
39 | }
40 | ],
41 | school: [
42 | {
43 | type: 'qol',
44 | text: '4',
45 | },
46 | {
47 | type: 'context',
48 | text: '10',
49 | },
50 | {
51 | type: 'balance',
52 | text: '11',
53 | balance: 'nerf',
54 | before: '100%',
55 | after: '10% - 100%',
56 | },
57 | {
58 | type: 'balance',
59 | text: '12',
60 | },
61 | {
62 | unlock: 'schoolLiteratureSubfeature',
63 | type: 'bugfix',
64 | text: '13',
65 | }
66 | ],
67 | horde: [
68 | {
69 | unlock: 'hordePrestige',
70 | type: 'clarity',
71 | text: '7',
72 | }
73 | ],
74 | card: [
75 | {
76 | type: 'clarity',
77 | text: '5',
78 | }
79 | ],
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/js/modules/patchnote/v1_1_1.js:
--------------------------------------------------------------------------------
1 | export default {
2 | day: '2023-09-29',
3 | content: {
4 | school: [
5 | {
6 | type: 'balance',
7 | text: '42',
8 | balance: 'buff',
9 | before: '+15%',
10 | after: '+35%',
11 | },
12 | {
13 | type: 'bugfix',
14 | text: '43',
15 | },
16 | {
17 | type: 'remove',
18 | text: '44',
19 | }
20 | ],
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/js/modules/patchnote/v1_3_1.js:
--------------------------------------------------------------------------------
1 | export default {
2 | day: '2023-10-16',
3 | content: {
4 | treasure: [
5 | {
6 | type: 'bugfix',
7 | text: '157'
8 | }
9 | ],
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/js/modules/patchnote/v1_3_3.js:
--------------------------------------------------------------------------------
1 | export default {
2 | day: '2023-10-18',
3 | content: {
4 | village: [
5 | {
6 | type: 'clarity',
7 | text: '178'
8 | }
9 | ],
10 | horde: [
11 | {
12 | type: 'new',
13 | text: '172'
14 | },
15 | {
16 | unlock: 'hordePrestige',
17 | type: 'new',
18 | text: '173'
19 | },
20 | {
21 | unlock: 'hordeItems',
22 | type: 'bugfix',
23 | text: '174'
24 | },
25 | {
26 | unlock: 'hordePrestige',
27 | type: 'bugfix',
28 | text: '176'
29 | },
30 | {
31 | unlock: 'hordePrestige',
32 | type: 'qol',
33 | text: '177'
34 | }
35 | ],
36 | achievement: [
37 | {
38 | type: 'balance',
39 | text: '175'
40 | }
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/js/modules/patchnote/v1_3_5.js:
--------------------------------------------------------------------------------
1 | export default {
2 | day: '2023-10-23',
3 | content: {
4 | meta: [
5 | {
6 | type: 'bugfix',
7 | text: '227'
8 | }
9 | ],
10 | horde: [
11 | {
12 | unlock: 'hordeItems',
13 | type: 'bugfix',
14 | text: '226'
15 | }
16 | ]
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/js/modules/patchnote/v1_3_6.js:
--------------------------------------------------------------------------------
1 | export default {
2 | day: '2023-10-31',
3 | content: {
4 | meta: [
5 | {
6 | type: 'bugfix',
7 | text: '228'
8 | }
9 | ],
10 | event: [
11 | {
12 | type: 'bugfix',
13 | text: '229'
14 | }
15 | ]
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/js/modules/patchnote/v1_4_2.js:
--------------------------------------------------------------------------------
1 | export default {
2 | day: '2024-06-09',
3 | content: {
4 | card: [
5 | {
6 | type: 'balance',
7 | text: '299_2'
8 | }
9 | ],
10 | farm: [
11 | {
12 | unlock: 'farmCropExp',
13 | type: 'balance',
14 | text: '299_4'
15 | },
16 | ],
17 | event: [
18 | {
19 | unlock: 'weatherChaosEvent',
20 | type: 'bugfix',
21 | text: '299_1'
22 | },
23 | {
24 | unlock: 'weatherChaosEvent',
25 | type: 'balance',
26 | text: '299_3'
27 | }
28 | ]
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/js/modules/patchnote/v1_5_1.js:
--------------------------------------------------------------------------------
1 | export default {
2 | day: '2024-09-28',
3 | content: {
4 | card: [
5 | {
6 | type: 'bugfix',
7 | text: '392'
8 | },
9 | ],
10 | horde: [
11 | {
12 | unlock: 'hordeItems',
13 | type: 'bugfix',
14 | text: '388'
15 | },
16 | ],
17 | farm: [
18 | {
19 | type: 'bugfix',
20 | text: '389'
21 | },
22 | ],
23 | gallery: [
24 | {
25 | unlock: 'galleryConversion',
26 | type: 'balance',
27 | text: '390',
28 | balance: 'nerf',
29 | before: '4x',
30 | after: '16x'
31 | },
32 | {
33 | unlock: 'galleryConversion',
34 | type: 'new',
35 | text: '391'
36 | },
37 | {
38 | unlock: 'galleryConversion',
39 | type: 'clarity',
40 | text: '394'
41 | },
42 | ],
43 | horde_1: [
44 | {
45 | type: 'bugfix',
46 | text: '393'
47 | },
48 | ],
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/js/modules/patchnote/v1_5_2.js:
--------------------------------------------------------------------------------
1 | export default {
2 | day: '2024-09-29',
3 | content: {
4 | gallery: [
5 | {
6 | unlock: 'galleryConversion',
7 | type: 'balance',
8 | text: '395',
9 | balance: 'buff',
10 | before: '1.5x',
11 | after: '1.9x'
12 | },
13 | ],
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/js/modules/patchnote/v1_5_3.js:
--------------------------------------------------------------------------------
1 | export default {
2 | day: '2024-09-29',
3 | content: {
4 | village: [
5 | {
6 | unlock: 'villageOffering1',
7 | type: 'bugfix',
8 | text: '396'
9 | }
10 | ],
11 | event: [
12 | {
13 | type: 'bugfix',
14 | text: '397'
15 | }
16 | ],
17 | village_1: [
18 | {
19 | type: 'bugfix',
20 | text: '398'
21 | }
22 | ]
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/js/modules/patchnote/v1_5_5.js:
--------------------------------------------------------------------------------
1 | export default {
2 | day: '2024-11-23',
3 | content: {
4 | meta: [
5 | {
6 | type: 'bugfix',
7 | text: '428'
8 | }
9 | ],
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/js/modules/patchnote/v1_5_7.js:
--------------------------------------------------------------------------------
1 | export default {
2 | day: '2025-01-19',
3 | content: {
4 | village: [
5 | {
6 | unlock: 'villageOffering1',
7 | type: 'bugfix',
8 | text: '440'
9 | },
10 | ],
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/js/modules/patchnote/v1_5_8.js:
--------------------------------------------------------------------------------
1 | export default {
2 | day: '2025-01-20',
3 | content: {
4 | meta: [
5 | {
6 | type: 'bugfix',
7 | text: '441'
8 | },
9 | ],
10 | farm: [
11 | {
12 | unlock: 'farmFertilizer',
13 | type: 'bugfix',
14 | text: '442'
15 | },
16 | ],
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/js/modules/relic.js:
--------------------------------------------------------------------------------
1 | import store from "../../store";
2 | import { buildArray } from "../utils/array";
3 | import glyph from "./relic/glyph";
4 |
5 | export default {
6 | name: 'relic',
7 | unlockNeeded: 'relicFeature',
8 | unlock: ['relicFeature', 'relicMuseum'],
9 | note: buildArray(1).map(() => 'g'),
10 | init() {
11 | for (const [key, elem] of Object.entries(glyph)) {
12 | store.commit('relic/initGlyph', {name: key, ...elem});
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/js/modules/school/upgradePremium.js:
--------------------------------------------------------------------------------
1 | import { fallbackArray } from "../../utils/array";
2 |
3 | export default {
4 | student: {type: 'premium', price(lvl) {
5 | return {gem_ruby: fallbackArray([5, 20, 60, 125], [4, 5, 6, 7][lvl % 4] * Math.pow(2, Math.floor(lvl / 4)) * 25, lvl)};
6 | }, effect: [
7 | {name: 'currencySchoolBookGain', type: 'base', value: lvl => 5 * lvl}
8 | ]},
9 | }
10 |
--------------------------------------------------------------------------------
/src/js/modules/treasure/upgradePremium.js:
--------------------------------------------------------------------------------
1 | export default {
2 | moreSlots: {type: 'premium', price(lvl) {
3 | return {gem_ruby: lvl * 10 + 50};
4 | }, effect: [
5 | {name: 'treasureSlots', type: 'base', value: lvl => lvl}
6 | ]},
7 | moreFragments: {type: 'premium', price(lvl) {
8 | return {gem_ruby: [2, 3][lvl % 2] * Math.pow(2, Math.floor(lvl / 2)) * 150};
9 | }, effect: [
10 | {name: 'currencyTreasureFragmentGain', type: 'mult', value: lvl => lvl * 0.2 + 1}
11 | ]}
12 | }
13 |
--------------------------------------------------------------------------------
/src/js/modules/village/offering.js:
--------------------------------------------------------------------------------
1 | import { buildNum } from "../../utils/format";
2 |
3 | export default {
4 | plantFiber: {unlock: 'villageOffering1', cost: lvl => Math.pow(1.5, lvl) * buildNum(1, 'M'), effect: 200},
5 | wood: {unlock: 'villageOffering1', cost: lvl => Math.pow(1.5, lvl) * buildNum(1, 'M'), effect: 200},
6 | stone: {unlock: 'villageOffering1', cost: lvl => Math.pow(1.5, lvl) * buildNum(1, 'M'), effect: 200},
7 |
8 | coin: {unlock: 'villageOffering2', amount: 3, cost: lvl => Math.pow(1.75, lvl) * buildNum(10, 'M'), effect: 200},
9 | metal: {unlock: 'villageOffering2', amount: 3, cost: lvl => Math.pow(1.5, lvl) * buildNum(3, 'M'), effect: 200},
10 | water: {unlock: 'villageOffering2', amount: 3, cost: lvl => Math.pow(2, lvl) * buildNum(5, 'M'), effect: 500},
11 |
12 | glass: {unlock: 'villageOffering3', amount: 8, cost: lvl => Math.pow(1.5, lvl) * buildNum(120, 'K'), effect: 100},
13 | hardwood: {unlock: 'villageOffering3', amount: 8, cost: lvl => Math.pow(1.5, lvl) * buildNum(40, 'K'), effect: 100},
14 | gem: {unlock: 'villageOffering3', amount: 8, cost: lvl => Math.pow(1.5, lvl) * buildNum(40, 'K'), effect: 100},
15 |
16 | knowledge: {unlock: 'villageOffering4', amount: 20, increment: 1, cost: lvl => Math.pow(1.25, lvl) * 250, effect: 2},
17 | science: {unlock: 'villageOffering4', amount: 20, increment: 1, cost: lvl => Math.pow(1.25, lvl) * 100, effect: 1},
18 | joy: {unlock: 'villageOffering4', amount: 20, increment: 1, cost: lvl => Math.pow(1.25, lvl) * 750, effect: 5},
19 | }
20 |
--------------------------------------------------------------------------------
/src/js/modules/village/policy.js:
--------------------------------------------------------------------------------
1 | export default {
2 | taxes: {mult: 'villagePolicyTaxes', icon: 'mdi-cash-register', effect: [
3 | {name: 'villageTaxRate', type: 'mult', value: lvl => lvl * 0.25 + 1},
4 | {name: 'villageHappiness', type: 'base', value: lvl => lvl * (lvl > 0 ? -0.05 : -0.03)}
5 | ]},
6 | immigration: {mult: 'villagePolicyImmigration', icon: 'mdi-account-group', effect: [
7 | {name: 'villageWorker', type: 'mult', value: lvl => lvl * 0.15 + 1},
8 | {name: 'villageHappiness', type: 'base', value: lvl => lvl * (lvl > 0 ? -0.05 : -0.1)}
9 | ]},
10 | religion: {mult: 'villagePolicyReligion', icon: 'mdi-hands-pray', effect: [
11 | {name: 'villageResourceGain', type: 'mult', value: lvl => lvl * (lvl > 0 ? -0.25 : -0.1) + 1},
12 | {name: 'currencyVillageFaithGain', type: 'mult', value: lvl => lvl * 0.25 + 1}
13 | ]},
14 | scanning: {mult: 'villagePolicyScanning', icon: 'mdi-magnify-scan', effect: [
15 | {name: 'villageLootGain', type: 'mult', value: lvl => 1 - lvl * (lvl > 0 ? 0.1 : 0.05)},
16 | {name: 'villageLootQuality', type: 'base', value: lvl => Math.max(lvl, 0)},
17 | {name: 'villageLootQuality', type: 'mult', value: lvl => Math.min(1 + lvl * 0.1, 1)}
18 | ]}
19 | }
20 |
--------------------------------------------------------------------------------
/src/js/theme/autumnForest.js:
--------------------------------------------------------------------------------
1 | export default {
2 | hasParticles: true,
3 | particles: {
4 | icons: ['mdi-leaf', 'mdi-leaf-maple'],
5 | colors: ['light-green', 'yellow', 'amber', 'orange', 'orange-red', 'brown', 'cherry'],
6 | opacity: [20, 70],
7 | size: [20, 80],
8 | time: [4, 12],
9 | amount: 4,
10 | rotate: true
11 | },
12 | light: {
13 | primary: '#74401B',
14 | secondary: '#424242',
15 | accent: '#503D30',
16 | },
17 | dark: {
18 | primary: '#74401B',
19 | secondary: '#424242',
20 | accent: '#503D30',
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/js/theme/brown.js:
--------------------------------------------------------------------------------
1 | export default {
2 | price: 1000,
3 | light: {
4 | primary: '#72400D',
5 | secondary: '#424242',
6 | accent: '#D2802D',
7 | },
8 | dark: {
9 | primary: '#72400D',
10 | secondary: '#424242',
11 | accent: '#D2802D',
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/js/theme/candlelight.js:
--------------------------------------------------------------------------------
1 | export default {
2 | hasCustomBackground: true
3 | }
4 |
--------------------------------------------------------------------------------
/src/js/theme/cherry.js:
--------------------------------------------------------------------------------
1 | export default {
2 | price: 6000,
3 | hasCustomBackground: true,
4 | light: {
5 | primary: '#E963D2',
6 | secondary: '#424242',
7 | accent: '#4D331A'
8 | },
9 | dark: {
10 | primary: '#EF8FDF',
11 | secondary: '#424242',
12 | accent: '#604020'
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/js/theme/colorful.js:
--------------------------------------------------------------------------------
1 | import colors from "./colors";
2 | import { filterColor, filterColorObject } from "../utils/color";
3 | import _default from "./default";
4 |
5 | const colorFilter = color => color.saturate(0.15);
6 |
7 | export default {
8 | hasCustomColors: true,
9 | light: {
10 | primary: '#D94712',
11 | secondary: '#424242',
12 | accent: '#FFA182',
13 | error: filterColor(_default.light.error, colorFilter),
14 | info: filterColor(_default.light.info, colorFilter),
15 | success: filterColor(_default.light.success, colorFilter),
16 | warning: filterColor(_default.light.warning, colorFilter),
17 |
18 | ...filterColorObject(colors, colorFilter)
19 | },
20 | dark: {
21 | primary: '#D94712',
22 | secondary: '#424242',
23 | accent: '#FFA182',
24 | error: filterColor(_default.dark.error, colorFilter),
25 | info: filterColor(_default.dark.info, colorFilter),
26 | success: filterColor(_default.dark.success, colorFilter),
27 | warning: filterColor(_default.dark.warning, colorFilter),
28 |
29 | ...filterColorObject(colors, colorFilter)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/js/theme/cyan.js:
--------------------------------------------------------------------------------
1 | export default {
2 | price: 1000,
3 | light: {
4 | primary: '#19D2D2',
5 | secondary: '#424242',
6 | accent: '#82FFFF',
7 | },
8 | dark: {
9 | primary: '#19D2D2',
10 | secondary: '#424242',
11 | accent: '#82FFFF',
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/js/theme/default.js:
--------------------------------------------------------------------------------
1 | import colors from "./colors";
2 | import shades from "./shades";
3 |
4 | export default {
5 | owned: true,
6 | light: {
7 | primary: '#1976D2',
8 | secondary: '#424242',
9 | accent: '#82B1FF',
10 | error: '#FF5252',
11 | info: '#2196F3',
12 | success: '#4CAF50',
13 | warning: '#FFC107',
14 | contrast: '#000000',
15 |
16 | ...shades,
17 | ...colors
18 | },
19 | dark: {
20 | primary: '#1976D2',
21 | secondary: '#424242',
22 | accent: '#82B1FF',
23 | error: '#FF5252',
24 | info: '#2196F3',
25 | success: '#4CAF50',
26 | warning: '#FFC107',
27 | contrast: '#FFFFFF',
28 |
29 | ...shades,
30 | ...colors
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/js/theme/factory.js:
--------------------------------------------------------------------------------
1 | export default {
2 | price: 4000,
3 | hasCustomBackground: true,
4 | light: {
5 | primary: '#5F6264',
6 | secondary: '#A85817',
7 | accent: '#82B1FF',
8 | },
9 | dark: {
10 | primary: '#8D9296',
11 | secondary: '#A85817',
12 | accent: '#82B1FF',
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/js/theme/forest.js:
--------------------------------------------------------------------------------
1 | export default {
2 | price: 5000,
3 | hasCustomBackground: true,
4 | light: {
5 | primary: '#29C229',
6 | secondary: '#B76715',
7 | accent: '#92EF92',
8 | },
9 | dark: {
10 | primary: '#1C831C',
11 | secondary: '#72400D',
12 | accent: '#92EF92',
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/js/theme/frozen.js:
--------------------------------------------------------------------------------
1 | import Color from "color";
2 | import colors from "./colors";
3 | import { filterColor, filterColorObject } from "../utils/color";
4 | import _default from "./default";
5 |
6 | const frozenBase = '#20DFDF';
7 | const frozenFilter = color => color.mix(Color(frozenBase), 0.3).desaturate(0.3);
8 |
9 | export default {
10 | hasCustomColors: true,
11 | hasParticles: true,
12 | particles: {
13 | icons: ['mdi-snowflake', 'mdi-snowflake-variant'],
14 | colors: ['white'],
15 | opacity: [10, 40],
16 | size: [10, 50],
17 | time: [5, 30],
18 | amount: 3,
19 | rotate: true
20 | },
21 | light: {
22 | primary: filterColor(frozenBase, color => color.desaturate(0.6)),
23 | secondary: '#424242',
24 | accent: filterColor(frozenBase, color => color.desaturate(0.7).lighten(0.3)),
25 | error: filterColor(_default.light.error, frozenFilter),
26 | info: filterColor(_default.light.info, frozenFilter),
27 | success: filterColor(_default.light.success, frozenFilter),
28 | warning: filterColor(_default.light.warning, frozenFilter),
29 |
30 | ...filterColorObject(colors, frozenFilter)
31 | },
32 | dark: {
33 | primary: filterColor(frozenBase, color => color.desaturate(0.6)),
34 | secondary: '#424242',
35 | accent: filterColor(frozenBase, color => color.desaturate(0.7).lighten(0.3)),
36 | error: filterColor(_default.dark.error, frozenFilter),
37 | info: filterColor(_default.dark.info, frozenFilter),
38 | success: filterColor(_default.dark.success, frozenFilter),
39 | warning: filterColor(_default.dark.warning, frozenFilter),
40 |
41 | ...filterColorObject(colors, frozenFilter)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/js/theme/green.js:
--------------------------------------------------------------------------------
1 | export default {
2 | price: 1000,
3 | light: {
4 | primary: '#29C229',
5 | secondary: '#424242',
6 | accent: '#92EF92',
7 | },
8 | dark: {
9 | primary: '#29C229',
10 | secondary: '#424242',
11 | accent: '#92EF92',
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/js/theme/grey.js:
--------------------------------------------------------------------------------
1 | export default {
2 | price: 1000,
3 | light: {
4 | primary: '#787878',
5 | secondary: '#424242',
6 | accent: '#C0C0C0',
7 | },
8 | dark: {
9 | primary: '#787878',
10 | secondary: '#424242',
11 | accent: '#C0C0C0',
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/js/theme/orange.js:
--------------------------------------------------------------------------------
1 | export default {
2 | price: 1000,
3 | light: {
4 | primary: '#DF760C',
5 | secondary: '#424242',
6 | accent: '#FFC182',
7 | },
8 | dark: {
9 | primary: '#DF760C',
10 | secondary: '#424242',
11 | accent: '#FFC182',
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/js/theme/pink.js:
--------------------------------------------------------------------------------
1 | export default {
2 | price: 1000,
3 | light: {
4 | primary: '#D219D2',
5 | secondary: '#424242',
6 | accent: '#FF82FF',
7 | },
8 | dark: {
9 | primary: '#D219D2',
10 | secondary: '#424242',
11 | accent: '#FF82FF',
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/js/theme/polar.js:
--------------------------------------------------------------------------------
1 | export default {
2 | price: 8000,
3 | hasCustomBackground: true,
4 | light: {
5 | primary: '#267373',
6 | secondary: '#424242',
7 | accent: '#66CC66',
8 | },
9 | dark: {
10 | primary: '#66CCCC',
11 | secondary: '#424242',
12 | accent: '#267326',
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/js/theme/prismatic.js:
--------------------------------------------------------------------------------
1 | import { buildNum } from "../utils/format";
2 |
3 | export default {
4 | price: buildNum(50, 'K'),
5 | hasCustomNavbar: true,
6 | hasCustomBackground: true,
7 | hasAnimations: true
8 | }
9 |
--------------------------------------------------------------------------------
/src/js/theme/purple.js:
--------------------------------------------------------------------------------
1 | export default {
2 | price: 1000,
3 | light: {
4 | primary: '#7619D2',
5 | secondary: '#424242',
6 | accent: '#C182FF',
7 | },
8 | dark: {
9 | primary: '#7619D2',
10 | secondary: '#424242',
11 | accent: '#C182FF',
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/js/theme/rain.js:
--------------------------------------------------------------------------------
1 | export default {
2 | hasCustomNavbar: true,
3 | hasAnimations: true,
4 | hasParticles: true,
5 | particles: {
6 | icons: ['mdi-water'],
7 | colors: ['light-blue', 'blue', 'dark-blue', 'indigo'],
8 | opacity: [10, 30],
9 | size: [15, 25],
10 | time: [2, 4],
11 | amount: 6,
12 | rotate: false
13 | },
14 | light: {
15 | primary: '#2A53B3',
16 | secondary: '#424242',
17 | accent: '#275A39',
18 | },
19 | dark: {
20 | primary: '#2A53B3',
21 | secondary: '#424242',
22 | accent: '#275A39',
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/js/theme/red.js:
--------------------------------------------------------------------------------
1 | export default {
2 | price: 1000,
3 | light: {
4 | primary: '#D21919',
5 | secondary: '#424242',
6 | accent: '#FF8282',
7 | },
8 | dark: {
9 | primary: '#D21919',
10 | secondary: '#424242',
11 | accent: '#FF8282',
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/js/theme/sepia.js:
--------------------------------------------------------------------------------
1 | import Color from "color";
2 | import colors from "./colors";
3 | import { filterColor, filterColorObject } from "../utils/color";
4 | import _default from "./default";
5 |
6 | const sepiaBase = '#704214';
7 | const sepiaFilter = color => color.mix(Color(sepiaBase), 0.3).desaturate(0.2);
8 |
9 | export default {
10 | price: 3000,
11 | hasCustomColors: true,
12 | light: {
13 | primary: filterColor(sepiaBase, color => color.desaturate(0.4)),
14 | secondary: '#424242',
15 | accent: filterColor(sepiaBase, color => color.desaturate(0.7).lighten(0.5)),
16 | error: filterColor(_default.light.error, sepiaFilter),
17 | info: filterColor(_default.light.info, sepiaFilter),
18 | success: filterColor(_default.light.success, sepiaFilter),
19 | warning: filterColor(_default.light.warning, sepiaFilter),
20 |
21 | ...filterColorObject(colors, sepiaFilter)
22 | },
23 | dark: {
24 | primary: filterColor(sepiaBase, color => color.desaturate(0.4)),
25 | secondary: '#424242',
26 | accent: filterColor(sepiaBase, color => color.desaturate(0.7).lighten(0.5)),
27 | error: filterColor(_default.dark.error, sepiaFilter),
28 | info: filterColor(_default.dark.info, sepiaFilter),
29 | success: filterColor(_default.dark.success, sepiaFilter),
30 | warning: filterColor(_default.dark.warning, sepiaFilter),
31 |
32 | ...filterColorObject(colors, sepiaFilter)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/js/theme/shades.js:
--------------------------------------------------------------------------------
1 | export default {
2 | black: '#000000',
3 | 'darkest-grey': '#202020',
4 | 'darker-grey': '#404040',
5 | 'dark-grey': '#606060',
6 | grey: {
7 | base: '#9e9e9e',
8 | lighten5: '#fafafa',
9 | lighten4: '#f5f5f5',
10 | lighten3: '#eeeeee',
11 | lighten2: '#e0e0e0',
12 | lighten1: '#bdbdbd',
13 | darken1: '#757575',
14 | darken2: '#616161',
15 | darken3: '#424242',
16 | darken4: '#212121'
17 | },
18 | 'lightest-grey': '#E0E0E0',
19 | 'lighter-grey': '#C0C0C0',
20 | 'light-grey': '#A0A0A0',
21 | white: '#FFFFFF'
22 | }
23 |
--------------------------------------------------------------------------------
/src/js/theme/sky.js:
--------------------------------------------------------------------------------
1 | import { buildNum } from "../utils/format";
2 |
3 | export default {
4 | price: buildNum(10, 'K'),
5 | hasCustomNavbar: true,
6 | hasCustomBackground: true,
7 | light: {
8 | primary: '#E89820',
9 | secondary: '#A0A0A0',
10 | accent: '#D18147',
11 | },
12 | dark: {
13 | primary: '#E89820',
14 | secondary: '#A0A0A0',
15 | accent: '#D18147',
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/js/theme/themes.js:
--------------------------------------------------------------------------------
1 | import autumnForest from "./autumnForest";
2 | import brown from "./brown";
3 | import candlelight from "./candlelight";
4 | import cherry from "./cherry";
5 | import colorful from "./colorful";
6 | import cyan from "./cyan";
7 | import defaultTheme from "./default";
8 | import factory from "./factory";
9 | import forest from "./forest";
10 | import frozen from "./frozen";
11 | import green from "./green";
12 | import grey from "./grey";
13 | import orange from "./orange";
14 | import pink from "./pink";
15 | import prismatic from "./prismatic";
16 | import purple from "./purple";
17 | import rain from "./rain";
18 | import red from "./red";
19 | import sepia from "./sepia";
20 | import sky from "./sky";
21 | import polar from "./polar";
22 | import waves from "./waves";
23 | import yellow from "./yellow";
24 |
25 | export default {
26 | default: defaultTheme,
27 | cyan,
28 | green,
29 | yellow,
30 | orange,
31 | brown,
32 | red,
33 | pink,
34 | purple,
35 | grey,
36 | sepia,
37 | factory,
38 | forest,
39 | cherry,
40 | polar,
41 | sky,
42 | prismatic,
43 | candlelight,
44 | colorful,
45 | rain,
46 | waves,
47 | autumnForest,
48 | frozen,
49 | }
50 |
--------------------------------------------------------------------------------
/src/js/theme/waves.js:
--------------------------------------------------------------------------------
1 | export default {
2 | hasCustomBackground: true
3 | }
4 |
--------------------------------------------------------------------------------
/src/js/theme/yellow.js:
--------------------------------------------------------------------------------
1 | export default {
2 | price: 1000,
3 | light: {
4 | primary: '#D2D219',
5 | secondary: '#424242',
6 | accent: '#FFFF82',
7 | },
8 | dark: {
9 | primary: '#D2D219',
10 | secondary: '#424242',
11 | accent: '#FFFF82',
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/js/utils/array.js:
--------------------------------------------------------------------------------
1 | export { buildArray, shuffleArray, fallbackArray, filterUnique }
2 |
3 | /**
4 | * Create an array with a fixed length
5 | * @param {Number} length Length of the desired array
6 | * @returns {Array} Array filled with incrementing numbers, starting with 0
7 | */
8 | function buildArray(length = 0) {
9 | return Array(length).fill().map((x, i) => i);
10 | }
11 |
12 | /**
13 | * Takes an array and returns it with its elements in a random order
14 | * @param {Array} array
15 | * @returns {Array}
16 | */
17 | function shuffleArray(array, rngGen = null) {
18 | if (rngGen === null) {
19 | rngGen = () => Math.random()
20 | }
21 | let arr = [...array];
22 | for (let i = arr.length - 1; i > 0; i--) {
23 | const j = Math.floor(rngGen() * (i + 1));
24 | const temp = arr[i];
25 | arr[i] = arr[j];
26 | arr[j] = temp;
27 | }
28 | return arr;
29 | }
30 |
31 | /**
32 | * Take an element from an array, or a fallback value if the array is too short
33 | * @param {Array} array
34 | * @param {*} fallback
35 | * @param {Number} index
36 | * @returns An array element or the fallback value
37 | */
38 | function fallbackArray(array = [], fallback = null, index = 0) {
39 | return (index >= 0 && index < array.length) ? array[index] : fallback;
40 | }
41 |
42 | /**
43 | * Return the array with duplicates removed
44 | * @param {Array} array
45 | * @returns {Array}
46 | */
47 | function filterUnique(array) {
48 | return array.filter((v, i, a) => a.indexOf(v) === i);
49 | }
50 |
--------------------------------------------------------------------------------
/src/js/utils/color.js:
--------------------------------------------------------------------------------
1 | export { filterColor, filterColorObject, mergeColorObject }
2 |
3 | const Color = require("color");
4 |
5 | /**
6 | *
7 | * @param {*} color a color in any form that can be parsed by the color library
8 | * @param {Function} filter a filter function used to modify the color
9 | * @returns {String} hex value of the filtered color
10 | */
11 | function filterColor(color, filter) {
12 | return filter(Color(color)).hex();
13 | }
14 |
15 | /**
16 | *
17 | * @param {Object} obj an object filled with colors in a parsable form
18 | * @param {Function} filter a filter function used to modify the color
19 | * @returns an object filled with hex values of the filtered colors
20 | */
21 | function filterColorObject(obj, filter) {
22 | let newObj = {};
23 | for (const [key, elem] of Object.entries(obj)) {
24 | newObj[key] = typeof elem === 'object' ? filterColorObject(elem, filter) : filterColor(elem, filter);
25 | }
26 | return newObj;
27 | }
28 |
29 | function mergeColorObject(obj1, obj2, weight = 0.5) {
30 | let newObj = {};
31 | for (const [key, elem] of Object.entries(obj1)) {
32 | newObj[key] = typeof elem === 'object' ? mergeColorObject(elem, obj2[key], weight) : Color(elem).mix(Color(obj2[key]), weight).hex();
33 | }
34 | return newObj;
35 | }
36 |
--------------------------------------------------------------------------------
/src/js/utils/date.js:
--------------------------------------------------------------------------------
1 | export { getDay, getWeek }
2 |
3 | /**
4 | * Get a readable string representation of the current day of a date
5 | * @param {Date} date The date object used to get the day string
6 | * @param {Boolean} includeOffset Whether to manually calculate the timezone offset or not
7 | * @returns {String} The date as string in YYYY-MM-DD format
8 | */
9 | function getDay(date = new Date()) {
10 | return applyOffset(date).toISOString().substring(0, 10);
11 | }
12 |
13 | /**
14 | * Get the week number from a date
15 | * @param {Date} date The date object used to get the week number
16 | * @returns {Number} The week number starting from 1970
17 | */
18 | function getWeek(date = new Date()) {
19 | return Math.floor((applyOffset(date).getTime() + 3 * 86400000) / 604800000);
20 | }
21 |
22 | function applyOffset(date = new Date()) {
23 | return new Date(date.getTime() - (date.getTimezoneOffset() * 60000));
24 | }
25 |
--------------------------------------------------------------------------------
/src/js/utils/file.js:
--------------------------------------------------------------------------------
1 | export { download }
2 |
3 | var fileDownload = require('js-file-download');
4 |
5 | /**
6 | * Generates a file and offers to download it
7 | * @param {String} file file content
8 | * @param {String} name name of the file
9 | */
10 | function download(file, name, mime = 'text/plain') {
11 | const fileBlob = new Blob([file], {type: mime});
12 | fileDownload(fileBlob, name);
13 | }
14 |
--------------------------------------------------------------------------------
/src/js/utils/math.js:
--------------------------------------------------------------------------------
1 | export { logBase, getSequence, splicedLinear, splicedPow, splicedPowLinear, deltaLinear, digitSum }
2 |
3 | /**
4 | * Returns the logarithm of a number
5 | * @param {Number} num
6 | * @param {Number} base
7 | * @returns {Number}
8 | */
9 | function logBase(num, base) {
10 | return Math.log(num) / Math.log(base);
11 | }
12 |
13 | /**
14 | * Returns the number of a sequence (1, 3, 6, 10, 15, 21, ...)
15 | * @param {Number} base
16 | * @param {Number} pos
17 | * @returns {Number}
18 | */
19 | function getSequence(base = 1, pos = 1) {
20 | return Math.round((base + (pos - 1) / 2) * pos);
21 | }
22 |
23 | function splicedLinear(increase1, increase2, breakpoint, value) {
24 | return Math.max(0, value - breakpoint) * increase2 + Math.min(breakpoint, value) * increase1;
25 | }
26 |
27 | function splicedPow(exponent1, exponent2, breakpoint, value) {
28 | return Math.pow(exponent2, Math.max(0, value - breakpoint)) * Math.pow(exponent1, Math.min(breakpoint, value));
29 | }
30 |
31 | function splicedPowLinear(exponent, increase, breakpoint, value) {
32 | return (Math.max(0, value - breakpoint) * increase + 1) * Math.pow(exponent, Math.min(breakpoint, value));
33 | }
34 |
35 | function deltaLinear(base, increase, amount = 1, skip = 0) {
36 | const finalBase = increase * skip + base;
37 | return (finalBase + ((amount - 1) * increase / 2)) * amount;
38 | }
39 |
40 | function digitSum(num) {
41 | return `${num}`.split('').reduce((acc, n) => acc += parseInt(n), 0);
42 | }
43 |
--------------------------------------------------------------------------------
/src/lang/de/tag.js:
--------------------------------------------------------------------------------
1 | export default {
2 | hordeEnergyToStr: '+{0} Stärke pro aktueller Energie',
3 | hordeEnergyToEnergyReg: '+{0} Energieregeneration pro fehlender Energie',
4 | hordeEnergyOnCrit: '+{0} Energie beim kritischen Treffer',
5 | hordeHealOnCrit: 'Heilt {0} der maximalen Leben beim kritischen Treffer',
6 | hordeRestoreCooldownOnCrit: 'Reduziert Abklingzeiten um {0} beim kritischen Treffer',
7 | hordeBloodOnCrit: 'Erhalte {0} vom gegnerischen Blut beim kritischen Treffer',
8 | hordeManaRest: 'Erhalte {1} Manaregeneration, wenn {0} keine aktiven Fähigkeiten benutzt werden',
9 | hordeManasteal: 'Erhalte {0} Mana pro getöteten Gegner',
10 | hordePassiveRecovery: 'Wende {0} der Erholung jede Sekunde an',
11 | hordeActiveDamageCrit: 'Aktive Fähigkeiten mit Schaden können mit {0} Effizienz kritisch treffen',
12 | hordeActiveHealCrit: 'Aktive Fähigkeiten mit Heilung können mit {0} Effizienz kritisch treffen',
13 | hordeAttackAfterTime: 'Erhalte +{0} Angriff pro Minute im selben Kampf',
14 | hordeStrIntAfterTime: 'Erhalte {0} Stärke und Intelligenz Angriff pro Minute im selben Kampf',
15 | }
16 |
--------------------------------------------------------------------------------
/src/lang/en/tag.js:
--------------------------------------------------------------------------------
1 | export default {
2 | hordeEnergyToStr: '+{0} strength per current energy',
3 | hordeEnergyToEnergyReg: '+{0} energy regeneration per missing energy',
4 | hordeEnergyOnCrit: '+{0} energy on critical hit',
5 | hordeHealOnCrit: 'Heal {0} maximum health on critical hit',
6 | hordeRestoreCooldownOnCrit: 'Reduce cooldowns by {0} on critical hit',
7 | hordeBloodOnCrit: 'Gain {0} enemy blood on critical hit',
8 | hordeManaRest: 'Gain {1} mana regeneration after not using actives for {0}',
9 | hordeManasteal: 'Gain {0} mana on kill',
10 | hordePassiveRecovery: 'Apply {0} of recovery each second',
11 | hordeActiveDamageCrit: 'Damaging actives can crit at {0} efficiency',
12 | hordeActiveHealCrit: 'Healing actives can crit at {0} efficiency',
13 | hordeAttackAfterTime: 'Gain +{0} attack per minute in the same fight',
14 | hordeStrIntAfterTime: 'Gain {0} strength and intelligence per minute in the same fight',
15 | }
16 |
--------------------------------------------------------------------------------
/src/plugins/vuetify.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuetify from 'vuetify/lib';
3 |
4 | import '@mdi/font/css/materialdesignicons.css'
5 |
6 | import en from '../lang/en';
7 | import de from '../lang/de';
8 | import { checkLocal, decodeFile } from '../js/savefile';
9 | import themes from '../js/theme/themes';
10 |
11 | let theme = 'default';
12 | const localFile = checkLocal();
13 | if (localFile) {
14 | const save = decodeFile(localFile, false);
15 | if (save?.theme) {
16 | theme = save.theme;
17 | }
18 | }
19 |
20 | Vue.use(Vuetify);
21 |
22 | export default new Vuetify({
23 | icons: {
24 | iconfont: 'mdi'
25 | },
26 | theme: {
27 | options: {customProperties: true},
28 | themes: {
29 | light: {...themes.default.light, ...themes[theme].light},
30 | dark: {...themes.default.dark, ...themes[theme].dark}
31 | }
32 | },
33 | lang: {
34 | locales: { en, de },
35 | current: "en"
36 | }
37 | });
38 |
--------------------------------------------------------------------------------
/src/store/gem.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import { GEM_SPEED_PER_ACHIEVEMENT } from "../js/constants";
3 |
4 | export default {
5 | namespaced: true,
6 | state: {
7 | progress: 0
8 | },
9 | getters: {
10 | genSpeed: (state, getters, rootState, rootGetters) => {
11 | return rootGetters['achievement/totalLevel'] * GEM_SPEED_PER_ACHIEVEMENT + 1;
12 | }
13 | },
14 | mutations: {
15 | updateKey(state, o) {
16 | Vue.set(state, o.key, o.value);
17 | }
18 | },
19 | actions: {
20 | cleanState({ commit }) {
21 | commit('updateKey', {key: 'progress', value: 0});
22 | },
23 | fastPrestige({ rootState, rootGetters, dispatch }, o) {
24 | if (rootGetters['consumable/canAfford']('gem_prestigeStone')) {
25 | dispatch('currency/gain', {feature: o.currency.split('_')[0], name: o.currency.split('_')[1], amount: rootState.stat[o.stat].total}, {root: true});
26 | dispatch('consumable/use', 'gem_prestigeStone', {root: true});
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 | import system from './system';
4 | import unlock from './unlock';
5 | import currency from './currency';
6 | import upgrade from './upgrade';
7 | import mult from './mult';
8 | import meta from './meta';
9 | import mining from './mining';
10 | import village from './village';
11 | import horde from './horde';
12 | import farm from './farm';
13 | import gallery from './gallery';
14 | import relic from './relic';
15 | import gem from './gem';
16 | import stat from './stat';
17 | import achievement from './achievement';
18 | import school from './school';
19 | import card from './card';
20 | import general from './general';
21 | import event from './event';
22 | import cinders from './cinders';
23 | import bloom from './bloom';
24 | import weatherChaos from './weatherChaos';
25 | import summerFestival from './summerFestival';
26 | import nightHunt from './nightHunt';
27 | import snowdown from './snowdown';
28 | import note from './note';
29 | import treasure from './treasure';
30 | import cryolab from './cryolab';
31 | import consumable from './consumable';
32 | import tag from './tag';
33 |
34 | // store modules
35 |
36 | Vue.use(Vuex);
37 |
38 | export default new Vuex.Store({
39 | modules: {
40 | system,
41 | unlock,
42 | currency,
43 | upgrade,
44 | mult,
45 | meta,
46 | mining,
47 | village,
48 | horde,
49 | farm,
50 | gallery,
51 | relic,
52 | gem,
53 | stat,
54 | achievement,
55 | school,
56 | card,
57 | general,
58 | event,
59 | cinders,
60 | bloom,
61 | weatherChaos,
62 | summerFestival,
63 | nightHunt,
64 | snowdown,
65 | note,
66 | treasure,
67 | cryolab,
68 | consumable,
69 | tag
70 | }
71 | })
72 |
--------------------------------------------------------------------------------
/src/store/note.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 |
3 | export default {
4 | namespaced: true,
5 | state: {},
6 | getters: {
7 | list: (state) => (feature = null) => {
8 | let arr = [];
9 | for (const [key, elem] of Object.entries(state)) {
10 | if ((feature === null || elem.feature === feature) && elem.found) {
11 | arr.push(key);
12 | }
13 | }
14 | return arr;
15 | }
16 | },
17 | mutations: {
18 | init(state, o) {
19 | const feature = o.feature ?? 'meta';
20 | Vue.set(state, `${feature}_${o.id}`, {
21 | feature,
22 | found: false,
23 | author: o.author
24 | });
25 | },
26 | find(state, name) {
27 | Vue.set(state[name], 'found', true);
28 | },
29 | updateKey(state, o) {
30 | Vue.set(state[o.name], o.key, o.value);
31 | }
32 | },
33 | actions: {
34 | cleanState({ state, commit }) {
35 | for (const [key] of Object.entries(state)) {
36 | commit('updateKey', {name: key, key: 'found', value: false});
37 | }
38 | },
39 | find({ state, rootState, commit }, name) {
40 | if (state[name] && !state[name].found) {
41 | commit('find', name);
42 |
43 | if (rootState.system.settings.notification.items.note.value) {
44 | // Create notification
45 | commit('system/addNotification', {color: 'info', timeout: name === 'mining_0' ? -1 : 10000, message: {
46 | type: 'note',
47 | name
48 | }}, {root: true});
49 | commit('system/addNoteHint', name, {root: true});
50 | }
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/store/tag.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue"
2 |
3 | export default {
4 | namespaced: true,
5 | state: {},
6 | getters: {
7 | isActive: (state) => (name) => {
8 | return Object.keys(state[name].values).length > 0;
9 | },
10 | values: (state) => (name) => {
11 | let values = state[name].params.map(() => 0);
12 | const stacking = state[name].stacking;
13 | for (const [, arr] of Object.entries(state[name].values)) {
14 | arr.forEach((elem, index) => {
15 | if (stacking === 'add') {
16 | values[index] += elem;
17 | } else if (stacking === 'max') {
18 | if (elem > values[index]) {
19 | values[index] = elem;
20 | }
21 | }
22 | });
23 | }
24 | return values;
25 | }
26 | },
27 | mutations: {
28 | init(state, o) {
29 | Vue.set(state, o.name, {
30 | params: o.params ?? [],
31 | stacking: o.stacking ?? 'add',
32 | values: {}
33 | });
34 | },
35 | set(state, o) {
36 | Vue.set(state[o.name].values, o.key, o.value);
37 | },
38 | reset(state, o) {
39 | let newObj = {};
40 | for (const [key, elem] of Object.entries(state[o.name].values)) {
41 | if (key !== o.key) {
42 | newObj[key] = elem;
43 | }
44 | }
45 | Vue.set(state[o.name], 'values', newObj);
46 | },
47 | fullReset(state, name) {
48 | Vue.set(state[name], 'values', {});
49 | }
50 | },
51 | actions: {
52 | cleanState({ state, commit }) {
53 | for (const [key] of Object.entries(state)) {
54 | commit('fullReset', key);
55 | }
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/store/unlock.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue"
2 |
3 | export default {
4 | namespaced: true,
5 | state: {},
6 | mutations: {
7 | init(state, name) {
8 | Vue.set(state, name, {
9 | see: false,
10 | use: false
11 | });
12 | },
13 | unlock(state, name) {
14 | Vue.set(state[name], 'see', true);
15 | Vue.set(state[name], 'use', true);
16 | },
17 | reset(state, name) {
18 | Vue.set(state[name], 'use', false);
19 | },
20 | lock(state, name) {
21 | Vue.set(state[name], 'see', false);
22 | Vue.set(state[name], 'use', false);
23 | }
24 | },
25 | actions: {
26 | cleanState({ state, commit }) {
27 | for (const [key] of Object.entries(state)) {
28 | commit('lock', key);
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/test/unit/autoplay.test.js:
--------------------------------------------------------------------------------
1 | import { newGame } from '../../src/js/init';
2 | import { autoplay } from '../../src/js/autoplay';
3 | import store from '../../src/store';
4 |
5 | test('game can simulate a day of autoplay', () => {
6 | newGame(false);
7 |
8 | autoplay(1);
9 |
10 | // General systems
11 | const reportSize = JSON.stringify(store.state.system.autoplayData).length;
12 |
13 | // Show report size
14 | console.info(reportSize);
15 |
16 | expect(reportSize).toBeGreaterThan(0);
17 | });
18 |
--------------------------------------------------------------------------------
/test/unit/treasure.test.js:
--------------------------------------------------------------------------------
1 | import store from '../../src/store';
2 |
3 | // get a clean store state
4 | beforeEach(() => {
5 | store.state.stat = {};
6 | });
7 |
8 | test('a stat has the value zero by default', () => {
9 | store.commit('stat/init', {feature: 'test', name: 'test'});
10 |
11 | expect(store.state.stat.test_test.feature).toBe('test');
12 | expect(store.state.stat.test_test.default).toBe(0);
13 | expect(store.state.stat.test_test.value).toBe(0);
14 | expect(store.state.stat.test_test.total).toBe(0);
15 | });
16 |
--------------------------------------------------------------------------------
/test/unit/unlock.test.js:
--------------------------------------------------------------------------------
1 | import store from '../../src/store';
2 |
3 | // get a clean store state
4 | beforeEach(() => {
5 | store.state.unlock = {};
6 | });
7 |
8 | test('an unlock is locked by default', () => {
9 | store.commit('unlock/init', 'test');
10 |
11 | expect(store.state.unlock.test.see).toBe(false);
12 | expect(store.state.unlock.test.use).toBe(false);
13 | });
14 |
15 | test('an unlocked unlock can be seen and used', () => {
16 | store.commit('unlock/init', 'test');
17 | store.commit('unlock/unlock', 'test');
18 |
19 | expect(store.state.unlock.test.see).toBe(true);
20 | expect(store.state.unlock.test.use).toBe(true);
21 | });
22 |
23 | test('a reset unlock can be seen, but not used', () => {
24 | store.commit('unlock/init', 'test');
25 | store.commit('unlock/unlock', 'test');
26 | store.commit('unlock/reset', 'test');
27 |
28 | expect(store.state.unlock.test.see).toBe(true);
29 | expect(store.state.unlock.test.use).toBe(false);
30 | });
31 |
32 | test('a reset unlock that was never unlocked can neither be seen nor used', () => {
33 | store.commit('unlock/init', 'test');
34 | store.commit('unlock/reset', 'test');
35 |
36 | expect(store.state.unlock.test.see).toBe(false);
37 | expect(store.state.unlock.test.use).toBe(false);
38 | });
39 |
40 | test('an locked unlock can neither be seen nor used', () => {
41 | store.commit('unlock/init', 'test');
42 | store.commit('unlock/unlock', 'test');
43 | store.commit('unlock/lock', 'test');
44 |
45 | expect(store.state.unlock.test.see).toBe(false);
46 | expect(store.state.unlock.test.use).toBe(false);
47 | });
48 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "transpileDependencies": [
3 | "vuetify"
4 | ],
5 | publicPath: process.env.NODE_ENV === 'production' ? '/gooboo/' : '/'
6 | }
7 |
--------------------------------------------------------------------------------