├── .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 | 9 | 10 | 28 | -------------------------------------------------------------------------------- /src/components/partial/event/BingoCell.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 28 | 29 | 46 | -------------------------------------------------------------------------------- /src/components/partial/event/BloomBuyFlower.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 42 | -------------------------------------------------------------------------------- /src/components/partial/event/BloomInventorySlot.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | 14 | 33 | -------------------------------------------------------------------------------- /src/components/partial/event/Casino.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 20 | -------------------------------------------------------------------------------- /src/components/partial/event/EventCalendar.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 39 | 40 | -------------------------------------------------------------------------------- /src/components/partial/event/NightHuntFavouritableDisplay.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 33 | -------------------------------------------------------------------------------- /src/components/partial/event/NightHuntPotion.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 45 | -------------------------------------------------------------------------------- /src/components/partial/event/Prize.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 50 | -------------------------------------------------------------------------------- /src/components/partial/event/SnowdownInventory.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 55 | -------------------------------------------------------------------------------- /src/components/partial/event/WeatherChaosInventory.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 19 | -------------------------------------------------------------------------------- /src/components/partial/farm/Building.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 40 | -------------------------------------------------------------------------------- /src/components/partial/farm/BuildingCard.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 31 | -------------------------------------------------------------------------------- /src/components/partial/farm/CropUpgrade.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 39 | -------------------------------------------------------------------------------- /src/components/partial/farm/FertilizerCard.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 35 | -------------------------------------------------------------------------------- /src/components/partial/gallery/IdeaItem.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 60 | -------------------------------------------------------------------------------- /src/components/partial/gallery/Inventory.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 40 | -------------------------------------------------------------------------------- /src/components/partial/gallery/PrestigeInventory.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 28 | -------------------------------------------------------------------------------- /src/components/partial/gallery/PrestigeStatus.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 26 | -------------------------------------------------------------------------------- /src/components/partial/gem/GemList.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | -------------------------------------------------------------------------------- /src/components/partial/horde/ActiveCost.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 55 | -------------------------------------------------------------------------------- /src/components/partial/horde/EquipDisplay.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 24 | 25 | 43 | -------------------------------------------------------------------------------- /src/components/partial/horde/HeirloomList.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 27 | -------------------------------------------------------------------------------- /src/components/partial/horde/PrestigeInventory.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 34 | -------------------------------------------------------------------------------- /src/components/partial/horde/TrinketList.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 45 | -------------------------------------------------------------------------------- /src/components/partial/main/NextTile.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 38 | 39 | 49 | -------------------------------------------------------------------------------- /src/components/partial/mining/PrestigeInventory.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 31 | -------------------------------------------------------------------------------- /src/components/partial/note/NoteList.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 47 | -------------------------------------------------------------------------------- /src/components/partial/note/ShowButton.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 70 | -------------------------------------------------------------------------------- /src/components/partial/relic/Mini.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 23 | 24 | 53 | -------------------------------------------------------------------------------- /src/components/partial/relic/MuseumTab.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 24 | 25 | 36 | -------------------------------------------------------------------------------- /src/components/partial/relic/RelicList.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 20 | -------------------------------------------------------------------------------- /src/components/partial/render/AlertText.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 23 | 24 | 54 | -------------------------------------------------------------------------------- /src/components/partial/render/GoobooTooltip.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 44 | -------------------------------------------------------------------------------- /src/components/partial/render/TabIconText.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 70 | -------------------------------------------------------------------------------- /src/components/partial/school/BookUpgrades.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 27 | -------------------------------------------------------------------------------- /src/components/partial/settings/Keybind.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 47 | -------------------------------------------------------------------------------- /src/components/partial/snackbar/AchievementMessage.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 52 | -------------------------------------------------------------------------------- /src/components/partial/snackbar/CardPackInstantEffect.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 28 | -------------------------------------------------------------------------------- /src/components/partial/snackbar/CardPackMessage.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 30 | -------------------------------------------------------------------------------- /src/components/partial/snackbar/ErrorMessage.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 25 | -------------------------------------------------------------------------------- /src/components/partial/snackbar/FeatureMessage.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 33 | -------------------------------------------------------------------------------- /src/components/partial/snackbar/HeirloomMessage.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 20 | -------------------------------------------------------------------------------- /src/components/partial/snackbar/ImportMessage.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 33 | -------------------------------------------------------------------------------- /src/components/partial/snackbar/NoteMessage.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 31 | -------------------------------------------------------------------------------- /src/components/partial/snackbar/PrizeMessage.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 29 | -------------------------------------------------------------------------------- /src/components/partial/snackbar/SaveMessage.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 24 | -------------------------------------------------------------------------------- /src/components/partial/snackbar/SchoolMessage.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 29 | -------------------------------------------------------------------------------- /src/components/partial/snackbar/UpdateMessage.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 25 | -------------------------------------------------------------------------------- /src/components/partial/treasure/BuyItem.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 55 | -------------------------------------------------------------------------------- /src/components/partial/treasure/StatList.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | 17 | 47 | -------------------------------------------------------------------------------- /src/components/partial/village/CraftingItem.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 28 | 29 | 44 | -------------------------------------------------------------------------------- /src/components/partial/village/OfferingInventory.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 32 | -------------------------------------------------------------------------------- /src/components/partial/village/OfferingList.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 38 | -------------------------------------------------------------------------------- /src/components/partial/village/PolicyList.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 29 | -------------------------------------------------------------------------------- /src/components/partial/village/PrestigeInventory.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 31 | -------------------------------------------------------------------------------- /src/components/partial/village/PrestigeStatus.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 38 | -------------------------------------------------------------------------------- /src/components/render/CurrencyIcon.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 25 | -------------------------------------------------------------------------------- /src/components/render/CurrentNote.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 45 | -------------------------------------------------------------------------------- /src/components/render/MultName.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 52 | -------------------------------------------------------------------------------- /src/components/render/NoteSimple.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 21 | 22 | 40 | -------------------------------------------------------------------------------- /src/components/view/Achievement.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 39 | -------------------------------------------------------------------------------- /src/components/view/Cryolab.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 45 | -------------------------------------------------------------------------------- /src/components/view/Patchnote.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 41 | -------------------------------------------------------------------------------- /src/components/view/Relic.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 29 | -------------------------------------------------------------------------------- /src/components/view/TabDuplicate.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 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 | --------------------------------------------------------------------------------