feat: improved missions UI and more sophisticated unlock options

This commit is contained in:
pskfyi 2022-01-10 21:48:15 -08:00 committed by John McCardle
parent e65587bbb7
commit 4f0b3c7741
4 changed files with 196 additions and 40 deletions

View File

@ -0,0 +1,20 @@
<template>
<div class="rounded-lg border text-center py-1">
{{ mission.name }}
</div>
</template>
<script>
export default {
props: {
mission: { type: Object, required: true },
},
}
</script>
<style scoped>
div {
border-color: currentColor;
background-color: rgba(0, 0, 0, 0.1);
}
</style>

View File

@ -4,8 +4,8 @@
:description="mission.description" :description="mission.description"
:max="max" :max="max"
:value="value" :value="value"
:unit="unit" :unit="mission.completionCriteria.unit"
@click="complete" @click="$emit('click')"
/> />
</template> </template>
@ -16,22 +16,21 @@ export default {
}, },
computed: { computed: {
value() { value() {
return 'cost' in this.mission.completionCriteria const { unit } = this.mission.completionCriteria
? this.$store.state.currency
: this.$store.state.playerAge if (unit === 'maxAge') {
return this.$store.state.playerAge
} else if (unit === 'spareTime') {
return this.$store.state.currency
} else {
// (unit === 'apprenticeLevels')
return this.$store.getters.apprenticeLevels
}
}, },
max() { max() {
return 'cost' in this.mission.completionCriteria return this.mission.completionCriteria.unit === 'maxAge'
? this.mission.completionCriteria.cost ? this.$store.state.playerAgeMax
: this.$store.state.playerAgeMax : this.mission.completionCriteria.value
},
unit() {
return 'cost' in this.mission.completionCriteria ? 'spareTime' : 'age'
},
},
methods: {
complete() {
this.$store.commit('completeMission', this.mission)
}, },
}, },
} }

View File

@ -1,9 +1,80 @@
<template> <template>
<responsive-grid> <div class="missions grid">
<mission-button <responsive-grid
v-for="(mission, index) in $store.state.missions" v-if="incomplete.length"
:key="index" :class="
:mission="mission" completed.length &&
/> `pb-6 border-b-2 border-${$store.getters.activeTab.darkColor}`
</responsive-grid> "
>
<mission-button
v-for="(mission, index) in incomplete"
:key="index"
:mission="mission"
@click="complete(mission)"
/>
</responsive-grid>
<div
v-else
:class="
completed.length &&
`pt-6 pb-10 border-b-2 border-${$store.getters.activeTab.darkColor}`
"
>
<h3 class="text-center">No Missions Currently Available</h3>
</div>
<template v-if="completed.length">
<h2 class="pt-2 pb-2 text-center text-xl">Completed Missions</h2>
<responsive-grid min="1" mid="3" max="6">
<completed-mission
v-for="(mission, index) in completed"
:key="index"
:mission="mission"
/>
</responsive-grid>
</template>
</div>
</template> </template>
<script>
export default {
computed: {
unlocked() {
return this.$store.state.missions.filter(({ unlockCriteria }) => {
if (unlockCriteria.unit === 'instruments') {
return unlockCriteria.value <= this.$store.getters.instruments
} else if (unlockCriteria.unit === 'apprenticeLevels') {
return unlockCriteria.value <= this.$store.getters.apprenticeLevels
} else if (unlockCriteria.unit === 'missionsCompleted') {
return unlockCriteria.value.every((name) =>
this.$store.getters.missionIsCompleted(name)
)
} else if (unlockCriteria.unit === 'timeJumpsBackwards') {
return unlockCriteria.value <= this.$store.state.timeJumpsBackwards
} else {
return false
}
})
},
incomplete() {
return this.unlocked.filter((m) => !m.complete)
},
completed() {
return this.unlocked.filter((m) => m.complete)
},
},
methods: {
complete(mission) {
this.$store.commit('completeMission', mission.name)
},
},
}
</script>
<style scoped>
.missions {
grid-template-rows: minmax(0, 1fr) auto auto;
}
</style>

View File

@ -65,6 +65,7 @@ export const state = () => ({
instrument: 'Mechanical Clock', instrument: 'Mechanical Clock',
worker: 'Engineer', worker: 'Engineer',
unlocked: true,
cost: 10, cost: 10,
created: false, created: false,
@ -73,7 +74,7 @@ export const state = () => ({
baseReward: 5, // currency added when the bar is completed baseReward: 5, // currency added when the bar is completed
workerLevel: 0, // 0 = not hired; 1+ = hired workerLevel: 0, // 0 = not hired; 1+ = hired
nextWorkerCost: 25, // currency cost of next worker nextWorkerCost: 50, // currency cost of next worker
nextWorkerFactor: 1.5, // worker cost *= this factor after each purchase nextWorkerFactor: 1.5, // worker cost *= this factor after each purchase
unlockThreshold: { tech: null, currency: 0 }, unlockThreshold: { tech: null, currency: 0 },
@ -82,6 +83,8 @@ export const state = () => ({
instrument: 'Hourglass', instrument: 'Hourglass',
worker: 'Glassblower', worker: 'Glassblower',
unlocked: false,
minDateUnlocked: 1100 * 12,
cost: 100, cost: 100,
created: false, created: false,
@ -90,7 +93,7 @@ export const state = () => ({
baseReward: 35, baseReward: 35,
workerLevel: 0, workerLevel: 0,
nextWorkerCost: 200, nextWorkerCost: 250,
nextWorkerFactor: 1.6, nextWorkerFactor: 1.6,
unlockThreshold: { tech: null, currency: 10000 }, unlockThreshold: { tech: null, currency: 10000 },
@ -99,6 +102,8 @@ export const state = () => ({
instrument: 'Pocket Watch', instrument: 'Pocket Watch',
worker: 'Miniaturist', worker: 'Miniaturist',
unlocked: false,
minDateUnlocked: 1600 * 12,
cost: 1000, cost: 1000,
created: false, created: false,
@ -107,7 +112,7 @@ export const state = () => ({
baseReward: 80, baseReward: 80,
workerLevel: 0, workerLevel: 0,
nextWorkerCost: 2000, nextWorkerCost: 500,
nextWorkerFactor: 1.8, nextWorkerFactor: 1.8,
unlockThreshold: { tech: 0, currency: new Decimal(10e5) }, unlockThreshold: { tech: 0, currency: new Decimal(10e5) },
@ -124,12 +129,50 @@ export const state = () => ({
missions: [ missions: [
{ {
name: 'Create the Time Machine', name: 'Train an Apprentice',
description: 'Soon you will be able to control time itself.', description:
completionCriteria: { 'One man can only spend so much time staring at clocks each day. Hiring a second may make this easier.',
cost: 6000, unlockCriteria: {
unit: 'instruments',
value: 1,
}, },
available: true, completionCriteria: {
unit: 'apprenticeLevels',
value: 5,
},
unlocked: true,
viewed: false,
complete: false,
},
{
name: 'Study Time Magic',
description:
"As time ticks away you begin to ponder the mysteries of time's origins and possibilities.",
unlockCriteria: {
unit: 'apprenticeLevels',
value: 1,
},
completionCriteria: {
unit: 'spareTime',
value: 250,
},
unlocked: true,
viewed: false,
complete: false,
},
{
name: 'Create the Time Machine',
description:
'Your magnum opus. Soon you will be able to control time itself.',
unlockCriteria: {
unit: 'missionsCompleted',
value: ['Train an Apprentice', 'Study Time Magic'],
},
completionCriteria: {
unit: 'spareTime',
value: 1000,
},
unlocked: false,
viewed: false, viewed: false,
complete: false, complete: false,
}, },
@ -139,24 +182,27 @@ export const state = () => ({
'Your body seems to be failing you. ' + 'Your body seems to be failing you. ' +
'Write a book to pass your knowedge to your younger self through the time machine. ' + 'Write a book to pass your knowedge to your younger self through the time machine. ' +
"Now where's your pen...", "Now where's your pen...",
appearanceCriteria: { unlockCriteria: {
age: 100, unit: 'timeJumpsBackwards',
value: 1,
}, },
completionCriteria: { completionCriteria: {
maxAge: true, unit: 'maxAge',
}, },
available: true, unlocked: false,
viewed: false, viewed: false,
complete: false, complete: false,
}, },
], ],
gameDate: 1991 * 12,
playerAge: 34 * 12, gameDate: 1400 * 12,
playerAgeMax: 80 * 12, playerAge: 30 * 12,
playerAgeMax: 60 * 12,
playerLivedTotal: 0, playerLivedTotal: 0,
wisdomGained: 0, // wisdom gained so far on this run, not applied until player sends the book. wisdomGained: 0, // wisdom gained so far on this run, not applied until player sends the book.
wisdomApplied: 0, // wisdom from previous runs wisdomApplied: 0, // wisdom from previous runs
totalLifetimes: 1, totalLifetimes: 1,
timeJumpsBackwards: 0,
}) })
export const getters = { export const getters = {
@ -205,6 +251,22 @@ export const getters = {
return `${year}y${month}m` return `${year}y${month}m`
}, },
missionIsCompleted: (state) => (missionName) => {
const mission = state.missions.find((m) => m.name === missionName)
return mission && mission.complete
},
apprenticeLevels: (state) =>
state.processes.reduce(
(totalLevels, process) => (totalLevels += process.workerLevel),
0
),
instruments: (state) =>
state.processes.reduce(
(totalInstruments, process) =>
process.created ? totalInstruments + 1 : totalInstruments,
0
),
} }
export const mutations = { export const mutations = {
@ -229,10 +291,14 @@ export const mutations = {
setMissionViewed: (state, missionIndex) => { setMissionViewed: (state, missionIndex) => {
Vue.set(state.missions[missionIndex], 'viewed', true) Vue.set(state.missions[missionIndex], 'viewed', true)
}, },
completeMission: (state, mission) => { completeMission: (state, missionName) => {
const index = state.missions.findIndex((m) => m.name === mission.name) const index = state.missions.findIndex((m) => m.name === missionName)
Vue.set(state.missions[index], 'complete', true) Vue.set(state.missions[index], 'complete', true)
}, },
unlockMission: (state, missionName) => {
const index = state.missions.findIndex((m) => m.name === missionName)
Vue.set(state.missions[index], 'unlocked', true)
},
levelUpApprentice: (state, process) => { levelUpApprentice: (state, process) => {
if (process.nextWorkerCost > state.currency) { if (process.nextWorkerCost > state.currency) {
return return