diff --git a/src/create.ts b/src/create.ts index 7540afb..299f573 100644 --- a/src/create.ts +++ b/src/create.ts @@ -1,7 +1,7 @@ import buildings from "./data/buildings"; import { NAMES } from "./data/heroes"; import { Hex } from "./hexgrid"; -import type { BuildingSource, BuildingType, HeroType, QuestType, ResourcesType } from "./types"; +import type { BuildingSource, BuildingType, HeroType, QuestType, Resource } from "./types"; import { random, shuffle } from "./utils"; @@ -37,7 +37,7 @@ export function createBuilding(buildingType: string): BuildingType { } -export function createQuest(resource: keyof ResourcesType, level: number): QuestType { +export function createQuest(resource: Resource, level: number): QuestType { const adjustedLevel = Math.ceil((level * level + 3) / 3); const duration = Math.max(1, random(adjustedLevel - 2, adjustedLevel + 2)); const reward = Math.max(10, random( @@ -60,5 +60,8 @@ export function createHero(): HeroType { return { id: uid++, name: shuffle(NAMES)[0], + health: 100.0, + level: 1, + experience: 0, }; } diff --git a/src/data/buildings.ts b/src/data/buildings.ts index 2296435..2137a33 100644 --- a/src/data/buildings.ts +++ b/src/data/buildings.ts @@ -58,7 +58,7 @@ export default [ }, description: { short: '', - long: 'Increases the construction time of buildings by 2,5% per level, and unlocks new buildings.' + long: 'Reduces the construction time of buildings by 2,5% per level, and unlocks new buildings.' }, }, { diff --git a/src/hud/Hero.svelte b/src/hud/Hero.svelte new file mode 100644 index 0000000..6af84cf --- /dev/null +++ b/src/hud/Hero.svelte @@ -0,0 +1,41 @@ + + +
{ hero.name }
+Exp: { hero.experience } / { heroes.getExperienceNeeded(hero) }
+ +{ hero.name }
+{ unit.name }: { getRemainingUnitCount($village, unit.type) } / { unit.count }
diff --git a/src/modules/heroes.ts b/src/modules/heroes.ts new file mode 100644 index 0000000..2e7be43 --- /dev/null +++ b/src/modules/heroes.ts @@ -0,0 +1,79 @@ +import type { HeroType } from "../types"; +import type { VillageState } from "../village"; + + +const LEVELS = [ + 0, + 10, + 25, + 50, + 100, + 250, + 500, + 1000, + 2500, + 5000, + 10000, +]; + + +export function getHero(V: VillageState, heroId: number) { + const hero = V.heroes.find(h => h.id === heroId); + if (!hero) { + throw new Error(`Cannot find hero with id "${heroId}"`); + } + return hero; +} + + +export function getMaxHealth(hero: HeroType): number { + return 100.0 + (hero.level - 1) * 5.0; +} + + +export function hurt(hero: HeroType, damage: number) { + hero.health -= damage; + + if (hero.health <= 0) { + hero.health = 0.0; + + // Do something to show that the hero is dead. + } +} + + +export function heal(hero: HeroType, health: number) { + hero.health -= health; + + const maxHealth = getMaxHealth(hero); + if (hero.health > maxHealth) { + hero.health = maxHealth; + } +} + + +export function gainExperience(hero: HeroType, xp: number) { + hero.experience += xp; + + if (hero.experience >= LEVELS[hero.level]) { + hero.experience -= LEVELS[hero.level]; + + hero.level++; + hero.health = getMaxHealth(hero); + } +} + + +export function getExperienceNeeded(hero: HeroType) { + return LEVELS[hero.level]; +} + + +export default { + getHero, + getExperienceNeeded, + getMaxHealth, + heal, + hurt, + gainExperience, +}; diff --git a/src/types.ts b/src/types.ts index 301e87a..bed51dc 100644 --- a/src/types.ts +++ b/src/types.ts @@ -136,6 +136,9 @@ export type RegionType = EmptyRegionType | OasisType | BourgadeType; export interface HeroType { id: number; name: string; + level: number; + health: number; + experience: number; } diff --git a/src/update.ts b/src/update.ts index 6691677..5335586 100644 --- a/src/update.ts +++ b/src/update.ts @@ -6,6 +6,7 @@ import { resolveMission } from './missions'; import type { ProductionType } from './types'; import { getProduction, getRegionsWithMissions, getStorage, shuffle } from './utils'; import village, { type VillageState } from "./village"; +import heroes from './modules/heroes'; let lastFrame: number; @@ -58,6 +59,10 @@ export default function update(timestamp: number) { if (quest.remainingTime <= 0) { V.resources[quest.resource] += quest.reward; + const hero = heroes.getHero(V, quest.hero as number); + heroes.hurt(hero, 10.0); + heroes.gainExperience(hero, 2); + // Replace the finished quest with a new one. const index = V.quests.findIndex(q => q.id === quest.id); V.quests[index] = createQuest(quest.resource, quest.level + 1); @@ -116,6 +121,11 @@ export default function update(timestamp: number) { } }); + // Heal heroes. + V.heroes.forEach(h => { + heroes.heal(h, delta / 5000.0) + }); + // Check if the game is won. if (V.resources.culture >= CULTURE_TO_WIN) { V.victory = true; diff --git a/src/utils.ts b/src/utils.ts index c02408c..cb893bb 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,6 @@ import { WORLD_MAP_HEIGHT, WORLD_MAP_WIDTH } from "./constants"; import units from "./data/units"; -import { WORLDMAP_TYPES, type BuildingType, type CostType, type OasisType, type Point, type ProductionType, type ResourcesType } from "./types"; +import { WORLDMAP_TYPES, type BuildingType, type CostType, type HeroType, type OasisType, type Point, type ProductionType, type ResourcesType } from "./types"; import type { VillageState } from "./village";