Vue 3 Migration
This commit is contained in:
parent
8103377ab0
commit
8fe91e88c9
75 changed files with 40190 additions and 28102 deletions
15063
package-lock.json
generated
15063
package-lock.json
generated
File diff suppressed because it is too large
Load diff
22
package.json
22
package.json
|
@ -8,30 +8,24 @@
|
||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@ivanv/vue-collapse-transition": "^1.0.2",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
"lodash.clonedeep": "^4.5.0",
|
"lodash.clonedeep": "^4.5.0",
|
||||||
"portal-vue": "^2.1.7",
|
"vue": "^3.1.4",
|
||||||
"simplebar-vue": "^1.6.4",
|
"vue-next-select": "^2.7.0",
|
||||||
"vue": "^2.6.11",
|
|
||||||
"vue-frag": "^1.1.5",
|
|
||||||
"vue-reactive-provide": "^0.3.0",
|
|
||||||
"vue-select": "^3.11.2",
|
|
||||||
"vue-sortable": "github:Netbel/vue-sortable#master-fix",
|
"vue-sortable": "github:Netbel/vue-sortable#master-fix",
|
||||||
"vue-textarea-autosize": "^1.1.1",
|
"vue-textarea-autosize": "^1.1.1",
|
||||||
"vue-transition-expand": "^0.1.0",
|
"vue-transition-expand": "^0.1.0"
|
||||||
"vuex": "^3.4.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/vue-select": "^3.11.1",
|
|
||||||
"@vue/cli-plugin-babel": "~4.5.0",
|
"@vue/cli-plugin-babel": "~4.5.0",
|
||||||
"@vue/cli-plugin-eslint": "~4.5.0",
|
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||||
"@vue/cli-plugin-vuex": "~4.5.0",
|
|
||||||
"@vue/cli-service": "~4.5.0",
|
"@vue/cli-service": "~4.5.0",
|
||||||
|
"@vue/compiler-sfc": "^3.0.0-beta.1",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"eslint": "^6.7.2",
|
"eslint": "^6.7.2",
|
||||||
"eslint-plugin-vue": "^6.2.2",
|
"eslint-plugin-vue": "^7.0.0-alpha.0",
|
||||||
"raw-loader": "^4.0.2",
|
"raw-loader": "^4.0.2"
|
||||||
"vue-template-compiler": "^2.6.11"
|
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"root": true,
|
"root": true,
|
||||||
|
@ -39,7 +33,7 @@
|
||||||
"node": true
|
"node": true
|
||||||
},
|
},
|
||||||
"extends": [
|
"extends": [
|
||||||
"plugin:vue/essential",
|
"plugin:vue/vue3-essential",
|
||||||
"eslint:recommended"
|
"eslint:recommended"
|
||||||
],
|
],
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
|
|
24
src/App.vue
24
src/App.vue
|
@ -1,29 +1,23 @@
|
||||||
<template>
|
<template>
|
||||||
<div id="app" @mousemove="updateMouse" :style="theme" :class="{ useHeader }">
|
<div id="modal-root" :style="theme" />
|
||||||
|
<div class="app" @mousemove="updateMouse" :style="theme" :class="{ useHeader }">
|
||||||
<Nav v-if="useHeader" />
|
<Nav v-if="useHeader" />
|
||||||
<Tabs />
|
<Tabs />
|
||||||
<TPS v-if="showTPS" />
|
<TPS v-if="showTPS" />
|
||||||
<GameOverScreen />
|
<GameOverScreen />
|
||||||
<NaNScreen />
|
<NaNScreen />
|
||||||
<portal-target name="modal-root" multiple />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Nav from './components/system/Nav';
|
|
||||||
import Tabs from './components/system/Tabs';
|
|
||||||
import TPS from './components/system/TPS';
|
|
||||||
import themes from './data/themes';
|
import themes from './data/themes';
|
||||||
import { mapState } from 'vuex';
|
import player from './game/player';
|
||||||
import { player } from './store/proxies';
|
|
||||||
import modInfo from './data/modInfo.json';
|
import modInfo from './data/modInfo.json';
|
||||||
|
import { mapState } from './util/vue';
|
||||||
import './main.css';
|
import './main.css';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
components: {
|
|
||||||
Nav, Tabs, TPS
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return { useHeader: modInfo.useHeader };
|
return { useHeader: modInfo.useHeader };
|
||||||
},
|
},
|
||||||
|
@ -42,10 +36,18 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
#app {
|
.app {
|
||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
color: var(--color);
|
color: var(--color);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
|
min-height: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal-root {
|
||||||
|
position: absolute;
|
||||||
|
min-height: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
#app .simplebar-scrollbar:before {
|
|
||||||
background: #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.simplebar-horizontal.simplebar-hover,
|
|
||||||
.simplebar-horizontal.simplebar-hover .simplebar-scrollbar {
|
|
||||||
height: 22px;
|
|
||||||
}
|
|
||||||
.simplebar-vertical.simplebar-hover {
|
|
||||||
width: 22px;
|
|
||||||
}
|
|
|
@ -10,7 +10,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="filteredAchievements" class="table">
|
<div v-if="filteredAchievements" class="table">
|
||||||
<div v-frag v-if="filteredAchievements.rows && filteredAchievements.cols">
|
<template v-if="filteredAchievements.rows && filteredAchievements.cols">
|
||||||
<div v-for="row in filteredAchievements.rows" class="row" :key="row">
|
<div v-for="row in filteredAchievements.rows" class="row" :key="row">
|
||||||
<div v-for="col in filteredAchievements.cols" :key="col">
|
<div v-for="col in filteredAchievements.cols" :key="col">
|
||||||
<achievement v-if="filteredAchievements[row * 10 + col] !== undefined" class="align" :id="row * 10 + col" />
|
<achievement v-if="filteredAchievements[row * 10 + col] !== undefined" class="align" :id="row * 10 + col" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
<div v-frag v-else>
|
<template v-frag v-else>
|
||||||
<achievement v-for="(achievement, id) in filteredAchievements" :key="id" :id="id" />
|
<achievement v-for="(achievement, id) in filteredAchievements" :key="id" :id="id" />
|
||||||
</div>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { getFiltered } from '../../util/vue';
|
import { getFiltered } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { UP, DOWN, LEFT, RIGHT, DEFAULT, coerceComponent } from '../../util/vue';
|
import { UP, DOWN, LEFT, RIGHT, DEFAULT, coerceComponent } from '../../util/vue';
|
||||||
import Decimal from '../../util/bignum';
|
import Decimal from '../../util/bignum';
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -2,15 +2,15 @@
|
||||||
<div v-if="filteredBuyables" class="table">
|
<div v-if="filteredBuyables" class="table">
|
||||||
<respec-button v-if="showRespec" style="margin-bottom: 12px;" :confirmRespec="confirmRespec"
|
<respec-button v-if="showRespec" style="margin-bottom: 12px;" :confirmRespec="confirmRespec"
|
||||||
@set-confirm-respec="setConfirmRespec" @respec="respec" />
|
@set-confirm-respec="setConfirmRespec" @respec="respec" />
|
||||||
<div v-frag v-if="filteredBuyables.rows && filteredBuyables.cols">
|
<template v-if="filteredBuyables.rows && filteredBuyables.cols">
|
||||||
<div v-for="row in filteredBuyables.rows" class="row" :key="row">
|
<div v-for="row in filteredBuyables.rows" class="row" :key="row">
|
||||||
<div v-for="col in filteredBuyables.cols" :key="col">
|
<div v-for="col in filteredBuyables.cols" :key="col">
|
||||||
<buyable v-if="filteredBuyables[row * 10 + col] !== undefined" class="align buyable-container" :style="{ height }"
|
<buyable v-if="filteredBuyables[row * 10 + col] !== undefined" class="align buyable-container" :style="{ height }"
|
||||||
:id="row * 10 + col" :size="height === 'inherit' ? null : height" />
|
:id="row * 10 + col" :size="height === 'inherit' ? null : height" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
<row v-frag v-else>
|
<row v-else>
|
||||||
<buyable v-for="(buyable, id) in filteredBuyables" :key="id" class="align buyable-container"
|
<buyable v-for="(buyable, id) in filteredBuyables" :key="id" class="align buyable-container"
|
||||||
:style="{ height }" :id="id" :size="height === 'inherit' ? null : height" />
|
:style="{ height }" :id="id" :size="height === 'inherit' ? null : height" />
|
||||||
</row>
|
</row>
|
||||||
|
@ -18,8 +18,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
import { getFiltered } from '../../util/vue';
|
import { getFiltered } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -33,6 +33,7 @@ export default {
|
||||||
default: "inherit"
|
default: "inherit"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
emits: [ 'set-confirm-respec' ],
|
||||||
computed: {
|
computed: {
|
||||||
filteredBuyables() {
|
filteredBuyables() {
|
||||||
return getFiltered(layers[this.layer || this.tab.layer].buyables, this.buyables);
|
return getFiltered(layers[this.layer || this.tab.layer].buyables, this.buyables);
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="filteredChallenges" class="table">
|
<div v-if="filteredChallenges" class="table">
|
||||||
<div v-frag v-if="filteredChallenges.rows && filteredChallenges.cols">
|
<template v-if="filteredChallenges.rows && filteredChallenges.cols">
|
||||||
<div v-for="row in filteredChallenges.rows" class="row" :key="row">
|
<div v-for="row in filteredChallenges.rows" class="row" :key="row">
|
||||||
<div v-for="col in filteredChallenges.cols" :key="col">
|
<div v-for="col in filteredChallenges.cols" :key="col">
|
||||||
<challenge v-if="filteredChallenges[row * 10 + col] !== undefined" :id="row * 10 + col" />
|
<challenge v-if="filteredChallenges[row * 10 + col] !== undefined" :id="row * 10 + col" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
<div v-frag v-else>
|
<row v-else>
|
||||||
<challenge v-for="(challenge, id) in filteredChallenges" :key="id" :id="id" />
|
<challenge v-for="(challenge, id) in filteredChallenges" :key="id" :id="id" />
|
||||||
</div>
|
</row>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { getFiltered } from '../../util/vue';
|
import { getFiltered } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="filteredClickables" class="table">
|
<div v-if="filteredClickables" class="table">
|
||||||
<master-button v-if="showMasterButton" style="margin-bottom: 12px;" @press="press" />
|
<master-button v-if="showMasterButton" style="margin-bottom: 12px;" @press="press" />
|
||||||
<div v-frag v-if="filteredClickables.rows && filteredClickables.cols">
|
<template v-if="filteredClickables.rows && filteredClickables.cols">
|
||||||
<div v-for="row in filteredClickables.rows" class="row" :key="row">
|
<div v-for="row in filteredClickables.rows" class="row" :key="row">
|
||||||
<div v-for="col in filteredClickables.cols" :key="col">
|
<div v-for="col in filteredClickables.cols" :key="col">
|
||||||
<clickable v-if="filteredClickables[row * 10 + col] !== undefined" class="align clickable-container"
|
<clickable v-if="filteredClickables[row * 10 + col] !== undefined" class="align clickable-container"
|
||||||
:style="{ height }" :id="row * 10 + col" :size="height === 'inherit' ? null : height" />
|
:style="{ height }" :id="row * 10 + col" :size="height === 'inherit' ? null : height" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
<div v-frag v-else>
|
<row v-else>
|
||||||
<clickable v-for="(clickable, id) in filteredClickables" :key="id" class="align clickable-container" :style="{ height }"
|
<clickable v-for="(clickable, id) in filteredClickables" :key="id" class="align clickable-container" :style="{ height }"
|
||||||
:id="id" :size="height === 'inherit' ? null : height" />
|
:id="id" :size="height === 'inherit' ? null : height" />
|
||||||
</div>
|
</row>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { getFiltered } from '../../util/vue';
|
import { getFiltered } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-frag>
|
<component :is="challengeDescription" v-bind="$attrs" />
|
||||||
<component :is="challengeDescription" />
|
|
||||||
<div>Goal: <component :is="goalDescription" /></div>
|
<div>Goal: <component :is="goalDescription" /></div>
|
||||||
<div>Reward: <component :is="rewardDescription" /></div>
|
<div>Reward: <component :is="rewardDescription" /></div>
|
||||||
<component v-if="rewardDisplay" :is="rewardDisplay" />
|
<component v-if="rewardDisplay" :is="rewardDisplay" />
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -29,7 +27,7 @@ export default {
|
||||||
if (this.challenge.goalDescription) {
|
if (this.challenge.goalDescription) {
|
||||||
return coerceComponent(this.challenge.goalDescription);
|
return coerceComponent(this.challenge.goalDescription);
|
||||||
}
|
}
|
||||||
return coerceComponent(`{{ format(${this.challenge.goal}) }} ${this.currencyDisplayName || 'points'}`);
|
return coerceComponent(`{{ format(${this.challenge.goal}) }} ${this.challenge.currencyDisplayName || 'points'}`);
|
||||||
},
|
},
|
||||||
rewardDescription() {
|
rewardDescription() {
|
||||||
return coerceComponent(this.challenge.rewardDescription);
|
return coerceComponent(this.challenge.rewardDescription);
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
import { format, formatWhole } from '../../util/bignum';
|
import { format, formatWhole } from '../../util/bignum';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
import { formatWhole } from '../../util/bignum';
|
import { formatWhole } from '../../util/bignum';
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'grid',
|
name: 'grid',
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -4,18 +4,18 @@
|
||||||
<span class="toggle">▼</span>
|
<span class="toggle">▼</span>
|
||||||
<component :is="title" />
|
<component :is="title" />
|
||||||
</button>
|
</button>
|
||||||
<transition-expand>
|
<collapse-transition>
|
||||||
<div v-if="!collapsed" class="body" :style="{ backgroundColor: this.borderColor }">
|
<div v-if="!collapsed" class="body" :style="{ backgroundColor: borderColor }">
|
||||||
<component :is="body" :style="bodyStyle" />
|
<component :is="body" :style="bodyStyle" />
|
||||||
</div>
|
</div>
|
||||||
</transition-expand>
|
</collapse-transition>
|
||||||
<branch-node :branches="infobox.branches" :id="id" featureType="infobox" />
|
<branch-node :branches="infobox.branches" :id="id" featureType="infobox" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
import themes from '../../data/themes';
|
import themes from '../../data/themes';
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<span v-if="showPrefix">You have</span>
|
<span v-if="showPrefix">You have </span>
|
||||||
<resource :amount="amount" :color="color" />
|
<resource :amount="amount" :color="color" />
|
||||||
{{ resource }}<!-- remove whitespace -->
|
{{ resource }}<!-- remove whitespace -->
|
||||||
<span v-if="effectDisplay">, <component :is="effectDisplay" /></span>
|
<span v-if="effectDisplay">, <component :is="effectDisplay" /></span>
|
||||||
|
@ -9,8 +9,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { format, formatWhole } from '../../util/bignum';
|
import { format, formatWhole } from '../../util/bignum';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -16,6 +16,7 @@ export default {
|
||||||
layer: String,
|
layer: String,
|
||||||
display: [ String, Object ]
|
display: [ String, Object ]
|
||||||
},
|
},
|
||||||
|
emits: [ 'press' ],
|
||||||
computed: {
|
computed: {
|
||||||
style() {
|
style() {
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { getFiltered } from '../../util/vue';
|
import { getFiltered } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { resetLayer } from '../../util/layers';
|
import { resetLayer } from '../../util/layers';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
import Decimal, { formatWhole } from '../../util/bignum';
|
import Decimal, { formatWhole } from '../../util/bignum';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -8,26 +8,28 @@
|
||||||
<component :is="respecButtonDisplay" />
|
<component :is="respecButtonDisplay" />
|
||||||
</button>
|
</button>
|
||||||
<Modal :show="confirming" @close="cancel">
|
<Modal :show="confirming" @close="cancel">
|
||||||
<div slot="header">
|
<template v-slot:header>
|
||||||
<h2>Confirm Respec</h2>
|
<h2>Confirm Respec</h2>
|
||||||
</div>
|
</template>
|
||||||
<slot name="respec-warning" slot="body">
|
<template v-slot:body>
|
||||||
|
<slot name="respec-warning">
|
||||||
<div>Are you sure you want to respec? This will force you to do a {{ name }} respec as well!</div>
|
<div>Are you sure you want to respec? This will force you to do a {{ name }} respec as well!</div>
|
||||||
</slot>
|
</slot>
|
||||||
<div slot="footer">
|
</template>
|
||||||
|
<template v-slot:footer>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<div class="modal-flex-grow"></div>
|
<div class="modal-flex-grow"></div>
|
||||||
<danger-button class="button modal-button" @click="confirm" skipConfirm>Yes</danger-button>
|
<danger-button class="button modal-button" @click="confirm" skipConfirm>Yes</danger-button>
|
||||||
<button class="button modal-button" @click="cancel">Cancel</button>
|
<button class="button modal-button" @click="cancel">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -43,6 +45,7 @@ export default {
|
||||||
confirmRespec: Boolean,
|
confirmRespec: Boolean,
|
||||||
display: [ String, Object ]
|
display: [ String, Object ]
|
||||||
},
|
},
|
||||||
|
emits: [ 'set-confirm-respec', 'respec' ],
|
||||||
computed: {
|
computed: {
|
||||||
style() {
|
style() {
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="filteredUpgrades" class="table">
|
<div v-if="filteredUpgrades" class="table">
|
||||||
<div v-frag v-if="filteredUpgrades.rows && filteredUpgrades.cols">
|
<template v-if="filteredUpgrades.rows && filteredUpgrades.cols">
|
||||||
<div v-for="row in filteredUpgrades.rows" class="row" :key="row">
|
<div v-for="row in filteredUpgrades.rows" class="row" :key="row">
|
||||||
<div v-for="col in filteredUpgrades.cols" :key="col">
|
<div v-for="col in filteredUpgrades.cols" :key="col">
|
||||||
<upgrade v-if="filteredUpgrades[row * 10 + col] !== undefined" class="align" :id="row * 10 + col" />
|
<upgrade v-if="filteredUpgrades[row * 10 + col] !== undefined" class="align" :id="row * 10 + col" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
<div v-frag v-else>
|
<row v-else>
|
||||||
<upgrade v-for="(upgrade, id) in filteredUpgrades" :key="id" class="align" :id="id" />
|
<upgrade v-for="(upgrade, id) in filteredUpgrades" :key="id" class="align" :id="id" />
|
||||||
</div>
|
</row>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { getFiltered } from '../../util/vue';
|
import { getFiltered } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<span class="container">
|
<span class="container" :class="{ confirming }">
|
||||||
<span v-if="confirming">Are you sure?</span>
|
<span v-if="confirming">Are you sure?</span>
|
||||||
<button @click.stop="click" class="button danger" :disabled="disabled">
|
<button @click.stop="click" class="button danger" :disabled="disabled">
|
||||||
<span v-if="confirming">Yes</span>
|
<span v-if="confirming">Yes</span>
|
||||||
|
@ -21,6 +21,7 @@ export default {
|
||||||
disabled: Boolean,
|
disabled: Boolean,
|
||||||
skipConfirm: Boolean
|
skipConfirm: Boolean
|
||||||
},
|
},
|
||||||
|
emits: [ 'click', 'confirmingChanged' ],
|
||||||
watch: {
|
watch: {
|
||||||
confirming(newValue) {
|
confirming(newValue) {
|
||||||
this.$emit('confirmingChanged', newValue);
|
this.$emit('confirmingChanged', newValue);
|
||||||
|
@ -50,6 +51,10 @@ export default {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.container.confirming button {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
.container > * {
|
.container > * {
|
||||||
margin: 0 4px;
|
margin: 0 4px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
left: Boolean
|
left: Boolean
|
||||||
},
|
},
|
||||||
|
emits: [ 'click' ],
|
||||||
methods: {
|
methods: {
|
||||||
click() {
|
click() {
|
||||||
this.$emit('click');
|
this.$emit('click');
|
||||||
|
|
|
@ -1,64 +1,62 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<span class="field-title" v-if="title">{{ title }}</span>
|
<span class="field-title" v-if="title">{{ title }}</span>
|
||||||
<v-select :options="options" :value="value" @input="setSelected" />
|
<vue-select :options="options" :model-value="value" @update:modelValue="setSelected" label-by="label" :value-by="getValue" :placeholder="placeholder" :close-on-select="closeOnSelect" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import vSelect from 'vue-select';
|
|
||||||
import 'vue-select/dist/vue-select.css';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Select',
|
name: 'Select',
|
||||||
props: {
|
props: {
|
||||||
title: String,
|
title: String,
|
||||||
options: Array, // https://vue-select.org/guide/options.html#options-prop
|
options: Array, // https://vue-select.org/guide/options.html#options-prop
|
||||||
value: [ String, Object ],
|
value: [ String, Object ],
|
||||||
default: [ String, Object ]
|
default: [ String, Object ],
|
||||||
},
|
placeholder: String,
|
||||||
components: {
|
closeOnSelect: Boolean
|
||||||
vSelect
|
|
||||||
},
|
},
|
||||||
|
emits: [ 'change' ],
|
||||||
methods: {
|
methods: {
|
||||||
setSelected(option) {
|
setSelected(value) {
|
||||||
const value = option?.value || this.default;
|
value = value || this.default;
|
||||||
this.$emit('change', value);
|
this.$emit('change', value);
|
||||||
|
},
|
||||||
|
getValue(item) {
|
||||||
|
return item?.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.v-select {
|
.vue-select {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-select .vs__dropdown-toggle {
|
.field-buttons .vue-select {
|
||||||
border-color: rgba(var(--color), .26);
|
width: unset;
|
||||||
margin: -1px 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-select .vs__selected {
|
.vue-select,
|
||||||
color: var(--color);
|
.vue-dropdown {
|
||||||
}
|
|
||||||
|
|
||||||
.v-select .vs__clear,
|
|
||||||
.v-select .vs__open-indicator {
|
|
||||||
fill: var(--color);
|
|
||||||
opacity: .5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v-select .vs__dropdown-menu {
|
|
||||||
background: var(--background);
|
|
||||||
border-color: rgba(var(--color), .26);
|
border-color: rgba(var(--color), .26);
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-select .vs__dropdown-option {
|
.vue-dropdown {
|
||||||
|
background: var(--secondary-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vue-dropdown-item {
|
||||||
color: var(--color);
|
color: var(--color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-select .vs__open-indicator {
|
.vue-dropdown-item.highlighted {
|
||||||
cursor: pointer;
|
background-color: var(--background-tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vue-dropdown-item.selected,
|
||||||
|
.vue-dropdown-item.highlighted.selected {
|
||||||
|
background-color: var(--bought);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -15,7 +15,8 @@ export default {
|
||||||
value: Number,
|
value: Number,
|
||||||
min: Number,
|
min: Number,
|
||||||
max: Number
|
max: Number
|
||||||
}
|
},
|
||||||
|
emits: [ 'change' ]
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<span class="field-title" v-if="title">{{ title }}</span>
|
<span class="field-title" v-if="title">{{ title }}</span>
|
||||||
<textarea-autosize v-if="textarea" :placeholder="placeholder" :value="value" :maxHeight="maxHeight"
|
<textarea-autosize v-if="textarea" :placeholder="placeholder" :value="value" :maxHeight="maxHeight"
|
||||||
@input="value => $emit('change', value)" ref="field" />
|
@input="value => $emit('change', value)" ref="field" />
|
||||||
<input v-else type="text" :value="value" @input="e => $emit('input', e.target.value)" :placeholder="placeholder" ref="field"
|
<input v-else type="text" :value="value" @input="e => $emit('change', e.target.value)" :placeholder="placeholder" ref="field"
|
||||||
:class="{ fullWidth: !title }" />
|
:class="{ fullWidth: !title }" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -20,6 +20,7 @@ export default {
|
||||||
placeholder: String,
|
placeholder: String,
|
||||||
maxHeight: Number
|
maxHeight: Number
|
||||||
},
|
},
|
||||||
|
emits: [ 'change', 'submit', 'input' ],
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$refs.field.focus();
|
this.$refs.field.focus();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ export default {
|
||||||
title: String,
|
title: String,
|
||||||
value: Boolean
|
value: Boolean
|
||||||
},
|
},
|
||||||
|
emits: [ 'change' ],
|
||||||
methods: {
|
methods: {
|
||||||
handleInput(e) {
|
handleInput(e) {
|
||||||
this.$emit('change', e.target.checked);
|
this.$emit('change', e.target.checked);
|
||||||
|
|
|
@ -1,29 +1,28 @@
|
||||||
// Import and register all components,
|
// Import and register all components,
|
||||||
// which will allow us to use them in any template strings anywhere in the project
|
// which will allow us to use them in any template strings anywhere in the project
|
||||||
|
|
||||||
import Vue from 'vue';
|
//import TransitionExpand from 'vue-transition-expand';
|
||||||
|
//import 'vue-transition-expand/dist/vue-transition-expand.css';
|
||||||
/* from files */
|
import CollapseTransition from '@ivanv/vue-collapse-transition/src/CollapseTransition.vue';
|
||||||
const componentsContext = require.context('./');
|
|
||||||
componentsContext.keys().forEach(path => {
|
|
||||||
const component = componentsContext(path).default;
|
|
||||||
if (component) {
|
|
||||||
Vue.component(component.name, component);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/* from packages */
|
|
||||||
import frag from 'vue-frag';
|
|
||||||
Vue.directive('frag', frag);
|
|
||||||
import TransitionExpand from 'vue-transition-expand';
|
|
||||||
import 'vue-transition-expand/dist/vue-transition-expand.css';
|
|
||||||
Vue.use(TransitionExpand);
|
|
||||||
import VueTextareaAutosize from 'vue-textarea-autosize';
|
import VueTextareaAutosize from 'vue-textarea-autosize';
|
||||||
Vue.use(VueTextareaAutosize);
|
|
||||||
import PortalVue from 'portal-vue';
|
|
||||||
Vue.use(PortalVue);
|
|
||||||
import Sortable from 'vue-sortable';
|
import Sortable from 'vue-sortable';
|
||||||
Vue.use(Sortable);
|
import VueNextSelect from 'vue-next-select';
|
||||||
import simplebar from 'simplebar-vue';
|
import 'vue-next-select/dist/index.css';
|
||||||
import 'simplebar/dist/simplebar.min.css';
|
|
||||||
Vue.component('simplebar', simplebar);
|
export function registerComponents(vue) {
|
||||||
|
/* from files */
|
||||||
|
const componentsContext = require.context('./');
|
||||||
|
componentsContext.keys().forEach(path => {
|
||||||
|
const component = componentsContext(path).default;
|
||||||
|
if (component && !(component.name in vue._context.components)) {
|
||||||
|
vue.component(component.name, component);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* from packages */
|
||||||
|
//vue.use(TransitionExpand);
|
||||||
|
vue.component('collapse-transition', CollapseTransition);
|
||||||
|
vue.use(VueTextareaAutosize);
|
||||||
|
vue.use(Sortable);
|
||||||
|
vue.component('vue-select', VueNextSelect);
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-frag>
|
|
||||||
<infobox v-if="infobox != undefined" :id="infobox" />
|
<infobox v-if="infobox != undefined" :id="infobox" />
|
||||||
<main-display />
|
<main-display />
|
||||||
<sticky v-if="showPrestigeButton"><prestige-button /></sticky>
|
<sticky v-if="showPrestigeButton"><prestige-button /></sticky>
|
||||||
|
@ -11,11 +10,10 @@
|
||||||
<upgrades />
|
<upgrades />
|
||||||
<challenges />
|
<challenges />
|
||||||
<achievements />
|
<achievements />
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<Modal :show="show">
|
<Modal :show="show">
|
||||||
<div slot="header" class="game-over-modal-header">
|
<template v-slot:header>
|
||||||
|
<div class="game-over-modal-header">
|
||||||
<img class="game-over-modal-logo" v-if="logo" :src="logo" :alt="modInfo" />
|
<img class="game-over-modal-logo" v-if="logo" :src="logo" :alt="modInfo" />
|
||||||
<div class="game-over-modal-title">
|
<div class="game-over-modal-title">
|
||||||
<h2>Congratulations!</h2>
|
<h2>Congratulations!</h2>
|
||||||
<h4>You've beaten {{ title }} v{{ versionNumber }}: {{ versionTitle }}</h4>
|
<h4>You've beaten {{ title }} v{{ versionNumber }}: {{ versionTitle }}</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
<template v-slot:body="{ shown }">
|
<template v-slot:body="{ shown }">
|
||||||
<div v-if="shown">
|
<div v-if="shown">
|
||||||
<div>It took you {{ timePlayed }} to beat the game.</div>
|
<div>It took you {{ timePlayed }} to beat the game.</div>
|
||||||
|
@ -21,17 +23,20 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div slot="footer" class="game-over-footer">
|
<template v-slot:footer>
|
||||||
|
<div class="game-over-footer">
|
||||||
<button @click="keepGoing" class="button">Keep Going</button>
|
<button @click="keepGoing" class="button">Keep Going</button>
|
||||||
<button @click="playAgain" class="button danger">Play Again</button>
|
<button @click="playAgain" class="button danger">Play Again</button>
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import modInfo from '../../data/modInfo.json';
|
import modInfo from '../../data/modInfo.json';
|
||||||
|
import { hasWon } from '../../data/mod';
|
||||||
import { formatTime } from '../../util/bignum';
|
import { formatTime } from '../../util/bignum';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'GameOverScreen',
|
name: 'GameOverScreen',
|
||||||
|
@ -44,7 +49,7 @@ export default {
|
||||||
return formatTime(player.timePlayed);
|
return formatTime(player.timePlayed);
|
||||||
},
|
},
|
||||||
show() {
|
show() {
|
||||||
return this.$store.getters.hasWon && !player.keepGoing;
|
return hasWon.value && !player.keepGoing;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<Modal :show="show" @close="$emit('closeDialog', 'Info')">
|
<Modal :show="show" @close="$emit('closeDialog', 'Info')">
|
||||||
<div slot="header" class="info-modal-header">
|
<template v-slot:header>
|
||||||
|
<div class="info-modal-header">
|
||||||
<img class="info-modal-logo" v-if="logo" :src="logo" :alt="title" />
|
<img class="info-modal-logo" v-if="logo" :src="logo" :alt="title" />
|
||||||
<div class="info-modal-title">
|
<div class="info-modal-title">
|
||||||
<h2>{{ title }}</h2>
|
<h2>{{ title }}</h2>
|
||||||
<h4>v{{ versionNumber}}: {{ versionTitle }}</h4>
|
<h4>v{{ versionNumber}}: {{ versionTitle }}</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
<template v-slot:body="{ shown }">
|
<template v-slot:body="{ shown }">
|
||||||
<div v-if="shown">
|
<div v-if="shown">
|
||||||
<div v-if="author">
|
<div v-if="author">
|
||||||
|
@ -59,7 +61,8 @@
|
||||||
<script>
|
<script>
|
||||||
import modInfo from '../../data/modInfo.json';
|
import modInfo from '../../data/modInfo.json';
|
||||||
import { formatTime } from '../../util/bignum';
|
import { formatTime } from '../../util/bignum';
|
||||||
import { hotkeys } from '../../store/layers';
|
import { hotkeys } from '../../game/layers';
|
||||||
|
import player from '../../game/player';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Info',
|
name: 'Info',
|
||||||
|
@ -70,9 +73,10 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
show: Boolean
|
show: Boolean
|
||||||
},
|
},
|
||||||
|
emits: [ 'closeDialog', 'openDialog' ],
|
||||||
computed: {
|
computed: {
|
||||||
timePlayed() {
|
timePlayed() {
|
||||||
return formatTime(this.$store.state.timePlayed);
|
return formatTime(player.timePlayed);
|
||||||
},
|
},
|
||||||
hotkeys() {
|
hotkeys() {
|
||||||
return Object.keys(hotkeys).reduce((acc, curr) => {
|
return Object.keys(hotkeys).reduce((acc, curr) => {
|
||||||
|
|
|
@ -1,20 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-frag>
|
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ReactiveProvideMixin } from 'vue-reactive-provide';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'LayerProvider',
|
name: 'LayerProvider',
|
||||||
mixins: [
|
provide() {
|
||||||
ReactiveProvideMixin({
|
return {
|
||||||
name: 'tab',
|
'tab': {
|
||||||
props: true
|
layer: this.layer,
|
||||||
})
|
index: this.index
|
||||||
],
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
layer: String,
|
layer: String,
|
||||||
index: Number
|
index: Number
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
import { isPlainObject } from '../../util/common';
|
import { isPlainObject } from '../../util/common';
|
||||||
import modInfo from '../../data/modInfo.json';
|
import modInfo from '../../data/modInfo.json';
|
||||||
|
@ -81,7 +81,7 @@ export default {
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
activeSubtab() {
|
activeSubtab() {
|
||||||
return layers[this.layer].activeSubtab.id;
|
return layers[this.layer].activeSubtab?.id;
|
||||||
},
|
},
|
||||||
firstTab() {
|
firstTab() {
|
||||||
if (this.forceFirstTab != undefined) {
|
if (this.forceFirstTab != undefined) {
|
||||||
|
@ -101,13 +101,13 @@ export default {
|
||||||
tab.style.flexGrow = 0;
|
tab.style.flexGrow = 0;
|
||||||
tab.style.flexShrink = 0;
|
tab.style.flexShrink = 0;
|
||||||
tab.style.width = "60px";
|
tab.style.width = "60px";
|
||||||
tab.style.minWidth = null;
|
tab.style.minWidth = tab.style.flexBasis = null;
|
||||||
tab.style.margin = 0;
|
tab.style.margin = 0;
|
||||||
} else {
|
} else {
|
||||||
tab.style.flexGrow = null;
|
tab.style.flexGrow = null;
|
||||||
tab.style.flexShrink = null;
|
tab.style.flexShrink = null;
|
||||||
tab.style.width = null;
|
tab.style.width = null;
|
||||||
tab.style.minWidth = `${layers[this.layer].minWidth}px`;
|
tab.style.minWidth = tab.style.flexBasis = `${layers[this.layer].minWidth}px`;
|
||||||
tab.style.margin = null;
|
tab.style.margin = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,13 +123,13 @@ export default {
|
||||||
tab.style.flexGrow = 0;
|
tab.style.flexGrow = 0;
|
||||||
tab.style.flexShrink = 0;
|
tab.style.flexShrink = 0;
|
||||||
tab.style.width = "60px";
|
tab.style.width = "60px";
|
||||||
tab.style.minWidth = null;
|
tab.style.minWidth = tab.style.flexBasis = null;
|
||||||
tab.style.margin = 0;
|
tab.style.margin = 0;
|
||||||
} else {
|
} else {
|
||||||
tab.style.flexGrow = null;
|
tab.style.flexGrow = null;
|
||||||
tab.style.flexShrink = null;
|
tab.style.flexShrink = null;
|
||||||
tab.style.width = null;
|
tab.style.width = null;
|
||||||
tab.style.minWidth = `${layers[this.layer].minWidth}px`;
|
tab.style.minWidth = tab.style.flexBasis = `${layers[this.layer].minWidth}px`;
|
||||||
tab.style.margin = null;
|
tab.style.margin = null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -180,7 +180,7 @@ export default {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-top: 50px;
|
padding-top: 55px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 40px;
|
font-size: 40px;
|
||||||
|
@ -299,3 +299,9 @@ export default {
|
||||||
text-shadow: 0 0 7px var(--color);
|
text-shadow: 0 0 7px var(--color);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.subtabs-container + * {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
import themes from '../../data/themes';
|
import themes from '../../data/themes';
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<portal to="modal-root">
|
<teleport to="#modal-root">
|
||||||
<transition name="modal" @before-enter="setAnimating(true)" @after-leave="setAnimating(false)">
|
<transition name="modal" @before-enter="setAnimating(true)" @after-leave="setAnimating(false)">
|
||||||
<div class="modal-mask" v-show="show" v-on:pointerdown.self="$emit('close')">
|
<div class="modal-mask" v-show="show" v-on:pointerdown.self="$emit('close')" v-bind="$attrs">
|
||||||
<div class="modal-wrapper">
|
<div class="modal-wrapper">
|
||||||
<div class="modal-container">
|
<div class="modal-container">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
|
@ -9,13 +9,13 @@
|
||||||
default header
|
default header
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
<simplebar class="modal-body">
|
<div class="modal-body">
|
||||||
<branches>
|
<branches>
|
||||||
<slot name="body" :shown="isVisible">
|
<slot name="body" :shown="isVisible">
|
||||||
default body
|
default body
|
||||||
</slot>
|
</slot>
|
||||||
</branches>
|
</branches>
|
||||||
</simplebar>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<slot name="footer" :shown="isVisible">
|
<slot name="footer" :shown="isVisible">
|
||||||
<div class="modal-default-footer">
|
<div class="modal-default-footer">
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</portal>
|
</teleport>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -44,6 +44,7 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
show: Boolean
|
show: Boolean
|
||||||
},
|
},
|
||||||
|
emits: [ 'close' ],
|
||||||
computed: {
|
computed: {
|
||||||
isVisible() {
|
isVisible() {
|
||||||
return this.show || this.isAnimating;
|
return this.show || this.isAnimating;
|
||||||
|
@ -96,7 +97,6 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-body {
|
.modal-body {
|
||||||
display: flex;
|
|
||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
@ -115,7 +115,7 @@ export default {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-enter {
|
.modal-enter-from {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ export default {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-enter .modal-container,
|
.modal-enter-from .modal-container,
|
||||||
.modal-leave-active .modal-container {
|
.modal-leave-active .modal-container {
|
||||||
-webkit-transform: scale(1.1);
|
-webkit-transform: scale(1.1);
|
||||||
transform: scale(1.1);
|
transform: scale(1.1);
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-frag>
|
<Modal :show="hasNaN" v-bind="$attrs">
|
||||||
<Modal :show="show">
|
<template v-slot:header>
|
||||||
<div slot="header" class="nan-modal-header">
|
<div class="nan-modal-header">
|
||||||
<h2>NaN value detected!</h2>
|
<h2>NaN value detected!</h2>
|
||||||
</div>
|
</div>
|
||||||
<div slot="body">
|
</template>
|
||||||
<div>Attempted to assign NaN value to "{{ property }}" (previously {{ format(previous) }}). Auto-saving has been {{ autosave ? 'enabled' : 'disabled' }}. Check the console for more details, and consider sharing it with the developers on discord.</div>
|
<template v-slot:body>
|
||||||
|
<div>Attempted to assign "{{ path }}" to NaN (previously {{ format(previous) }}). Auto-saving has been {{ autosave ? 'enabled' : 'disabled' }}. Check the console for more details, and consider sharing it with the developers on discord.</div>
|
||||||
<br>
|
<br>
|
||||||
<div>
|
<div>
|
||||||
<a :href="discordLink" class="nan-modal-discord-link">
|
<a :href="discordLink" class="nan-modal-discord-link">
|
||||||
|
@ -16,23 +17,25 @@
|
||||||
<br>
|
<br>
|
||||||
<Toggle title="Autosave" :value="autosave" @change="setAutosave" />
|
<Toggle title="Autosave" :value="autosave" @change="setAutosave" />
|
||||||
<Toggle title="Pause game" :value="paused" @change="togglePaused" />
|
<Toggle title="Pause game" :value="paused" @change="togglePaused" />
|
||||||
</div>
|
</template>
|
||||||
<div slot="footer" class="nan-footer">
|
<template v-slot:footer>
|
||||||
|
<div class="nan-footer">
|
||||||
<button @click="toggleSavesManager" class="button">Open Saves Manager</button>
|
<button @click="toggleSavesManager" class="button">Open Saves Manager</button>
|
||||||
<button @click="setZero" class="button">Set to 0</button>
|
<button @click="setZero" class="button">Set to 0</button>
|
||||||
<button @click="setOne" class="button">Set to 1</button>
|
<button @click="setOne" class="button">Set to 1</button>
|
||||||
<button @click="setPrev" class="button" v-if="previous && previous.neq(0) && previous.neq(1)">Set to previous</button>
|
<button @click="setPrev" class="button" v-if="previous && previous.neq(0) && previous.neq(1)">Set to previous</button>
|
||||||
<button @click="ignore" class="button danger">Ignore</button>
|
<button @click="ignore" class="button danger">Ignore</button>
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
</Modal>
|
</Modal>
|
||||||
<SavesManager :show="showSaves" @closeDialog="toggleSavesManager" />
|
<SavesManager :show="showSaves" @closeDialog="toggleSavesManager" />
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import modInfo from '../../data/modInfo.json';
|
import modInfo from '../../data/modInfo.json';
|
||||||
import Decimal, { format } from '../../util/bignum';
|
import Decimal, { format } from '../../util/bignum';
|
||||||
import { player } from '../../store/proxies';
|
import { mapState } from '../../util/vue';
|
||||||
|
import player from '../../game/player';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NaNScreen',
|
name: 'NaNScreen',
|
||||||
|
@ -41,36 +44,34 @@ export default {
|
||||||
return { discordName, discordLink, format, showSaves: false };
|
return { discordName, discordLink, format, showSaves: false };
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
show() {
|
...mapState([ 'hasNaN', 'autosave' ]),
|
||||||
return player.hasNaN;
|
path() {
|
||||||
},
|
return player.NaNPath.join('.');
|
||||||
property() {
|
|
||||||
return player.NaNProperty;
|
|
||||||
},
|
|
||||||
autosave() {
|
|
||||||
return player.autosave;
|
|
||||||
},
|
},
|
||||||
previous() {
|
previous() {
|
||||||
return player.NaNPrevious;
|
return player.NaNReceiver?.[this.property];
|
||||||
},
|
},
|
||||||
paused() {
|
paused() {
|
||||||
return player.devSpeed === 0;
|
return player.devSpeed === 0;
|
||||||
|
},
|
||||||
|
property() {
|
||||||
|
return player.NaNPath.slice(-1)[0];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setZero() {
|
setZero() {
|
||||||
player.NaNReceiver[player.NaNProperty] = new Decimal(0);
|
player.NaNReceiver[this.property] = new Decimal(0);
|
||||||
player.hasNaN = false;
|
player.hasNaN = false;
|
||||||
},
|
},
|
||||||
setOne() {
|
setOne() {
|
||||||
player.NaNReceiver[player.NaNProperty] = new Decimal(1);
|
player.NaNReceiver[this.property] = new Decimal(1);
|
||||||
player.hasNaN = false;
|
player.hasNaN = false;
|
||||||
},
|
},
|
||||||
setPrev() {
|
setPrev() {
|
||||||
player.NaNReceiver[player.NaNProperty] = player.NaNPrevious;
|
|
||||||
player.hasNaN = false;
|
player.hasNaN = false;
|
||||||
},
|
},
|
||||||
ignore() {
|
ignore() {
|
||||||
|
player.NaNReceiver[this.property] = new Decimal(NaN);
|
||||||
player.hasNaN = false;
|
player.hasNaN = false;
|
||||||
},
|
},
|
||||||
setAutosave(autosave) {
|
setAutosave(autosave) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-frag>
|
<div class="nav" v-if="useHeader" v-bind="$attrs">
|
||||||
<div class="nav" v-if="useHeader">
|
|
||||||
<img v-if="banner" :src="banner" height="100%" :alt="title" />
|
<img v-if="banner" :src="banner" height="100%" :alt="title" />
|
||||||
<div v-else class="title">{{ title }}</div>
|
<div v-else class="title">{{ title }}</div>
|
||||||
<div @click="openDialog('Changelog')" class="version-container">
|
<div @click="openDialog('Changelog')" class="version-container">
|
||||||
|
@ -32,7 +31,7 @@
|
||||||
</tooltip>
|
</tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="overlay-nav">
|
<div v-else class="overlay-nav" v-bind="$attrs">
|
||||||
<div @click="openDialog('Changelog')" class="version-container">
|
<div @click="openDialog('Changelog')" class="version-container">
|
||||||
<tooltip display="Changelog" right xoffset="25%" class="version"><span>v{{ version }}</span></tooltip>
|
<tooltip display="Changelog" right xoffset="25%" class="version"><span>v{{ version }}</span></tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
@ -60,7 +59,6 @@
|
||||||
<Info :show="showInfo" @openDialog="openDialog" @closeDialog="closeDialog" />
|
<Info :show="showInfo" @openDialog="openDialog" @closeDialog="closeDialog" />
|
||||||
<SavesManager :show="showSaves" @closeDialog="closeDialog" />
|
<SavesManager :show="showSaves" @closeDialog="closeDialog" />
|
||||||
<Options :show="showOptions" @closeDialog="closeDialog" />
|
<Options :show="showOptions" @closeDialog="closeDialog" />
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -173,7 +171,7 @@ export default {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
transition: right .25s ease;
|
transition: right .25s ease;
|
||||||
background: var(--secondary-background);
|
background: var(--secondary-background);
|
||||||
z-index: 1;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
.overlay-nav .discord-links {
|
.overlay-nav .discord-links {
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<Modal :show="show" @close="$emit('closeDialog', 'Options')">
|
<Modal :show="show" @close="$emit('closeDialog', 'Options')">
|
||||||
<div slot="header" class="header">
|
<template v-slot:header>
|
||||||
|
<div class="header">
|
||||||
<h2>Options</h2>
|
<h2>Options</h2>
|
||||||
</div>
|
</div>
|
||||||
<div slot="body">
|
</template>
|
||||||
|
<template v-slot:body>
|
||||||
<Select title="Theme" :options="themes" :value="theme" @change="setTheme" default="classic" />
|
<Select title="Theme" :options="themes" :value="theme" @change="setTheme" default="classic" />
|
||||||
<Select title="Show Milestones" :options="msDisplayOptions" :value="msDisplay" @change="setMSDisplay" default="all" />
|
<Select title="Show Milestones" :options="msDisplayOptions" :value="msDisplay" @change="setMSDisplay" default="all" />
|
||||||
<Toggle title="Offline Production" :value="offlineProd" @change="toggleOption('offlineProd')" />
|
<Toggle title="Offline Production" :value="offlineProd" @change="toggleOption('offlineProd')" />
|
||||||
|
@ -11,21 +13,22 @@
|
||||||
<Toggle title="Pause game" :value="paused" @change="togglePaused" />
|
<Toggle title="Pause game" :value="paused" @change="togglePaused" />
|
||||||
<Toggle title="Show TPS" :value="showTPS" @change="toggleOption('showTPS')" />
|
<Toggle title="Show TPS" :value="showTPS" @change="toggleOption('showTPS')" />
|
||||||
<Toggle title="Hide Maxed Challenges" :value="hideChallenges" @change="toggleOption('hideChallenges')" />
|
<Toggle title="Hide Maxed Challenges" :value="hideChallenges" @change="toggleOption('hideChallenges')" />
|
||||||
</div>
|
</template>
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import themes from '../../data/themes';
|
import themes from '../../data/themes';
|
||||||
import { camelToTitle } from '../../util/common';
|
import { camelToTitle } from '../../util/common';
|
||||||
import { mapState } from 'vuex';
|
import { mapState } from '../../util/vue';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Options',
|
name: 'Options',
|
||||||
props: {
|
props: {
|
||||||
show: Boolean
|
show: Boolean
|
||||||
},
|
},
|
||||||
|
emits: [ 'closeDialog' ],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
themes: Object.keys(themes).map(theme => ({ label: camelToTitle(theme), value: theme })),
|
themes: Object.keys(themes).map(theme => ({ label: camelToTitle(theme), value: theme })),
|
||||||
|
@ -34,13 +37,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState([ "autosave", "offlineProd", "showTPS", "hideChallenges" ]),
|
...mapState([ "autosave", "offlineProd", "showTPS", "hideChallenges", "theme", "msDisplay" ]),
|
||||||
theme() {
|
|
||||||
return { label: camelToTitle(player.theme), value: player.theme };
|
|
||||||
},
|
|
||||||
msDisplay() {
|
|
||||||
return { label: camelToTitle(player.msDisplay), value: player.msDisplay };
|
|
||||||
},
|
|
||||||
paused() {
|
paused() {
|
||||||
return player.devSpeed === 0;
|
return player.devSpeed === 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,13 +40,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'save',
|
name: 'save',
|
||||||
props: {
|
props: {
|
||||||
save: Object
|
save: Object
|
||||||
},
|
},
|
||||||
|
emits: [ 'export', 'open', 'duplicate', 'delete', 'editSave' ],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
dateFormat: new Intl.DateTimeFormat('en-US', {
|
dateFormat: new Intl.DateTimeFormat('en-US', {
|
||||||
|
@ -161,8 +162,7 @@ export default {
|
||||||
.save .button.danger {
|
.save .button.danger {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0;
|
padding: 4px;
|
||||||
padding-left: 6px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.save .field {
|
.save .field {
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
<Modal :show="show" @close="$emit('closeDialog', 'Saves')">
|
<Modal :show="show" @close="$emit('closeDialog', 'Saves')">
|
||||||
<div slot="header">
|
<template v-slot:header>
|
||||||
<h2>Saves Manager</h2>
|
<h2>Saves Manager</h2>
|
||||||
</div>
|
</template>
|
||||||
<div slot="body" v-sortable="{ update, handle: '.handle' }">
|
<template v-slot:body v-sortable="{ update, handle: '.handle' }">
|
||||||
<save v-for="(save, index) in saves" :key="index" :save="save" @open="openSave(save.id)" @export="exportSave(save.id)"
|
<save v-for="(save, index) in saves" :key="index" :save="save" @open="openSave(save.id)" @export="exportSave(save.id)"
|
||||||
@editSave="name => editSave(save.id, name)" @duplicate="duplicateSave(save.id)" @delete="deleteSave(save.id)" />
|
@editSave="name => editSave(save.id, name)" @duplicate="duplicateSave(save.id)" @delete="deleteSave(save.id)" />
|
||||||
</div>
|
</template>
|
||||||
<div slot="footer" class="modal-footer">
|
<template v-slot:footer>
|
||||||
|
<div class="modal-footer">
|
||||||
<TextField :value="saveToImport" @submit="importSave" @input="importSave"
|
<TextField :value="saveToImport" @submit="importSave" @input="importSave"
|
||||||
title="Import Save" placeholder="Paste your save here!" :class="{ importingFailed }" />
|
title="Import Save" placeholder="Paste your save here!" :class="{ importingFailed }" />
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<span class="field-title">Create Save</span>
|
<span class="field-title">Create Save</span>
|
||||||
<div class="field-buttons">
|
<div class="field-buttons">
|
||||||
<button class="button" @click="newSave">New Game</button>
|
<button class="button" @click="newSave">New Game</button>
|
||||||
<Select v-if="Object.keys(bank).length > 0" :value="{ label: 'Select preset' }" :options="bank"
|
<Select v-if="Object.keys(bank).length > 0" :options="bank" closeOnSelect
|
||||||
@change="newFromPreset" />
|
@change="newFromPreset" placeholder="Select preset" class="presets" :value="[]" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
|
@ -25,13 +26,13 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Vue from 'vue';
|
|
||||||
import { newSave, getUniqueID, loadSave, save } from '../../util/save';
|
import { newSave, getUniqueID, loadSave, save } from '../../util/save';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
import modInfo from '../../data/modInfo.json';
|
import modInfo from '../../data/modInfo.json';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -39,6 +40,7 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
show: Boolean
|
show: Boolean
|
||||||
},
|
},
|
||||||
|
emits: [ 'closeDialog' ],
|
||||||
data() {
|
data() {
|
||||||
let bankContext = require.context('raw-loader!../../../saves', true, /\.txt$/);
|
let bankContext = require.context('raw-loader!../../../saves', true, /\.txt$/);
|
||||||
let bank = bankContext.keys().reduce((acc, curr) => {
|
let bank = bankContext.keys().reduce((acc, curr) => {
|
||||||
|
@ -109,14 +111,14 @@ export default {
|
||||||
const modData = JSON.parse(decodeURIComponent(escape(atob(localStorage.getItem(modInfo.id)))));
|
const modData = JSON.parse(decodeURIComponent(escape(atob(localStorage.getItem(modInfo.id)))));
|
||||||
modData.saves.push(playerData.id);
|
modData.saves.push(playerData.id);
|
||||||
localStorage.setItem(modInfo.id, btoa(unescape(encodeURIComponent(JSON.stringify(modData)))));
|
localStorage.setItem(modInfo.id, btoa(unescape(encodeURIComponent(JSON.stringify(modData)))));
|
||||||
Vue.set(this.saves, playerData.id, playerData);
|
this.saves[playerData.id] = playerData;
|
||||||
},
|
},
|
||||||
deleteSave(id) {
|
deleteSave(id) {
|
||||||
const modData = JSON.parse(decodeURIComponent(escape(atob(localStorage.getItem(modInfo.id)))));
|
const modData = JSON.parse(decodeURIComponent(escape(atob(localStorage.getItem(modInfo.id)))));
|
||||||
modData.saves = modData.saves.filter(save => save !== id);
|
modData.saves = modData.saves.filter(save => save !== id);
|
||||||
localStorage.removeItem(id);
|
localStorage.removeItem(id);
|
||||||
localStorage.setItem(modInfo.id, btoa(unescape(encodeURIComponent(JSON.stringify(modData)))));
|
localStorage.setItem(modInfo.id, btoa(unescape(encodeURIComponent(JSON.stringify(modData)))));
|
||||||
Vue.delete(this.saves, id);
|
delete this.saves[id];
|
||||||
},
|
},
|
||||||
openSave(id) {
|
openSave(id) {
|
||||||
this.saves[player.id].time = player.time;
|
this.saves[player.id].time = player.time;
|
||||||
|
@ -127,7 +129,7 @@ export default {
|
||||||
},
|
},
|
||||||
async newSave() {
|
async newSave() {
|
||||||
const playerData = await newSave();
|
const playerData = await newSave();
|
||||||
Vue.set(this.saves, playerData.id, playerData);
|
this.saves[playerData.id] = playerData;
|
||||||
},
|
},
|
||||||
newFromPreset(preset) {
|
newFromPreset(preset) {
|
||||||
const playerData = JSON.parse(decodeURIComponent(escape(atob(preset))));
|
const playerData = JSON.parse(decodeURIComponent(escape(atob(preset))));
|
||||||
|
@ -137,7 +139,7 @@ export default {
|
||||||
const modData = JSON.parse(decodeURIComponent(escape(atob(localStorage.getItem(modInfo.id)))));
|
const modData = JSON.parse(decodeURIComponent(escape(atob(localStorage.getItem(modInfo.id)))));
|
||||||
modData.saves.push(playerData.id);
|
modData.saves.push(playerData.id);
|
||||||
localStorage.setItem(modInfo.id, btoa(unescape(encodeURIComponent(JSON.stringify(modData)))));
|
localStorage.setItem(modInfo.id, btoa(unescape(encodeURIComponent(JSON.stringify(modData)))));
|
||||||
Vue.set(this.saves, playerData.id, playerData);
|
this.saves[playerData.id] = playerData;
|
||||||
},
|
},
|
||||||
editSave(id, newName) {
|
editSave(id, newName) {
|
||||||
this.saves[id].name = newName;
|
this.saves[id].name = newName;
|
||||||
|
@ -157,7 +159,7 @@ export default {
|
||||||
const id = getUniqueID();
|
const id = getUniqueID();
|
||||||
playerData.id = id;
|
playerData.id = id;
|
||||||
localStorage.setItem(id, btoa(unescape(encodeURIComponent(JSON.stringify(playerData)))));
|
localStorage.setItem(id, btoa(unescape(encodeURIComponent(JSON.stringify(playerData)))));
|
||||||
Vue.set(this.saves, id, playerData);
|
this.saves[id] = playerData;
|
||||||
this.saveToImport = "";
|
this.saveToImport = "";
|
||||||
this.importingFailed = false;
|
this.importingFailed = false;
|
||||||
|
|
||||||
|
@ -217,4 +219,12 @@ export default {
|
||||||
.field-buttons .v-select {
|
.field-buttons .v-select {
|
||||||
width: 220px;
|
width: 220px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.presets .vue-dropdown {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.presets .vue-select[aria-expanded='true'] vue-dropdown {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Decimal, { formatWhole } from '../../util/bignum';
|
import Decimal, { formatWhole } from '../../util/bignum';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TPS',
|
name: 'TPS',
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
import themes from '../../data/themes';
|
import themes from '../../data/themes';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -18,6 +18,7 @@ export default {
|
||||||
options: Object,
|
options: Object,
|
||||||
activeTab: Boolean
|
activeTab: Boolean
|
||||||
},
|
},
|
||||||
|
emits: [ 'selectTab' ],
|
||||||
inject: [ 'tab' ],
|
inject: [ 'tab' ],
|
||||||
computed: {
|
computed: {
|
||||||
floating() {
|
floating() {
|
||||||
|
|
|
@ -1,26 +1,24 @@
|
||||||
<template>
|
<template>
|
||||||
<simplebar class="tabs-container">
|
<div class="tabs-container">
|
||||||
<div v-for="(tab, index) in tabs" :key="index" class="tab" :ref="`tab-${index}`">
|
<div v-for="(tab, index) in tabs" :key="index" class="tab" :ref="`tab-${index}`">
|
||||||
<Nav v-if="index === 0 && !useHeader" />
|
<Nav v-if="index === 0 && !useHeader" />
|
||||||
<simplebar>
|
|
||||||
<div class="inner-tab">
|
<div class="inner-tab">
|
||||||
<LayerProvider :layer="tab" :index="index" v-if="tab in components && components[tab]">
|
<LayerProvider :layer="tab" :index="index" v-if="tab in components && components[tab]">
|
||||||
<component :is="components[tab]" />
|
<component :is="components[tab]" />
|
||||||
</LayerProvider>
|
</LayerProvider>
|
||||||
<layer-tab :layer="tab" :index="index" v-else-if="tab in components" :minimizable="true"
|
<layer-tab :layer="tab" :index="index" v-else-if="tab in components" :minimizable="true"
|
||||||
:tab="() => $refs[`tab-${index}`] && $refs[`tab-${index}`][0]" />
|
:tab="() => $refs[`tab-${index}`]" />
|
||||||
<component :is="tab" :index="index" v-else />
|
<component :is="tab" :index="index" v-else />
|
||||||
</div>
|
</div>
|
||||||
</simplebar>
|
|
||||||
<div class="separator" v-if="index !== tabs.length - 1"></div>
|
<div class="separator" v-if="index !== tabs.length - 1"></div>
|
||||||
</div>
|
</div>
|
||||||
</simplebar>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import modInfo from '../../data/modInfo.json';
|
import modInfo from '../../data/modInfo.json';
|
||||||
import { mapState } from 'vuex';
|
import { layers } from '../../game/layers';
|
||||||
import { layers } from '../../store/layers';
|
import { mapState } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Tabs',
|
name: 'Tabs',
|
||||||
|
@ -45,6 +43,7 @@ export default {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabs {
|
.tabs {
|
||||||
|
@ -77,11 +76,6 @@ export default {
|
||||||
background: var(--separator);
|
background: var(--separator);
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab > [data-simplebar] {
|
|
||||||
height: 100%;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -95,23 +89,4 @@ export default {
|
||||||
.tab .modal-body hr {
|
.tab .modal-body hr {
|
||||||
margin: 7px 0;
|
margin: 7px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabs-container > .simplebar-wrapper > .simplebar-mask > .simplebar-offset > .simplebar-content-wrapper > .simplebar-content {
|
|
||||||
display: flex;
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.useHeader .tabs-container > .simplebar-wrapper > .simplebar-mask > .simplebar-offset > .simplebar-content-wrapper > .simplebar-content {
|
|
||||||
height: calc(100vh - 50px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab > [data-simplebar] > .simplebar-wrapper > .simplebar-mask > .simplebar-offset > .simplebar-content-wrapper {
|
|
||||||
position: static;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab > [data-simplebar] > .simplebar-wrapper > .simplebar-mask > .simplebar-offset > .simplebar-content-wrapper > .simplebar-content {
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 100%;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="tooltip-container" :class="{ shown }" @mouseenter="setHover(true)" @mouseleave="setHover(false)">
|
<div class="tooltip-container" :class="{ shown }" @mouseenter="setHover(true)" @mouseleave="setHover(false)">
|
||||||
<slot />
|
<slot />
|
||||||
<!-- Make sure slot is *before* the transition in case the slot uses v-frag, which messes up the tooltip -->
|
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<div v-if="shown" class="tooltip" :class="{ top, left, right, bottom }"
|
<div v-if="shown" class="tooltip" :class="{ top, left, right, bottom }"
|
||||||
:style="{ '--xoffset': xoffset, '--yoffset': yoffset }">
|
:style="{ '--xoffset': xoffset || '0px', '--yoffset': yoffset || '0px' }">
|
||||||
<component :is="tooltipDisplay" />
|
<component :is="tooltipDisplay" />
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
|
@ -81,7 +80,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.shown {
|
.shown {
|
||||||
z-index: 1;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade-enter, .fade-leave-to {
|
.fade-enter, .fade-leave-to {
|
||||||
|
|
|
@ -20,7 +20,7 @@ export default {
|
||||||
this.branches?.map(this.handleBranch).forEach(branch => this.registerBranch(id, branch));
|
this.branches?.map(this.handleBranch).forEach(branch => this.registerBranch(id, branch));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeUnmount() {
|
||||||
const id = `${this.featureType}@${this.id}`;
|
const id = `${this.featureType}@${this.id}`;
|
||||||
if (this.unregisterNode) {
|
if (this.unregisterNode) {
|
||||||
this.unregisterNode(id);
|
this.unregisterNode(id);
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-frag>
|
|
||||||
<slot />
|
<slot />
|
||||||
<div ref="resizeListener" class="resize-listener" />
|
<div ref="resizeListener" class="resize-listener" />
|
||||||
<svg>
|
<svg v-bind="$attrs">
|
||||||
<branch-line v-for="(branch, index) in branches" :key="index"
|
<branch-line v-for="(branch, index) in branches" :key="index"
|
||||||
:startNode="nodes[branch.start]" :endNode="nodes[branch.end]" :options="branch.options" />
|
:startNode="nodes[branch.start]" :endNode="nodes[branch.end]" :options="branch.options" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Vue from 'vue';
|
|
||||||
|
|
||||||
const observerOptions = {
|
const observerOptions = {
|
||||||
attributes: true,
|
attributes: true,
|
||||||
childList: true,
|
childList: true,
|
||||||
|
@ -57,12 +53,12 @@ export default {
|
||||||
},
|
},
|
||||||
updateNode(id, containerRect) {
|
updateNode(id, containerRect) {
|
||||||
const linkStartRect = this.nodes[id].element.getBoundingClientRect();
|
const linkStartRect = this.nodes[id].element.getBoundingClientRect();
|
||||||
Vue.set(this.nodes[id], 'x', linkStartRect.x + linkStartRect.width / 2 - containerRect.x);
|
this.nodes[id].x = linkStartRect.x + linkStartRect.width / 2 - containerRect.x;
|
||||||
Vue.set(this.nodes[id], 'y', linkStartRect.y + linkStartRect.height / 2 - containerRect.y);
|
this.nodes[id].y = linkStartRect.y + linkStartRect.height / 2 - containerRect.y;
|
||||||
},
|
},
|
||||||
registerNode(id, component) {
|
registerNode(id, component) {
|
||||||
const element = component.$el.parentElement;
|
const element = component.$el.parentElement;
|
||||||
Vue.set(this.nodes, id, { component, element });
|
this.nodes[id] = { component, element };
|
||||||
this.observer.observe(element, observerOptions);
|
this.observer.observe(element, observerOptions);
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (this.$refs.resizeListener != undefined) {
|
if (this.$refs.resizeListener != undefined) {
|
||||||
|
@ -71,17 +67,15 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
unregisterNode(id) {
|
unregisterNode(id) {
|
||||||
Vue.delete(this.nodes, id);
|
delete this.nodes[id];
|
||||||
},
|
},
|
||||||
registerBranch(start, options) {
|
registerBranch(start, options) {
|
||||||
const end = typeof options === 'string' ? options : options.target;
|
const end = typeof options === 'string' ? options : options.target;
|
||||||
this.links.push({ start, end, options });
|
this.links.push({ start, end, options });
|
||||||
Vue.set(this, 'links', this.links);
|
|
||||||
},
|
},
|
||||||
unregisterBranch(start, options) {
|
unregisterBranch(start, options) {
|
||||||
const index = this.links.findIndex(l => l.start === start && l.options === options);
|
const index = this.links.findIndex(l => l.start === start && l.options === options);
|
||||||
this.links.splice(index, 1);
|
this.links.splice(index, 1);
|
||||||
Vue.set(this, 'links', this.links);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-frag>
|
|
||||||
<span class="row" v-for="(row, index) in rows" :key="index">
|
<span class="row" v-for="(row, index) in rows" :key="index">
|
||||||
<tree-node v-for="(node, nodeIndex) in row" :key="nodeIndex" :id="node" @show-modal="openModal" :append="append" />
|
<tree-node v-for="(node, nodeIndex) in row" :key="nodeIndex" :id="node" @show-modal="openModal" :append="append" />
|
||||||
</span>
|
</span>
|
||||||
|
@ -7,14 +6,13 @@
|
||||||
<tree-node v-for="(node, nodeIndex) in rows.side" :key="nodeIndex" :id="node" @show-modal="openModal" :append="append" small />
|
<tree-node v-for="(node, nodeIndex) in rows.side" :key="nodeIndex" :id="node" @show-modal="openModal" :append="append" small />
|
||||||
</span>
|
</span>
|
||||||
<modal :show="showModal" @close="closeModal">
|
<modal :show="showModal" @close="closeModal">
|
||||||
<div slot="header"><h2 v-if="modalHeader">{{ modalHeader }}</h2></div>
|
<template v-slot:header><h2 v-if="modalHeader">{{ modalHeader }}</h2></template>
|
||||||
<layer-tab slot="body" v-if="modal" :layer="modal" :index="tab.index" :forceFirstTab="true" />
|
<template v-slot:body><layer-tab v-if="modal" :layer="modal" :index="tab.index" :forceFirstTab="true" /></template>
|
||||||
</modal>
|
</modal>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'tree',
|
name: 'tree',
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
import { coerceComponent } from '../../util/vue';
|
import { coerceComponent } from '../../util/vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -32,6 +32,7 @@ export default {
|
||||||
small: Boolean,
|
small: Boolean,
|
||||||
append: Boolean
|
append: Boolean
|
||||||
},
|
},
|
||||||
|
emits: [ 'show-modal' ],
|
||||||
inject: [ 'tab' ],
|
inject: [ 'tab' ],
|
||||||
computed: {
|
computed: {
|
||||||
layer() {
|
layer() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import Decimal from '../../../util/bignum';
|
import Decimal from '../../../util/bignum';
|
||||||
import { player } from '../../../store/proxies';
|
import player from '../../../game/player';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
id: "a",
|
id: "a",
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import Decimal, { format, formatWhole } from '../../../util/bignum';
|
import Decimal, { format, formatWhole } from '../../../util/bignum';
|
||||||
import { player, tmp } from '../../../store/proxies';
|
import player from '../../../game/player';
|
||||||
import { layers } from '../../../store/layers';
|
import { layers } from '../../../game/layers';
|
||||||
import { hasUpgrade, hasMilestone, getBuyableAmount, setBuyableAmount, upgradeEffect, buyableEffect, challengeCompletions } from '../../../util/features';
|
import { hasUpgrade, hasMilestone, getBuyableAmount, setBuyableAmount, upgradeEffect, buyableEffect, challengeCompletions } from '../../../util/features';
|
||||||
import { resetLayer, resetLayerData } from '../../../util/layers';
|
import { resetLayer, resetLayerData } from '../../../util/layers';
|
||||||
import { UP, RIGHT } from '../../../util/vue';
|
import { UP, RIGHT } from '../../../util/vue';
|
||||||
|
|
||||||
|
const tmp = layers;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
id: "c", // This is assigned automatically, both to the layer and all upgrades, etc. Shown here so you know about it
|
id: "c", // This is assigned automatically, both to the layer and all upgrades, etc. Shown here so you know about it
|
||||||
name: "Candies", // This is optional, only used in a few places, If absent it just uses the layer id.
|
name: "Candies", // This is optional, only used in a few places, If absent it just uses the layer id.
|
||||||
|
@ -230,10 +232,9 @@ export default {
|
||||||
microtabs: {
|
microtabs: {
|
||||||
stuff: {
|
stuff: {
|
||||||
first: {
|
first: {
|
||||||
display: `<div v-frag>
|
display: `
|
||||||
<upgrades />
|
<upgrades />
|
||||||
<div>confirmed</div>
|
<div>confirmed</div>`
|
||||||
</div>`
|
|
||||||
},
|
},
|
||||||
second: {
|
second: {
|
||||||
embedLayer: "f"
|
embedLayer: "f"
|
||||||
|
@ -304,7 +305,6 @@ export default {
|
||||||
buttonStyle() {return {'color': 'orange'}},
|
buttonStyle() {return {'color': 'orange'}},
|
||||||
notify: true,
|
notify: true,
|
||||||
display: `
|
display: `
|
||||||
<div v-frag>
|
|
||||||
<main-display />
|
<main-display />
|
||||||
<sticky><prestige-button /></sticky>
|
<sticky><prestige-button /></sticky>
|
||||||
<resource-display />
|
<resource-display />
|
||||||
|
@ -317,9 +317,7 @@ export default {
|
||||||
<milestones />
|
<milestones />
|
||||||
<spacer />
|
<spacer />
|
||||||
<upgrades />
|
<upgrades />
|
||||||
<challenges />
|
<challenges />`,
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
glowColor: "blue",
|
glowColor: "blue",
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -328,7 +326,6 @@ export default {
|
||||||
style() {return {'background-color': '#222222', '--background': '#222222'}},
|
style() {return {'background-color': '#222222', '--background': '#222222'}},
|
||||||
buttonStyle() {return {'border-color': 'orange'}},
|
buttonStyle() {return {'border-color': 'orange'}},
|
||||||
display: `
|
display: `
|
||||||
<div v-frag>
|
|
||||||
<buyables />
|
<buyables />
|
||||||
<spacer />
|
<spacer />
|
||||||
<row style="width: 600px; height: 350px; background-color: green; border-style: solid;">
|
<row style="width: 600px; height: 350px; background-color: green; border-style: solid;">
|
||||||
|
@ -343,13 +340,10 @@ export default {
|
||||||
</column>
|
</column>
|
||||||
</row>
|
</row>
|
||||||
<spacer />
|
<spacer />
|
||||||
<img src="https://unsoftcapped2.github.io/The-Modding-Tree-2/discord.png" />
|
<img src="https://unsoftcapped2.github.io/The-Modding-Tree-2/discord.png" />`
|
||||||
</div>
|
|
||||||
`
|
|
||||||
},
|
},
|
||||||
jail: {
|
jail: {
|
||||||
display: `
|
display: `
|
||||||
<div v-frag>
|
|
||||||
<infobox id="coolInfo" />
|
<infobox id="coolInfo" />
|
||||||
<bar id="longBoi" />
|
<bar id="longBoi" />
|
||||||
<spacer />
|
<spacer />
|
||||||
|
@ -366,21 +360,16 @@ export default {
|
||||||
</row>
|
</row>
|
||||||
<spacer />
|
<spacer />
|
||||||
<div>It's jail because "bars"! So funny! Ha ha!</div>
|
<div>It's jail because "bars"! So funny! Ha ha!</div>
|
||||||
<tree :nodes="[['f', 'c'], ['g', 'spook', 'h']]" />
|
<tree :nodes="[['f', 'c'], ['g', 'spook', 'h']]" />`
|
||||||
</div>
|
|
||||||
`
|
|
||||||
},
|
},
|
||||||
illuminati: {
|
illuminati: {
|
||||||
unlocked() {return (hasUpgrade("c", 13))},
|
unlocked() {return (hasUpgrade("c", 13))},
|
||||||
display: `
|
display: `
|
||||||
<div v-frag>
|
|
||||||
<h1> C O N F I R M E D </h1>
|
<h1> C O N F I R M E D </h1>
|
||||||
<spacer />
|
<spacer />
|
||||||
<microtab family="stuff" style="width: 660px; height: 370px; background-color: brown; --background: brown; border: solid white; margin: auto" />
|
<microtab family="stuff" style="width: 660px; height: 370px; background-color: brown; --background: brown; border: solid white; margin: auto" />
|
||||||
<div>Adjust how many points H gives you!</div>
|
<div>Adjust how many points H gives you!</div>
|
||||||
<Slider :value="player.c.otherThingy" @change="value => player.c.otherThingy = value" :min="1" :max="30" />
|
<Slider :value="player.c.otherThingy" @change="value => player.c.otherThingy = value" :min="1" :max="30" />`
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import Decimal, { formatWhole } from '../../../util/bignum';
|
import Decimal, { formatWhole } from '../../../util/bignum';
|
||||||
import { player, tmp } from '../../../store/proxies';
|
import player from '../../../game/player';
|
||||||
|
import { layers as tmp } from '../../../game/layers';
|
||||||
import { getClickableState } from '../../../util/features';
|
import { getClickableState } from '../../../util/features';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Decimal, { format } from '../../util/bignum';
|
import Decimal, { format } from '../../util/bignum';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { hasUpgrade, hasMilestone, getBuyableAmount, setBuyableAmount, hasChallenge } from '../../util/features';
|
import { hasUpgrade, hasMilestone, getBuyableAmount, setBuyableAmount, hasChallenge } from '../../util/features';
|
||||||
import { resetLayer } from '../../util/layers';
|
import { resetLayer } from '../../util/layers';
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Decimal, { format } from '../../util/bignum';
|
import Decimal, { format } from '../../util/bignum';
|
||||||
import { player } from '../../store/proxies';
|
import player from '../../game/player';
|
||||||
import { layers } from '../../store/layers';
|
import { layers } from '../../game/layers';
|
||||||
import { hasUpgrade, hasMilestone, getBuyableAmount, setBuyableAmount, hasChallenge } from '../../util/features';
|
import { hasUpgrade, hasMilestone, getBuyableAmount, setBuyableAmount, hasChallenge } from '../../util/features';
|
||||||
import { resetLayer } from '../../util/layers';
|
import { resetLayer } from '../../util/layers';
|
||||||
|
|
||||||
|
@ -871,38 +871,35 @@ challenges:{
|
||||||
},
|
},
|
||||||
subtabs: {
|
subtabs: {
|
||||||
"Upgrades": {
|
"Upgrades": {
|
||||||
display: `<div v-frag>
|
display: `
|
||||||
<main-display />
|
<main-display />
|
||||||
<spacer />
|
<spacer />
|
||||||
<prestige-button display="" />
|
<prestige-button display="" />
|
||||||
<spacer />
|
<spacer />
|
||||||
<spacer />
|
<spacer />
|
||||||
<upgrades />
|
<upgrades />`
|
||||||
</div>`
|
|
||||||
},
|
},
|
||||||
"Challenges": {
|
"Challenges": {
|
||||||
unlocked() { return hasUpgrade("p", 51) || hasMilestone("p", 0); },
|
unlocked() { return hasUpgrade("p", 51) || hasMilestone("p", 0); },
|
||||||
display: `<div v-frag>
|
display: `
|
||||||
<spacer />
|
<spacer />
|
||||||
<spacer />
|
<spacer />
|
||||||
<challenges />
|
<challenges />`
|
||||||
</div>`
|
|
||||||
},
|
},
|
||||||
"Buyables and Milestones": {
|
"Buyables and Milestones": {
|
||||||
unlocked(){return hasUpgrade("p",74)||hasMilestone("p",0)},
|
unlocked(){return hasUpgrade("p",74)||hasMilestone("p",0)},
|
||||||
display: `<div v-frag>
|
display: `
|
||||||
<spacer />
|
<spacer />
|
||||||
<spacer />
|
<spacer />
|
||||||
<row><buyable id="11" /></row>
|
<row><buyable id="11" /></row>
|
||||||
<spacer />
|
<spacer />
|
||||||
<div v-if="hasMilestone('p', 0)">Your boosts are making the point challenge {{ getBuyableAmount('p', 11).plus(1) }}x less pointy</div>
|
<div v-if="hasMilestone('p', 0)">Your boosts are making the point challenge {{ getBuyableAmount('p', 11).plus(1) }}x less pointy</div>
|
||||||
<spacer />
|
<spacer />
|
||||||
<milestones />
|
<milestones />`
|
||||||
</div>`
|
|
||||||
},
|
},
|
||||||
"Generators": {
|
"Generators": {
|
||||||
unlocked(){return hasMilestone("p",5)||player.i.points.gte(1)},
|
unlocked(){return hasMilestone("p",5)||player.i.points.gte(1)},
|
||||||
display: `<div v-frag>
|
display: `
|
||||||
<spacer />
|
<spacer />
|
||||||
<div>You have {{ format(player.p.gp) }} generator points, adding {{ format(hasUpgrade("p",132)?player.p.gp.plus(1).pow(new Decimal(1).div(2)):hasUpgrade("p",101)?player.p.gp.plus(1).pow(new Decimal(1).div(3)):hasUpgrade("p",93)?player.p.gp.plus(1).pow(0.2):player.p.gp.plus(1).log10()) }} to point gain</div>
|
<div>You have {{ format(player.p.gp) }} generator points, adding {{ format(hasUpgrade("p",132)?player.p.gp.plus(1).pow(new Decimal(1).div(2)):hasUpgrade("p",101)?player.p.gp.plus(1).pow(new Decimal(1).div(3)):hasUpgrade("p",93)?player.p.gp.plus(1).pow(0.2):player.p.gp.plus(1).log10()) }} to point gain</div>
|
||||||
<div>You have {{ format(player.p.g) }} generators, generating {{ format(player.p.g.times(player.p.geff)) }} generator points per second</div>
|
<div>You have {{ format(player.p.g) }} generators, generating {{ format(player.p.g.times(player.p.geff)) }} generator points per second</div>
|
||||||
|
@ -910,12 +907,11 @@ challenges:{
|
||||||
<spacer />
|
<spacer />
|
||||||
<spacer />
|
<spacer />
|
||||||
<buyables :buyables="[12, 13, 14]" />
|
<buyables :buyables="[12, 13, 14]" />
|
||||||
<row><clickable id="11" /></row>
|
<row><clickable id="11" /></row>`
|
||||||
</div>`
|
|
||||||
},
|
},
|
||||||
"Pointy Points": {
|
"Pointy Points": {
|
||||||
unlocked(){return hasUpgrade("p",104)||player.i.points.gte(1)},
|
unlocked(){return hasUpgrade("p",104)||player.i.points.gte(1)},
|
||||||
display: `<div v-frag>
|
display: `
|
||||||
<div style="color: red; font-size: 32px; font-family: Comic Sans MS">{{ format(player.p.buyables[21]) }} pointy points</div>
|
<div style="color: red; font-size: 32px; font-family: Comic Sans MS">{{ format(player.p.buyables[21]) }} pointy points</div>
|
||||||
<div style="color: red; font-size: 32px; font-family: Comic Sans MS">My pointy points are multiplying generator efficiency by {{ format(new Decimal(player.p.buyables[21]).plus(1)) }}</div>
|
<div style="color: red; font-size: 32px; font-family: Comic Sans MS">My pointy points are multiplying generator efficiency by {{ format(new Decimal(player.p.buyables[21]).plus(1)) }}</div>
|
||||||
<spacer />
|
<spacer />
|
||||||
|
@ -932,15 +928,13 @@ challenges:{
|
||||||
<spacer />
|
<spacer />
|
||||||
<spacer />
|
<spacer />
|
||||||
<div v-if="hasMilestone('p', 11)" style="font-size: 24px">Booster upgrades</div>
|
<div v-if="hasMilestone('p', 11)" style="font-size: 24px">Booster upgrades</div>
|
||||||
<upgrades :upgrades="[231, 232, 233, 234, 235]" />
|
<upgrades :upgrades="[231, 232, 233, 234, 235]" />`
|
||||||
</div>`
|
|
||||||
},
|
},
|
||||||
"Buyables": {
|
"Buyables": {
|
||||||
unlocked(){return hasMilestone("p",13)},
|
unlocked(){return hasMilestone("p",13)},
|
||||||
display: `<div v-frag>
|
display: `
|
||||||
<buyables :buyables="[31, 32, 33]" />
|
<buyables :buyables="[31, 32, 33]" />
|
||||||
<buyables :buyables="[41, 42, 43]" />
|
<buyables :buyables="[41, 42, 43]" />`
|
||||||
</div>`
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
|
import { computed } from 'vue';
|
||||||
import { hasUpgrade, upgradeEffect, hasMilestone, inChallenge, getBuyableAmount } from '../util/features';
|
import { hasUpgrade, upgradeEffect, hasMilestone, inChallenge, getBuyableAmount } from '../util/features';
|
||||||
import { layers } from '../store/layers';
|
import { layers } from '../game/layers';
|
||||||
import { player } from '../store/proxies';
|
import player from '../game/player';
|
||||||
import Decimal from '../util/bignum';
|
import Decimal from '../util/bignum';
|
||||||
import modInfo from './modInfo';
|
|
||||||
|
|
||||||
// Import initial layers
|
// Import initial layers
|
||||||
import f from './layers/aca/f.js';
|
import f from './layers/aca/f.js';
|
||||||
|
@ -40,7 +40,7 @@ const spook = {
|
||||||
|
|
||||||
const main = {
|
const main = {
|
||||||
id: 'main',
|
id: 'main',
|
||||||
display: `<div v-frag>
|
display: `
|
||||||
<div v-if="player.devSpeed === 0">Game Paused</div>
|
<div v-if="player.devSpeed === 0">Game Paused</div>
|
||||||
<div v-else-if="player.devSpeed && player.devSpeed !== 1">Dev Speed: {{ format(player.devSpeed) }}x</div>
|
<div v-else-if="player.devSpeed && player.devSpeed !== 1">Dev Speed: {{ format(player.devSpeed) }}x</div>
|
||||||
<div v-if="player.offTime != undefined">Offline Time: {{ formatTime(player.offTime.remain) }}</div>
|
<div v-if="player.offTime != undefined">Offline Time: {{ formatTime(player.offTime.remain) }}</div>
|
||||||
|
@ -49,12 +49,11 @@ const main = {
|
||||||
<h2>{{ format(player.points) }}</h2>
|
<h2>{{ format(player.points) }}</h2>
|
||||||
<span v-if="player.points.lt('1e1e6')"> points</span>
|
<span v-if="player.points.lt('1e1e6')"> points</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="Decimal.gt($store.getters.pointGain, 0)">
|
<div v-if="Decimal.gt(pointGain, 0)">
|
||||||
({{ player.oompsMag != 0 ? format(player.oomps) + " OOM" + (player.oompsMag < 0 ? "^OOM" : player.oompsMag > 1 ? "^" + player.oompsMag : "") + "s" : formatSmall($store.getters.pointGain) }}/sec)
|
({{ player.oompsMag != 0 ? format(player.oomps) + " OOM" + (player.oompsMag < 0 ? "^OOM" : player.oompsMag > 1 ? "^" + player.oompsMag : "") + "s" : formatSmall(pointGain) }}/sec)
|
||||||
</div>
|
</div>
|
||||||
<spacer />
|
<spacer />
|
||||||
<tree :append="true" />
|
<tree :append="true" />`,
|
||||||
</div>`,
|
|
||||||
name: "Tree"
|
name: "Tree"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,11 +65,11 @@ export function getStartingData() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getters = {
|
export const hasWon = computed(() => {
|
||||||
hasWon() {
|
|
||||||
return false;
|
return false;
|
||||||
},
|
});
|
||||||
pointGain() {
|
|
||||||
|
export const pointGain = computed(() => {
|
||||||
if(!hasUpgrade("c", 11))
|
if(!hasUpgrade("c", 11))
|
||||||
return new Decimal(0);
|
return new Decimal(0);
|
||||||
let gain = new Decimal(3.19)
|
let gain = new Decimal(3.19)
|
||||||
|
@ -110,8 +109,7 @@ export const getters = {
|
||||||
if (hasMilestone("p",13))gain=gain.times(layers.p.buyables[31].effect)
|
if (hasMilestone("p",13))gain=gain.times(layers.p.buyables[31].effect)
|
||||||
if (hasMilestone("p",13))gain=gain.pow(layers.p.buyables[42].effect)
|
if (hasMilestone("p",13))gain=gain.pow(layers.p.buyables[42].effect)
|
||||||
return gain;
|
return gain;
|
||||||
}
|
});
|
||||||
};
|
|
||||||
|
|
||||||
/* eslint-disable-next-line no-unused-vars */
|
/* eslint-disable-next-line no-unused-vars */
|
||||||
export function update(delta) {
|
export function update(delta) {
|
||||||
|
@ -120,5 +118,3 @@ export function update(delta) {
|
||||||
/* eslint-disable-next-line no-unused-vars */
|
/* eslint-disable-next-line no-unused-vars */
|
||||||
export function fixOldSave(oldVersion, playerData) {
|
export function fixOldSave(oldVersion, playerData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
document.title = modInfo.title;
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import { update as modUpdate } from '../data/mod';
|
import { update as modUpdate, hasWon, pointGain } from '../data/mod';
|
||||||
import Decimal from '../util/bignum';
|
import Decimal from '../util/bignum';
|
||||||
import modInfo from '../data/modInfo.json';
|
import modInfo from '../data/modInfo.json';
|
||||||
import store from './index';
|
|
||||||
import { layers } from './layers';
|
import { layers } from './layers';
|
||||||
import { player } from './proxies';
|
import player from './player';
|
||||||
|
|
||||||
function updatePopups(/* diff */) {
|
function updatePopups(/* diff */) {
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -104,7 +103,7 @@ function update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop here if the game is paused on the win screen
|
// Stop here if the game is paused on the win screen
|
||||||
if (store.getters.hasWon && !player.keepGoing) {
|
if (hasWon.value && !player.keepGoing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Stop here if the player had a NaN value
|
// Stop here if the player had a NaN value
|
||||||
|
@ -145,13 +144,13 @@ function update() {
|
||||||
}
|
}
|
||||||
player.timePlayed = player.timePlayed.add(diff);
|
player.timePlayed = player.timePlayed.add(diff);
|
||||||
if (player.points != undefined) {
|
if (player.points != undefined) {
|
||||||
player.points = player.points.add(Decimal.times(store.getters.pointGain, diff));
|
player.points = player.points.add(Decimal.times(pointGain.value, diff));
|
||||||
}
|
}
|
||||||
modUpdate(diff);
|
modUpdate(diff);
|
||||||
updateOOMPS(trueDiff);
|
updateOOMPS(trueDiff);
|
||||||
updateLayers(diff);
|
updateLayers(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function startGameLoop() {
|
export default function startGameLoop() {
|
||||||
setInterval(update, 50);
|
setInterval(update, 50);
|
||||||
}
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
import Vue from 'vue';
|
|
||||||
import clone from 'lodash.clonedeep';
|
import clone from 'lodash.clonedeep';
|
||||||
import { isFunction, isPlainObject } from '../util/common';
|
import { isFunction, isPlainObject } from '../util/common';
|
||||||
import { createProxy, createGridProxy, player as playerProxy } from './proxies';
|
import { createProxy, createGridProxy } from '../util/proxies';
|
||||||
|
import playerProxy from './player';
|
||||||
import Decimal from '../util/bignum';
|
import Decimal from '../util/bignum';
|
||||||
import store from './index';
|
|
||||||
import { noCache, getStartingBuyables, getStartingClickables, getStartingChallenges, defaultLayerProperties } from '../util/layers';
|
import { noCache, getStartingBuyables, getStartingClickables, getStartingChallenges, defaultLayerProperties } from '../util/layers';
|
||||||
import { applyPlayerData } from '../util/save';
|
import { applyPlayerData } from '../util/save';
|
||||||
|
import { isRef } from 'vue';
|
||||||
|
|
||||||
export const layers = {};
|
export const layers = {};
|
||||||
export const hotkeys = [];
|
export const hotkeys = [];
|
||||||
|
@ -49,11 +49,9 @@ export function addLayer(layer, player = null) {
|
||||||
layer.base = 2;
|
layer.base = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getters = {};
|
|
||||||
|
|
||||||
// Process each feature
|
// Process each feature
|
||||||
for (let property of uncachedProperties) {
|
for (let property of uncachedProperties) {
|
||||||
if (layer[property]) {
|
if (layer[property] && !isRef(layer.property)) {
|
||||||
layer[property].forceCached = false;
|
layer[property].forceCached = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -312,21 +310,20 @@ export function addLayer(layer, player = null) {
|
||||||
setDefault(layer.grids[id], 'hold', null, false);
|
setDefault(layer.grids[id], 'hold', null, false);
|
||||||
setDefault(layer.grids[id], 'getTitle', null, false);
|
setDefault(layer.grids[id], 'getTitle', null, false);
|
||||||
setDefault(layer.grids[id], 'getDisplay', null, false);
|
setDefault(layer.grids[id], 'getDisplay', null, false);
|
||||||
layer.grids[id] = createGridProxy(layer.grids[id], getters, `${layer.id}/grids-${id}-`);
|
layer.grids[id] = createGridProxy(layer.grids[id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (layer.subtabs) {
|
if (layer.subtabs) {
|
||||||
layer.activeSubtab = function() {
|
layer.activeSubtab = function() {
|
||||||
if (this.subtabs != undefined) {
|
if (layer.subtabs[playerProxy.subtabs[layer.id].mainTabs] &&
|
||||||
if (this.subtabs[player.subtabs[layer.id].mainTabs] &&
|
layer.subtabs[playerProxy.subtabs[layer.id].mainTabs].unlocked !== false) {
|
||||||
this.subtabs[player.subtabs[layer.id].mainTabs].unlocked !== false) {
|
return layer.subtabs[playerProxy.subtabs[layer.id].mainTabs];
|
||||||
return this.subtabs[player.subtabs[layer.id].mainTabs];
|
|
||||||
}
|
}
|
||||||
// Default to first unlocked tab
|
// Default to first unlocked tab
|
||||||
return Object.values(this.subtabs).find(subtab => subtab.unlocked !== false);
|
return Object.values(layer.subtabs).find(subtab => subtab.unlocked !== false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
setDefault(player, 'subtabs', {});
|
||||||
setDefault(player.subtabs, layer.id, {});
|
setDefault(player.subtabs, layer.id, {});
|
||||||
setDefault(player.subtabs[layer.id], 'mainTabs', Object.keys(layer.subtabs)[0]);
|
setDefault(player.subtabs[layer.id], 'mainTabs', Object.keys(layer.subtabs)[0]);
|
||||||
for (let id in layer.subtabs) {
|
for (let id in layer.subtabs) {
|
||||||
|
@ -338,16 +335,17 @@ export function addLayer(layer, player = null) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (layer.microtabs) {
|
if (layer.microtabs) {
|
||||||
|
setDefault(player, 'subtabs', {});
|
||||||
setDefault(player.subtabs, layer.id, {});
|
setDefault(player.subtabs, layer.id, {});
|
||||||
for (let family in layer.microtabs) {
|
for (let family in layer.microtabs) {
|
||||||
layer.microtabs[family].activeMicrotab = function() {
|
layer.microtabs[family].activeMicrotab = function() {
|
||||||
if (this[player.subtabs[this.layer]?.[family]] && this[player.subtabs[this.layer][family]].unlocked !== false) {
|
if (this[playerProxy.subtabs[this.layer][family]] && this[playerProxy.subtabs[this.layer][family]].unlocked !== false) {
|
||||||
return this[player.subtabs[this.layer][family]];
|
return this[playerProxy.subtabs[this.layer][family]];
|
||||||
}
|
}
|
||||||
// Default to first unlocked tab
|
// Default to first unlocked tab
|
||||||
return this[Object.keys(this).find(microtab => microtab !== 'activeMicrotab' && this[microtab].unlocked !== false)];
|
return this[Object.keys(this).find(microtab => microtab !== 'activeMicrotab' && this[microtab].unlocked !== false)];
|
||||||
}
|
}
|
||||||
setDefault(player.subtabs[layer.id], family, Object.keys(layer.microtabs[family])[0]);
|
setDefault(player.subtabs[layer.id], family, Object.keys(layer.microtabs[family]).find(tab => tab !== 'activeMicrotab'));
|
||||||
layer.microtabs[family].layer = layer.id;
|
layer.microtabs[family].layer = layer.id;
|
||||||
layer.microtabs[family].family = family;
|
layer.microtabs[family].family = family;
|
||||||
for (let id in layer.microtabs[family]) {
|
for (let id in layer.microtabs[family]) {
|
||||||
|
@ -356,7 +354,7 @@ export function addLayer(layer, player = null) {
|
||||||
layer.microtabs[family][id].family = family;
|
layer.microtabs[family][id].family = family;
|
||||||
layer.microtabs[family][id].id = id;
|
layer.microtabs[family][id].id = id;
|
||||||
layer.microtabs[family][id].active = function() {
|
layer.microtabs[family][id].active = function() {
|
||||||
return player.subtabs[this.layer]?.[this.family] === this.id;
|
return playerProxy.subtabs[this.layer][this.family] === this.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -374,11 +372,10 @@ export function addLayer(layer, player = null) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create layer proxy
|
// Create layer proxy
|
||||||
layer = createProxy(layer, getters, `${layer.id}/`);
|
layer = createProxy(layer);
|
||||||
|
|
||||||
// Register layer
|
// Register layer
|
||||||
layers[layer.id] = layer;
|
layers[layer.id] = layer;
|
||||||
store.registerModule(`layer-${layer.id}`, { getters });
|
|
||||||
|
|
||||||
// Register hotkeys
|
// Register hotkeys
|
||||||
if (layer.hotkeys) {
|
if (layer.hotkeys) {
|
||||||
|
@ -392,12 +389,11 @@ export function removeLayer(layer) {
|
||||||
// Un-set hotkeys
|
// Un-set hotkeys
|
||||||
if (layers[layer].hotkeys) {
|
if (layers[layer].hotkeys) {
|
||||||
for (let id in layers[layer].hotkeys) {
|
for (let id in layers[layer].hotkeys) {
|
||||||
Vue.delete(hotkeys, id);
|
delete hotkeys[id];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Un-register layer
|
delete layers[layer];
|
||||||
store.unregisterModule(`layer-${layer}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function reloadLayer(layer) {
|
export function reloadLayer(layer) {
|
52
src/game/player.js
Normal file
52
src/game/player.js
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
import { reactive } from 'vue';
|
||||||
|
import { isPlainObject } from '../util/common';
|
||||||
|
import Decimal from '../util/bignum';
|
||||||
|
|
||||||
|
const state = reactive({});
|
||||||
|
|
||||||
|
const playerHandler = {
|
||||||
|
get(target, key) {
|
||||||
|
if (key === '__state' || key === '__path') {
|
||||||
|
return target[key];
|
||||||
|
}
|
||||||
|
if (target.__state[key] == undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isPlainObject(target.__state[key]) && !(target.__state[key] instanceof Decimal)) {
|
||||||
|
if (target.__state[key] !== target[key]?.__state) {
|
||||||
|
const path = [ ...target.__path, key ];
|
||||||
|
target[key] = new Proxy({ __state: target.__state[key], __path: path }, playerHandler);
|
||||||
|
}
|
||||||
|
return target[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
return target.__state[key];
|
||||||
|
},
|
||||||
|
set(target, property, value, receiver) {
|
||||||
|
if (!state.hasNaN && ((typeof value === 'number' && isNaN(value)) || (value instanceof Decimal && (isNaN(value.sign) || isNaN(value.layer) || isNaN(value.mag))))) {
|
||||||
|
const currentValue = target.__state[property];
|
||||||
|
if (!((typeof currentValue === 'number' && isNaN(currentValue)) || (currentValue instanceof Decimal && (isNaN(currentValue.sign) || isNaN(currentValue.layer) || isNaN(currentValue.mag))))) {
|
||||||
|
state.autosave = false;
|
||||||
|
state.hasNaN = true;
|
||||||
|
state.NaNPath = [ ...target.__path, property ];
|
||||||
|
state.NaNReceiver = receiver;
|
||||||
|
console.error(`Attempted to set NaN value`, [ ...target.__path, property ], target.__state);
|
||||||
|
throw 'Attempted to set NaN value. See above for details';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
target.__state[property] = value;
|
||||||
|
if (property === 'points') {
|
||||||
|
if (target.__state.best != undefined) {
|
||||||
|
target.__state.best = Decimal.max(target.__state.best, value);
|
||||||
|
}
|
||||||
|
if (target.__state.total != undefined) {
|
||||||
|
const diff = Decimal.sub(value, target.__state.points);
|
||||||
|
if (diff.gt(0)) {
|
||||||
|
target.__state.total = target.__state.total.add(diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
export default window.player = new Proxy({ __state: state, __path: [ 'player' ] }, playerHandler);
|
|
@ -1,3 +1,7 @@
|
||||||
|
:root {
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
transition-duration: 0.5s;
|
transition-duration: 0.5s;
|
||||||
font-family: "Roboto Mono", monospace;
|
font-family: "Roboto Mono", monospace;
|
||||||
|
|
22
src/main.js
22
src/main.js
|
@ -1,24 +1,22 @@
|
||||||
import Vue from 'vue';
|
import { createApp } from 'vue';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
import store from './store';
|
|
||||||
import { load } from './util/save';
|
import { load } from './util/save';
|
||||||
import { setVue } from './util/vue';
|
import { setVue } from './util/vue';
|
||||||
import { startGameLoop } from './store/game';
|
import gameLoop from './game/gameLoop';
|
||||||
import './components/index';
|
import { registerComponents } from './components/index';
|
||||||
|
import modInfo from './data/modInfo.json';
|
||||||
// Setup
|
|
||||||
Vue.config.productionTip = false;
|
|
||||||
|
|
||||||
requestAnimationFrame(async () => {
|
requestAnimationFrame(async () => {
|
||||||
await load();
|
await load();
|
||||||
|
|
||||||
// Create Vue
|
// Create Vue
|
||||||
const vue = window.vue = new Vue({
|
const vue = window.vue = createApp({
|
||||||
store,
|
...App
|
||||||
render: h => h(App)
|
|
||||||
});
|
});
|
||||||
setVue(vue);
|
setVue(vue);
|
||||||
vue.$mount('#app');
|
registerComponents(vue);
|
||||||
|
vue.mount('#app');
|
||||||
|
document.title = modInfo.title;
|
||||||
|
|
||||||
startGameLoop();
|
gameLoop();
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
import Vue from 'vue'
|
|
||||||
import Vuex from 'vuex'
|
|
||||||
import { getInitialStore } from '../util/save';
|
|
||||||
import { getters } from '../data/mod';
|
|
||||||
|
|
||||||
Vue.use(Vuex);
|
|
||||||
|
|
||||||
export default new Vuex.Store({
|
|
||||||
state: getInitialStore(),
|
|
||||||
getters
|
|
||||||
});
|
|
|
@ -1,223 +0,0 @@
|
||||||
import { layers } from './layers';
|
|
||||||
import { isFunction, isPlainObject } from '../util/common';
|
|
||||||
import Decimal from '../util/bignum';
|
|
||||||
import store from './index';
|
|
||||||
import Vue from 'vue';
|
|
||||||
|
|
||||||
export const tmp = new Proxy({}, {
|
|
||||||
get(target, property) {
|
|
||||||
if (property in layers) {
|
|
||||||
return layers[property];
|
|
||||||
}
|
|
||||||
// TODO implement other tmp values for backwards compatibility
|
|
||||||
console.error(`No getter for "${property}"`, target);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const playerHandler = {
|
|
||||||
get(target, key) {
|
|
||||||
if (key === 'isProxy') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target[key] == undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target[key].isProxy && !(target[key] instanceof Decimal) && (isPlainObject(target[key]) || Array.isArray(target[key]))) {
|
|
||||||
// Note that player isn't pre-created since it (shouldn't) have functions or getters
|
|
||||||
// so creating proxies as they're requested is A-OK
|
|
||||||
target[key] = new Proxy(target[key], playerHandler);
|
|
||||||
return target[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
return target[key];
|
|
||||||
},
|
|
||||||
set(target, property, value, receiver) {
|
|
||||||
if (!player.hasNaN && value instanceof Decimal && (isNaN(value.sign) || isNaN(value.layer) || isNaN(value.mag))) {
|
|
||||||
player.autosave = false;
|
|
||||||
player.hasNaN = true;
|
|
||||||
player.NaNProperty = property;
|
|
||||||
player.NaNReceiver = receiver;
|
|
||||||
player.NaNPrevious = target[property];
|
|
||||||
Vue.set(target, property, value);
|
|
||||||
console.error(`Attempted to set NaN value`, target, property);
|
|
||||||
throw 'Attempted to set NaN value. See above for details';
|
|
||||||
}
|
|
||||||
Vue.set(target, property, value);
|
|
||||||
if (property === 'points') {
|
|
||||||
if (target.best != undefined) {
|
|
||||||
target.best = Decimal.max(target.best, value);
|
|
||||||
}
|
|
||||||
if (target.total != undefined) {
|
|
||||||
const diff = Decimal.sub(value, target.points);
|
|
||||||
if (diff.gt(0)) {
|
|
||||||
target.total = target.total.add(diff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
deleteProperty(target, prop) {
|
|
||||||
Vue.delete(target, prop);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
export const player = window.player = new Proxy(store.state, playerHandler);
|
|
||||||
|
|
||||||
export function createProxy(object, getters, prefix) {
|
|
||||||
if (object.isProxy) {
|
|
||||||
console.warn("Creating a proxy out of a proxy! This may cause unintentional function calls and stack overflows.");
|
|
||||||
}
|
|
||||||
const objectProxy = new Proxy(object, getHandler(prefix));
|
|
||||||
travel(createProxy, object, objectProxy, getters, prefix);
|
|
||||||
return objectProxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO cache grid values? Currently they'll be calculated every render they're visible
|
|
||||||
export function createGridProxy(object, getters, prefix) {
|
|
||||||
if (object.isProxy) {
|
|
||||||
console.warn("Creating a proxy out of a proxy! This may cause unintentional function calls and stack overflows.");
|
|
||||||
}
|
|
||||||
const objectProxy = new Proxy(object, getGridHandler(prefix));
|
|
||||||
travel(createGridProxy, object, objectProxy, getters, prefix);
|
|
||||||
return objectProxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
function travel(callback, object, objectProxy, getters, prefix) {
|
|
||||||
for (let key in object) {
|
|
||||||
if (object[key].isProxy) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (isFunction(object[key])) {
|
|
||||||
if ((object[key].length !== 0 && object[key].forceCached !== true) || object[key].forceCached === false) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
getters[`${prefix}${key}`] = () => {
|
|
||||||
return object[key].call(objectProxy);
|
|
||||||
}
|
|
||||||
} else if ((isPlainObject(object[key]) || Array.isArray(object[key])) && !(object[key] instanceof Decimal)) {
|
|
||||||
object[key] = callback(object[key], getters, `${prefix}${key}-`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getHandler(prefix) {
|
|
||||||
return {
|
|
||||||
get(target, key, receiver) {
|
|
||||||
if (key === 'isProxy') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target[key] == undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target[key].isProxy || target[key] instanceof Decimal) {
|
|
||||||
return target[key];
|
|
||||||
} else if ((isPlainObject(target[key]) || Array.isArray(target[key])) && key.slice(0, 2) !== '__') {
|
|
||||||
console.warn("Creating proxy outside `createProxy`. This may cause issues when calling proxied functions.",
|
|
||||||
target, key);
|
|
||||||
target[key] = new Proxy(target[key], getHandler(`${prefix}${key}-`));
|
|
||||||
return target[key];
|
|
||||||
} else if (isFunction(target[key])) {
|
|
||||||
const getterID = `${prefix}${key}`;
|
|
||||||
if (getterID in store.getters) {
|
|
||||||
return store.getters[getterID];
|
|
||||||
} else {
|
|
||||||
return target[key].bind(receiver);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return target[key];
|
|
||||||
},
|
|
||||||
set(target, key, value, receiver) {
|
|
||||||
if (`${key}Set` in target && isFunction(target[`${key}Set`]) && target[`${key}Set`].length < 2) {
|
|
||||||
target[`${key}Set`].call(receiver, value);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
console.warn(`No setter for "${key}".`, target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function getGridHandler(prefix) {
|
|
||||||
return {
|
|
||||||
get(target, key) {
|
|
||||||
if (key === 'isProxy') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target[key] && (target[key].isProxy || target[key] instanceof Decimal)) {
|
|
||||||
return target[key];
|
|
||||||
} else if (isPlainObject(target[key]) || Array.isArray(target[key])) {
|
|
||||||
console.warn("Creating proxy outside `createProxy`. This may cause issues when calling proxied functions.",
|
|
||||||
target, key);
|
|
||||||
target[key] = new Proxy(target[key], getHandler(`${prefix}${key}-`));
|
|
||||||
return target[key];
|
|
||||||
} else if (isFunction(target[key])) {
|
|
||||||
const getterID = `${prefix}${key}`;
|
|
||||||
if (getterID in store.getters) {
|
|
||||||
return store.getters[getterID];
|
|
||||||
}
|
|
||||||
// Non-cached functions are going to be cell-specific, so don't call them with the grid handler
|
|
||||||
}
|
|
||||||
if (typeof key !== 'symbol' && !isNaN(key)) {
|
|
||||||
target[key] = new Proxy(target, getCellHandler(key));
|
|
||||||
}
|
|
||||||
return target[key];
|
|
||||||
},
|
|
||||||
set(target, key, value, receiver) {
|
|
||||||
if (`${key}Set` in target && isFunction(target[`${key}Set`]) && target[`${key}Set`].length < 2) {
|
|
||||||
target[`${key}Set`].call(receiver, value);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
console.warn(`No setter for "${key}".`, target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCellHandler(id) {
|
|
||||||
return {
|
|
||||||
get(target, key, receiver) {
|
|
||||||
if (key === 'isProxy') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let prop = target[key];
|
|
||||||
|
|
||||||
if (isFunction(prop) && prop.forceCached === false) {
|
|
||||||
return () => prop.call(receiver, id, target.getData(id));
|
|
||||||
}
|
|
||||||
if (prop != undefined || key.slice == undefined) {
|
|
||||||
return prop;
|
|
||||||
}
|
|
||||||
|
|
||||||
key = key.slice(0, 1).toUpperCase() + key.slice(1);
|
|
||||||
prop = target[`get${key}`];
|
|
||||||
if (isFunction(prop)) {
|
|
||||||
return prop.call(receiver, id, target.getData(id));
|
|
||||||
} else if (prop != undefined) {
|
|
||||||
return prop;
|
|
||||||
}
|
|
||||||
|
|
||||||
prop = target[`on${key}`];
|
|
||||||
if (isFunction(prop)) {
|
|
||||||
return () => prop.call(receiver, id, target.getData(id));
|
|
||||||
} else if (prop != undefined) {
|
|
||||||
return prop;
|
|
||||||
}
|
|
||||||
|
|
||||||
return target[key];
|
|
||||||
},
|
|
||||||
set(target, key, value, receiver) {
|
|
||||||
if (`${key}Set` in target && isFunction(target[`${key}Set`]) && target[`${key}Set`].length < 3) {
|
|
||||||
target[`${key}Set`].call(receiver, id, value);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
console.warn(`No setter for "${key}".`, target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { layers } from '../store/layers';
|
import { layers } from '../game/layers';
|
||||||
|
|
||||||
export function hasUpgrade(layer, id) {
|
export function hasUpgrade(layer, id) {
|
||||||
return layers[layer]?.upgrades?.[id]?.bought;
|
return layers[layer]?.upgrades?.[id]?.bought;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import Decimal from './bignum';
|
import Decimal from './bignum';
|
||||||
import { isPlainObject } from './common';
|
import { isPlainObject } from './common';
|
||||||
import { layers, hotkeys } from '../store/layers';
|
import { layers, hotkeys } from '../game/layers';
|
||||||
import { player } from '../store/proxies';
|
import player from '../game/player';
|
||||||
|
|
||||||
export function resetLayer(layer, force = false) {
|
export function resetLayer(layer, force = false) {
|
||||||
layers[layer].reset(force);
|
layers[layer].reset(force);
|
||||||
|
@ -72,7 +72,6 @@ export function resetLayerData(layer, keep = []) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resetRow(row, ignore) {
|
export function resetRow(row, ignore) {
|
||||||
console.log(row, ignore);
|
|
||||||
Object.values(layers).filter(layer => layer.row === row && layer.layer !== ignore).forEach(layer => layer.hardReset());
|
Object.values(layers).filter(layer => layer.row === row && layer.layer !== ignore).forEach(layer => layer.hardReset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
149
src/util/proxies.js
Normal file
149
src/util/proxies.js
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
import { isFunction, isPlainObject } from './common';
|
||||||
|
import Decimal from './bignum';
|
||||||
|
import { isRef, computed } from 'vue';
|
||||||
|
|
||||||
|
export function createProxy(object) {
|
||||||
|
if (object.isProxy) {
|
||||||
|
console.warn("Creating a proxy out of a proxy! This may cause unintentional function calls and stack overflows.");
|
||||||
|
}
|
||||||
|
const objectProxy = new Proxy(object, mainHandler);
|
||||||
|
travel(createProxy, object, objectProxy);
|
||||||
|
return objectProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO cache grid values? Currently they'll be calculated every render they're visible
|
||||||
|
export function createGridProxy(object) {
|
||||||
|
if (object.isProxy) {
|
||||||
|
console.warn("Creating a proxy out of a proxy! This may cause unintentional function calls and stack overflows.");
|
||||||
|
}
|
||||||
|
const objectProxy = new Proxy(object, gridHandler);
|
||||||
|
travel(createGridProxy, object, objectProxy);
|
||||||
|
return objectProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
function travel(callback, object, objectProxy) {
|
||||||
|
for (let key in object) {
|
||||||
|
if (object[key].isProxy) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (isFunction(object[key])) {
|
||||||
|
if ((object[key].length !== 0 && object[key].forceCached !== true) || object[key].forceCached === false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
object[key] = computed(object[key].bind(objectProxy));
|
||||||
|
} else if ((isPlainObject(object[key]) || Array.isArray(object[key])) && !(object[key] instanceof Decimal)) {
|
||||||
|
object[key] = callback(object[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mainHandler = {
|
||||||
|
get(target, key, receiver) {
|
||||||
|
if (key === 'isProxy') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target[key] == undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isRef(target[key])) {
|
||||||
|
return target[key].value;
|
||||||
|
} else if (target[key].isProxy || target[key] instanceof Decimal) {
|
||||||
|
return target[key];
|
||||||
|
} else if ((isPlainObject(target[key]) || Array.isArray(target[key])) && key.slice(0, 2) !== '__') {
|
||||||
|
console.warn("Creating proxy outside `createProxy`. This may cause issues when calling proxied functions.",
|
||||||
|
target, key);
|
||||||
|
target[key] = new Proxy(target[key], mainHandler);
|
||||||
|
return target[key];
|
||||||
|
} else if (isFunction(target[key])) {
|
||||||
|
return target[key].bind(receiver);
|
||||||
|
}
|
||||||
|
return target[key];
|
||||||
|
},
|
||||||
|
set(target, key, value, receiver) {
|
||||||
|
if (`${key}Set` in target && isFunction(target[`${key}Set`]) && target[`${key}Set`].length < 2) {
|
||||||
|
target[`${key}Set`].call(receiver, value);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
console.warn(`No setter for "${key}".`, target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const gridHandler = {
|
||||||
|
get(target, key, receiver) {
|
||||||
|
if (key === 'isProxy') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isRef(target[key])) {
|
||||||
|
return target[key].value;
|
||||||
|
} else if (target[key] && (target[key].isProxy || target[key] instanceof Decimal)) {
|
||||||
|
return target[key];
|
||||||
|
} else if (isPlainObject(target[key]) || Array.isArray(target[key])) {
|
||||||
|
console.warn("Creating proxy outside `createProxy`. This may cause issues when calling proxied functions.",
|
||||||
|
target, key);
|
||||||
|
target[key] = new Proxy(target[key], mainHandler);
|
||||||
|
return target[key];
|
||||||
|
} else if (isFunction(target[key])) {
|
||||||
|
return target[key].bind(receiver);
|
||||||
|
}
|
||||||
|
if (typeof key !== 'symbol' && !isNaN(key)) {
|
||||||
|
target[key] = new Proxy(target, getCellHandler(key));
|
||||||
|
}
|
||||||
|
return target[key];
|
||||||
|
},
|
||||||
|
set(target, key, value, receiver) {
|
||||||
|
if (`${key}Set` in target && isFunction(target[`${key}Set`]) && target[`${key}Set`].length < 2) {
|
||||||
|
target[`${key}Set`].call(receiver, value);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
console.warn(`No setter for "${key}".`, target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function getCellHandler(id) {
|
||||||
|
return {
|
||||||
|
get(target, key, receiver) {
|
||||||
|
if (key === 'isProxy') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let prop = target[key];
|
||||||
|
|
||||||
|
if (isFunction(prop) && prop.forceCached === false) {
|
||||||
|
return () => prop.call(receiver, id, target.getData(id));
|
||||||
|
}
|
||||||
|
if (prop != undefined || key.slice == undefined) {
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = key.slice(0, 1).toUpperCase() + key.slice(1);
|
||||||
|
prop = target[`get${key}`];
|
||||||
|
if (isFunction(prop)) {
|
||||||
|
return prop.call(receiver, id, target.getData(id));
|
||||||
|
} else if (prop != undefined) {
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
prop = target[`on${key}`];
|
||||||
|
if (isFunction(prop)) {
|
||||||
|
return () => prop.call(receiver, id, target.getData(id));
|
||||||
|
} else if (prop != undefined) {
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
return target[key];
|
||||||
|
},
|
||||||
|
set(target, key, value, receiver) {
|
||||||
|
if (`${key}Set` in target && isFunction(target[`${key}Set`]) && target[`${key}Set`].length < 3) {
|
||||||
|
target[`${key}Set`].call(receiver, id, value);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
console.warn(`No setter for "${key}".`, target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
import modInfo from '../data/modInfo';
|
import modInfo from '../data/modInfo';
|
||||||
import { getStartingData, getInitialLayers, fixOldSave } from '../data/mod';
|
import { getStartingData, getInitialLayers, fixOldSave } from '../data/mod';
|
||||||
import { player } from '../store/proxies';
|
import player from '../game/player';
|
||||||
import Decimal from './bignum';
|
import Decimal from './bignum';
|
||||||
|
|
||||||
export const NOT_IMPORTING = false;
|
export const NOT_IMPORTING = false;
|
||||||
|
@ -32,9 +32,8 @@ export function getInitialStore(playerData = {}) {
|
||||||
|
|
||||||
// Values that don't get loaded/saved
|
// Values that don't get loaded/saved
|
||||||
hasNaN: false,
|
hasNaN: false,
|
||||||
NaNProperty: "",
|
NaNPath: [],
|
||||||
NaNReceiver: null,
|
NaNReceiver: null,
|
||||||
NaNPrevious: null,
|
|
||||||
importing: NOT_IMPORTING,
|
importing: NOT_IMPORTING,
|
||||||
saveToImport: "",
|
saveToImport: "",
|
||||||
saveToExport: ""
|
saveToExport: ""
|
||||||
|
@ -43,7 +42,7 @@ export function getInitialStore(playerData = {}) {
|
||||||
|
|
||||||
export function save() {
|
export function save() {
|
||||||
/* eslint-disable-next-line no-unused-vars */
|
/* eslint-disable-next-line no-unused-vars */
|
||||||
let { hasNaN, NaNProperty, NaNReceiver, NaNPrevious, importing, saveToImport, saveToExport, ...playerData } = player;
|
let { hasNaN, NaNPath, NaNReceiver, importing, saveToImport, saveToExport, ...playerData } = player.__state;
|
||||||
player.saveToExport = btoa(unescape(encodeURIComponent(JSON.stringify(playerData))));
|
player.saveToExport = btoa(unescape(encodeURIComponent(JSON.stringify(playerData))));
|
||||||
|
|
||||||
localStorage.setItem(player.id, player.saveToExport);
|
localStorage.setItem(player.id, player.saveToExport);
|
||||||
|
@ -67,6 +66,7 @@ export async function load() {
|
||||||
await loadSave(newSave());
|
await loadSave(newSave());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
playerData.id = modData.active;
|
||||||
await loadSave(playerData);
|
await loadSave(playerData);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await loadSave(newSave());
|
await loadSave(newSave());
|
||||||
|
@ -99,7 +99,7 @@ export function getUniqueID() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadSave(playerData) {
|
export async function loadSave(playerData) {
|
||||||
const { layers, removeLayer, addLayer } = await import('../store/layers');
|
const { layers, removeLayer, addLayer } = await import('../game/layers');
|
||||||
|
|
||||||
for (let layer in layers) {
|
for (let layer in layers) {
|
||||||
removeLayer(layer);
|
removeLayer(layer);
|
||||||
|
@ -119,7 +119,7 @@ export async function loadSave(playerData) {
|
||||||
|
|
||||||
Object.assign(player, playerData);
|
Object.assign(player, playerData);
|
||||||
for (let prop in player) {
|
for (let prop in player) {
|
||||||
if (!(prop in playerData) && !(prop in layers)) {
|
if (!(prop in playerData) && !(prop in layers) && prop !== '__state' && prop !== '__path') {
|
||||||
delete player[prop];
|
delete player[prop];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,3 +157,4 @@ window.onbeforeunload = () => {
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
window.save = save;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { player } from '../store/proxies';
|
import player from '../game/player';
|
||||||
import { layers } from '../store/layers';
|
import { layers } from '../game/layers';
|
||||||
|
import { hasWon, pointGain } from '../data/mod';
|
||||||
import { hasUpgrade, hasMilestone, hasAchievement, hasChallenge, maxedChallenge, challengeCompletions, inChallenge, getBuyableAmount, setBuyableAmount, getClickableState, setClickableState, getGridData, setGridData, upgradeEffect, challengeEffect, buyableEffect, clickableEffect, achievementEffect, gridEffect } from './features';
|
import { hasUpgrade, hasMilestone, hasAchievement, hasChallenge, maxedChallenge, challengeCompletions, inChallenge, getBuyableAmount, setBuyableAmount, getClickableState, setClickableState, getGridData, setGridData, upgradeEffect, challengeEffect, buyableEffect, clickableEffect, achievementEffect, gridEffect } from './features';
|
||||||
import Decimal, * as numberUtils from './bignum';
|
import Decimal, * as numberUtils from './bignum';
|
||||||
|
|
||||||
|
@ -9,12 +10,8 @@ export function setVue(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass in various data that the template could potentially use
|
// Pass in various data that the template could potentially use
|
||||||
const computed = {
|
|
||||||
player() { return player; },
|
|
||||||
layers() { return layers; }
|
|
||||||
};
|
|
||||||
const data = function() {
|
const data = function() {
|
||||||
return { Decimal, ...numberUtils };
|
return { Decimal, player, layers, hasWon, pointGain, ...numberUtils };
|
||||||
}
|
}
|
||||||
export function coerceComponent(component, defaultWrapper = 'span') {
|
export function coerceComponent(component, defaultWrapper = 'span') {
|
||||||
if (typeof component === 'number') {
|
if (typeof component === 'number') {
|
||||||
|
@ -22,12 +19,12 @@ export function coerceComponent(component, defaultWrapper = 'span') {
|
||||||
}
|
}
|
||||||
if (typeof component === 'string') {
|
if (typeof component === 'string') {
|
||||||
component = component.trim();
|
component = component.trim();
|
||||||
if (!(component in vue.$options.components)) {
|
if (!(component in vue._context.components)) {
|
||||||
if (component.charAt(0) !== '<') {
|
if (component.charAt(0) !== '<') {
|
||||||
component = `<${defaultWrapper}>${component}</${defaultWrapper}>`;
|
component = `<${defaultWrapper}>${component}</${defaultWrapper}>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { template: component, computed, data, inject: [ 'tab' ], methods: { hasUpgrade, hasMilestone, hasAchievement, hasChallenge, maxedChallenge, challengeCompletions, inChallenge, getBuyableAmount, setBuyableAmount, getClickableState, setClickableState, getGridData, setGridData, upgradeEffect, challengeEffect, buyableEffect, clickableEffect, achievementEffect, gridEffect } };
|
return { template: component, data, inject: [ 'tab' ], methods: { hasUpgrade, hasMilestone, hasAchievement, hasChallenge, maxedChallenge, challengeCompletions, inChallenge, getBuyableAmount, setBuyableAmount, getClickableState, setClickableState, getGridData, setGridData, upgradeEffect, challengeEffect, buyableEffect, clickableEffect, achievementEffect, gridEffect } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return component;
|
return component;
|
||||||
|
@ -46,6 +43,13 @@ export function getFiltered(objects, filter = null) {
|
||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function mapState(properties = []) {
|
||||||
|
return properties.reduce((acc, curr) => {
|
||||||
|
acc[curr] = () => player[curr];
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
export const UP = 'UP';
|
export const UP = 'UP';
|
||||||
export const DOWN = 'DOWN';
|
export const DOWN = 'DOWN';
|
||||||
export const LEFT = 'LEFT';
|
export const LEFT = 'LEFT';
|
||||||
|
|
Loading…
Reference in a new issue