Android build v1.1.36

This commit is contained in:
Warren H
2026-07-08 23:33:57 -04:00
parent 802dadc7f3
commit 1fa1c8c070
10 changed files with 195 additions and 34 deletions
+41 -4
View File
@@ -10,13 +10,17 @@ import {
import type { Iwt2BossId } from '../content/bosses'
import {
createDefaultIwt2GearProgress,
IWT2_ACTIVE_INFUSION_MIN_GEAR_LEVEL,
IWT2_GEAR_SLOTS,
IWT2_MAX_GEAR_LEVEL,
iwt2GearUpgradeCosts,
iwt2InfusionCosts,
isIwt2InfusionUnlocked,
isIwt2PassiveInfusionUnlocked,
type Iwt2GearLevel,
type Iwt2GearProgress,
type Iwt2GearSlotId,
type Iwt2PassiveInfusionId,
} from '../content/gear'
import {
IWT2_INFUSION_ABILITIES,
@@ -263,7 +267,7 @@ export function upgradeIwt2GearSlot(
): Iwt2Save {
const classProgress = save.gearProgress[classId]
const slot = classProgress.slots[slotId]
if (slot.level >= 5) throw new Error('Gear slot already at +5.')
if (slot.level >= IWT2_MAX_GEAR_LEVEL) throw new Error(`Gear slot already at +${IWT2_MAX_GEAR_LEVEL}.`)
const costs = iwt2GearUpgradeCosts(classId, slotId, slot.level)
const inventory = spendInventoryCosts(save.inventory, costs)
return {
@@ -294,8 +298,10 @@ export function setIwt2InfusionAbility(
const classProgress = save.gearProgress[classId]
const ability = IWT2_INFUSION_ABILITIES[abilityId]
if (!ability || ability.classId !== classId) throw new Error('Ability is not available for this class.')
if (!isIwt2InfusionUnlocked(classProgress)) throw new Error('Upgrade any gear slot to +5 first.')
if (classProgress.slots[slotId].level < 5) throw new Error('Select a +5 gear slot to anchor the infusion cost.')
if (!isIwt2InfusionUnlocked(classProgress)) throw new Error(`Upgrade any gear slot to +${IWT2_ACTIVE_INFUSION_MIN_GEAR_LEVEL} first.`)
if (classProgress.slots[slotId].level < IWT2_ACTIVE_INFUSION_MIN_GEAR_LEVEL) {
throw new Error(`Select a +${IWT2_ACTIVE_INFUSION_MIN_GEAR_LEVEL} gear slot to anchor the infusion cost.`)
}
if (classProgress.infusionAbilityId === abilityId) return save
const inventory = spendInventoryCosts(save.inventory, iwt2InfusionCosts(classId, slotId, abilityId))
return {
@@ -312,6 +318,27 @@ export function setIwt2InfusionAbility(
}
}
export function setIwt2PassiveInfusion(
save: Iwt2Save,
passiveInfusionId: Iwt2PassiveInfusionId,
): Iwt2Save {
if (!isIwt2PassiveInfusionUnlocked(save.gearProgress)) {
throw new Error(`Upgrade any gear slot to +${IWT2_MAX_GEAR_LEVEL} first.`)
}
if (save.gearProgress.healer.passiveInfusionId === passiveInfusionId) return save
return {
...save,
updatedAt: Date.now(),
gearProgress: {
...save.gearProgress,
healer: {
...save.gearProgress.healer,
passiveInfusionId,
},
},
}
}
export function canAffordIwt2Costs(save: Iwt2Save, costs: Array<{ itemId: string, quantity: number }>): boolean {
return costs.every((cost) => inventoryQuantity(save.inventory, cost.itemId) >= cost.quantity)
}
@@ -450,6 +477,7 @@ function normalizeGearProgress(value: unknown): Iwt2GearProgress {
const classProgress = rawClassProgress as {
slots?: Partial<Record<Iwt2GearSlotId, { level?: unknown }>>
infusionAbilityId?: unknown
passiveInfusionId?: unknown
}
for (const slotId of IWT2_GEAR_SLOTS) {
next[classId].slots[slotId] = {
@@ -461,6 +489,10 @@ function normalizeGearProgress(value: unknown): Iwt2GearProgress {
&& isIwt2InfusionUnlocked(next[classId])
? infusionAbilityId as Iwt2InfusionAbilityId
: null
next[classId].passiveInfusionId = classId === 'healer'
&& isIwt2PassiveInfusionUnlocked(next)
? asPassiveInfusionId(classProgress.passiveInfusionId)
: null
}
return next
}
@@ -470,10 +502,15 @@ function cloneGearProgress(progress: Iwt2GearProgress): Iwt2GearProgress {
}
function asGearLevel(value: unknown): Iwt2GearLevel {
const level = Math.max(0, Math.min(5, Math.floor(Number(value) || 0)))
const level = Math.max(0, Math.min(IWT2_MAX_GEAR_LEVEL, Math.floor(Number(value) || 0)))
return level as Iwt2GearLevel
}
function asPassiveInfusionId(value: unknown): Iwt2PassiveInfusionId | null {
if (typeof value !== 'string' || value === 'revive-party-members') return null
return value as Iwt2PassiveInfusionId
}
function normalizeInventory(value: unknown): Iwt2InventoryItem[] {
if (!Array.isArray(value)) return []
const byId = new Map<string, Iwt2InventoryItem>()