69 lines
2.4 KiB
TypeScript
69 lines
2.4 KiB
TypeScript
import { useCombatStore } from "./combatStore";
|
|
import { LOOT_CATALOG, rollBossLoot } from "./lootCatalog";
|
|
import { useManastormStore } from "./manastormStore";
|
|
import { useGameStore } from "./store";
|
|
import { getManastormCatalog, manastormScaling } from "./manastorm";
|
|
import { requestOnlineInteraction } from "./onlineSessionRuntime";
|
|
|
|
/** Shared keyboard, controller, touch, and HUD interaction for the active corpse. */
|
|
export function lootCurrentManastormBoss(now = Date.now()): boolean {
|
|
const game = useGameStore.getState();
|
|
const manastorm = useManastormStore.getState();
|
|
if (game.gameMode !== "manastorm" || manastorm.status !== "awaiting-loot") return false;
|
|
const bossId = manastorm.currentEncounter?.bossRuntimeId;
|
|
if (!bossId) return false;
|
|
if (requestOnlineInteraction("loot", bossId)) return true;
|
|
return useCombatStore.getState().lootMob(bossId, now);
|
|
}
|
|
|
|
function stableCacheHash(value: string): number {
|
|
let hash = 2_166_136_261;
|
|
for (let index = 0; index < value.length; index += 1) {
|
|
hash ^= value.charCodeAt(index);
|
|
hash = Math.imul(hash, 16_777_619);
|
|
}
|
|
return hash >>> 0;
|
|
}
|
|
|
|
/**
|
|
* Opens a persisted cache and grants concrete character-level loot. Ascension's
|
|
* private cache tables are unavailable, so templates come from the checked-in
|
|
* SQL loot catalog while the Manastorm cache supplies level and bonus chance.
|
|
*/
|
|
export function openManastormRewardCache(
|
|
cacheId: string,
|
|
now = Date.now(),
|
|
random: () => number = Math.random,
|
|
): boolean {
|
|
const manastorm = useManastormStore.getState();
|
|
const cache = manastorm.rewardCache.find((candidate) => candidate.id === cacheId);
|
|
if (!cache || !LOOT_CATALOG.bosses.length) return false;
|
|
const tableIndex = stableCacheHash(`${cache.cacheId}:${cache.level}`) % LOOT_CATALOG.bosses.length;
|
|
const table = LOOT_CATALOG.bosses[tableIndex];
|
|
const combat = useCombatStore.getState();
|
|
const bonusItemChance = Math.max(
|
|
0,
|
|
Math.min(
|
|
0.75,
|
|
manastormScaling(
|
|
cache.level,
|
|
getManastormCatalog(),
|
|
manastorm.modeId,
|
|
).bonusLootChance
|
|
+ (cache.cacheId === "manastorm-bonus-cache" ? 0.35 : 0),
|
|
),
|
|
);
|
|
const items = rollBossLoot(table.bossKey, combat.level, {
|
|
now,
|
|
random,
|
|
bonusItemChance,
|
|
});
|
|
if (!useManastormStore.getState().openRewardCache(cacheId)) return false;
|
|
if (items.length) {
|
|
useCombatStore.setState((state) => ({
|
|
inventory: [...state.inventory, ...items],
|
|
}));
|
|
}
|
|
return true;
|
|
}
|