87 lines
3.3 KiB
TypeScript
87 lines
3.3 KiB
TypeScript
import type { State } from './engine.ts';
|
|||
|
|
|
||
|
|
export interface Upgrade {
|
||
|
|
id: string;
|
||
|
|
name: string;
|
||
|
|
desc: string;
|
||
|
|
cost: Partial<{ andakt: number; dread: number }>;
|
||
|
|
effect: (s: State) => void;
|
||
|
|
available: (s: State) => boolean;
|
||
|
|
once: boolean;
|
||
|
|
}
|
||
|
|
|
||
|
|
export const UPGRADES: Upgrade[] = [
|
||
|
|
{
|
||
|
|
id: 'recruit_neighbor',
|
||
|
|
name: 'Rekrytera en granne',
|
||
|
|
desc: '+1 Troende. De undrade varför källarlamporna flimrade. Nu vet de.',
|
||
|
|
cost: { andakt: 20 },
|
||
|
|
effect: s => { s.troende += 1; },
|
||
|
|
available: s => !s.upgrades.has('first_meeting'),
|
||
|
|
once: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'first_meeting',
|
||
|
|
name: 'Källarmöte i Rosengård',
|
||
|
|
desc: 'Formalisera mötena. +1 andakt/s. Det luktar lite konstigt men ingen säger något.',
|
||
|
|
cost: { andakt: 30 },
|
||
|
|
effect: s => { s.andaktRate += 1; s.areas.rosengard = true; },
|
||
|
|
available: s => s.troende >= 2 && !s.upgrades.has('first_meeting'),
|
||
|
|
once: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'the_manuscript',
|
||
|
|
name: 'Översätt Skriften',
|
||
|
|
desc: 'Någon hittade ett dokument i en källarlokal vid Davidshallsgatan. Texten översätts bäst som "snälla sluta." Vi fortsätter.',
|
||
|
|
cost: { andakt: 80 },
|
||
|
|
effect: s => { s.dreadRate += 0.5; s.ritualUnlocked = true; },
|
||
|
|
available: s => s.troende >= 3 && s.upgrades.has('first_meeting') && !s.upgrades.has('the_manuscript'),
|
||
|
|
once: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'idol_under_bridge',
|
||
|
|
name: 'Idolen under bron',
|
||
|
|
desc: 'Vi placerade en idol under Øresundsbron vid nattens mörkaste timme. Danskarna la märke till det. De säger ingenting.',
|
||
|
|
cost: { andakt: 120, dread: 20 },
|
||
|
|
effect: s => { s.dreadRate += 1; s.andaktRate += 0.5; },
|
||
|
|
available: s => s.upgrades.has('the_manuscript') && !s.upgrades.has('idol_under_bridge'),
|
||
|
|
once: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'varnhem_circle',
|
||
|
|
name: 'Cirkeln på Värnhemstorget',
|
||
|
|
desc: 'Rita cirkeln. Använd krita. Det är viktigt att det är krita. Kommunen tvättar bort den varje morgon. Den är tillbaka varje kväll.',
|
||
|
|
cost: { andakt: 200, dread: 40 },
|
||
|
|
effect: s => { s.areas.varnhem = true; s.dreadRate += 1.5; s.kaosRate += 0.2; },
|
||
|
|
available: s => s.upgrades.has('idol_under_bridge') && s.dread >= 50 && !s.upgrades.has('varnhem_circle'),
|
||
|
|
once: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'recruit_2',
|
||
|
|
name: 'Rekrytera ytterligare troende',
|
||
|
|
desc: '+2 Troende. Ryktet sprids längs de rätta kanalerna.',
|
||
|
|
cost: { andakt: 150 },
|
||
|
|
effect: s => { s.troende += 2; s.andaktRate += 0.5; },
|
||
|
|
available: s => s.upgrades.has('first_meeting') && s.troende < 8,
|
||
|
|
once: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'torso_beacon',
|
||
|
|
name: 'Altaret vid Turning Torso',
|
||
|
|
desc: 'Byggnaden har alltid lyssnat. Nu ber vi den svara. Den gör det.',
|
||
|
|
cost: { andakt: 400, dread: 100 },
|
||
|
|
effect: s => { s.areas.torso = true; s.dreadRate += 3; s.ritualRate += 0.5; },
|
||
|
|
available: s => s.upgrades.has('varnhem_circle') && s.dread >= 100 && !s.upgrades.has('torso_beacon'),
|
||
|
|
once: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'grand_ritual_prep',
|
||
|
|
name: 'Förberedelser för Den Stora Ritualen',
|
||
|
|
desc: 'Allt har lett hit. Turning Torso pekar. Värnhemstorget väntar. Öresund drar sig tillbaka.',
|
||
|
|
cost: { andakt: 600, dread: 200 },
|
||
|
|
effect: s => { s.ritualRate += 2; s.kaosRate += 0.5; },
|
||
|
|
available: s => s.upgrades.has('torso_beacon') && s.ritual >= 50 && !s.upgrades.has('grand_ritual_prep'),
|
||
|
|
once: true,
|
||
|
|
},
|
||
|
|
];
|