Files
i-want-to-heal/src/modes/iwt2/content/roguelike.ts
T
2026-07-05 22:48:56 -04:00

244 lines
8.8 KiB
TypeScript

import {
buildOpponentSlotDebuffChoices,
buildSelfSlotUpgradeChoices,
} from '../../../combat/roguelikeUpgrades'
import type { Spell } from '../../../game'
import { type Iwt2HealerAbility } from './healerAbilities'
export type Iwt2RoguelikeVariant = 'pve' | 'pvp'
export type Iwt2RoguelikeContentType = 'dungeon' | 'raid' | 'stadium'
export type Iwt2RoguelikeSlot = '1' | '2' | '3' | '4' | '5'
export type Iwt2RoguelikeSelfBuffId =
| 'revive-party-members'
| 'dawnweaver-mend-applies-renew'
| 'dawnweaver-mend-applies-sun-ward'
| 'dawnweaver-renew-applies-sun-ward'
| 'dawnweaver-radiance-applies-renew'
| 'dawnweaver-radiance-applies-sun-ward'
| 'dawnweaver-sun-ward-applies-renew'
| 'dawnweaver-sun-ward-damage-reduction'
| 'dawnweaver-purify-applies-renew'
| 'dawnweaver-purify-applies-sun-ward'
| 'lifebinder-verdant-touch-applies-seed-of-life'
| 'lifebinder-verdant-touch-applies-barkskin'
| 'lifebinder-seed-of-life-applies-barkskin'
| 'lifebinder-wild-growth-applies-seed-of-life'
| 'lifebinder-wild-growth-applies-barkskin'
| 'lifebinder-barkskin-applies-seed-of-life'
| 'lifebinder-barkskin-hot-bonus'
| 'lifebinder-purging-sap-applies-seed-of-life'
| 'lifebinder-purging-sap-applies-barkskin'
| 'runesage-etched-mend-applies-mending-rune'
| 'runesage-etched-mend-applies-aegis-script'
| 'runesage-mending-rune-applies-aegis-script'
| 'runesage-concordance-applies-mending-rune'
| 'runesage-concordance-applies-aegis-script'
| 'runesage-aegis-script-applies-mending-rune'
| 'runesage-aegis-script-damage-reduction'
| 'runesage-unravel-applies-mending-rune'
| 'runesage-unravel-applies-aegis-script'
| `slot${Iwt2RoguelikeSlot}-extra-target`
| `slot${Iwt2RoguelikeSlot}-cost-down`
| `slot${Iwt2RoguelikeSlot}-cooldown-down`
export type Iwt2RoguelikeOpponentDebuffId =
| `opp-slot${Iwt2RoguelikeSlot}-cost-up`
| `opp-slot${Iwt2RoguelikeSlot}-cooldown-up`
export type Iwt2RoguelikeChoice<T extends string> = {
id: T
name: string
description: string
}
export const IWT2_ROGUELIKE_SLOTS: readonly Iwt2RoguelikeSlot[] = ['1', '2', '3', '4', '5']
export const IWT2_SUN_WARD_DAMAGE_REDUCTION_BUFF_ID = 'dawnweaver-sun-ward-damage-reduction'
export const IWT2_BARKSKIN_HOT_BONUS_BUFF_ID = 'lifebinder-barkskin-hot-bonus'
export const IWT2_AEGIS_SCRIPT_DAMAGE_REDUCTION_BUFF_ID = 'runesage-aegis-script-damage-reduction'
export const IWT2_REVIVE_PARTY_CHOICE: Iwt2RoguelikeChoice<Iwt2RoguelikeSelfBuffId> = {
id: 'revive-party-members',
name: 'Revive Party Members',
description: 'Revive fallen party members before the next IWT2 arena.',
}
export const IWT2_DAWNWEAVER_SYNERGY_CHOICES: Array<Iwt2RoguelikeChoice<Iwt2RoguelikeSelfBuffId>> = [
{
id: 'dawnweaver-mend-applies-renew',
name: 'Mend Applies Renew',
description: 'Mend also applies Renew to the target.',
},
{
id: 'dawnweaver-mend-applies-sun-ward',
name: 'Mend Applies Sun Ward',
description: 'Mend also applies Sun Ward to the target.',
},
{
id: 'dawnweaver-renew-applies-sun-ward',
name: 'Renew Applies Sun Ward',
description: 'Renew also applies Sun Ward to the target.',
},
{
id: 'dawnweaver-radiance-applies-renew',
name: 'Radiance Applies Renew',
description: 'Radiance also applies Renew to affected allies.',
},
{
id: 'dawnweaver-radiance-applies-sun-ward',
name: 'Radiance Applies 50% Sun Ward',
description: 'Radiance also applies Sun Ward at 50% strength to affected allies.',
},
{
id: 'dawnweaver-sun-ward-applies-renew',
name: 'Sun Ward Applies Renew',
description: 'Sun Ward also applies Renew to the target.',
},
{
id: IWT2_SUN_WARD_DAMAGE_REDUCTION_BUFF_ID,
name: 'Sun Ward Reduces Damage',
description: 'While shielded by Sun Ward, the target takes 50% less damage.',
},
{
id: 'dawnweaver-purify-applies-renew',
name: 'Purify Applies Renew',
description: 'Purify also applies Renew to the target.',
},
{
id: 'dawnweaver-purify-applies-sun-ward',
name: 'Purify Applies Sun Ward',
description: 'Purify also applies Sun Ward to the target.',
},
]
export const IWT2_LIFEBINDER_SYNERGY_CHOICES: Array<Iwt2RoguelikeChoice<Iwt2RoguelikeSelfBuffId>> = [
{
id: 'lifebinder-verdant-touch-applies-seed-of-life',
name: 'Verdant Touch Applies Seed of Life',
description: 'Verdant Touch also applies Seed of Life to the target.',
},
{
id: 'lifebinder-verdant-touch-applies-barkskin',
name: 'Verdant Touch Applies 50% Barkskin',
description: 'Verdant Touch also applies Barkskin at 50% strength to the target.',
},
{
id: 'lifebinder-seed-of-life-applies-barkskin',
name: 'Seed of Life Applies Barkskin',
description: 'Seed of Life also applies Barkskin to the target.',
},
{
id: 'lifebinder-wild-growth-applies-seed-of-life',
name: 'Wild Growth Applies Seed of Life',
description: 'Wild Growth also applies Seed of Life to affected allies.',
},
{
id: 'lifebinder-wild-growth-applies-barkskin',
name: 'Wild Growth Applies 50% Barkskin',
description: 'Wild Growth also applies Barkskin at 50% strength to affected allies.',
},
{
id: 'lifebinder-barkskin-applies-seed-of-life',
name: 'Barkskin Applies Seed of Life',
description: 'Barkskin also applies Seed of Life to the target.',
},
{
id: IWT2_BARKSKIN_HOT_BONUS_BUFF_ID,
name: 'Barkskin Feeds HoTs',
description: 'While shielded by Barkskin, the target receives 25% more healing over time.',
},
{
id: 'lifebinder-purging-sap-applies-seed-of-life',
name: 'Purging Sap Applies Seed of Life',
description: 'Purging Sap also applies Seed of Life to the target.',
},
{
id: 'lifebinder-purging-sap-applies-barkskin',
name: 'Purging Sap Applies Barkskin',
description: 'Purging Sap also applies Barkskin to the target.',
},
]
export const IWT2_RUNESAGE_SYNERGY_CHOICES: Array<Iwt2RoguelikeChoice<Iwt2RoguelikeSelfBuffId>> = [
{
id: 'runesage-etched-mend-applies-mending-rune',
name: 'Etched Mend Applies Mending Rune',
description: 'Etched Mend also applies Mending Rune to the target.',
},
{
id: 'runesage-etched-mend-applies-aegis-script',
name: 'Etched Mend Applies 50% Aegis Script',
description: 'Etched Mend also applies Aegis Script at 50% strength to the target.',
},
{
id: 'runesage-mending-rune-applies-aegis-script',
name: 'Mending Rune Applies Aegis Script',
description: 'Mending Rune also applies Aegis Script to the target.',
},
{
id: 'runesage-concordance-applies-mending-rune',
name: 'Concordance Applies Mending Rune',
description: 'Concordance also applies Mending Rune to affected allies.',
},
{
id: 'runesage-concordance-applies-aegis-script',
name: 'Concordance Applies 50% Aegis Script',
description: 'Concordance also applies Aegis Script at 50% strength to affected allies.',
},
{
id: 'runesage-aegis-script-applies-mending-rune',
name: 'Aegis Script Applies Mending Rune',
description: 'Aegis Script also applies Mending Rune to the target.',
},
{
id: IWT2_AEGIS_SCRIPT_DAMAGE_REDUCTION_BUFF_ID,
name: 'Aegis Script Reduces Damage',
description: 'While shielded by Aegis Script, the target takes 30% less damage.',
},
{
id: 'runesage-unravel-applies-mending-rune',
name: 'Unravel Applies Mending Rune',
description: 'Unravel also applies Mending Rune to the target.',
},
{
id: 'runesage-unravel-applies-aegis-script',
name: 'Unravel Applies Aegis Script',
description: 'Unravel also applies Aegis Script to the target.',
},
]
export function iwt2AbilityToSpell(ability: Iwt2HealerAbility): Spell {
return {
id: ability.id,
key: String(ability.slot),
name: ability.name,
description: ability.name,
cost: ability.manaCost,
cooldown: ability.cooldownSeconds,
power: ability.power,
glyph: ability.icon,
kind: ability.kind,
effectType: ability.effectType,
}
}
export function buildIwt2SelfBuffChoices(abilities: Iwt2HealerAbility[]) {
const baseChoices = buildSelfSlotUpgradeChoices<Iwt2RoguelikeSelfBuffId>({
slots: IWT2_ROGUELIKE_SLOTS,
spells: abilities.map(iwt2AbilityToSpell),
labelMode: 'ability',
})
if (abilities.some((ability) => ability.id === 'dawnweaver-mend')) return [...baseChoices, ...IWT2_DAWNWEAVER_SYNERGY_CHOICES]
if (abilities.some((ability) => ability.id === 'lifebinder-verdant-touch')) return [...baseChoices, ...IWT2_LIFEBINDER_SYNERGY_CHOICES]
if (abilities.some((ability) => ability.id === 'runesage-etched-mend')) return [...baseChoices, ...IWT2_RUNESAGE_SYNERGY_CHOICES]
return baseChoices
}
export function buildIwt2OpponentDebuffChoices(abilities: Iwt2HealerAbility[]) {
return buildOpponentSlotDebuffChoices<Iwt2RoguelikeOpponentDebuffId>({
slots: IWT2_ROGUELIKE_SLOTS,
spells: abilities.map(iwt2AbilityToSpell),
labelMode: 'ability',
})
}