feat: unveiling rivens by doing the challenge (#1031)

Closes #722

Reviewed-on: OpenWF/SpaceNinjaServer#1031
This commit is contained in:
Sainan 2025-02-27 18:01:06 -08:00
parent 9267c9929e
commit 526ce1529b
6 changed files with 85 additions and 46 deletions

View File

@ -1,4 +1,5 @@
import { toOid } from "@/src/helpers/inventoryHelpers";
import { IRivenChallenge } from "@/src/helpers/rivenFingerprintHelper";
import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { addMods, getInventory } from "@/src/services/inventoryService";
import { getAccountIdForRequest } from "@/src/services/loginService";
@ -19,7 +20,7 @@ export const activateRandomModController: RequestHandler = async (req, res) => {
]);
const rivenType = getRandomElement(rivenRawToRealWeighted[request.ItemType]);
const challenge = getRandomElement(ExportUpgrades[rivenType].availableChallenges!);
const fingerprintChallenge: IRandomModChallenge = {
const fingerprintChallenge: IRivenChallenge = {
Type: challenge.fullName,
Progress: 0,
Required: getRandomInt(challenge.countRange[0], challenge.countRange[1])
@ -62,13 +63,6 @@ interface IActiveRandomModRequest {
ItemType: string;
}
interface IRandomModChallenge {
Type: string;
Progress: number;
Required: number;
Complication?: string;
}
const rivenRawToRealWeighted: Record<string, string[]> = {
"/Lotus/Upgrades/Mods/Randomized/RawArchgunRandomMod": [
"/Lotus/Upgrades/Mods/Randomized/LotusArchgunRandomModRare"

View File

@ -4,8 +4,7 @@ import { addMiscItems, getInventory, updateCurrency } from "@/src/services/inven
import { IInventoryChanges } from "@/src/types/purchaseTypes";
import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { IUnveiledRivenFingerprint, randomiseRivenStats } from "@/src/helpers/rivenFingerprintHelper";
import { getRandomElement, getRandomInt } from "@/src/services/rngService";
import { createUnveiledRivenFingerprint } from "@/src/helpers/rivenFingerprintHelper";
import { ExportUpgrades } from "warframe-public-export-plus";
export const completeRandomModChallengeController: RequestHandler = async (req, res) => {
@ -31,17 +30,7 @@ export const completeRandomModChallengeController: RequestHandler = async (req,
// Update riven fingerprint to a randomised unveiled state
const upgrade = inventory.Upgrades.id(request.ItemId)!;
const meta = ExportUpgrades[upgrade.ItemType];
const fingerprint: IUnveiledRivenFingerprint = {
compat: getRandomElement(meta.compatibleItems!),
lim: 0,
lvl: 0,
lvlReq: getRandomInt(8, 16),
pol: getRandomElement(["AP_ATTACK", "AP_DEFENSE", "AP_TACTIC"]),
buffs: [],
curses: []
};
randomiseRivenStats(meta, fingerprint);
upgrade.UpgradeFingerprint = JSON.stringify(fingerprint);
upgrade.UpgradeFingerprint = JSON.stringify(createUnveiledRivenFingerprint(meta));
await inventory.save();

View File

@ -2,19 +2,32 @@ import { RequestHandler } from "express";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { addMiscItems, getInventory } from "@/src/services/inventoryService";
import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { IUnveiledRivenFingerprint, randomiseRivenStats } from "@/src/helpers/rivenFingerprintHelper";
import {
createUnveiledRivenFingerprint,
randomiseRivenStats,
RivenFingerprint
} from "@/src/helpers/rivenFingerprintHelper";
import { ExportUpgrades } from "warframe-public-export-plus";
import { IOid } from "@/src/types/commonTypes";
export const rerollRandomModController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const request = getJSONfromString<RerollRandomModRequest>(String(req.body));
if ("ItemIds" in request) {
const inventory = await getInventory(accountId, "Upgrades MiscItems");
const upgrade = inventory.Upgrades.id(request.ItemIds[0])!;
const fingerprint = JSON.parse(upgrade.UpgradeFingerprint!) as IUnveiledRivenFingerprint;
const changes: IChange[] = [];
let totalKuvaCost = 0;
request.ItemIds.forEach(itemId => {
const upgrade = inventory.Upgrades.id(itemId)!;
const fingerprint = JSON.parse(upgrade.UpgradeFingerprint!) as RivenFingerprint;
if ("challenge" in fingerprint) {
upgrade.UpgradeFingerprint = JSON.stringify(
createUnveiledRivenFingerprint(ExportUpgrades[upgrade.ItemType])
);
} else {
fingerprint.rerolls ??= 0;
const kuvaCost = fingerprint.rerolls < rerollCosts.length ? rerollCosts[fingerprint.rerolls] : 3500;
totalKuvaCost += kuvaCost;
addMiscItems(inventory, [
{
ItemType: "/Lotus/Types/Items/MiscItems/Kuva",
@ -27,18 +40,20 @@ export const rerollRandomModController: RequestHandler = async (req, res) => {
randomiseRivenStats(ExportUpgrades[upgrade.ItemType], fingerprint);
upgrade.PendingRerollFingerprint = JSON.stringify(fingerprint);
}
changes.push({
ItemId: { $oid: request.ItemIds[0] },
UpgradeFingerprint: upgrade.UpgradeFingerprint,
PendingRerollFingerprint: upgrade.PendingRerollFingerprint
});
});
await inventory.save();
res.json({
changes: [
{
ItemId: { $oid: request.ItemIds[0] },
UpgradeFingerprint: upgrade.UpgradeFingerprint,
PendingRerollFingerprint: upgrade.PendingRerollFingerprint
}
],
cost: kuvaCost
changes: changes,
cost: totalKuvaCost
});
} else {
const inventory = await getInventory(accountId, "Upgrades");
@ -63,4 +78,10 @@ interface AwDangitRequest {
CommitReroll: boolean;
}
interface IChange {
ItemId: IOid;
UpgradeFingerprint?: string;
PendingRerollFingerprint?: string;
}
const rerollCosts = [900, 1000, 1200, 1400, 1700, 2000, 2350, 2750, 3150];

View File

@ -1,5 +1,18 @@
import { IUpgrade } from "warframe-public-export-plus";
import { getRandomElement } from "../services/rngService";
import { getRandomElement, getRandomInt } from "../services/rngService";
export type RivenFingerprint = IVeiledRivenFingerprint | IUnveiledRivenFingerprint;
export interface IVeiledRivenFingerprint {
challenge: IRivenChallenge;
}
export interface IRivenChallenge {
Type: string;
Progress: number;
Required: number;
Complication?: string;
}
export interface IUnveiledRivenFingerprint {
compat: string;
@ -17,6 +30,20 @@ interface IRivenStat {
Value: number;
}
export const createUnveiledRivenFingerprint = (meta: IUpgrade): IUnveiledRivenFingerprint => {
const fingerprint: IUnveiledRivenFingerprint = {
compat: getRandomElement(meta.compatibleItems!),
lim: 0,
lvl: 0,
lvlReq: getRandomInt(8, 16),
pol: getRandomElement(["AP_ATTACK", "AP_DEFENSE", "AP_TACTIC"]),
buffs: [],
curses: []
};
randomiseRivenStats(meta, fingerprint);
return fingerprint;
};
export const randomiseRivenStats = (meta: IUpgrade, fingerprint: IUnveiledRivenFingerprint): void => {
fingerprint.buffs = [];
const numBuffs = 2 + Math.trunc(Math.random() * 2); // 2 or 3

View File

@ -201,6 +201,12 @@ export const addMissionInventoryUpdates = (
}
});
break;
case "Upgrades":
value.forEach(clientUpgrade => {
const upgrade = inventory.Upgrades.id(clientUpgrade.ItemId.$oid)!;
upgrade.UpgradeFingerprint = clientUpgrade.UpgradeFingerprint; // primitive way to copy over the riven challenge progress
});
break;
case "SyndicateId": {
inventory.CompletedSyndicates.push(value);
break;

View File

@ -14,7 +14,8 @@ import {
ICustomMarkers,
IPlayerSkills,
IQuestKeyDatabase,
ILoreFragmentScan
ILoreFragmentScan,
IUpgradeClient
} from "./inventoryTypes/inventoryTypes";
export interface IThemeUpdateRequest {
@ -98,6 +99,7 @@ export type IMissionInventoryUpdateRequest = {
CodexScanCount: number;
Standing: number;
}[];
Upgrades?: IUpgradeClient[]; // riven challenge progress
} & {
[K in TEquipmentKey]?: IEquipmentClient[];
};