diff --git a/src/controllers/api/nemesisController.ts b/src/controllers/api/nemesisController.ts index 43fe2cb7..8c192a16 100644 --- a/src/controllers/api/nemesisController.ts +++ b/src/controllers/api/nemesisController.ts @@ -1,10 +1,17 @@ -import { getInfNodes, getNemesisPasscode } from "@/src/helpers/nemesisHelpers"; +import { encodeNemesisGuess, getInfNodes, getNemesisPasscode } from "@/src/helpers/nemesisHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { freeUpSlot, getInventory } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { SRng } from "@/src/services/rngService"; import { IMongoDate, IOid } from "@/src/types/commonTypes"; -import { IInnateDamageFingerprint, InventorySlot, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; +import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { + IInnateDamageFingerprint, + InventorySlot, + IUpgradeClient, + IWeaponSkinClient, + TEquipmentKey +} from "@/src/types/inventoryTypes/inventoryTypes"; import { logger } from "@/src/utils/logger"; import { RequestHandler } from "express"; @@ -66,6 +73,69 @@ export const nemesisController: RequestHandler = async (req, res) => { } } res.json({ GuessResult: guessResult }); + } else if (req.query.mode == "r") { + const inventory = await getInventory(accountId, "Nemesis"); + const body = getJSONfromString(String(req.body)); + if (inventory.Nemesis!.Faction == "FC_INFESTATION") { + const guess: number[] = [body.guess & 0xf, (body.guess >> 4) & 0xf, (body.guess >> 8) & 0xf]; + const passcode = getNemesisPasscode(inventory.Nemesis!)[0]; + + // Add to GuessHistory + const result1 = passcode == guess[0] ? 0 : 1; + const result2 = passcode == guess[1] ? 0 : 1; + const result3 = passcode == guess[2] ? 0 : 1; + inventory.Nemesis!.GuessHistory.push( + encodeNemesisGuess(guess[0], result1, guess[1], result2, guess[2], result3) + ); + + // Increase antivirus + let antivirusGain = 5; + for (const upgrade of body.knife!.AttachedUpgrades) { + switch (upgrade.ItemType) { + case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusAndSpeedOnUseMod": + antivirusGain += 10; + break; + case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusAndWeaponDamageOnUseMod": + antivirusGain += 10; + break; + case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusLargeOnSingleUseMod": // Instant Secure + antivirusGain += 15; + break; + case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusOnUseMod": // Immuno Shield + antivirusGain += 15; + break; + case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusSmallOnSingleUseMod": + antivirusGain += 10; + break; + } + } + inventory.Nemesis!.HenchmenKilled += antivirusGain; + if (inventory.Nemesis!.HenchmenKilled >= 100) { + inventory.Nemesis!.InfNodes = [ + { + Node: "CrewBattleNode559", + Influence: 1 + } + ]; + inventory.Nemesis!.Weakened = true; + } else { + inventory.Nemesis!.InfNodes = getInfNodes("FC_INFESTATION", 0); + } + + // TODO: Consume mod charges? + + await inventory.save(); + res.end(); + } else { + const passcode = getNemesisPasscode(inventory.Nemesis!); + if (passcode[body.position] != body.guess) { + res.end(); + } else { + inventory.Nemesis!.Rank += 1; + await inventory.save(); + res.json({ RankIncrease: 1 }); + } + } } else if ((req.query.mode as string) == "rs") { // report spawn; POST but no application data in body const inventory = await getInventory(accountId, "Nemesis"); @@ -179,6 +249,20 @@ interface INemesisPrespawnCheckRequest { potency?: number[]; } +interface INemesisRequiemRequest { + guess: number; // grn/crp: 4 bits | coda: 3x 4 bits + position: number; // grn/crp: 0-2 | coda: 0 + // knife field provided for coda only + knife?: { + Item: IEquipmentClient; + Skins: IWeaponSkinClient[]; + ModSlot: number; + CustSlot: number; + AttachedUpgrades: IUpgradeClient[]; + HiddenWhenHolstered: boolean; + }; +} + const kuvaLichVersionSixWeapons = [ "/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Drakgoon/KuvaDrakgoon", "/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Karak/KuvaKarak", diff --git a/src/helpers/nemesisHelpers.ts b/src/helpers/nemesisHelpers.ts index 9b9f54b6..9dcaa2cf 100644 --- a/src/helpers/nemesisHelpers.ts +++ b/src/helpers/nemesisHelpers.ts @@ -42,3 +42,25 @@ export const getNemesisPasscode = (nemesis: { fp: bigint; Faction: string }): nu } return passcode; }; + +export const encodeNemesisGuess = ( + symbol1: number, + result1: number, + symbol2: number, + result2: number, + symbol3: number, + result3: number +): number => { + return ( + (symbol1 & 0xf) | + ((result1 & 3) << 12) | + ((symbol2 << 4) & 0xff) | + ((result2 << 14) & 0xffff) | + ((symbol3 & 0xf) << 8) | + ((result3 & 3) << 16) + ); +}; + +export const decodeNemesisGuess = (val: number): number[] => { + return [val & 0xf, (val >> 12) & 3, (val & 0xff) >> 4, (val & 0xffff) >> 14, (val >> 8) & 0xf, (val >> 16) & 3]; +}; diff --git a/src/services/missionInventoryUpdateService.ts b/src/services/missionInventoryUpdateService.ts index e6492a6e..de488ec4 100644 --- a/src/services/missionInventoryUpdateService.ts +++ b/src/services/missionInventoryUpdateService.ts @@ -699,25 +699,10 @@ export const addMissionRewards = async ( } if (inventory.Nemesis.Faction == "FC_INFESTATION") { - inventoryChanges.Nemesis.HenchmenKilled ??= 0; - inventoryChanges.Nemesis.MissionCount ??= 0; - - inventory.Nemesis.HenchmenKilled += 5; inventory.Nemesis.MissionCount += 1; - inventoryChanges.Nemesis.HenchmenKilled += 5; + inventoryChanges.Nemesis.MissionCount ??= 0; inventoryChanges.Nemesis.MissionCount += 1; - - if (inventory.Nemesis.HenchmenKilled >= 100) { - inventory.Nemesis.InfNodes = [ - { - Node: "CrewBattleNode559", - Influence: 1 - } - ]; - inventory.Nemesis.Weakened = true; - inventoryChanges.Nemesis.Weakened = true; - } } inventoryChanges.Nemesis.InfNodes = inventory.Nemesis.InfNodes;