feat: narrative modal and game flow draft 4
This commit is contained in:
parent
3f1a6140a2
commit
08951244ab
|
@ -0,0 +1,34 @@
|
||||||
|
/* eslint-disable vue/no-v-html */
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="backdrop absolute top-0 bottom-0 left-0 right-0 flex items-center justify-center"
|
||||||
|
@click.self="$store.commit('closeModal')"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="modal rounded-lg px-8 pt-8 pb-4 flex flex-col items-center bg-teal-100 text-teal-900"
|
||||||
|
>
|
||||||
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
|
<div class="" v-html="$store.state.modalText" />
|
||||||
|
<button
|
||||||
|
class="border bg-teal-900 text-teal-100 rounded-lg mt-4 px-8 py-2 font-bold"
|
||||||
|
@click="$store.commit('closeModal')"
|
||||||
|
>
|
||||||
|
OK
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.backdrop {
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
backdrop-filter: blur(2px);
|
||||||
|
}
|
||||||
|
.modal {
|
||||||
|
width: 22rem;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -28,6 +28,7 @@
|
||||||
<nuxt />
|
<nuxt />
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
<narrative-modal v-if="$store.state.modalIsOpen" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -43,10 +44,17 @@ export default {
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
if (this.$store.state.playerAge < this.$store.state.playerAgeMax)
|
if (this.$store.state.modalIsOpen || this.$store.state.gameStopped) return
|
||||||
|
|
||||||
|
if (this.$store.state.playerAge < this.$store.state.playerAgeMax) {
|
||||||
this.gametick()
|
this.gametick()
|
||||||
|
} else {
|
||||||
|
this.checkLossCondition()
|
||||||
|
}
|
||||||
}, 100)
|
}, 100)
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
|
if (this.$store.state.modalIsOpen || this.$store.state.gameStopped) return
|
||||||
|
|
||||||
if (this.$store.state.playerAge < this.$store.state.playerAgeMax)
|
if (this.$store.state.playerAge < this.$store.state.playerAgeMax)
|
||||||
this.$store.commit('tickGameDate')
|
this.$store.commit('tickGameDate')
|
||||||
}, 1000)
|
}, 1000)
|
||||||
|
@ -56,7 +64,7 @@ export default {
|
||||||
// Instruments tick
|
// Instruments tick
|
||||||
this.$store.state.processes
|
this.$store.state.processes
|
||||||
.filter((p) => p.created)
|
.filter((p) => p.created)
|
||||||
.forEach((process, index) => {
|
.forEach((process) => {
|
||||||
if (process.completion >= process.completionRequired) {
|
if (process.completion >= process.completionRequired) {
|
||||||
const reward = process.baseReward * (1 + process.workerLevel)
|
const reward = process.baseReward * (1 + process.workerLevel)
|
||||||
|
|
||||||
|
@ -75,6 +83,32 @@ export default {
|
||||||
this.$store.commit('tickEnergy')
|
this.$store.commit('tickEnergy')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
checkLossCondition() {
|
||||||
|
this.$store.commit('stopGame')
|
||||||
|
|
||||||
|
// End state
|
||||||
|
const lostTheGame =
|
||||||
|
this.$store.state.playerAge === this.$store.state.playerAgeMax &&
|
||||||
|
!this.$store.getters.isTabUnlocked('Time Machine')
|
||||||
|
|
||||||
|
if (lostTheGame) {
|
||||||
|
const message =
|
||||||
|
'You wasted your precious time your whole life with nothing to show for it.' +
|
||||||
|
'<br><br>' +
|
||||||
|
'You have lost the game. Reload the page and try again.'
|
||||||
|
|
||||||
|
this.$store.commit('openModal', message)
|
||||||
|
} else {
|
||||||
|
const message =
|
||||||
|
"You are too frail to continue. It's time to gather your knowledge into a book and " +
|
||||||
|
'send it, along with the time machine and your timekeeping instruments, to your younger self. ' +
|
||||||
|
'Hopefully they will know what to do with this valuable wisdom.' +
|
||||||
|
'<br><br>' +
|
||||||
|
'Go to the <b>Missions</b> tab to continue.'
|
||||||
|
|
||||||
|
this.$store.commit('openModal', message)
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -80,6 +80,15 @@ export default {
|
||||||
this.$store.commit('setPlayerAge', { year: 30 })
|
this.$store.commit('setPlayerAge', { year: 30 })
|
||||||
this.$store.commit('timeTravel', { year: 1400, era: 'Early Modern' })
|
this.$store.commit('timeTravel', { year: 1400, era: 'Early Modern' })
|
||||||
this.$store.commit('tickLifetime')
|
this.$store.commit('tickLifetime')
|
||||||
|
this.$store.commit('spendCurrency', this.$store.state.currency)
|
||||||
|
this.$store.commit('startGame')
|
||||||
|
|
||||||
|
const message =
|
||||||
|
'You are young-ish once again and back in the year 1400 with all your wisdom intact.' +
|
||||||
|
'<br><br>' +
|
||||||
|
'Continue to explore the eras and unlock the secrets of time.'
|
||||||
|
|
||||||
|
this.$store.commit('openModal', message)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mission.name === 'Live Forever') {
|
if (mission.name === 'Live Forever') {
|
||||||
|
|
|
@ -62,6 +62,7 @@ export default {
|
||||||
},
|
},
|
||||||
isEnabled(process) {
|
isEnabled(process) {
|
||||||
const isCurrentEra = process.unlockEra === this.$store.state.gameEra
|
const isCurrentEra = process.unlockEra === this.$store.state.gameEra
|
||||||
|
|
||||||
if (isCurrentEra) {
|
if (isCurrentEra) {
|
||||||
return false
|
return false
|
||||||
} else if (process.visited) {
|
} else if (process.visited) {
|
||||||
|
@ -78,9 +79,13 @@ export default {
|
||||||
const latestEraIndex = processes.map((p) => p.visited).lastIndexOf(true)
|
const latestEraIndex = processes.map((p) => p.visited).lastIndexOf(true)
|
||||||
const nextLatestEraIndex = latestEraIndex + 1
|
const nextLatestEraIndex = latestEraIndex + 1
|
||||||
|
|
||||||
|
const middleAges = this.$store.state.processes.find(
|
||||||
|
(p) => p.unlockEra === 'Middle Ages'
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
processIndex === nextEarliestEraIndex ||
|
processIndex === nextEarliestEraIndex ||
|
||||||
processIndex === nextLatestEraIndex
|
(middleAges.visited && processIndex === nextLatestEraIndex)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -91,13 +96,23 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
travelToEra(process) {
|
travelToEra(process) {
|
||||||
|
const hadBeenVisited = process.visited // save this before we time travel
|
||||||
|
|
||||||
this.$store.commit('spendEnergy', process.travelCost)
|
this.$store.commit('spendEnergy', process.travelCost)
|
||||||
this.$store.commit('timeTravel', {
|
this.$store.commit('timeTravel', {
|
||||||
era: process.unlockEra,
|
era: process.unlockEra,
|
||||||
month: process.minDateUnlocked,
|
month: process.minDateUnlocked,
|
||||||
})
|
})
|
||||||
if (process.unlockEra === 'Middle Ages') {
|
|
||||||
// do era-specific things
|
if (process.unlockEra === 'Middle Ages' && !hadBeenVisited) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const message =
|
||||||
|
'Congratulations! ' +
|
||||||
|
"You've successfully traveled through time and landed in the year 1100" +
|
||||||
|
'... though it was rather hard on your body.'
|
||||||
|
|
||||||
|
this.$store.commit('openModal', message)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -58,8 +58,15 @@ export const state = () => ({
|
||||||
unlocked: false,
|
unlocked: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
modalText:
|
||||||
|
'{{ Premise }}' +
|
||||||
|
'<br><br>' +
|
||||||
|
'{{ Click to generate <span class="fas fa-hourglass-half text-sm"></span> <b>Spare Time</b> }}',
|
||||||
|
modalIsOpen: true,
|
||||||
|
|
||||||
currency: new Decimal(10000),
|
gameStopped: false,
|
||||||
|
|
||||||
|
currency: new Decimal(0),
|
||||||
currencyTotal: new Decimal(0),
|
currencyTotal: new Decimal(0),
|
||||||
|
|
||||||
gameDate: 1400 * 12,
|
gameDate: 1400 * 12,
|
||||||
|
@ -387,7 +394,7 @@ export const state = () => ({
|
||||||
},
|
},
|
||||||
completionCriteria: {
|
completionCriteria: {
|
||||||
unit: 'spareTime',
|
unit: 'spareTime',
|
||||||
value: 1000,
|
value: 300,
|
||||||
},
|
},
|
||||||
unlocked: false,
|
unlocked: false,
|
||||||
viewed: false,
|
viewed: false,
|
||||||
|
@ -485,7 +492,7 @@ export const state = () => ({
|
||||||
],
|
],
|
||||||
|
|
||||||
// Time Machine
|
// Time Machine
|
||||||
energy: 599,
|
energy: 0,
|
||||||
energyMax: 600, // 60 seconds
|
energyMax: 600, // 60 seconds
|
||||||
fluxCapacitorLevel: 1,
|
fluxCapacitorLevel: 1,
|
||||||
nextFluxCapacitorCost: 500,
|
nextFluxCapacitorCost: 500,
|
||||||
|
@ -519,7 +526,7 @@ export const state = () => ({
|
||||||
],
|
],
|
||||||
|
|
||||||
// Time Magic
|
// Time Magic
|
||||||
mana: 99,
|
mana: 0,
|
||||||
manaMax: 100,
|
manaMax: 100,
|
||||||
philosophersStoneUnlocked: false,
|
philosophersStoneUnlocked: false,
|
||||||
|
|
||||||
|
@ -688,6 +695,27 @@ export const getters = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mutations = {
|
export const mutations = {
|
||||||
|
// UI
|
||||||
|
unlockTab: (state, title) => {
|
||||||
|
const index = state.tabs.findIndex((t) => t.title === title)
|
||||||
|
Vue.set(state.tabs[index], 'unlocked', true)
|
||||||
|
},
|
||||||
|
openModal: (state, text) => {
|
||||||
|
state.modalText = text
|
||||||
|
state.modalIsOpen = true
|
||||||
|
},
|
||||||
|
closeModal: (state) => {
|
||||||
|
state.modalIsOpen = false
|
||||||
|
state.modalText = ''
|
||||||
|
},
|
||||||
|
stopGame: (state) => {
|
||||||
|
state.gameStopped = true
|
||||||
|
},
|
||||||
|
startGame: (state) => {
|
||||||
|
state.gameStopped = false
|
||||||
|
},
|
||||||
|
|
||||||
|
// Currency
|
||||||
addCurrency: (state, value) => {
|
addCurrency: (state, value) => {
|
||||||
state.currency = Decimal.add(state.currency, value)
|
state.currency = Decimal.add(state.currency, value)
|
||||||
state.currencyTotal = Decimal.add(state.currencyTotal, value)
|
state.currencyTotal = Decimal.add(state.currencyTotal, value)
|
||||||
|
@ -696,10 +724,21 @@ export const mutations = {
|
||||||
value = Decimal.mul(value, -1)
|
value = Decimal.mul(value, -1)
|
||||||
state.currency = Decimal.add(state.currency, value)
|
state.currency = Decimal.add(state.currency, value)
|
||||||
},
|
},
|
||||||
unlockTab: (state, title) => {
|
|
||||||
const index = state.tabs.findIndex((t) => t.title === title)
|
// Dates
|
||||||
Vue.set(state.tabs[index], 'unlocked', true)
|
tickGameDate: (state) => {
|
||||||
|
state.gameDate += 1
|
||||||
|
state.playerAge += 1
|
||||||
|
if (!(state.playerAge % 12)) state.wisdomGained++
|
||||||
},
|
},
|
||||||
|
setPlayerAge: (state, { year, month = 0 }) => {
|
||||||
|
state.playerAge = year * 12 + month
|
||||||
|
},
|
||||||
|
tickLifetime: (state) => {
|
||||||
|
state.lifetimes += 1
|
||||||
|
},
|
||||||
|
|
||||||
|
// Instruments
|
||||||
createInstrument: (state, instrument) => {
|
createInstrument: (state, instrument) => {
|
||||||
const index = state.processes.findIndex((p) => p.instrument === instrument)
|
const index = state.processes.findIndex((p) => p.instrument === instrument)
|
||||||
Vue.set(state.processes[index], 'created', true)
|
Vue.set(state.processes[index], 'created', true)
|
||||||
|
@ -716,6 +755,23 @@ export const mutations = {
|
||||||
)
|
)
|
||||||
Vue.set(state.processes[index], 'completion', 0)
|
Vue.set(state.processes[index], 'completion', 0)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Apprentices
|
||||||
|
levelUpApprentice: (state, process) => {
|
||||||
|
if (process.nextWorkerCost > state.currency) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const index = state.processes.findIndex((p) => p.worker === process.worker)
|
||||||
|
state.currency = Decimal.subtract(state.currency, process.nextWorkerCost)
|
||||||
|
Vue.set(state.processes[index], 'workerLevel', process.workerLevel + 1)
|
||||||
|
Vue.set(
|
||||||
|
state.processes[index],
|
||||||
|
'nextWorkerCost',
|
||||||
|
Math.floor(process.nextWorkerCost * process.nextWorkerFactor)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
// Missions
|
||||||
setMissionAvailable: (state, missionIndex) => {
|
setMissionAvailable: (state, missionIndex) => {
|
||||||
Vue.set(state.missions[missionIndex], 'available', true)
|
Vue.set(state.missions[missionIndex], 'available', true)
|
||||||
},
|
},
|
||||||
|
@ -730,24 +786,8 @@ export const mutations = {
|
||||||
const index = state.missions.findIndex((m) => m.name === missionName)
|
const index = state.missions.findIndex((m) => m.name === missionName)
|
||||||
Vue.set(state.missions[index], 'unlocked', true)
|
Vue.set(state.missions[index], 'unlocked', true)
|
||||||
},
|
},
|
||||||
levelUpApprentice: (state, process) => {
|
|
||||||
if (process.nextWorkerCost > state.currency) {
|
// Time Machine
|
||||||
return
|
|
||||||
}
|
|
||||||
const index = state.processes.findIndex((p) => p.worker === process.worker)
|
|
||||||
state.currency = Decimal.subtract(state.currency, process.nextWorkerCost)
|
|
||||||
Vue.set(state.processes[index], 'workerLevel', process.workerLevel + 1)
|
|
||||||
Vue.set(
|
|
||||||
state.processes[index],
|
|
||||||
'nextWorkerCost',
|
|
||||||
Math.floor(process.nextWorkerCost * process.nextWorkerFactor)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
tickGameDate: (state) => {
|
|
||||||
state.gameDate += 1
|
|
||||||
state.playerAge += 1
|
|
||||||
if (!(state.playerAge % 12)) state.wisdomGained++
|
|
||||||
},
|
|
||||||
tickEnergy: (state) => {
|
tickEnergy: (state) => {
|
||||||
state.energy += 1
|
state.energy += 1
|
||||||
},
|
},
|
||||||
|
@ -759,7 +799,7 @@ export const mutations = {
|
||||||
upgradeMaxEnergy: (state) => {
|
upgradeMaxEnergy: (state) => {
|
||||||
state.energyMax += 200
|
state.energyMax += 200
|
||||||
state.fluxCapacitorLevel += 1
|
state.fluxCapacitorLevel += 1
|
||||||
state.nextFluxCapacitorCost *= 2
|
state.nextFluxCapacitorCost *= 10
|
||||||
},
|
},
|
||||||
unlockTimeMachineAction: (state, name) => {
|
unlockTimeMachineAction: (state, name) => {
|
||||||
const index = state.timeMachineActions.findIndex((t) => t.name === name)
|
const index = state.timeMachineActions.findIndex((t) => t.name === name)
|
||||||
|
@ -801,12 +841,6 @@ export const mutations = {
|
||||||
const processIndex = state.processes.findIndex((p) => p.unlockEra === era)
|
const processIndex = state.processes.findIndex((p) => p.unlockEra === era)
|
||||||
Vue.set(state.processes[processIndex], 'visited', true)
|
Vue.set(state.processes[processIndex], 'visited', true)
|
||||||
},
|
},
|
||||||
setPlayerAge: (state, { year, month = 0 }) => {
|
|
||||||
state.playerAge = year * 12 + month
|
|
||||||
},
|
|
||||||
tickLifetime: (state) => {
|
|
||||||
state.lifetimes += 1
|
|
||||||
},
|
|
||||||
|
|
||||||
// Time Magic
|
// Time Magic
|
||||||
unlockSpell: (state, name) => {
|
unlockSpell: (state, name) => {
|
||||||
|
|
Reference in New Issue