Change quests to only offer one resource, but there is always one quest per type of resource.
This commit is contained in:
parent
3b38d16868
commit
f7f86db510
@ -1,7 +1,12 @@
|
||||
import type { Resource } from "./types";
|
||||
|
||||
|
||||
export const CULTURE_TO_WIN = 20000;
|
||||
export const WORLD_MAP_HEIGHT = 9;
|
||||
export const WORLD_MAP_WIDTH = 9;
|
||||
|
||||
export const RESOURCES: Resource[] = ['wood', 'stone', 'iron', 'food', 'culture'];
|
||||
|
||||
// Debug values.
|
||||
export const TOWN_HALL_START_LEVEL = 1;
|
||||
export const RESOURCE_BUILDINGS_START_LEVEL = 1;
|
||||
|
@ -2,7 +2,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 { getEmptyResources, random, shuffle } from "./utils";
|
||||
import { random, shuffle } from "./utils";
|
||||
|
||||
|
||||
let uid = 0;
|
||||
@ -37,25 +37,18 @@ export function createBuilding(buildingType: string): BuildingType {
|
||||
}
|
||||
|
||||
|
||||
export function createQuest(level: number): QuestType {
|
||||
const reward = getEmptyResources();
|
||||
const adjustedLevel = level * level + 3;
|
||||
const duration = random(adjustedLevel - 2, adjustedLevel + 2);
|
||||
Object.keys(reward).forEach(r => {
|
||||
const resource = r as keyof ResourcesType;
|
||||
reward[resource] = random(
|
||||
export function createQuest(resource: keyof ResourcesType, 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(
|
||||
Math.round((duration * 5 - level * 10) * (1 + level / 3)),
|
||||
Math.round((duration * 5 + level * 10) * (1 + level / 3)),
|
||||
);
|
||||
|
||||
if (resource === 'culture') {
|
||||
reward[resource] = Math.round(reward[resource] / 20);
|
||||
}
|
||||
});
|
||||
));
|
||||
|
||||
return {
|
||||
id: uid++,
|
||||
duration,
|
||||
resource,
|
||||
reward,
|
||||
level,
|
||||
started: false,
|
||||
|
@ -3,7 +3,8 @@
|
||||
import { fly } from "svelte/transition";
|
||||
|
||||
import moves from "../moves";
|
||||
import { getPrettyTime } from "../utils";
|
||||
import type { Resource, ResourcesType } from "../types";
|
||||
import { getEmptyResources, getPrettyTime } from "../utils";
|
||||
import village from "../village";
|
||||
import Reward from "./Reward.svelte";
|
||||
|
||||
@ -13,6 +14,12 @@
|
||||
function startQuest(id: number, heroId: number) {
|
||||
moves.startQuest(id, heroId);
|
||||
}
|
||||
|
||||
function getRewardAsResources(resource: Resource, reward: number): ResourcesType {
|
||||
const output = getEmptyResources();
|
||||
output[resource] = reward;
|
||||
return output;
|
||||
}
|
||||
</script>
|
||||
|
||||
<section>
|
||||
@ -23,15 +30,19 @@
|
||||
out:fly={{ duration: 200, x: 500 }}
|
||||
animate:flip={{ duration: 100 }}
|
||||
>
|
||||
<p>
|
||||
<Reward reward={ quest.reward } />
|
||||
</p>
|
||||
<p>
|
||||
<p class="reward">
|
||||
<span>
|
||||
<img src="./img/icons/time.png" alt="Duration">
|
||||
{ #if quest.started }
|
||||
{ getPrettyTime(quest.remainingTime || 0) }
|
||||
{ :else }
|
||||
{ quest.duration }
|
||||
{ /if }
|
||||
</span>
|
||||
<Reward reward={ getRewardAsResources(quest.resource, quest.reward) } />
|
||||
</p>
|
||||
{ #if !quest.started }
|
||||
<p>
|
||||
{ #each availableHeroes as hero }
|
||||
<button
|
||||
on:click={ () => startQuest(quest.id, hero.id) }
|
||||
@ -41,14 +52,29 @@
|
||||
{ :else }
|
||||
<span>No heroes available</span>
|
||||
{ /each }
|
||||
{ /if }
|
||||
</p>
|
||||
{ /if }
|
||||
</div>
|
||||
{ /each }
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.quest {
|
||||
border: 1px solid hsl(0, 0%, 20%);
|
||||
border-radius: 1em;
|
||||
margin-bottom: 0.5em;
|
||||
padding: 0 1em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.quest .reward {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.quest .reward span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5em;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import type { VillageState } from "../village";
|
||||
|
||||
|
||||
export default function startQuest(V: VillageState, questId: number, heroId: number) {
|
||||
const quest = V.quests.find(q => q.id === questId);
|
||||
if (!quest) {
|
||||
|
@ -26,6 +26,9 @@ export interface ResourcesType extends CostType {
|
||||
}
|
||||
|
||||
|
||||
export type Resource = keyof ResourcesType;
|
||||
|
||||
|
||||
export interface BuildingSource {
|
||||
name: string;
|
||||
type: string;
|
||||
@ -139,7 +142,8 @@ export interface HeroType {
|
||||
export interface QuestType {
|
||||
id: number;
|
||||
duration: number;
|
||||
reward: ResourcesType;
|
||||
resource: keyof ResourcesType
|
||||
reward: number;
|
||||
level: number;
|
||||
started: boolean;
|
||||
hero?: number;
|
||||
|
@ -56,15 +56,11 @@ export default function update(timestamp: number) {
|
||||
|
||||
quest.remainingTime -= delta;
|
||||
if (quest.remainingTime <= 0) {
|
||||
V.resources.wood += quest.reward.wood;
|
||||
V.resources.stone += quest.reward.stone;
|
||||
V.resources.iron += quest.reward.iron;
|
||||
V.resources.food += quest.reward.food;
|
||||
V.resources.culture += quest.reward.culture;
|
||||
V.resources[quest.resource] += quest.reward;
|
||||
|
||||
// Replace the finished quest with a new one.
|
||||
V.quests = V.quests.filter(q => q.id !== quest.id);
|
||||
V.quests.push(createQuest(quest.level + 1));
|
||||
const index = V.quests.findIndex(q => q.id === quest.id);
|
||||
V.quests[index] = createQuest(quest.resource, quest.level + 1);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
import { RESOURCE_BUILDINGS_START_LEVEL, RESOURCES, TOWN_HALL_START_LEVEL, WORLD_MAP_HEIGHT, WORLD_MAP_WIDTH } from "./constants";
|
||||
import { createBuilding, createHero, createQuest } from "./create";
|
||||
import worldmap from "./data/worldmap";
|
||||
import { getTilesAtDistance, Hex } from "./hexgrid";
|
||||
import { WORLDMAP_TYPES, type BuildingType, type CostType, type HeroType, type QuestType, type RegionType, type ResourcesType } from "./types";
|
||||
import { distanceBetweenCells, getAdjacentWorldmapCells, getKeysAsNumbers, indexToPoint, shuffle } from "./utils";
|
||||
import { RESOURCE_BUILDINGS_START_LEVEL, TOWN_HALL_START_LEVEL, WORLD_MAP_HEIGHT, WORLD_MAP_WIDTH } from "./constants";
|
||||
import { distanceBetweenCells, getKeysAsNumbers, indexToPoint, shuffle } from "./utils";
|
||||
|
||||
|
||||
type Board = {
|
||||
@ -106,11 +106,9 @@ function getInitialWorldmap(): RegionType[] {
|
||||
|
||||
|
||||
function getInitialQuests(): QuestType[] {
|
||||
return [
|
||||
createQuest(1),
|
||||
createQuest(1),
|
||||
createQuest(1),
|
||||
];
|
||||
return RESOURCES.map(r => {
|
||||
return createQuest(r, 1);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user