new experimental quest view

This commit is contained in:
2025-05-08 21:08:03 +02:00
parent 3c79074c4c
commit 20567be96d
6 changed files with 147 additions and 169 deletions
+52 -74
View File
@@ -100,41 +100,29 @@ export default defineComponent({
allAdventurers: {} as { [key: string]: Adventurer },
adventurers: {} as { [key: string]: Adventurer },
quests: {} as { [key: string]: { [key: string]: Quest } },
missives: {
F: {} as { [key: string]: Quest },
E: {} as { [key: string]: Quest },
D: {} as { [key: string]: Quest },
C: {} as { [key: string]: Quest },
B: {} as { [key: string]: Quest },
A: {} as { [key: string]: Quest },
S: {} as { [key: string]: Quest },
} as { [key: string]: { [key: string]: Quest } },
missives: [] as Array<Quest>,
}),
methods: {
async updateMissives() {
for (const missiveRank in this.missives) {
const rank = getFromString(missiveRank as QuestRank);
for (const missiveId in this.missives[rank.toString() as QuestRank]) {
const missive = this.missives[rank.toString()][missiveId];
for (const missive of this.missives) {
if (missive.adventurers.length <= 0) {
missive.progressPoints = 0;
continue;
}
if (missive.progressPoints >= missive.maxProgress) {
if (this.guild.autoFinishQuestsUpgrade.getRanksToAutoFinishQuestsIn().includes(rank)) {
this.finalizeQuest(missive);
continue;
}
continue;
}
for (const adventurerId in missive.adventurers) {
const adventurer = missive.adventurers[adventurerId];
const attack = adventurer.getAttack();
missive.progressPoints = Math.min(missive.progressPoints + attack, missive.maxProgress);
}
if (
missive.progressPoints >= missive.maxProgress
&& this.guild.autoFinishQuestsUpgrade.getRanksToAutoFinishQuestsIn().includes(missive.rank)
) {
this.finalizeQuest(missive);
}
}
},
async checkForNewRecruit(currentTimestamp: number) {
@@ -173,7 +161,10 @@ export default defineComponent({
adventurer.busy = false;
}
missive.adventurers = [];
delete this.missives[missive.rank.toString() as QuestRank][missive.id];
const missiveIndex = this.missives.indexOf(missive);
if (missiveIndex > -1) {
this.missives.splice(missiveIndex, 1);
}
},
getRandomQuest(rank: QuestRank): Quest | null {
const keys = Object.keys(this.quests[rank]);
@@ -183,11 +174,10 @@ export default defineComponent({
const randomIdString = keys[randomId] as string;
return getQuestWithRewards(questsForRank[randomIdString], this.guild.expModifier.getModifier(), this.guild.goldModifier.getModifier());
},
createMissive(questToAdd: Quest, rank: QuestRank) {
createMissive(questToAdd: Quest) {
const quest = JSON.parse(JSON.stringify(questToAdd));
const newId = Math.random().toString(16).slice(2).toString();
quest.id = newId;
this.missives[rank][newId] = quest;
quest.id = Math.random().toString(16).slice(2).toString();
this.missives.push(quest);
},
loadGame() {
const saveData = loadGame();
@@ -239,23 +229,20 @@ export default defineComponent({
}
this.adventurers = adventurers;
const missives = {} as { [key: string]: { [key: string]: Quest } };
for (const id in saveData.missives) {
const missiveRank = {} as { [key: string]: Quest }
for (const questId in saveData.missives[id]) {
const data = saveData.missives[id][questId];
const quest = new Quest(questId, getFromString(data.rank), data.title, data.text, data.maxProgress, data.expReward, data.goldReward);
if (Array.isArray(saveData.missives)) {
for (const data of saveData.missives) {
const quest = new Quest(data.id, getFromString(data.rank), data.title, data.text, data.maxProgress, data.expReward, data.goldReward);
quest.progressPoints = data.progressPoints;
if (data.adventurers.length > 0) {
quest.adventurers.push(this.adventurers[data.adventurers[0].id])
for (const adventurer of data.adventurers) {
const adventurerId = adventurer.id;
if (this.adventurers[adventurerId] == null) continue;
quest.adventurers.push(this.adventurers[adventurerId]);
}
missiveRank[questId] = quest;
}
missives[id] = missiveRank;
this.missives.push(quest)
}
}
this.missives = missives;
this.lastRecruitHandled = saveData.lastRecruitAction ?? 0;
@@ -284,7 +271,8 @@ export default defineComponent({
try {
this.screenWakeLock = await navigator.wakeLock.request("screen");
console.debug("Screen wake lock acquired");
} catch (e) {}
} catch (e) {
}
}, 1000);
console.debug("Loading game data")
@@ -326,7 +314,6 @@ export default defineComponent({
}));
}, 10 * 1000));
this.gameTickTask = Number(setInterval(() => {
this.updateMissives();
@@ -341,78 +328,64 @@ export default defineComponent({
if (Number(now) - Number(this.lastQuestGot.F) >= 12 * 1000) {
this.lastQuestGot.F = now;
const keys = Object.keys(this.missives[QuestRank.F]);
if (keys.length >= 5) return;
const currentQuestAmount = this.missives.filter(quest => quest.rank === QuestRank.F).length;
if (currentQuestAmount >= 5) return;
const quest = this.getRandomQuest(QuestRank.F);
if (quest !== null) {
this.createMissive(quest, QuestRank.F);
}
if (quest !== null) this.createMissive(quest);
}
if (this.guild.level < 2) return;
if (Number(now) - Number(this.lastQuestGot.E) >= 20 * 1000) {
this.lastQuestGot.E = now;
const keys = Object.keys(this.missives[QuestRank.E]);
if (keys.length >= 5) return;
const currentQuestAmount = this.missives.filter(quest => quest.rank === QuestRank.E).length;
if (currentQuestAmount >= 5) return;
const quest = this.getRandomQuest(QuestRank.E);
if (quest !== null) {
this.createMissive(quest, QuestRank.E);
}
if (quest !== null) this.createMissive(quest);
}
if (this.guild.level < 3) return;
if (Number(now) - Number(this.lastQuestGot.D) >= 50 * 1000) {
this.lastQuestGot.D = now;
const keys = Object.keys(this.missives[QuestRank.D]);
if (keys.length >= 5) return;
const currentQuestAmount = this.missives.filter(quest => quest.rank === QuestRank.D).length;
if (currentQuestAmount >= 5) return;
const quest = this.getRandomQuest(QuestRank.D);
if (quest !== null) {
this.createMissive(quest, QuestRank.D);
}
if (quest !== null) this.createMissive(quest);
}
if (this.guild.level < 4) return;
if (Number(now) - Number(this.lastQuestGot.C) >= 2 * 60 * 1000) {
this.lastQuestGot.C = now;
const keys = Object.keys(this.missives[QuestRank.C]);
if (keys.length >= 5) return;
const currentQuestAmount = this.missives.filter(quest => quest.rank === QuestRank.C).length;
if (currentQuestAmount >= 5) return;
const quest = this.getRandomQuest(QuestRank.C);
if (quest !== null) {
this.createMissive(quest, QuestRank.C);
}
if (quest !== null) this.createMissive(quest);
}
if (this.guild.level < 5) return;
if (Number(now) - Number(this.lastQuestGot.B) >= 2 * 60 * 1000) {
this.lastQuestGot.B = now;
const keys = Object.keys(this.missives[QuestRank.B]);
if (keys.length >= 5) return;
const currentQuestAmount = this.missives.filter(quest => quest.rank === QuestRank.B).length;
if (currentQuestAmount >= 5) return;
const quest = this.getRandomQuest(QuestRank.B);
if (quest !== null) {
this.createMissive(quest, QuestRank.B);
}
if (quest !== null) this.createMissive(quest);
}
if (this.guild.level < 6) return;
if (Number(now) - Number(this.lastQuestGot.A) >= 3 * 60 * 1000) {
this.lastQuestGot.A = now;
const keys = Object.keys(this.missives[QuestRank.A]);
if (keys.length >= 5) return;
const currentQuestAmount = this.missives.filter(quest => quest.rank === QuestRank.A).length;
if (currentQuestAmount >= 5) return;
const quest = this.getRandomQuest(QuestRank.A);
if (quest !== null) {
this.createMissive(quest, QuestRank.A);
}
if (quest !== null) this.createMissive(quest);
}
if (this.guild.level < 6) return;
if (Number(now) - Number(this.lastQuestGot.S) >= 5 * 60 * 1000) {
this.lastQuestGot.S = now;
const keys = Object.keys(this.missives[QuestRank.S]);
if (keys.length >= 5) return;
const currentQuestAmount = this.missives.filter(quest => quest.rank === QuestRank.S).length;
if (currentQuestAmount >= 5) return;
const quest = this.getRandomQuest(QuestRank.S);
if (quest !== null) {
this.createMissive(quest, QuestRank.S);
}
if (quest !== null) this.createMissive(quest);
}
}, 250));
@@ -504,6 +477,7 @@ nav {
width: 80px;
height: 80px;
}
.lds-ring div {
box-sizing: border-box;
display: block;
@@ -516,15 +490,19 @@ nav {
animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
border-color: #000 transparent transparent transparent;
}
.lds-ring div:nth-child(1) {
animation-delay: -0.45s;
}
.lds-ring div:nth-child(2) {
animation-delay: -0.3s;
}
.lds-ring div:nth-child(3) {
animation-delay: -0.15s;
}
@keyframes lds-ring {
0% {
transform: rotate(0deg);
+2 -2
View File
@@ -6,7 +6,7 @@ import {getFromString, QuestRank} from "@/classes/QuestRank";
export class GameData {
guild: Guild;
adventurers: { [key: string]: Adventurer };
missives: { [key: string]: { [key: string]: Quest } };
missives: Array<Quest>;
lastQuestGot: { [key: string]: null | number };
lastRecruitAction: null | number;
adventurerForHireId: string | null;
@@ -16,7 +16,7 @@ export class GameData {
) {
this.guild = data.guild ?? new Guild(1, 0);
this.adventurers = data.adventurers ?? {} as { [key: string]: Adventurer };
this.missives = data.missives ?? {} as { [key: string]: { [key: string]: Quest } };
this.missives = data.missives ?? [] as Array<Quest>;
this.lastQuestGot = data.lastQuestGot ?? {} as { [key: string]: null | number };
this.lastRecruitAction = data.lastRecruitAction ?? null;
this.adventurerForHireId = data.adventurerForHireId ?? null;
+12 -1
View File
@@ -7,12 +7,22 @@ export class Quest {
title: string;
text: string;
adventurers: Array<Adventurer>;
maxAdventurers: number;
progressPoints: number;
maxProgress: number;
expReward: number;
goldReward: number;
constructor(id: string, rank: QuestRank, title: string, text: string, maxProgress: number, expReward: number, goldReward: number) {
constructor(
id: string,
rank: QuestRank,
title: string,
text: string,
maxProgress: number,
expReward: number,
goldReward: number,
maxAdventurers: number = 1
) {
this.id = id;
this.rank = rank;
this.title = title;
@@ -22,6 +32,7 @@ export class Quest {
this.goldReward = goldReward;
this.progressPoints = 0;
this.adventurers = [];
this.maxAdventurers = maxAdventurers;
}
getPercentProgress(): number {
+11 -7
View File
@@ -59,27 +59,31 @@ h1 {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: start;
align-items: stretch;
justify-content: flex-start;
gap: 1rem;
padding-block: 0.5rem;
padding-inline: 40%;
padding-inline: 5rem;
overflow-x: auto;
scroll-snap-type: x mandatory;
width: max-content;
width: 100vw;
max-width: 100%;
}
@media(min-width: 800px) {
.missives-wrapper {
padding-inline: 1rem;
max-width: 100vw;
overflow-x: hidden;
}
.missives {
justify-content: center;
flex-wrap: wrap;
overflow-x: inherit;
display: grid;
padding-inline: 0;
max-width: 1200px;
grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
grid-auto-rows: auto;
gap: 1rem;
}
}
</style>
+22 -6
View File
@@ -12,6 +12,7 @@
<div class="drink-stain" v-if="drinkStain.exists">
<DrinkStain/>
</div>
<div class="rank">{{missive.rank}}</div>
<h2>{{ missive.title }}</h2>
<p>{{ missive.text }}</p>
<div class="slots">
@@ -36,7 +37,7 @@
</div>
<div class="progressWrap">
<span class="progress"></span>
<span class="percentage">{{ progressPercentage }}</span>
<span class="percentage">{{ `${progressPercentage.toFixed(2)}%` }}</span>
</div>
<h3>Rewards</h3>
<div class="rewards">
@@ -58,6 +59,11 @@ import Parchment from "@/components/misc/Parchment.vue";
export default defineComponent({
name: "QuestMissive",
components: {Parchment, WaterStain, DrinkStain, AdventurerComponent},
computed: {
progressPercentageValue(): string {
return `${this.missive.progressPoints / this.missive.maxProgress * 100}%`;
},
},
props: {
missive: {
type: Object as PropType<Quest | any>,
@@ -73,7 +79,7 @@ export default defineComponent({
},
data: () => {
return {
progressPercentage: "0%",
progressPercentage: 0,
stain: false,
drinkStain: {
exists: false,
@@ -85,8 +91,7 @@ export default defineComponent({
methods: {
updateProgress() {
if (this.missive === undefined) return;
const progress = (this.missive.progressPoints / this.missive.maxProgress * 100).toFixed(2);
this.progressPercentage = `${progress}%`;
this.progressPercentage = this.missive.progressPoints / this.missive.maxProgress * 100;
},
randomNumber(min: number, max: number) {
return Math.random() * (max - min) + min;
@@ -102,7 +107,7 @@ export default defineComponent({
}
},
watch: {
missive: {
"missive.progressPoints": {
handler() {
this.updateProgress();
},
@@ -121,6 +126,7 @@ export default defineComponent({
padding: 0.5rem;
position: relative;
scroll-snap-align: center;
margin: 0 auto;
.parchment {
position: absolute;
@@ -161,7 +167,7 @@ export default defineComponent({
left: 0;
height: 100%;
display: block;
width: v-bind(progressPercentage);
width: v-bind(progressPercentageValue);
background-color: rgba(0, 128, 0, 0.65);
transition: width 250ms linear;
}
@@ -178,6 +184,16 @@ export default defineComponent({
}
}
.rank {
position: absolute;
top: -0.5rem;
left: 0.25rem;
font-size: 3rem;
font-weight: bold;
color: #ab0707;
z-index: -1;
}
.rewards {
display: flex;
flex-direction: row;
+16 -47
View File
@@ -1,55 +1,18 @@
<template>
<section>
<QuestGroup
v-if="guild.level >= 7 && Object.keys(quests.S).length > 0"
:adventurers="adventurers"
:quests="quests.S"
:quests="quests.filter(quest => quest.progressPoints < quest.maxProgress)"
:finalizeQuest="finalizeQuest"
label="Rank S Quests"
label="Quests"
v-show="quests.filter(quest => quest.progressPoints < quest.maxProgress).length > 0"
/>
<QuestGroup
v-if="guild.level >= 6 && Object.keys(quests.A).length > 0"
:finalize-quest="finalizeQuest"
:adventurers="adventurers"
:quests="quests.A"
:finalizeQuest="finalizeQuest"
label="Rank A Quests"
/>
<QuestGroup
v-if="guild.level >= 5 && Object.keys(quests.B).length > 0"
:adventurers="adventurers"
:quests="quests.B"
:finalizeQuest="finalizeQuest"
label="Rank B Quests"
/>
<QuestGroup
v-if="guild.level >= 4 && Object.keys(quests.C).length > 0"
:adventurers="adventurers"
:quests="quests.C"
:finalizeQuest="finalizeQuest"
label="Rank C Quests"
/>
<QuestGroup
v-if="guild.level >= 3 && Object.keys(quests.D).length > 0"
:adventurers="adventurers"
:quests="quests.D"
:finalizeQuest="finalizeQuest"
label="Rank D Quests"
/>
<QuestGroup
v-if="guild.level >= 2 && Object.keys(quests.E).length > 0"
:adventurers="adventurers"
:quests="quests.E"
:finalizeQuest="finalizeQuest"
label="Rank E Quests"
/>
<QuestGroup
v-if="Object.keys(quests.F).length > 0"
:adventurers="adventurers"
:quests="quests.F"
:finalizeQuest="finalizeQuest"
label="Rank F Quests"
:quests="quests.filter(quest => quest.progressPoints >= quest.maxProgress)"
label="Completed Quests"
v-show="quests.filter(quest => quest.progressPoints >= quest.maxProgress).length > 0"
/>
</section>
</template>
@@ -76,7 +39,7 @@ export default defineComponent({
required: true,
},
quests: {
type: Object as PropType<{ [key: string]: Quest }>,
type: Object as PropType<Array<Quest>>,
required: true,
},
lastRecruitTime: {
@@ -98,13 +61,19 @@ export default defineComponent({
</script>
<style lang="scss" scoped>
.guild {
section {
display: flex;
flex-direction: column;
justify-content: center;
justify-content: flex-start;
align-items: center;
width: 100%;
padding-bottom: 0.5rem;
}
@media(min-width: 800px) {
section {
flex-direction: column-reverse;
}
}
</style>