Compare commits

...

5 Commits

10 changed files with 186 additions and 153 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "adventurers-guild",
"version": "0.3.0",
"version": "0.4.0",
"private": true,
"scripts": {
"dev": "vite",
+50 -4
View File
@@ -14,10 +14,10 @@ import {RouterLink, RouterView} from 'vue-router'</script>
:guild="guild"
:adventurers="adventurers"
:quests="missives"
:lastRecruitTime="lastRecruitHandled"
:adventurerForHire="adventurerForHire"
@finalizeQuest="finalizeQuest($event)"
@wipeSave="resetSave()"
@recruitActionTaken="lastRecruitHandled = Number(new Date())"
@recruitActionTaken="recruitAction($event)"
/>
</template>
@@ -27,9 +27,10 @@ import {Adventurer} from "@/classes/Adventurer";
import {getQuestWithRewards, Quest} from "@/classes/Quest";
import {Guild} from "@/classes/Guild";
import {getFromString, QuestRank} from "@/classes/QuestRank";
import {GameData, loadAvailableQuests, loadGame, saveGame} from "@/GameData";
import {GameData, loadAdventurersForHire, loadAvailableQuests, loadGame, saveGame} from "@/GameData";
import type {GuildUpgrade} from "@/classes/GuildUpgrade";
import {AdventurerCapacityUpgrade} from "@/classes/guildUpgrades/AdventurerCapacityUpgrade";
import {getNewAdventurerForHire} from "@/classes/Recruitment";
export default defineComponent({
name: "GuildView",
@@ -45,6 +46,8 @@ export default defineComponent({
F: null as null|number,
} as { [key: string]: null|number },
lastRecruitHandled: null as null|number,
adventurerForHire: null as Adventurer|null,
adventurersDatabase: {} as Array<Adventurer>,
adventurers: {} as { [key: string]: Adventurer },
quests: {} as { [key: string]: { [key: string]: Quest } },
missives: {
@@ -77,6 +80,28 @@ export default defineComponent({
}
},
async checkForNewRecruit(currentTimestamp: number) {
if (this.lastRecruitHandled === null) {
this.lastRecruitHandled = 0;
}
if (currentTimestamp - this.lastRecruitHandled >= 1000 * 60 * 30 && this.adventurerForHire === null) {
this.adventurerForHire = getNewAdventurerForHire(this.adventurersDatabase);
}
},
recruitAction(adventurer: Adventurer|null): void {
this.lastRecruitHandled = Number(new Date());
this.adventurerForHire = null;
if (adventurer === null) return;
this.adventurers[adventurer.id] = adventurer;
for (const id in this.adventurersDatabase) {
const databaseAdventurer = this.adventurersDatabase[id];
if (databaseAdventurer.id === adventurer.id) {
this.adventurersDatabase.splice(Number(id), 1);
break;
}
}
},
finalizeQuest(missive: Quest) {
missive.progressPoints = 0;
this.guild.gold += missive.goldReward;
@@ -134,6 +159,8 @@ export default defineComponent({
}
this.adventurers = adventurers;
const missives = {} as { [key: string]: { [key: string]: Quest } };
for (const id in saveData.missives) {
@@ -153,6 +180,21 @@ export default defineComponent({
this.missives = missives;
this.lastRecruitHandled = saveData.lastRecruitAction ?? 0;
if (Object.keys(this.adventurers).length <= 0) {
this.adventurerForHire = this.adventurersDatabase[0];
return;
}
if (saveData.currentlyForHireId !== null) {
for (const id in this.adventurersDatabase) {
const adventurer = this.adventurersDatabase[id];
if (adventurer.id === saveData.currentlyForHireId) {
this.adventurerForHire = adventurer;
return;
}
}
}
},
resetSave() {
if (!confirm("You are about to wipe your save file. Are you sure?")) return;
@@ -163,6 +205,7 @@ export default defineComponent({
async mounted() {
this.loadGame();
this.quests = await loadAvailableQuests();
this.adventurersDatabase = await loadAdventurersForHire(Object.keys(this.adventurers));
setInterval(() => {
saveGame(new GameData(
@@ -170,7 +213,8 @@ export default defineComponent({
this.adventurers,
this.missives,
this.lastQuestGot,
this.lastRecruitHandled
this.lastRecruitHandled,
this.adventurerForHire?.id ?? null
)
);
}, 10*1000)
@@ -180,6 +224,8 @@ export default defineComponent({
const now = Number(new Date());
this.checkForNewRecruit(now);
for (const id in this.lastQuestGot) {
const lastTime = this.lastQuestGot[getFromString(id as QuestRank)];
if (lastTime === null) this.lastQuestGot[getFromString(id as QuestRank)] = 0;
+10 -1
View File
@@ -9,13 +9,21 @@ export class GameData {
missives: { [key: string]: { [key: string]: Quest } };
lastQuestGot: { [key: string]: null | number };
lastRecruitAction: null | number;
currentlyForHireId: string|null;
constructor(guild: Guild, adventurers: { [key: string]: Adventurer }, missives: { [key: string]: { [key: string]: Quest } }, lastQuestGot: { [key: string]: null | number }, lastRecruitAction: null | number) {
constructor(
guild: Guild, adventurers: { [key: string]: Adventurer },
missives: { [key: string]: { [key: string]: Quest } },
lastQuestGot: { [key: string]: null | number },
lastRecruitAction: null | number,
currentlyForHireId: string|null = null
) {
this.guild = guild;
this.adventurers = adventurers;
this.missives = missives;
this.lastQuestGot = lastQuestGot;
this.lastRecruitAction = lastRecruitAction;
this.currentlyForHireId = currentlyForHireId;
}
}
@@ -33,6 +41,7 @@ export function saveGame(
missives: data.missives,
lastQuestGot: data.lastQuestGot,
lastRecruitAction: data.lastRecruitAction,
adventurerForHireId: data.currentlyForHireId,
}));
}
+2 -1
View File
@@ -1,5 +1,6 @@
import type {GuildUpgrade} from "@/classes/GuildUpgrade";
import {AdventurerCapacityUpgrade} from "@/classes/guildUpgrades/AdventurerCapacityUpgrade";
import formatGold from "@/classes/NumberMagic";
export class Guild {
gold: number;
@@ -30,7 +31,7 @@ export class Guild {
} else {
const newCost = this.getUpgradeCost();
if (newCost === null) return;
this.displayUpgradeCost = newCost;
this.displayUpgradeCost = formatGold(newCost);
this.upgradeCost = newCost;
}
}
+10
View File
@@ -0,0 +1,10 @@
const formatter = new Intl.NumberFormat('en-US', {
maximumFractionDigits: 3,
// @ts-ignore - typescript doesn't know about this option for some godforsaken reason
notation: "compact",
useGrouping: true,
});
export default function formatGold(number: number): string {
return formatter.format(number);
}
+13
View File
@@ -0,0 +1,13 @@
import type {Adventurer} from "@/classes/Adventurer";
/**
* Get a random adventurer from the pool
* @param adventurerPool
* @returns {Adventurer|null} null if the pool is empty
*/
export function getNewAdventurerForHire(adventurerPool: Array<Adventurer>): Adventurer|null {
if (adventurerPool.length <= 0) return null;
const randomId = adventurerPool.length * Math.random() << 0;
return adventurerPool[randomId];
}
+3 -1
View File
@@ -8,7 +8,7 @@
:disabled="guild.gold < guild.adventurerCapacity.nextLevelCost"
@click="upgradeAdventurerCapacity()"
>
Upgrade ({{ guild.adventurerCapacity.nextLevelCost.toFixed(0) }} gold)
Upgrade ({{ formatGold(guild.adventurerCapacity.nextLevelCost) }} gold)
</button>
</div>
</section>
@@ -17,6 +17,7 @@
<script lang="ts">
import {Guild} from "@/classes/Guild";
import {defineComponent, type PropType} from "vue";
import formatGold from "../classes/NumberMagic";
export default defineComponent({
name: "UpgradesList",
@@ -30,6 +31,7 @@ export default defineComponent({
}
},
methods: {
formatGold,
upgradeAdventurerCapacity(): void {
if (!this.guild.adventurerCapacity) return;
if (!this.guild.adventurerCapacity.nextLevelCost) return;
+8 -59
View File
@@ -3,12 +3,12 @@
<section class="recruit panel pinned-paper">
<h1>Applying adventurers</h1>
<div class="adventurers">
<div v-if="currentlyForHire">
<adventurer-tile class="hire-tile" :adventurer="currentlyForHire"/>
<div v-if="adventurerForHire">
<adventurer-tile class="hire-tile" :adventurer="adventurerForHire"/>
<div class="decision">
<span
title="Hire"
@click="hireAdventurer(currentlyForHire)"
@click="hireAdventurer()"
:class="{disabled: Object.keys(adventurers).length >= guild.adventurerCapacity.getAdventurerCapacity()}"
>
@@ -73,76 +73,25 @@ export default defineComponent({
},
required: true,
},
lastRecruitTime: {
type: Number as PropType<number>,
adventurerForHire: {
type: Object as PropType<Adventurer|null>,
default() {
return 0;
return null;
}
},
},
methods: {
getRandomAdventurer(): Adventurer | null {
if (this.adventurersForHire.length <= 0) return null;
const randomId = this.adventurersForHire.length * Math.random() << 0;
return this.adventurersForHire[randomId];
},
getNewAdventurerForHire(): void {
const adventurer = this.getRandomAdventurer();
if (adventurer === null) {
this.currentlyForHire = null;
return;
}
if (this.adventurers[adventurer.id] != null) {
this.currentlyForHire = null;
return;
}
this.currentlyForHire = adventurer;
window.localStorage.setItem("currentlyForHire", adventurer.id);
},
hireAdventurer(adventurer: Adventurer | any): void {
hireAdventurer(): void {
if (Object.keys(this.adventurers).length >= this.guild.adventurerCapacity.getAdventurerCapacity()) return;
this.adventurers[adventurer.id] = adventurer;
this.currentlyForHire = null;
window.localStorage.removeItem("currentlyForHire");
this.$emit("recruitActionTaken", adventurer);
this.$emit("recruitActionTaken", this.adventurerForHire);
},
dismissAdventurer() {
if (Object.keys(this.adventurers).length <= 0) return;
this.currentlyForHire = null;
this.$emit("recruitActionTaken", null);
window.localStorage.removeItem("currentlyForHire");
}
},
async mounted() {
this.adventurersForHire = await loadAdventurersForHire(Object.keys(this.adventurers));
if (Object.keys(this.adventurers).length <= 0) {
this.currentlyForHire = this.adventurersForHire[0];
window.localStorage.setItem("currentlyForHire", this.adventurersForHire[0].id);
return;
}
const savedCurrentForHire = window.localStorage.getItem("currentlyForHire");
if (savedCurrentForHire !== null) {
for (const id in this.adventurersForHire) {
const adventurer = this.adventurersForHire[id];
if (adventurer.id === savedCurrentForHire) {
this.currentlyForHire = adventurer;
return;
}
}
}
const now = Number(new Date());
if (now - this.lastRecruitTime >= 1000 * 60 * 30 && this.currentlyForHire === null) {
this.getNewAdventurerForHire();
}
},
emits: ["recruitActionTaken"]
+3 -1
View File
@@ -13,7 +13,7 @@
<img src="/img/quests/overlays/nail.png" alt="" draggable="false"/>
</div>
<section class="coffer">
<p>Coffer: {{ guild.gold }} gold</p>
<p>Coffer: {{ formatGold(guild.gold) }} gold</p>
</section>
<section class="upgrade">
<p>Guild level: {{ guild.level }}</p>
@@ -40,9 +40,11 @@ import {Guild} from "@/classes/Guild";
import {version} from "../../package.json"
import UpgradesList from "@/components/UpgradesList.vue";
import formatGold from "../classes/NumberMagic";
export default defineComponent({
name: "GuildView",
methods: {formatGold},
components: {UpgradesList},
data: () => {
return {
+2 -1
View File
@@ -1,4 +1,5 @@
<template>
<section>
<div class="guild" v-if="guild.level >= 7 && Object.keys(quests.S).length > 0">
<h1>Rank S Quests</h1>
<section class="missives">
@@ -83,7 +84,7 @@
/>
</section>
</div>
</section>
</template>
<script lang="ts">