more balanced math,

adventurer max levels,
recruits duplicate protection
This commit is contained in:
2023-03-25 16:32:14 +01:00
parent c71eeda11f
commit b6e2a7e813
5 changed files with 55 additions and 32 deletions
+1 -14
View File
@@ -31,19 +31,6 @@ import {GameData, loadAvailableQuests, loadGame, saveGame} from "@/GameData";
export default defineComponent({ export default defineComponent({
name: "GuildView", name: "GuildView",
watch: {
adventurers: {
deep: true,
handler(newAdventurers) {
for (const adventurerId in newAdventurers) {
const adventurer = newAdventurers[adventurerId] as Adventurer;
if (adventurer.canLevelUp()) {
adventurer.levelUp();
}
}
}
}
},
data: () => ({ data: () => ({
guild: new Guild(1, 500), guild: new Guild(1, 500),
lastQuestGot: { lastQuestGot: {
@@ -129,7 +116,7 @@ export default defineComponent({
this.guild.gold += missive.goldReward; this.guild.gold += missive.goldReward;
for (const adventurerId in missive.adventurers) { for (const adventurerId in missive.adventurers) {
const adventurer = missive.adventurers[adventurerId]; const adventurer = missive.adventurers[adventurerId];
adventurer.exp += (missive.expReward / missive.adventurers.length); adventurer.addExp(missive.expReward / missive.adventurers.length);
adventurer.busy = false; adventurer.busy = false;
} }
missive.adventurers = []; missive.adventurers = [];
+38 -2
View File
@@ -5,6 +5,7 @@ export class Adventurer {
level: number; level: number;
exp: number; exp: number;
attackExponent: number; attackExponent: number;
prestige: number;
busy: boolean; busy: boolean;
constructor( constructor(
@@ -13,7 +14,8 @@ export class Adventurer {
portrait: string, portrait: string,
attackExponent: number, attackExponent: number,
level: number = 1, level: number = 1,
exp: number = 0 exp: number = 0,
prestige: number = 0
) { ) {
this.id = id; this.id = id;
this.name = name; this.name = name;
@@ -21,6 +23,7 @@ export class Adventurer {
this.attackExponent = attackExponent; this.attackExponent = attackExponent;
this.level = level; this.level = level;
this.exp = exp; this.exp = exp;
this.prestige = prestige;
this.busy = false; this.busy = false;
} }
@@ -29,10 +32,22 @@ export class Adventurer {
this.level += 1; this.level += 1;
} }
prestigeUp(): void {
this.level = 1;
this.exp = 0;
this.prestige += 1;
}
canLevelUp(): boolean { canLevelUp(): boolean {
if (this.level >= this.getMaxLevel()) return false;
return this.exp >= this.getNextLevelExpRequirement(); return this.exp >= this.getNextLevelExpRequirement();
} }
canPrestigeUp(): boolean {
if (this.level < getMaxLevelForPrestige(this.prestige)) return false;
return this.prestige < 5
}
getNextLevelExpRequirement(): number { getNextLevelExpRequirement(): number {
return this.level * 3; return this.level * 3;
} }
@@ -44,12 +59,33 @@ export class Adventurer {
return (this.exp / this.getNextLevelExpRequirement()) * 100; return (this.exp / this.getNextLevelExpRequirement()) * 100;
} }
addExp(exp: number): void {
if (this.isMaxLevel()) return;
this.exp += exp;
if (this.canLevelUp()) {
this.levelUp();
}
}
getAttack(): number { getAttack(): number {
return Math.floor(2 * this.level ^ this.attackExponent); const scalingFactor = Math.pow(1.05, this.level - 1);
return (2 * scalingFactor) * Math.pow(this.attackExponent, this.level - 1);
} }
getDPS(): number { getDPS(): number {
return this.getAttack() * 4; return this.getAttack() * 4;
} }
getMaxLevel(): number {
return getMaxLevelForPrestige(this.prestige);
}
isMaxLevel(): boolean {
return this.level >= this.getMaxLevel();
}
}
function getMaxLevelForPrestige(prestige: number): number {
return 25 + (prestige * 5);
} }
+13 -13
View File
@@ -40,28 +40,28 @@ export function getQuestWithRewards(quest: Quest) {
switch (quest.rank) { switch (quest.rank) {
case QuestRank.S: case QuestRank.S:
// at level 30 adventurers have ~2353 dps, this will take 30 seconds on level 30 // at level 30 adventurers have ~6513 dps, this will take 30 seconds on level 30
maxProgress = 70590 maxProgress = 195390;
break; break;
case QuestRank.A: case QuestRank.A:
// at level 25 adventurers have ~1122 dps, this will take 15 seconds on level 25 // at level 25 adventurers have ~2051 dps, this will take 15 seconds on level 25
maxProgress = 16800 maxProgress = 30770;
break; break;
case QuestRank.B: case QuestRank.B:
// at level 20 adventurers have ~564 dps, this will take 15 seconds on level 20 // at level 20 adventurers have ~645 dps, this will take 15 seconds on level 20
maxProgress = 8460; maxProgress = 9690;
break; break;
case QuestRank.C: case QuestRank.C:
// at level 15 adventurers have ~256 dps, this will take 15 seconds on level 15 // at level 15 adventurers have ~203 dps, this will take 15 seconds on level 15
maxProgress = 3840; maxProgress = 3045;
break; break;
case QuestRank.D: case QuestRank.D:
// at level 10 adventurers have ~103 dps, this will take 15 seconds on level 10 // at level 10 adventurers have ~64 dps, this will take 15 seconds on level 10
maxProgress = 1545; maxProgress = 960;
break; break;
case QuestRank.E: case QuestRank.E:
// at level 5 adventurers have ~45 dps, this will take 15 seconds on level 5 // at level 5 adventurers have ~20 dps, this will take 15 seconds on level 5
maxProgress = 675; maxProgress = 300;
break; break;
case QuestRank.F: case QuestRank.F:
// at level 1 adventurers have ~8 dps, this will take 15 seconds on level 1 // at level 1 adventurers have ~8 dps, this will take 15 seconds on level 1
@@ -74,7 +74,7 @@ export function getQuestWithRewards(quest: Quest) {
// add some randomness to the rewards // add some randomness to the rewards
goldReward = Math.floor(randomNumberBetween(goldReward * 0.95, goldReward * 1.1)); goldReward = Math.floor(randomNumberBetween(goldReward * 0.95, goldReward * 1.1));
expReward = Math.max(1, Math.floor(randomNumberBetween(expReward * 0.95, expReward * 1.1))); expReward = Math.max(1, Math.floor(randomNumberBetween(expReward * 0.95, expReward * 1.2)));
return new Quest(quest.id, quest.rank, quest.title, quest.text, maxProgress, expReward, goldReward); return new Quest(quest.id, quest.rank, quest.title, quest.text, maxProgress, expReward, goldReward);
} }
+1 -1
View File
@@ -4,7 +4,7 @@
:title="adventurer.name + (adventurer.busy ? ' (busy)' : '')" :title="adventurer.name + (adventurer.busy ? ' (busy)' : '')"
> >
<img :src="adventurer.portrait" :alt="adventurer.name" draggable="false"> <img :src="adventurer.portrait" :alt="adventurer.name" draggable="false">
<div class="level">{{adventurer.level}}</div> <div class="level" :title="adventurer.isMaxLevel() ? 'Max level' : ''">{{adventurer.level}}<span v-if="adventurer.isMaxLevel()"></span></div>
<div class="exp"></div> <div class="exp"></div>
</article> </article>
</template> </template>
+2 -2
View File
@@ -43,7 +43,7 @@
import type {PropType} from "vue"; import type {PropType} from "vue";
import {defineComponent} from "vue"; import {defineComponent} from "vue";
import AdventurerTile from "@/components/AdventurerTile.vue"; import AdventurerTile from "@/components/AdventurerTile.vue";
import {Adventurer} from "@/classes/Adventurer"; import type {Adventurer} from "@/classes/Adventurer";
import { loadAdventurersForHire } from "@/GameData"; import { loadAdventurersForHire } from "@/GameData";
export default defineComponent({ export default defineComponent({
@@ -106,7 +106,7 @@ export default defineComponent({
}, },
async mounted() { async mounted() {
this.adventurersForHire = await loadAdventurersForHire(); this.adventurersForHire = await loadAdventurersForHire(Object.keys(this.adventurers));
if (Object.keys(this.adventurers).length <= 0) { if (Object.keys(this.adventurers).length <= 0) {
this.currentlyForHire = this.adventurersForHire[0]; this.currentlyForHire = this.adventurersForHire[0];