+
{parts.map((p) => (
-
-
-
Challenge Tier
-
Difficulty
-
-
-
{selectedDifficulty.name}
diff --git a/src/components/CombatScreen.tsx b/src/components/CombatScreen.tsx
index 68490f6..08d9cb7 100644
--- a/src/components/CombatScreen.tsx
+++ b/src/components/CombatScreen.tsx
@@ -35,6 +35,7 @@ import {
} from '../dualScreen'
const TICK_MS = 700
+const TARGET_RENDER_THROTTLE_MS = 180
type RoguelikeMode = 'dungeon' | 'raid'
type RoguelikeUpgradeTiming = 'boss' | 'encounter'
@@ -73,6 +74,16 @@ type FloatingCombatText = {
value: number
}
+type SinglePlayerCombatState = {
+ party: PartyMember[]
+ resource: number
+ enemyHealth: number
+ cooldowns: Record
+ elapsedTicks: number
+ castsTowardFree: number
+ freeCastReady: boolean
+}
+
const ROGUELIKE_MECHANICS: RoguelikeMechanic[] = [
'party-pulse',
'searing-mark',
@@ -340,13 +351,18 @@ export function CombatScreen({
const sectionName = isRoguelike ? 'Stage' : dungeon.contentType === 'raid' ? 'Phase' : 'Part'
const contentName = isRoguelike ? 'Roguelike' : dungeon.contentType === 'raid' ? 'Raid' : 'Dungeon'
const initialEncounterIndex = (startPart - 1) * 3
- const [party, setParty] = useState(partyTemplate)
+ const initialCombatState = useMemo(() => ({
+ party: partyTemplate,
+ resource: maxResource,
+ enemyHealth: encounters[initialEncounterIndex].maxHealth,
+ cooldowns: {},
+ elapsedTicks: 0,
+ castsTowardFree: 0,
+ freeCastReady: false,
+ }), [encounters, initialEncounterIndex, maxResource, partyTemplate])
+ const [combatState, setCombatState] = useState(() => initialCombatState)
const [selectedId, setSelectedId] = useState(partyTemplate[0].id)
- const [resource, setResource] = useState(maxResource)
const [encounterIndex, setEncounterIndex] = useState(initialEncounterIndex)
- const [enemyHealth, setEnemyHealth] = useState(encounters[initialEncounterIndex].maxHealth)
- const [cooldowns, setCooldowns] = useState>({})
- const [, setElapsedTicks] = useState(0)
const [status, setStatus] = useState<'playing' | 'won' | 'lost' | 'part-complete' | 'upgrade-choice'>('playing')
const [paused, setPaused] = useState(false)
const [targetGroup, setTargetGroup] = useState<0 | 1 | 2>(0)
@@ -360,8 +376,6 @@ export function CombatScreen({
const [floatingTexts, setFloatingTexts] = useState([])
const [roguelikeUpgrades, setRoguelikeUpgrades] = useState([])
const [upgradeChoices, setUpgradeChoices] = useState([])
- const [, setCastsTowardFree] = useState(0)
- const [freeCastReady, setFreeCastReady] = useState(false)
const rewardClaimedRef = useRef(false)
const profileRefreshedRef = useRef(false)
const rolledEncounterIdsRef = useRef(new Set())
@@ -371,10 +385,11 @@ export function CombatScreen({
const partStartTimesRef = useRef>({})
const nextLogId = useRef(2)
const nextFloatingTextId = useRef(1)
- const partyRef = useRef(partyTemplate)
- const enemyHealthRef = useRef(encounters[initialEncounterIndex].maxHealth)
- const elapsedTicksRef = useRef(0)
+ const combatRef = useRef(initialCombatState)
const selectedIdRef = useRef(partyTemplate[0].id)
+ const selectedRenderTimeoutRef = useRef(null)
+ const lastSelectedRenderAtRef = useRef(0)
+ const { party, resource, enemyHealth, cooldowns, freeCastReady } = combatState
const encounter = encounters[encounterIndex]
const currentPart = getCurrentPart(encounterIndex)
const firstEncounterIndex = (startPart - 1) * 3
@@ -416,9 +431,38 @@ export function CombatScreen({
})
}, [paused])
+ const setCombat = useCallback((
+ nextState: SinglePlayerCombatState | ((current: SinglePlayerCombatState) => SinglePlayerCombatState),
+ ) => {
+ const next = typeof nextState === 'function'
+ ? nextState(combatRef.current)
+ : nextState
+ combatRef.current = next
+ setCombatState(next)
+ }, [])
+
const setSelectedTargetId = useCallback((id: string) => {
+ if (selectedIdRef.current === id) return
selectedIdRef.current = id
- setSelectedId(id)
+ const now = performance.now()
+ const elapsed = now - lastSelectedRenderAtRef.current
+ if (elapsed >= TARGET_RENDER_THROTTLE_MS) {
+ lastSelectedRenderAtRef.current = now
+ setSelectedId(id)
+ return
+ }
+ if (selectedRenderTimeoutRef.current !== null) return
+ selectedRenderTimeoutRef.current = window.setTimeout(() => {
+ selectedRenderTimeoutRef.current = null
+ lastSelectedRenderAtRef.current = performance.now()
+ setSelectedId(selectedIdRef.current)
+ }, TARGET_RENDER_THROTTLE_MS - elapsed)
+ }, [])
+
+ useEffect(() => () => {
+ if (selectedRenderTimeoutRef.current !== null) {
+ window.clearTimeout(selectedRenderTimeoutRef.current)
+ }
}, [])
const addLog = useCallback((text: string, tone: CombatLogEntry['tone']) => {
@@ -468,18 +512,19 @@ export function CombatScreen({
: []
const nextEncounters = roguelikeMode ? nextRoguelikeEncounters : staticEncounters
const freshParty = partyTemplate.map((member) => ({ ...member }))
- partyRef.current = freshParty
- enemyHealthRef.current = nextEncounters[initialEncounterIndex].maxHealth
+ setCombat({
+ party: freshParty,
+ resource: maxResource,
+ enemyHealth: nextEncounters[initialEncounterIndex].maxHealth,
+ cooldowns: {},
+ elapsedTicks: 0,
+ castsTowardFree: 0,
+ freeCastReady: false,
+ })
if (roguelikeMode) setRoguelikeEncounters(nextRoguelikeEncounters)
setRoguelikeStage(1)
- setParty(freshParty)
setSelectedTargetId(partyTemplate[0].id)
- setResource(maxResource)
setEncounterIndex(initialEncounterIndex)
- setEnemyHealth(nextEncounters[initialEncounterIndex].maxHealth)
- setCooldowns({})
- elapsedTicksRef.current = 0
- setElapsedTicks(0)
setStatus('playing')
setPaused(false)
setTargetGroup(0)
@@ -490,8 +535,6 @@ export function CombatScreen({
setFloatingTexts([])
setRoguelikeUpgrades([])
setUpgradeChoices([])
- setCastsTowardFree(0)
- setFreeCastReady(false)
rewardClaimedRef.current = false
profileRefreshedRef.current = false
rolledEncounterIdsRef.current = new Set()
@@ -500,18 +543,19 @@ export function CombatScreen({
runStartedAtRef.current = Date.now()
partStartTimesRef.current = { [startPart]: runStartedAtRef.current }
setLog([{ id: nextLogId.current++, text: 'A new run begins.', tone: 'system' }])
- }, [difficulty, initialEncounterIndex, maxResource, partyTemplate, roguelikeMode, roguelikePool, setSelectedTargetId, startPart, staticEncounters])
+ }, [difficulty, initialEncounterIndex, maxResource, partyTemplate, roguelikeMode, roguelikePool, setCombat, setSelectedTargetId, startPart, staticEncounters])
const castSpell = useCallback(
(spell: Spell) => {
- const effectiveCost = spellResourceCost(spell, roguelikeUpgrades, freeCastReady)
- if (status !== 'playing' || cooldowns[spell.id] > 0 || resource < effectiveCost) return
- const healer = partyRef.current.find((member) => member.id === 'mira')
+ const current = combatRef.current
+ const effectiveCost = spellResourceCost(spell, roguelikeUpgrades, current.freeCastReady)
+ if (status !== 'playing' || current.cooldowns[spell.id] > 0 || current.resource < effectiveCost) return
+ const healer = current.party.find((member) => member.id === 'mira')
if (!healer || healer.health <= 0) return
const targetId = selectedIdRef.current
- const selected = partyRef.current.find((member) => member.id === targetId)
+ const selected = current.party.find((member) => member.id === targetId)
if (!selected || selected.health <= 0) return
- const extraTarget = (blockedIds: string[]) => partyRef.current
+ const extraTarget = (blockedIds: string[]) => current.party
.filter((member) => member.health > 0 && !blockedIds.includes(member.id))
.sort((left, right) => (left.health / left.maxHealth) - (right.health / right.maxHealth))[0]
const directTargets = new Set([targetId])
@@ -547,28 +591,7 @@ export function CombatScreen({
if (extra) directTargets.add(extra.id)
}
- setResource((value) => value - effectiveCost)
- resourceSpentRef.current += effectiveCost
- setCooldowns((current) => ({
- ...current,
- [spell.id]: spell.cooldown * cooldownMultiplier(spell, roguelikeUpgrades),
- }))
- if (upgradeStackCount(roguelikeUpgrades, 'fifth-cast-free') > 0) {
- if (freeCastReady) {
- setFreeCastReady(false)
- setCastsTowardFree(0)
- } else {
- setCastsTowardFree((current) => {
- const next = current + 1
- if (next >= 5) {
- setFreeCastReady(true)
- return 0
- }
- return next
- })
- }
- }
- const nextParty = partyRef.current.map((member) => {
+ const nextParty = current.party.map((member) => {
if (member.health <= 0) return member
if (spell.kind === 'group') {
const power = Math.round(spell.power * (1.25 ** upgradeStackCount(roguelikeUpgrades, 'group-heal-boost')))
@@ -602,11 +625,35 @@ export function CombatScreen({
hotTicks: hotTargets.has(member.id) ? 5 : member.hotTicks,
}
})
- partyRef.current = nextParty
- setParty(nextParty)
+ const freeCastStacks = upgradeStackCount(roguelikeUpgrades, 'fifth-cast-free')
+ const nextFreeCastReady = freeCastStacks > 0 && current.freeCastReady
+ ? false
+ : current.freeCastReady
+ const nextCastsTowardFree = freeCastStacks > 0
+ ? current.freeCastReady
+ ? 0
+ : current.castsTowardFree + 1 >= 5
+ ? 0
+ : current.castsTowardFree + 1
+ : current.castsTowardFree
+ const gainedFreeCast = freeCastStacks > 0
+ && !current.freeCastReady
+ && current.castsTowardFree + 1 >= 5
+ resourceSpentRef.current += effectiveCost
+ setCombat({
+ ...current,
+ party: nextParty,
+ resource: current.resource - effectiveCost,
+ cooldowns: {
+ ...current.cooldowns,
+ [spell.id]: spell.cooldown * cooldownMultiplier(spell, roguelikeUpgrades),
+ },
+ castsTowardFree: nextCastsTowardFree,
+ freeCastReady: gainedFreeCast || nextFreeCastReady,
+ })
addLog(`${spell.name} cast on ${spell.kind === 'group' ? 'the party' : selected.name}${effectiveCost === 0 ? ' for free' : ''}.`, 'heal')
},
- [activeSetEffects, addFloatingHeal, addLog, cooldowns, freeCastReady, resource, roguelikeUpgrades, status],
+ [activeSetEffects, addFloatingHeal, addLog, roguelikeUpgrades, setCombat, status],
)
const finishRun = useCallback(
@@ -669,7 +716,7 @@ export function CombatScreen({
)
const selectRelativeTarget = useCallback((direction: -1 | 1) => {
- const living = partyRef.current.filter((member) => member.health > 0)
+ const living = combatRef.current.party.filter((member) => member.health > 0)
if (living.length === 0) return
const currentIndex = living.findIndex((member) => member.id === selectedIdRef.current)
const nextIndex = currentIndex < 0
@@ -680,14 +727,14 @@ export function CombatScreen({
const selectDirectionalTarget = useCallback((action: InputAction) => {
const columns = dungeon.partySize >= 10 ? 6 : 3
- const currentIndex = partyRef.current.findIndex((member) => member.id === selectedIdRef.current)
+ const currentIndex = combatRef.current.party.findIndex((member) => member.id === selectedIdRef.current)
if (currentIndex < 0) {
- setSelectedTargetId(partyRef.current[0].id)
+ setSelectedTargetId(combatRef.current.party[0].id)
return
}
const currentRow = Math.floor(currentIndex / columns)
const currentColumn = currentIndex % columns
- const candidates = partyRef.current
+ const candidates = combatRef.current.party
.map((member, index) => ({
member,
index,
@@ -721,14 +768,15 @@ export function CombatScreen({
const selectDirectTarget = useCallback((slot: number) => {
const index = slot + (dungeon.partySize > 6 ? targetGroup * 6 : 0)
- const member = partyRef.current[index]
+ const member = combatRef.current.party[index]
if (member) setSelectedTargetId(member.id)
}, [dungeon.partySize, setSelectedTargetId, targetGroup])
const chooseRoguelikeUpgrade = useCallback((upgrade: RoguelikeUpgrade) => {
if (!roguelikeMode) return
+ const current = combatRef.current
const clearedBoss = encounters[encounterIndex]?.isBoss ?? false
- const recoveredParty = partyRef.current.map((member) => ({
+ const recoveredParty = current.party.map((member) => ({
...member,
health: member.health <= 0
? 0
@@ -747,24 +795,24 @@ export function CombatScreen({
? nextSegment[0]
: encounters[encounterIndex + 1]
if (!nextEncounter) return
- partyRef.current = recoveredParty
- enemyHealthRef.current = nextEncounter.maxHealth
setRoguelikeUpgrades((current) => [...current, upgrade])
if (clearedBoss) {
setRoguelikeStage(nextStage)
setRoguelikeEncounters((current) => [...current, ...nextSegment])
}
- setParty(recoveredParty)
setEncounterIndex((current) => current + 1)
- setEnemyHealth(nextEncounter.maxHealth)
- elapsedTicksRef.current = 0
- setElapsedTicks(0)
- setCooldowns({})
- setResource((value) => clamp(value + Math.round(maxResource * 0.25), 0, maxResource))
+ setCombat({
+ ...current,
+ party: recoveredParty,
+ enemyHealth: nextEncounter.maxHealth,
+ elapsedTicks: 0,
+ cooldowns: {},
+ resource: clamp(current.resource + Math.round(maxResource * 0.25), 0, maxResource),
+ })
setUpgradeChoices([])
setStatus('playing')
addLog(`${upgrade.name} gained. ${nextEncounter.enemyName} approaches.`, 'system')
- }, [addLog, difficulty, encounterIndex, encounters, maxResource, roguelikeMode, roguelikePool, roguelikeStage])
+ }, [addLog, difficulty, encounterIndex, encounters, maxResource, roguelikeMode, roguelikePool, roguelikeStage, setCombat])
useGameAction((action, device) => {
if (action === 'pause' || (action === 'back' && device === 'pc')) {
@@ -783,10 +831,10 @@ export function CombatScreen({
if (action === 'toggleTargetGroup') {
if (dungeon.partySize <= 6) return
setTargetGroup((current) => {
- const groupCount = Math.max(1, Math.ceil(partyRef.current.length / 6))
+ const groupCount = Math.max(1, Math.ceil(combatRef.current.party.length / 6))
const next = ((current + 1) % groupCount) as 0 | 1 | 2
- const selectedIndex = partyRef.current.findIndex((member) => member.id === selectedIdRef.current)
- const nextMember = partyRef.current[(selectedIndex < 0 ? 0 : selectedIndex % 6) + next * 6]
+ const selectedIndex = combatRef.current.party.findIndex((member) => member.id === selectedIdRef.current)
+ const nextMember = combatRef.current.party[(selectedIndex < 0 ? 0 : selectedIndex % 6) + next * 6]
if (nextMember) setSelectedTargetId(nextMember.id)
return next
})
@@ -809,20 +857,17 @@ export function CombatScreen({
useEffect(() => {
if (status !== 'playing' || paused) return
const timer = window.setInterval(() => {
- const nextElapsedTicks = elapsedTicksRef.current + 1
- elapsedTicksRef.current = nextElapsedTicks
- setElapsedTicks(nextElapsedTicks)
- setResource((value) => clamp(value + 2.4, 0, maxResource))
- setCooldowns((current) =>
- Object.fromEntries(
- Object.entries(current).map(([id, seconds]) => [
- id,
- Math.max(0, seconds - TICK_MS / 1000),
- ]),
- ),
+ const current = combatRef.current
+ const nextElapsedTicks = current.elapsedTicks + 1
+ const nextCooldowns = Object.fromEntries(
+ Object.entries(current.cooldowns).map(([id, seconds]) => [
+ id,
+ Math.max(0, seconds - TICK_MS / 1000),
+ ]),
)
+ let nextResource = clamp(current.resource + 2.4, 0, maxResource)
- const living = partyRef.current.filter((member) => member.health > 0)
+ const living = current.party.filter((member) => member.health > 0)
if (living.length === 0) {
if (isRoguelike) finishRoguelikeRun(encounterIndex)
setStatus('lost')
@@ -854,12 +899,12 @@ export function CombatScreen({
if (appliesHealingReduction) addLog(`${primaryTarget.name} receives reduced healing.`, 'danger')
if (tankBuster) addLog(`${encounter.enemyName} crushes the tanks.`, 'danger')
if (resourceDrain) {
- setResource((value) => clamp(value - 8, 0, maxResource))
+ nextResource = clamp(nextResource - 8, 0, maxResource)
addLog(`${encounter.enemyName} drains ${gameClass.resourceName}.`, 'danger')
}
- const healerBeforeDamage = partyRef.current.find((member) => member.id === 'mira')
- const nextParty = partyRef.current.map((member) => {
+ const healerBeforeDamage = current.party.find((member) => member.id === 'mira')
+ const nextParty = current.party.map((member) => {
if (member.health <= 0) return member
let damage = member.id === primaryTarget.id ? encounter.damage : 0
if (member.role === 'Tank') damage += encounter.tankDamage
@@ -898,8 +943,6 @@ export function CombatScreen({
}
})
const healerAfterDamage = nextParty.find((member) => member.id === 'mira')
- partyRef.current = nextParty
- setParty(nextParty)
if (
healerBeforeDamage
@@ -911,16 +954,30 @@ export function CombatScreen({
}
if (nextParty.every((member) => member.health <= 0)) {
+ setCombat({
+ ...current,
+ party: nextParty,
+ resource: nextResource,
+ cooldowns: nextCooldowns,
+ elapsedTicks: nextElapsedTicks,
+ enemyHealth: current.enemyHealth,
+ })
if (isRoguelike) finishRoguelikeRun(encounterIndex)
setStatus('lost')
addLog('The party has fallen.', 'danger')
return
}
- const nextEnemyHealth = enemyHealthRef.current - encounter.partyDamage
+ const nextEnemyHealth = current.enemyHealth - encounter.partyDamage
if (nextEnemyHealth > 0) {
- enemyHealthRef.current = nextEnemyHealth
- setEnemyHealth(nextEnemyHealth)
+ setCombat({
+ ...current,
+ party: nextParty,
+ resource: nextResource,
+ cooldowns: nextCooldowns,
+ elapsedTicks: nextElapsedTicks,
+ enemyHealth: nextEnemyHealth,
+ })
return
}
@@ -929,8 +986,14 @@ export function CombatScreen({
}
if (isRoguelike && (upgradesEveryEncounter || encounter.isBoss)) {
- enemyHealthRef.current = 0
- setEnemyHealth(0)
+ setCombat({
+ ...current,
+ party: nextParty,
+ resource: nextResource,
+ cooldowns: nextCooldowns,
+ elapsedTicks: nextElapsedTicks,
+ enemyHealth: 0,
+ })
setUpgradeChoices(chooseRandom(roguelikeUpgradeCatalog, 3))
setStatus('upgrade-choice')
addLog(`${encounter.enemyName} defeated. Choose an upgrade.`, 'loot')
@@ -938,16 +1001,28 @@ export function CombatScreen({
}
if (isPartBoss && !isFinalBoss) {
- enemyHealthRef.current = 0
- setEnemyHealth(0)
+ setCombat({
+ ...current,
+ party: nextParty,
+ resource: nextResource,
+ cooldowns: nextCooldowns,
+ elapsedTicks: nextElapsedTicks,
+ enemyHealth: 0,
+ })
setStatus('part-complete')
addLog(`${encounter.enemyName} is defeated.`, 'loot')
return
}
if (encounterIndex === encounters.length - 1) {
- enemyHealthRef.current = 0
- setEnemyHealth(0)
+ setCombat({
+ ...current,
+ party: nextParty,
+ resource: nextResource,
+ cooldowns: nextCooldowns,
+ elapsedTicks: nextElapsedTicks,
+ enemyHealth: 0,
+ })
finishRun(currentPart, startPart)
addLog(`${encounter.enemyName} is defeated. Rolling its loot table.`, 'loot')
return
@@ -965,13 +1040,15 @@ export function CombatScreen({
maxHealthPenaltyTicks: undefined,
healingReductionTicks: undefined,
}))
- partyRef.current = recoveredParty
- enemyHealthRef.current = nextEncounter.maxHealth
- setParty(recoveredParty)
setEncounterIndex((value) => value + 1)
- setEnemyHealth(nextEncounter.maxHealth)
- elapsedTicksRef.current = 0
- setElapsedTicks(0)
+ setCombat({
+ ...current,
+ party: recoveredParty,
+ resource: nextResource,
+ cooldowns: nextCooldowns,
+ elapsedTicks: 0,
+ enemyHealth: nextEncounter.maxHealth,
+ })
addLog(`${encounter.enemyName} defeated. ${nextEncounter.enemyName} approaches.`, 'system')
}, TICK_MS)
return () => window.clearInterval(timer)
@@ -994,6 +1071,7 @@ export function CombatScreen({
gameClass.resourceName,
requestLootRoll,
profile.character.name,
+ setCombat,
startPart,
status,
currentPart,
@@ -1398,19 +1476,20 @@ export function CombatScreen({
const nextIndex = encounterIndex + 1
partStartTimesRef.current[currentPart + 1] = Date.now()
const nextEncounter = encounters[nextIndex]
- const recoveredParty = partyRef.current.map((member) => ({
+ const current = combatRef.current
+ const recoveredParty = current.party.map((member) => ({
...member,
health: clamp(member.health + 35, 0, member.maxHealth),
debuff: undefined,
debuffTicks: undefined,
}))
- partyRef.current = recoveredParty
- enemyHealthRef.current = nextEncounter.maxHealth
- setParty(recoveredParty)
setEncounterIndex(nextIndex)
- setEnemyHealth(nextEncounter.maxHealth)
- elapsedTicksRef.current = 0
- setElapsedTicks(0)
+ setCombat({
+ ...current,
+ party: recoveredParty,
+ enemyHealth: nextEncounter.maxHealth,
+ elapsedTicks: 0,
+ })
setStatus('playing')
addLog(`Proceeding to ${sectionName} ${currentPart + 1}. ${nextEncounter.enemyName} approaches.`, 'system')
}}
diff --git a/src/components/EquipmentScreen.tsx b/src/components/EquipmentScreen.tsx
index 60f8913..d726775 100644
--- a/src/components/EquipmentScreen.tsx
+++ b/src/components/EquipmentScreen.tsx
@@ -61,15 +61,24 @@ export function EquipmentScreen({ profile, onBack, onUpdated, embedded = false }
firstRecipe?.id ?? null,
)
const selectedRecipe = profile.craftingRecipes.find((recipe) => recipe.id === selectedRecipeId)
+ const selectedRecipeRequiresUpgrade = selectedRecipe
+ ? profile.craftingRecipes.some((recipe) =>
+ recipe.sourceEncounterId === selectedRecipe.sourceEncounterId
+ && recipe.item.slot === selectedRecipe.item.slot
+ && recipe.item.itemLevel < selectedRecipe.item.itemLevel,
+ )
+ : false
const selectedItemRecipe = selectedItem
? profile.craftingRecipes.find((recipe) => recipe.item.id === selectedItem.id)
: undefined
const upgradeRecipe = selectedItem && selectedItemRecipe
- ? profile.craftingRecipes.find((recipe) =>
- recipe.sourceEncounterId === selectedItemRecipe.sourceEncounterId
- && recipe.item.slot === selectedItem.slot
- && recipe.item.itemLevel === selectedItem.itemLevel + 5,
- )
+ ? profile.craftingRecipes
+ .filter((recipe) =>
+ recipe.sourceEncounterId === selectedItemRecipe.sourceEncounterId
+ && recipe.item.slot === selectedItem.slot
+ && recipe.item.itemLevel > selectedItem.itemLevel,
+ )
+ .sort((left, right) => left.item.itemLevel - right.item.itemLevel)[0]
: undefined
const equippedBySlot = useMemo(
() => new Map(
@@ -503,11 +512,11 @@ export function EquipmentScreen({ profile, onBack, onUpdated, embedded = false }
)}
diff --git a/src/gameRepository.ts b/src/gameRepository.ts
index 2e924aa..422cecf 100644
--- a/src/gameRepository.ts
+++ b/src/gameRepository.ts
@@ -760,8 +760,7 @@ function emptyCharacterData(classId: number): CharacterData {
const gc = static_.classes.find((c) => c.id === classId)!
const talentRanks: Record
= {}
for (const t of gc.talents) talentRanks[String(t.id)] = 0
- const starterItemIds = [100, 101, 102, 103, 104, 105, 106, 107, 108, 109]
- const inventory: Item[] = static_.inventory.filter((i) => starterItemIds.includes(i.id)).map((i) => ({ ...i }))
+ const inventory: Item[] = []
const startingAbilitySlots: Array = gc.spells
.filter((s) => s.unlockLevel === 1)
.slice(0, 5)
@@ -1164,6 +1163,12 @@ function createLocalRepository(store: LocalSaveStore): GameRepository {
const profile = buildProfile(save)
const recipe = profile.craftingRecipes.find((candidate) => candidate.id === recipeId)
if (!recipe) throw new Error('That crafting recipe does not exist.')
+ const requiresUpgrade = profile.craftingRecipes.some((candidate) =>
+ candidate.sourceEncounterId === recipe.sourceEncounterId
+ && candidate.item.slot === recipe.item.slot
+ && candidate.item.itemLevel < recipe.item.itemLevel,
+ )
+ if (requiresUpgrade) throw new Error('Upgrade the previous item tier instead.')
const missing = recipe.components.find((component) => component.owned < component.quantity)
if (missing) {
throw new Error(`Need ${missing.quantity} ${missing.item.name} to craft this item.`)
@@ -1191,11 +1196,13 @@ function createLocalRepository(store: LocalSaveStore): GameRepository {
if (item.slot === 'component') throw new Error('Components cannot be upgraded.')
const currentRecipe = profile.craftingRecipes.find((recipe) => recipe.item.id === item.id)
const targetRecipe = currentRecipe
- ? profile.craftingRecipes.find((recipe) =>
- recipe.sourceEncounterId === currentRecipe.sourceEncounterId
- && recipe.item.slot === item.slot
- && recipe.item.itemLevel === item.itemLevel + 5,
- )
+ ? profile.craftingRecipes
+ .filter((recipe) =>
+ recipe.sourceEncounterId === currentRecipe.sourceEncounterId
+ && recipe.item.slot === item.slot
+ && recipe.item.itemLevel > item.itemLevel,
+ )
+ .sort((left, right) => left.item.itemLevel - right.item.itemLevel)[0]
: null
if (!targetRecipe) throw new Error('No upgrade is available for this item.')
const missing = targetRecipe.components.find((component) => component.owned < component.quantity)
diff --git a/src/input.tsx b/src/input.tsx
index c65cb03..61351f0 100644
--- a/src/input.tsx
+++ b/src/input.tsx
@@ -121,6 +121,7 @@ const STORAGE_KEY = 'ashen-halls-input-bindings-v1'
const PREFERENCES_STORAGE_KEY = 'ashen-halls-input-preferences-v1'
const GAME_ACTION_EVENT = 'ashen-halls-game-action'
const NATIVE_CONTROLLER_EVENT = 'ashen-halls-native-controller'
+const COMBAT_TARGET_NAVIGATION_THROTTLE_MS = 220
type CaptureState = {
device: InputDevice
@@ -446,7 +447,7 @@ export function InputProvider({ children }: { children: ReactNode }) {
const combatActive = Boolean(document.querySelector('[data-combat-active="true"]'))
if (combatActive && !uiOverlay && isCombatTargetAction(action)) {
const now = performance.now()
- if (now - lastCombatNavigationRef.current < 125) return
+ if (now - lastCombatNavigationRef.current < COMBAT_TARGET_NAVIGATION_THROTTLE_MS) return
lastCombatNavigationRef.current = now
}
diff --git a/src/offline-starter-profile.json b/src/offline-starter-profile.json
index 5ec34fe..7fd4f5f 100644
--- a/src/offline-starter-profile.json
+++ b/src/offline-starter-profile.json
@@ -812,182 +812,11 @@
"necklace",
"trinket"
],
- "inventory": [
- {
- "id": 104,
- "slug": "novice-slippers",
- "name": "Novice Slippers",
- "slot": "boots",
- "rarity": "common",
- "itemLevel": 1,
- "healingPower": 0,
- "maxResourceBonus": 1,
- "glyph": "b",
- "description": "Comfortable enough for a first expedition.",
- "setId": null,
- "setSlug": null,
- "setName": null,
- "quantity": 1,
- "equipped": true
- },
- {
- "id": 102,
- "slug": "novice-vestment",
- "name": "Novice Vestment",
- "slot": "chest",
- "rarity": "common",
- "itemLevel": 1,
- "healingPower": 1,
- "maxResourceBonus": 0,
- "glyph": "C",
- "description": "Unadorned robes issued to apprentice healers.",
- "setId": null,
- "setSlug": null,
- "setName": null,
- "quantity": 1,
- "equipped": true
- },
- {
- "id": 103,
- "slug": "novice-wraps",
- "name": "Novice Wraps",
- "slot": "gloves",
- "rarity": "common",
- "itemLevel": 1,
- "healingPower": 1,
- "maxResourceBonus": 0,
- "glyph": "g",
- "description": "Soft wraps that leave the fingers free for spellwork.",
- "setId": null,
- "setSlug": null,
- "setName": null,
- "quantity": 1,
- "equipped": true
- },
- {
- "id": 101,
- "slug": "novice-cowl",
- "name": "Novice Cowl",
- "slot": "helmet",
- "rarity": "common",
- "itemLevel": 1,
- "healingPower": 0,
- "maxResourceBonus": 1,
- "glyph": "^",
- "description": "Plain cloth that helps steady a beginner's thoughts.",
- "setId": null,
- "setSlug": null,
- "setName": null,
- "quantity": 1,
- "equipped": true
- },
- {
- "id": 109,
- "slug": "novice-pendant",
- "name": "Novice Pendant",
- "slot": "necklace",
- "rarity": "common",
- "itemLevel": 1,
- "healingPower": 1,
- "maxResourceBonus": 0,
- "glyph": "n",
- "description": "A simple charm worn by apprentice healers.",
- "setId": null,
- "setSlug": null,
- "setName": null,
- "quantity": 1,
- "equipped": true
- },
- {
- "id": 108,
- "slug": "novice-trousers",
- "name": "Novice Trousers",
- "slot": "pants",
- "rarity": "common",
- "itemLevel": 1,
- "healingPower": 0,
- "maxResourceBonus": 1,
- "glyph": "P",
- "description": "Plain trousers for a first expedition.",
- "setId": null,
- "setSlug": null,
- "setName": null,
- "quantity": 1,
- "equipped": true
- },
- {
- "id": 105,
- "slug": "novice-band",
- "name": "Novice Band",
- "slot": "ring",
- "rarity": "common",
- "itemLevel": 1,
- "healingPower": 0,
- "maxResourceBonus": 1,
- "glyph": "o",
- "description": "A copper band etched with a minor restorative rune.",
- "setId": null,
- "setSlug": null,
- "setName": null,
- "quantity": 1,
- "equipped": true
- },
- {
- "id": 106,
- "slug": "novice-token",
- "name": "Novice Token",
- "slot": "trinket",
- "rarity": "common",
- "itemLevel": 1,
- "healingPower": 1,
- "maxResourceBonus": 0,
- "glyph": "*",
- "description": "A small charm commemorating the healer's oath.",
- "setId": null,
- "setSlug": null,
- "setName": null,
- "quantity": 1,
- "equipped": true
- },
- {
- "id": 100,
- "slug": "novice-crook",
- "name": "Novice Crook",
- "slot": "weapon",
- "rarity": "common",
- "itemLevel": 1,
- "healingPower": 1,
- "maxResourceBonus": 0,
- "glyph": "/",
- "description": "A simple focus carried by every new healer.",
- "setId": null,
- "setSlug": null,
- "setName": null,
- "quantity": 1,
- "equipped": true
- },
- {
- "id": 107,
- "slug": "novice-wand",
- "name": "Novice Wand",
- "slot": "weapon",
- "rarity": "common",
- "itemLevel": 1,
- "healingPower": 0,
- "maxResourceBonus": 2,
- "glyph": "!",
- "description": "A spare focus that favors a deeper resource pool.",
- "setId": null,
- "setSlug": null,
- "setName": null,
- "quantity": 1,
- "equipped": false
- }
- ],
+ "inventory": [],
"gearStats": {
- "averageItemLevel": 1,
- "healingPower": 5,
- "maxResourceBonus": 4
+ "averageItemLevel": 0,
+ "healingPower": 0,
+ "maxResourceBonus": 0
},
"setBonuses": [
{
@@ -1022,6 +851,366 @@
}
],
"craftingRecipes": [
+ {
+ "id": 904,
+ "difficultyId": 1,
+ "sourceDungeonId": 1,
+ "sourceEncounterId": 12,
+ "item": {
+ "id": 104,
+ "slug": "novice-slippers",
+ "name": "Raw Yian Kut-Ku Boots",
+ "slot": "boots",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 0,
+ "maxResourceBonus": 1,
+ "glyph": "b",
+ "description": "Crafted with Yian Kut-Ku coins.",
+ "setId": null,
+ "setSlug": null,
+ "setName": null
+ },
+ "components": [
+ {
+ "item": {
+ "id": 281201,
+ "slug": "yian-kut-ku-coin-ilvl-1",
+ "name": "Raw Yian Kut-Ku Coin",
+ "slot": "component",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 0,
+ "maxResourceBonus": 0,
+ "glyph": "$",
+ "description": "A boss coin from Yian Kut-Ku used for item level 1 crafting."
+ },
+ "quantity": 1,
+ "owned": 0
+ }
+ ],
+ "canCraft": false
+ },
+ {
+ "id": 902,
+ "difficultyId": 1,
+ "sourceDungeonId": 1,
+ "sourceEncounterId": 3,
+ "item": {
+ "id": 102,
+ "slug": "novice-vestment",
+ "name": "Raw Bulldrome Chest",
+ "slot": "chest",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 1,
+ "maxResourceBonus": 0,
+ "glyph": "C",
+ "description": "Crafted with Bulldrome coins.",
+ "setId": null,
+ "setSlug": null,
+ "setName": null
+ },
+ "components": [
+ {
+ "item": {
+ "id": 280301,
+ "slug": "bulldrome-coin-ilvl-1",
+ "name": "Raw Bulldrome Coin",
+ "slot": "component",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 0,
+ "maxResourceBonus": 0,
+ "glyph": "$",
+ "description": "A boss coin from Bulldrome used for item level 1 crafting."
+ },
+ "quantity": 1,
+ "owned": 0
+ }
+ ],
+ "canCraft": false
+ },
+ {
+ "id": 903,
+ "difficultyId": 1,
+ "sourceDungeonId": 1,
+ "sourceEncounterId": 3,
+ "item": {
+ "id": 103,
+ "slug": "novice-wraps",
+ "name": "Raw Bulldrome Gloves",
+ "slot": "gloves",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 1,
+ "maxResourceBonus": 0,
+ "glyph": "g",
+ "description": "Crafted with Bulldrome coins.",
+ "setId": null,
+ "setSlug": null,
+ "setName": null
+ },
+ "components": [
+ {
+ "item": {
+ "id": 280301,
+ "slug": "bulldrome-coin-ilvl-1",
+ "name": "Raw Bulldrome Coin",
+ "slot": "component",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 0,
+ "maxResourceBonus": 0,
+ "glyph": "$",
+ "description": "A boss coin from Bulldrome used for item level 1 crafting."
+ },
+ "quantity": 1,
+ "owned": 0
+ }
+ ],
+ "canCraft": false
+ },
+ {
+ "id": 901,
+ "difficultyId": 1,
+ "sourceDungeonId": 1,
+ "sourceEncounterId": 3,
+ "item": {
+ "id": 101,
+ "slug": "novice-cowl",
+ "name": "Raw Bulldrome Helmet",
+ "slot": "helmet",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 0,
+ "maxResourceBonus": 1,
+ "glyph": "^",
+ "description": "Crafted with Bulldrome coins.",
+ "setId": null,
+ "setSlug": null,
+ "setName": null
+ },
+ "components": [
+ {
+ "item": {
+ "id": 280301,
+ "slug": "bulldrome-coin-ilvl-1",
+ "name": "Raw Bulldrome Coin",
+ "slot": "component",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 0,
+ "maxResourceBonus": 0,
+ "glyph": "$",
+ "description": "A boss coin from Bulldrome used for item level 1 crafting."
+ },
+ "quantity": 1,
+ "owned": 0
+ }
+ ],
+ "canCraft": false
+ },
+ {
+ "id": 909,
+ "difficultyId": 1,
+ "sourceDungeonId": 1,
+ "sourceEncounterId": 22,
+ "item": {
+ "id": 109,
+ "slug": "novice-pendant",
+ "name": "Raw Rathian Necklace",
+ "slot": "necklace",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 1,
+ "maxResourceBonus": 0,
+ "glyph": "n",
+ "description": "Crafted with Rathian coins.",
+ "setId": null,
+ "setSlug": null,
+ "setName": null
+ },
+ "components": [
+ {
+ "item": {
+ "id": 282201,
+ "slug": "rathian-coin-ilvl-1",
+ "name": "Raw Rathian Coin",
+ "slot": "component",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 0,
+ "maxResourceBonus": 0,
+ "glyph": "$",
+ "description": "A boss coin from Rathian used for item level 1 crafting."
+ },
+ "quantity": 1,
+ "owned": 0
+ }
+ ],
+ "canCraft": false
+ },
+ {
+ "id": 908,
+ "difficultyId": 1,
+ "sourceDungeonId": 1,
+ "sourceEncounterId": 22,
+ "item": {
+ "id": 108,
+ "slug": "novice-trousers",
+ "name": "Raw Rathian Pants",
+ "slot": "pants",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 0,
+ "maxResourceBonus": 1,
+ "glyph": "P",
+ "description": "Crafted with Rathian coins.",
+ "setId": null,
+ "setSlug": null,
+ "setName": null
+ },
+ "components": [
+ {
+ "item": {
+ "id": 282201,
+ "slug": "rathian-coin-ilvl-1",
+ "name": "Raw Rathian Coin",
+ "slot": "component",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 0,
+ "maxResourceBonus": 0,
+ "glyph": "$",
+ "description": "A boss coin from Rathian used for item level 1 crafting."
+ },
+ "quantity": 1,
+ "owned": 0
+ }
+ ],
+ "canCraft": false
+ },
+ {
+ "id": 905,
+ "difficultyId": 1,
+ "sourceDungeonId": 1,
+ "sourceEncounterId": 12,
+ "item": {
+ "id": 105,
+ "slug": "novice-band",
+ "name": "Raw Yian Kut-Ku Ring",
+ "slot": "ring",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 0,
+ "maxResourceBonus": 1,
+ "glyph": "o",
+ "description": "Crafted with Yian Kut-Ku coins.",
+ "setId": null,
+ "setSlug": null,
+ "setName": null
+ },
+ "components": [
+ {
+ "item": {
+ "id": 281201,
+ "slug": "yian-kut-ku-coin-ilvl-1",
+ "name": "Raw Yian Kut-Ku Coin",
+ "slot": "component",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 0,
+ "maxResourceBonus": 0,
+ "glyph": "$",
+ "description": "A boss coin from Yian Kut-Ku used for item level 1 crafting."
+ },
+ "quantity": 1,
+ "owned": 0
+ }
+ ],
+ "canCraft": false
+ },
+ {
+ "id": 906,
+ "difficultyId": 1,
+ "sourceDungeonId": 1,
+ "sourceEncounterId": 12,
+ "item": {
+ "id": 106,
+ "slug": "novice-token",
+ "name": "Raw Yian Kut-Ku Trinket",
+ "slot": "trinket",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 1,
+ "maxResourceBonus": 0,
+ "glyph": "*",
+ "description": "Crafted with Yian Kut-Ku coins.",
+ "setId": null,
+ "setSlug": null,
+ "setName": null
+ },
+ "components": [
+ {
+ "item": {
+ "id": 281201,
+ "slug": "yian-kut-ku-coin-ilvl-1",
+ "name": "Raw Yian Kut-Ku Coin",
+ "slot": "component",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 0,
+ "maxResourceBonus": 0,
+ "glyph": "$",
+ "description": "A boss coin from Yian Kut-Ku used for item level 1 crafting."
+ },
+ "quantity": 1,
+ "owned": 0
+ }
+ ],
+ "canCraft": false
+ },
+ {
+ "id": 907,
+ "difficultyId": 1,
+ "sourceDungeonId": 1,
+ "sourceEncounterId": 22,
+ "item": {
+ "id": 100,
+ "slug": "novice-crook",
+ "name": "Raw Rathian Weapon",
+ "slot": "weapon",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 1,
+ "maxResourceBonus": 0,
+ "glyph": "/",
+ "description": "Crafted with Rathian coins.",
+ "setId": null,
+ "setSlug": null,
+ "setName": null
+ },
+ "components": [
+ {
+ "item": {
+ "id": 282201,
+ "slug": "rathian-coin-ilvl-1",
+ "name": "Raw Rathian Coin",
+ "slot": "component",
+ "rarity": "common",
+ "itemLevel": 1,
+ "healingPower": 0,
+ "maxResourceBonus": 0,
+ "glyph": "$",
+ "description": "A boss coin from Rathian used for item level 1 crafting."
+ },
+ "quantity": 1,
+ "owned": 0
+ }
+ ],
+ "canCraft": false
+ },
{
"id": 1004,
"difficultyId": 1,
@@ -1030,7 +1219,7 @@
"item": {
"id": 4,
"slug": "cinderstep-boots",
- "name": "Yian Kut-Ku Boots",
+ "name": "Honed Yian Kut-Ku Boots",
"slot": "boots",
"rarity": "common",
"itemLevel": 5,
@@ -1045,16 +1234,16 @@
"components": [
{
"item": {
- "id": 281205,
- "slug": "yian-kut-ku-coin-ilvl-5",
- "name": "Yian Kut-Ku Coin",
+ "id": 281201,
+ "slug": "yian-kut-ku-coin-ilvl-1",
+ "name": "Raw Yian Kut-Ku Coin",
"slot": "component",
"rarity": "common",
- "itemLevel": 5,
+ "itemLevel": 1,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Yian Kut-Ku used for item level 5 crafting."
+ "description": "A boss coin from Yian Kut-Ku used for item level 1 crafting."
},
"quantity": 5,
"owned": 0
@@ -1070,7 +1259,7 @@
"item": {
"id": 2,
"slug": "wardens-cinderwrap",
- "name": "Bulldrome Chest",
+ "name": "Honed Bulldrome Chest",
"slot": "chest",
"rarity": "common",
"itemLevel": 5,
@@ -1085,16 +1274,16 @@
"components": [
{
"item": {
- "id": 280305,
- "slug": "bulldrome-coin-ilvl-5",
- "name": "Bulldrome Coin",
+ "id": 280301,
+ "slug": "bulldrome-coin-ilvl-1",
+ "name": "Raw Bulldrome Coin",
"slot": "component",
"rarity": "common",
- "itemLevel": 5,
+ "itemLevel": 1,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Bulldrome used for item level 5 crafting."
+ "description": "A boss coin from Bulldrome used for item level 1 crafting."
},
"quantity": 5,
"owned": 0
@@ -1110,7 +1299,7 @@
"item": {
"id": 6,
"slug": "furnace-tenders-wraps",
- "name": "Bulldrome Gloves",
+ "name": "Honed Bulldrome Gloves",
"slot": "gloves",
"rarity": "common",
"itemLevel": 5,
@@ -1125,16 +1314,16 @@
"components": [
{
"item": {
- "id": 280305,
- "slug": "bulldrome-coin-ilvl-5",
- "name": "Bulldrome Coin",
+ "id": 280301,
+ "slug": "bulldrome-coin-ilvl-1",
+ "name": "Raw Bulldrome Coin",
"slot": "component",
"rarity": "common",
- "itemLevel": 5,
+ "itemLevel": 1,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Bulldrome used for item level 5 crafting."
+ "description": "A boss coin from Bulldrome used for item level 1 crafting."
},
"quantity": 5,
"owned": 0
@@ -1150,7 +1339,7 @@
"item": {
"id": 5,
"slug": "adepts-hood",
- "name": "Bulldrome Helmet",
+ "name": "Honed Bulldrome Helmet",
"slot": "helmet",
"rarity": "common",
"itemLevel": 5,
@@ -1165,16 +1354,16 @@
"components": [
{
"item": {
- "id": 280305,
- "slug": "bulldrome-coin-ilvl-5",
- "name": "Bulldrome Coin",
+ "id": 280301,
+ "slug": "bulldrome-coin-ilvl-1",
+ "name": "Raw Bulldrome Coin",
"slot": "component",
"rarity": "common",
- "itemLevel": 5,
+ "itemLevel": 1,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Bulldrome used for item level 5 crafting."
+ "description": "A boss coin from Bulldrome used for item level 1 crafting."
},
"quantity": 5,
"owned": 0
@@ -1190,7 +1379,7 @@
"item": {
"id": 9,
"slug": "sootglass-pendant",
- "name": "Rathian Necklace",
+ "name": "Honed Rathian Necklace",
"slot": "necklace",
"rarity": "common",
"itemLevel": 5,
@@ -1205,16 +1394,16 @@
"components": [
{
"item": {
- "id": 282205,
- "slug": "rathian-coin-ilvl-5",
- "name": "Rathian Coin",
+ "id": 282201,
+ "slug": "rathian-coin-ilvl-1",
+ "name": "Raw Rathian Coin",
"slot": "component",
"rarity": "common",
- "itemLevel": 5,
+ "itemLevel": 1,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Rathian used for item level 5 crafting."
+ "description": "A boss coin from Rathian used for item level 1 crafting."
},
"quantity": 5,
"owned": 0
@@ -1230,7 +1419,7 @@
"item": {
"id": 8,
"slug": "ashwalker-legwraps",
- "name": "Rathian Pants",
+ "name": "Honed Rathian Pants",
"slot": "pants",
"rarity": "common",
"itemLevel": 5,
@@ -1245,16 +1434,16 @@
"components": [
{
"item": {
- "id": 282205,
- "slug": "rathian-coin-ilvl-5",
- "name": "Rathian Coin",
+ "id": 282201,
+ "slug": "rathian-coin-ilvl-1",
+ "name": "Raw Rathian Coin",
"slot": "component",
"rarity": "common",
- "itemLevel": 5,
+ "itemLevel": 1,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Rathian used for item level 5 crafting."
+ "description": "A boss coin from Rathian used for item level 1 crafting."
},
"quantity": 5,
"owned": 0
@@ -1270,7 +1459,7 @@
"item": {
"id": 1,
"slug": "emberglass-sigil",
- "name": "Yian Kut-Ku Ring",
+ "name": "Honed Yian Kut-Ku Ring",
"slot": "ring",
"rarity": "common",
"itemLevel": 5,
@@ -1285,16 +1474,16 @@
"components": [
{
"item": {
- "id": 281205,
- "slug": "yian-kut-ku-coin-ilvl-5",
- "name": "Yian Kut-Ku Coin",
+ "id": 281201,
+ "slug": "yian-kut-ku-coin-ilvl-1",
+ "name": "Raw Yian Kut-Ku Coin",
"slot": "component",
"rarity": "common",
- "itemLevel": 5,
+ "itemLevel": 1,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Yian Kut-Ku used for item level 5 crafting."
+ "description": "A boss coin from Yian Kut-Ku used for item level 1 crafting."
},
"quantity": 5,
"owned": 0
@@ -1310,7 +1499,7 @@
"item": {
"id": 7,
"slug": "warden-ember",
- "name": "Yian Kut-Ku Trinket",
+ "name": "Honed Yian Kut-Ku Trinket",
"slot": "trinket",
"rarity": "common",
"itemLevel": 5,
@@ -1325,16 +1514,16 @@
"components": [
{
"item": {
- "id": 281205,
- "slug": "yian-kut-ku-coin-ilvl-5",
- "name": "Yian Kut-Ku Coin",
+ "id": 281201,
+ "slug": "yian-kut-ku-coin-ilvl-1",
+ "name": "Raw Yian Kut-Ku Coin",
"slot": "component",
"rarity": "common",
- "itemLevel": 5,
+ "itemLevel": 1,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Yian Kut-Ku used for item level 5 crafting."
+ "description": "A boss coin from Yian Kut-Ku used for item level 1 crafting."
},
"quantity": 5,
"owned": 0
@@ -1350,7 +1539,7 @@
"item": {
"id": 3,
"slug": "ashwood-crook",
- "name": "Rathian Weapon",
+ "name": "Honed Rathian Weapon",
"slot": "weapon",
"rarity": "common",
"itemLevel": 5,
@@ -1365,16 +1554,16 @@
"components": [
{
"item": {
- "id": 282205,
- "slug": "rathian-coin-ilvl-5",
- "name": "Rathian Coin",
+ "id": 282201,
+ "slug": "rathian-coin-ilvl-1",
+ "name": "Raw Rathian Coin",
"slot": "component",
"rarity": "common",
- "itemLevel": 5,
+ "itemLevel": 1,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Rathian used for item level 5 crafting."
+ "description": "A boss coin from Rathian used for item level 1 crafting."
},
"quantity": 5,
"owned": 0
@@ -1744,7 +1933,7 @@
},
{
"id": 1204,
- "difficultyId": 3,
+ "difficultyId": 2,
"sourceDungeonId": 1,
"sourceEncounterId": 12,
"item": {
@@ -1765,16 +1954,16 @@
"components": [
{
"item": {
- "id": 281215,
- "slug": "yian-kut-ku-coin-ilvl-15",
- "name": "Blue Yian Kut-Ku Coin",
+ "id": 281210,
+ "slug": "yian-kut-ku-coin-ilvl-10",
+ "name": "Green Yian Kut-Ku Coin",
"slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
+ "rarity": "uncommon",
+ "itemLevel": 10,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Yian Kut-Ku used for item level 15 crafting."
+ "description": "A boss coin from Yian Kut-Ku used for item level 10 crafting."
},
"quantity": 15,
"owned": 0
@@ -1784,7 +1973,7 @@
},
{
"id": 1202,
- "difficultyId": 3,
+ "difficultyId": 2,
"sourceDungeonId": 1,
"sourceEncounterId": 3,
"item": {
@@ -1805,16 +1994,16 @@
"components": [
{
"item": {
- "id": 280315,
- "slug": "bulldrome-coin-ilvl-15",
- "name": "Blue Bulldrome Coin",
+ "id": 280310,
+ "slug": "bulldrome-coin-ilvl-10",
+ "name": "Green Bulldrome Coin",
"slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
+ "rarity": "uncommon",
+ "itemLevel": 10,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Bulldrome used for item level 15 crafting."
+ "description": "A boss coin from Bulldrome used for item level 10 crafting."
},
"quantity": 15,
"owned": 0
@@ -1824,7 +2013,7 @@
},
{
"id": 1203,
- "difficultyId": 3,
+ "difficultyId": 2,
"sourceDungeonId": 1,
"sourceEncounterId": 3,
"item": {
@@ -1845,16 +2034,16 @@
"components": [
{
"item": {
- "id": 280315,
- "slug": "bulldrome-coin-ilvl-15",
- "name": "Blue Bulldrome Coin",
+ "id": 280310,
+ "slug": "bulldrome-coin-ilvl-10",
+ "name": "Green Bulldrome Coin",
"slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
+ "rarity": "uncommon",
+ "itemLevel": 10,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Bulldrome used for item level 15 crafting."
+ "description": "A boss coin from Bulldrome used for item level 10 crafting."
},
"quantity": 15,
"owned": 0
@@ -1864,7 +2053,7 @@
},
{
"id": 1201,
- "difficultyId": 3,
+ "difficultyId": 2,
"sourceDungeonId": 1,
"sourceEncounterId": 3,
"item": {
@@ -1885,16 +2074,16 @@
"components": [
{
"item": {
- "id": 280315,
- "slug": "bulldrome-coin-ilvl-15",
- "name": "Blue Bulldrome Coin",
+ "id": 280310,
+ "slug": "bulldrome-coin-ilvl-10",
+ "name": "Green Bulldrome Coin",
"slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
+ "rarity": "uncommon",
+ "itemLevel": 10,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Bulldrome used for item level 15 crafting."
+ "description": "A boss coin from Bulldrome used for item level 10 crafting."
},
"quantity": 15,
"owned": 0
@@ -1904,7 +2093,7 @@
},
{
"id": 1209,
- "difficultyId": 3,
+ "difficultyId": 2,
"sourceDungeonId": 1,
"sourceEncounterId": 22,
"item": {
@@ -1925,16 +2114,16 @@
"components": [
{
"item": {
- "id": 282215,
- "slug": "rathian-coin-ilvl-15",
- "name": "Blue Rathian Coin",
+ "id": 282210,
+ "slug": "rathian-coin-ilvl-10",
+ "name": "Green Rathian Coin",
"slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
+ "rarity": "uncommon",
+ "itemLevel": 10,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Rathian used for item level 15 crafting."
+ "description": "A boss coin from Rathian used for item level 10 crafting."
},
"quantity": 15,
"owned": 0
@@ -1944,7 +2133,7 @@
},
{
"id": 1208,
- "difficultyId": 3,
+ "difficultyId": 2,
"sourceDungeonId": 1,
"sourceEncounterId": 22,
"item": {
@@ -1965,16 +2154,16 @@
"components": [
{
"item": {
- "id": 282215,
- "slug": "rathian-coin-ilvl-15",
- "name": "Blue Rathian Coin",
+ "id": 282210,
+ "slug": "rathian-coin-ilvl-10",
+ "name": "Green Rathian Coin",
"slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
+ "rarity": "uncommon",
+ "itemLevel": 10,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Rathian used for item level 15 crafting."
+ "description": "A boss coin from Rathian used for item level 10 crafting."
},
"quantity": 15,
"owned": 0
@@ -1984,7 +2173,7 @@
},
{
"id": 1205,
- "difficultyId": 3,
+ "difficultyId": 2,
"sourceDungeonId": 1,
"sourceEncounterId": 12,
"item": {
@@ -2005,16 +2194,16 @@
"components": [
{
"item": {
- "id": 281215,
- "slug": "yian-kut-ku-coin-ilvl-15",
- "name": "Blue Yian Kut-Ku Coin",
+ "id": 281210,
+ "slug": "yian-kut-ku-coin-ilvl-10",
+ "name": "Green Yian Kut-Ku Coin",
"slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
+ "rarity": "uncommon",
+ "itemLevel": 10,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Yian Kut-Ku used for item level 15 crafting."
+ "description": "A boss coin from Yian Kut-Ku used for item level 10 crafting."
},
"quantity": 15,
"owned": 0
@@ -2024,7 +2213,7 @@
},
{
"id": 1206,
- "difficultyId": 3,
+ "difficultyId": 2,
"sourceDungeonId": 1,
"sourceEncounterId": 12,
"item": {
@@ -2045,16 +2234,16 @@
"components": [
{
"item": {
- "id": 281215,
- "slug": "yian-kut-ku-coin-ilvl-15",
- "name": "Blue Yian Kut-Ku Coin",
+ "id": 281210,
+ "slug": "yian-kut-ku-coin-ilvl-10",
+ "name": "Green Yian Kut-Ku Coin",
"slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
+ "rarity": "uncommon",
+ "itemLevel": 10,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Yian Kut-Ku used for item level 15 crafting."
+ "description": "A boss coin from Yian Kut-Ku used for item level 10 crafting."
},
"quantity": 15,
"owned": 0
@@ -2064,7 +2253,7 @@
},
{
"id": 1207,
- "difficultyId": 3,
+ "difficultyId": 2,
"sourceDungeonId": 1,
"sourceEncounterId": 22,
"item": {
@@ -2085,16 +2274,16 @@
"components": [
{
"item": {
- "id": 282215,
- "slug": "rathian-coin-ilvl-15",
- "name": "Blue Rathian Coin",
+ "id": 282210,
+ "slug": "rathian-coin-ilvl-10",
+ "name": "Green Rathian Coin",
"slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
+ "rarity": "uncommon",
+ "itemLevel": 10,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Rathian used for item level 15 crafting."
+ "description": "A boss coin from Rathian used for item level 10 crafting."
},
"quantity": 15,
"owned": 0
@@ -3201,12 +3390,12 @@
"id": 1,
"slug": "initiate",
"name": "Initiate",
- "droppedItemLevel": 5,
+ "droppedItemLevel": 1,
"unlockLevel": 1,
- "healthMultiplier": 1,
- "damageMultiplier": 1,
+ "healthMultiplier": 0.8,
+ "damageMultiplier": 0.8,
"experienceMultiplier": 1,
- "description": "Entry-level dungeon difficulty."
+ "description": "Entry-level dungeon difficulty for crafting the first real set."
},
{
"dungeonId": 1,
@@ -3214,23 +3403,11 @@
"slug": "veteran",
"name": "Veteran",
"droppedItemLevel": 10,
- "unlockLevel": 5,
- "healthMultiplier": 1.35,
- "damageMultiplier": 1.2,
- "experienceMultiplier": 1.5,
- "description": "Enemies deal more damage and drop stronger gear."
- },
- {
- "dungeonId": 1,
- "id": 3,
- "slug": "champion",
- "name": "Champion",
- "droppedItemLevel": 15,
"unlockLevel": 10,
- "healthMultiplier": 1.7,
- "damageMultiplier": 1.45,
- "experienceMultiplier": 2.2,
- "description": "Demanding encounters for developed characters."
+ "healthMultiplier": 1.45,
+ "damageMultiplier": 1.25,
+ "experienceMultiplier": 2,
+ "description": "A major step up that rewards refined gear components."
},
{
"dungeonId": 1,
@@ -3238,10 +3415,10 @@
"slug": "mythic",
"name": "Mythic",
"droppedItemLevel": 20,
- "unlockLevel": 15,
- "healthMultiplier": 2.1,
- "damageMultiplier": 1.75,
- "experienceMultiplier": 3,
+ "unlockLevel": 20,
+ "healthMultiplier": 2.25,
+ "damageMultiplier": 1.85,
+ "experienceMultiplier": 3.5,
"description": "Endgame dungeon difficulty."
},
{
@@ -3250,10 +3427,10 @@
"slug": "ascendant",
"name": "Ascendant",
"droppedItemLevel": 25,
- "unlockLevel": 20,
- "healthMultiplier": 2.6,
- "damageMultiplier": 2.1,
- "experienceMultiplier": 4,
+ "unlockLevel": 25,
+ "healthMultiplier": 2.8,
+ "damageMultiplier": 2.25,
+ "experienceMultiplier": 4.5,
"description": "The current pinnacle difficulty."
}
],
@@ -3310,16 +3487,16 @@
"difficultyId": 1,
"dropWeight": 100,
"dropChance": 1,
- "id": 280305,
- "slug": "bulldrome-coin-ilvl-5",
- "name": "Bulldrome Coin",
+ "id": 280301,
+ "slug": "bulldrome-coin-ilvl-1",
+ "name": "Raw Bulldrome Coin",
"slot": "component",
"rarity": "common",
- "itemLevel": 5,
+ "itemLevel": 1,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Bulldrome used for item level 5 crafting.",
+ "description": "A boss coin from Bulldrome used for item level 1 crafting.",
"setId": null,
"setSlug": null,
"setName": null
@@ -3343,25 +3520,6 @@
"setSlug": null,
"setName": null
},
- {
- "encounterId": 3,
- "difficultyId": 3,
- "dropWeight": 100,
- "dropChance": 1,
- "id": 280315,
- "slug": "bulldrome-coin-ilvl-15",
- "name": "Blue Bulldrome Coin",
- "slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
- "healingPower": 0,
- "maxResourceBonus": 0,
- "glyph": "$",
- "description": "A boss coin from Bulldrome used for item level 15 crafting.",
- "setId": null,
- "setSlug": null,
- "setName": null
- },
{
"encounterId": 3,
"difficultyId": 4,
@@ -3454,16 +3612,16 @@
"difficultyId": 1,
"dropWeight": 100,
"dropChance": 1,
- "id": 281205,
- "slug": "yian-kut-ku-coin-ilvl-5",
- "name": "Yian Kut-Ku Coin",
+ "id": 281201,
+ "slug": "yian-kut-ku-coin-ilvl-1",
+ "name": "Raw Yian Kut-Ku Coin",
"slot": "component",
"rarity": "common",
- "itemLevel": 5,
+ "itemLevel": 1,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Yian Kut-Ku used for item level 5 crafting.",
+ "description": "A boss coin from Yian Kut-Ku used for item level 1 crafting.",
"setId": null,
"setSlug": null,
"setName": null
@@ -3487,25 +3645,6 @@
"setSlug": null,
"setName": null
},
- {
- "encounterId": 12,
- "difficultyId": 3,
- "dropWeight": 100,
- "dropChance": 1,
- "id": 281215,
- "slug": "yian-kut-ku-coin-ilvl-15",
- "name": "Blue Yian Kut-Ku Coin",
- "slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
- "healingPower": 0,
- "maxResourceBonus": 0,
- "glyph": "$",
- "description": "A boss coin from Yian Kut-Ku used for item level 15 crafting.",
- "setId": null,
- "setSlug": null,
- "setName": null
- },
{
"encounterId": 12,
"difficultyId": 4,
@@ -3598,16 +3737,16 @@
"difficultyId": 1,
"dropWeight": 100,
"dropChance": 1,
- "id": 282205,
- "slug": "rathian-coin-ilvl-5",
- "name": "Rathian Coin",
+ "id": 282201,
+ "slug": "rathian-coin-ilvl-1",
+ "name": "Raw Rathian Coin",
"slot": "component",
"rarity": "common",
- "itemLevel": 5,
+ "itemLevel": 1,
"healingPower": 0,
"maxResourceBonus": 0,
"glyph": "$",
- "description": "A boss coin from Rathian used for item level 5 crafting.",
+ "description": "A boss coin from Rathian used for item level 1 crafting.",
"setId": null,
"setSlug": null,
"setName": null
@@ -3631,25 +3770,6 @@
"setSlug": null,
"setName": null
},
- {
- "encounterId": 22,
- "difficultyId": 3,
- "dropWeight": 100,
- "dropChance": 1,
- "id": 282215,
- "slug": "rathian-coin-ilvl-15",
- "name": "Blue Rathian Coin",
- "slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
- "healingPower": 0,
- "maxResourceBonus": 0,
- "glyph": "$",
- "description": "A boss coin from Rathian used for item level 15 crafting.",
- "setId": null,
- "setSlug": null,
- "setName": null
- },
{
"encounterId": 22,
"difficultyId": 4,
@@ -3718,10 +3838,10 @@
"slug": "raid-normal",
"name": "Normal",
"droppedItemLevel": 10,
- "unlockLevel": 5,
- "healthMultiplier": 1.35,
- "damageMultiplier": 1.2,
- "experienceMultiplier": 1.75,
+ "unlockLevel": 10,
+ "healthMultiplier": 1.45,
+ "damageMultiplier": 1.25,
+ "experienceMultiplier": 2,
"description": "Veteran raid difficulty with extra monster-part drops."
}
],
@@ -3958,11 +4078,11 @@
"slug": "veteran",
"name": "Veteran",
"droppedItemLevel": 10,
- "unlockLevel": 5,
- "healthMultiplier": 1.35,
- "damageMultiplier": 1.2,
- "experienceMultiplier": 1.5,
- "description": "Enemies deal more damage and drop stronger gear."
+ "unlockLevel": 10,
+ "healthMultiplier": 1.45,
+ "damageMultiplier": 1.25,
+ "experienceMultiplier": 2,
+ "description": "A major step up that rewards refined gear components."
}
],
"encounters": [
@@ -4191,226 +4311,8 @@
"experienceReward": 245,
"description": "A three-boss hunt featuring Nargacuga, Azuros, and Diablos.",
"locationName": "The Monster Frontier",
- "difficulties": [
- {
- "dungeonId": 4,
- "id": 3,
- "slug": "champion",
- "name": "Champion",
- "droppedItemLevel": 15,
- "unlockLevel": 10,
- "healthMultiplier": 1.7,
- "damageMultiplier": 1.45,
- "experienceMultiplier": 2.2,
- "description": "Demanding encounters for developed characters."
- }
- ],
- "encounters": [
- {
- "id": 401,
- "dungeonId": 4,
- "sequence": 1,
- "slug": "nargacuga-dungeon-approach",
- "enemyName": "Nargacuga Approach",
- "encounterType": "trash",
- "maxHealth": 1325,
- "damage": 18,
- "tankDamage": 10,
- "partyDamage": 28,
- "description": "Hunters clear the path before Nargacuga.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": false,
- "lootTables": []
- },
- {
- "id": 402,
- "dungeonId": 4,
- "sequence": 2,
- "slug": "nargacuga-dungeon-guardians",
- "enemyName": "Nargacuga Guardians",
- "encounterType": "trash",
- "maxHealth": 1395,
- "damage": 19,
- "tankDamage": 11,
- "partyDamage": 30,
- "description": "Hunters clear the path before Nargacuga.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": false,
- "lootTables": []
- },
- {
- "id": 403,
- "dungeonId": 4,
- "sequence": 3,
- "slug": "nargacuga-dungeon-boss",
- "enemyName": "Nargacuga",
- "encounterType": "boss",
- "maxHealth": 1655,
- "damage": 23,
- "tankDamage": 15,
- "partyDamage": 34,
- "description": "Nargacuga drops boss coins for item level 15 crafting.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": true,
- "lootTables": [
- {
- "encounterId": 403,
- "difficultyId": 3,
- "dropWeight": 100,
- "dropChance": 1,
- "id": 320315,
- "slug": "nargacuga-dungeon-boss-coin-ilvl-15",
- "name": "Blue Nargacuga Coin",
- "slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
- "healingPower": 0,
- "maxResourceBonus": 0,
- "glyph": "$",
- "description": "A boss coin from Nargacuga used for item level 15 crafting.",
- "setId": null,
- "setSlug": null,
- "setName": null
- }
- ]
- },
- {
- "id": 404,
- "dungeonId": 4,
- "sequence": 4,
- "slug": "azuros-dungeon-approach",
- "enemyName": "Azuros Approach",
- "encounterType": "trash",
- "maxHealth": 1445,
- "damage": 20,
- "tankDamage": 12,
- "partyDamage": 31,
- "description": "Hunters clear the path before Azuros.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": false,
- "lootTables": []
- },
- {
- "id": 405,
- "dungeonId": 4,
- "sequence": 5,
- "slug": "azuros-dungeon-guardians",
- "enemyName": "Azuros Guardians",
- "encounterType": "trash",
- "maxHealth": 1515,
- "damage": 21,
- "tankDamage": 13,
- "partyDamage": 33,
- "description": "Hunters clear the path before Azuros.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": false,
- "lootTables": []
- },
- {
- "id": 406,
- "dungeonId": 4,
- "sequence": 6,
- "slug": "azuros-dungeon-boss",
- "enemyName": "Azuros",
- "encounterType": "boss",
- "maxHealth": 1775,
- "damage": 25,
- "tankDamage": 17,
- "partyDamage": 37,
- "description": "Azuros drops boss coins for item level 15 crafting.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": true,
- "lootTables": [
- {
- "encounterId": 406,
- "difficultyId": 3,
- "dropWeight": 100,
- "dropChance": 1,
- "id": 320615,
- "slug": "azuros-dungeon-boss-coin-ilvl-15",
- "name": "Blue Azuros Coin",
- "slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
- "healingPower": 0,
- "maxResourceBonus": 0,
- "glyph": "$",
- "description": "A boss coin from Azuros used for item level 15 crafting.",
- "setId": null,
- "setSlug": null,
- "setName": null
- }
- ]
- },
- {
- "id": 407,
- "dungeonId": 4,
- "sequence": 7,
- "slug": "diablos-dungeon-approach",
- "enemyName": "Diablos Approach",
- "encounterType": "trash",
- "maxHealth": 1565,
- "damage": 22,
- "tankDamage": 14,
- "partyDamage": 34,
- "description": "Hunters clear the path before Diablos.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": false,
- "lootTables": []
- },
- {
- "id": 408,
- "dungeonId": 4,
- "sequence": 8,
- "slug": "diablos-dungeon-guardians",
- "enemyName": "Diablos Guardians",
- "encounterType": "trash",
- "maxHealth": 1635,
- "damage": 23,
- "tankDamage": 15,
- "partyDamage": 36,
- "description": "Hunters clear the path before Diablos.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": false,
- "lootTables": []
- },
- {
- "id": 409,
- "dungeonId": 4,
- "sequence": 9,
- "slug": "diablos-dungeon-boss",
- "enemyName": "Diablos",
- "encounterType": "boss",
- "maxHealth": 1895,
- "damage": 27,
- "tankDamage": 19,
- "partyDamage": 40,
- "description": "Diablos drops boss coins for item level 15 crafting.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": true,
- "lootTables": [
- {
- "encounterId": 409,
- "difficultyId": 3,
- "dropWeight": 100,
- "dropChance": 1,
- "id": 320915,
- "slug": "diablos-dungeon-boss-coin-ilvl-15",
- "name": "Blue Diablos Coin",
- "slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
- "healingPower": 0,
- "maxResourceBonus": 0,
- "glyph": "$",
- "description": "A boss coin from Diablos used for item level 15 crafting.",
- "setId": null,
- "setSlug": null,
- "setName": null
- }
- ]
- }
- ],
+ "difficulties": [],
+ "encounters": [],
"completionLoot": [],
"leaderboard": [],
"leaderboards": {
@@ -4431,226 +4333,8 @@
"experienceReward": 325,
"description": "A raid-scale hunt against Nargacuga, Azuros, and Diablos.",
"locationName": "The Monster Frontier",
- "difficulties": [
- {
- "dungeonId": 5,
- "id": 103,
- "slug": "raid-champion",
- "name": "Champion Raid",
- "droppedItemLevel": 15,
- "unlockLevel": 10,
- "healthMultiplier": 1.7,
- "damageMultiplier": 1.45,
- "experienceMultiplier": 2.4,
- "description": "Champion raid difficulty with extra monster-part drops."
- }
- ],
- "encounters": [
- {
- "id": 501,
- "dungeonId": 5,
- "sequence": 1,
- "slug": "nargacuga-raid-approach",
- "enemyName": "Nargacuga Approach",
- "encounterType": "trash",
- "maxHealth": 2225,
- "damage": 18,
- "tankDamage": 10,
- "partyDamage": 52,
- "description": "Hunters clear the raid path before Nargacuga.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": false,
- "lootTables": []
- },
- {
- "id": 502,
- "dungeonId": 5,
- "sequence": 2,
- "slug": "nargacuga-raid-guardians",
- "enemyName": "Nargacuga Guardians",
- "encounterType": "trash",
- "maxHealth": 2295,
- "damage": 19,
- "tankDamage": 11,
- "partyDamage": 54,
- "description": "Hunters clear the raid path before Nargacuga.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": false,
- "lootTables": []
- },
- {
- "id": 503,
- "dungeonId": 5,
- "sequence": 3,
- "slug": "nargacuga-raid-boss",
- "enemyName": "Nargacuga",
- "encounterType": "boss",
- "maxHealth": 2555,
- "damage": 23,
- "tankDamage": 15,
- "partyDamage": 58,
- "description": "Nargacuga drops boss coins for item level 15 crafting.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": true,
- "lootTables": [
- {
- "encounterId": 503,
- "difficultyId": 103,
- "dropWeight": 100,
- "dropChance": 1,
- "id": 330315,
- "slug": "nargacuga-raid-boss-coin-ilvl-15",
- "name": "Blue Nargacuga Coin",
- "slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
- "healingPower": 0,
- "maxResourceBonus": 0,
- "glyph": "$",
- "description": "A boss coin from Nargacuga used for item level 15 crafting.",
- "setId": null,
- "setSlug": null,
- "setName": null
- }
- ]
- },
- {
- "id": 504,
- "dungeonId": 5,
- "sequence": 4,
- "slug": "azuros-raid-approach",
- "enemyName": "Azuros Approach",
- "encounterType": "trash",
- "maxHealth": 2345,
- "damage": 20,
- "tankDamage": 12,
- "partyDamage": 55,
- "description": "Hunters clear the raid path before Azuros.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": false,
- "lootTables": []
- },
- {
- "id": 505,
- "dungeonId": 5,
- "sequence": 5,
- "slug": "azuros-raid-guardians",
- "enemyName": "Azuros Guardians",
- "encounterType": "trash",
- "maxHealth": 2415,
- "damage": 21,
- "tankDamage": 13,
- "partyDamage": 57,
- "description": "Hunters clear the raid path before Azuros.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": false,
- "lootTables": []
- },
- {
- "id": 506,
- "dungeonId": 5,
- "sequence": 6,
- "slug": "azuros-raid-boss",
- "enemyName": "Azuros",
- "encounterType": "boss",
- "maxHealth": 2675,
- "damage": 25,
- "tankDamage": 17,
- "partyDamage": 61,
- "description": "Azuros drops boss coins for item level 15 crafting.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": true,
- "lootTables": [
- {
- "encounterId": 506,
- "difficultyId": 103,
- "dropWeight": 100,
- "dropChance": 1,
- "id": 330615,
- "slug": "azuros-raid-boss-coin-ilvl-15",
- "name": "Blue Azuros Coin",
- "slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
- "healingPower": 0,
- "maxResourceBonus": 0,
- "glyph": "$",
- "description": "A boss coin from Azuros used for item level 15 crafting.",
- "setId": null,
- "setSlug": null,
- "setName": null
- }
- ]
- },
- {
- "id": 507,
- "dungeonId": 5,
- "sequence": 7,
- "slug": "diablos-raid-approach",
- "enemyName": "Diablos Approach",
- "encounterType": "trash",
- "maxHealth": 2465,
- "damage": 22,
- "tankDamage": 14,
- "partyDamage": 58,
- "description": "Hunters clear the raid path before Diablos.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": false,
- "lootTables": []
- },
- {
- "id": 508,
- "dungeonId": 5,
- "sequence": 8,
- "slug": "diablos-raid-guardians",
- "enemyName": "Diablos Guardians",
- "encounterType": "trash",
- "maxHealth": 2535,
- "damage": 23,
- "tankDamage": 15,
- "partyDamage": 60,
- "description": "Hunters clear the raid path before Diablos.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": false,
- "lootTables": []
- },
- {
- "id": 509,
- "dungeonId": 5,
- "sequence": 9,
- "slug": "diablos-raid-boss",
- "enemyName": "Diablos",
- "encounterType": "boss",
- "maxHealth": 2795,
- "damage": 27,
- "tankDamage": 19,
- "partyDamage": 64,
- "description": "Diablos drops boss coins for item level 15 crafting.",
- "imageUrl": "/boss-placeholder.svg",
- "isBoss": true,
- "lootTables": [
- {
- "encounterId": 509,
- "difficultyId": 103,
- "dropWeight": 100,
- "dropChance": 1,
- "id": 330915,
- "slug": "diablos-raid-boss-coin-ilvl-15",
- "name": "Blue Diablos Coin",
- "slot": "component",
- "rarity": "rare",
- "itemLevel": 15,
- "healingPower": 0,
- "maxResourceBonus": 0,
- "glyph": "$",
- "description": "A boss coin from Diablos used for item level 15 crafting.",
- "setId": null,
- "setSlug": null,
- "setName": null
- }
- ]
- }
- ],
+ "difficulties": [],
+ "encounters": [],
"completionLoot": [],
"leaderboard": [],
"leaderboards": {
@@ -4678,10 +4362,10 @@
"slug": "mythic",
"name": "Mythic",
"droppedItemLevel": 20,
- "unlockLevel": 15,
- "healthMultiplier": 2.1,
- "damageMultiplier": 1.75,
- "experienceMultiplier": 3,
+ "unlockLevel": 20,
+ "healthMultiplier": 2.25,
+ "damageMultiplier": 1.85,
+ "experienceMultiplier": 3.5,
"description": "Endgame dungeon difficulty."
}
],
@@ -4918,10 +4602,10 @@
"slug": "raid-mythic",
"name": "Mythic Raid",
"droppedItemLevel": 20,
- "unlockLevel": 15,
- "healthMultiplier": 2.1,
- "damageMultiplier": 1.75,
- "experienceMultiplier": 3.2,
+ "unlockLevel": 20,
+ "healthMultiplier": 2.25,
+ "damageMultiplier": 1.85,
+ "experienceMultiplier": 3.5,
"description": "Mythic raid difficulty with extra monster-part drops."
}
],
@@ -5158,10 +4842,10 @@
"slug": "ascendant",
"name": "Ascendant",
"droppedItemLevel": 25,
- "unlockLevel": 20,
- "healthMultiplier": 2.6,
- "damageMultiplier": 2.1,
- "experienceMultiplier": 4,
+ "unlockLevel": 25,
+ "healthMultiplier": 2.8,
+ "damageMultiplier": 2.25,
+ "experienceMultiplier": 4.5,
"description": "The current pinnacle difficulty."
}
],
@@ -5398,10 +5082,10 @@
"slug": "raid-ascendant",
"name": "Ascendant Raid",
"droppedItemLevel": 25,
- "unlockLevel": 20,
- "healthMultiplier": 2.6,
- "damageMultiplier": 2.1,
- "experienceMultiplier": 4.2,
+ "unlockLevel": 25,
+ "healthMultiplier": 2.8,
+ "damageMultiplier": 2.25,
+ "experienceMultiplier": 4.5,
"description": "Ascendant raid difficulty with extra monster-part drops."
}
],