Nemesis cheats code and webUI adaption

Nemesis Henchmen Kills Multiplier

Nemesis Hint Progress Multiplier

Nemesis Weapon Fusion Multiplier

Nemesis Gain Extra Rank

Nemesis Always Correct

code fix

webUI updates

Live Heart Multiplier
This commit is contained in:
AlexisinGit 2025-08-30 16:18:58 +08:00
parent 31e121ab22
commit 90cb433f10
5 changed files with 140 additions and 18 deletions

View File

@ -18,7 +18,7 @@ import {
import { getJSONfromString } from "../../helpers/stringHelpers.ts";
import type { TInventoryDatabaseDocument } from "../../models/inventoryModels/inventoryModel.ts";
import { Loadout } from "../../models/inventoryModels/loadoutModel.ts";
import { addMods, freeUpSlot, getInventory } from "../../services/inventoryService.ts";
import { addMods, freeUpSlot, getInventory, getAccountCheats } from "../../services/inventoryService.ts";
import { getAccountForRequest } from "../../services/loginService.ts";
import { SRng } from "../../services/rngService.ts";
import type { IMongoDate, IOid } from "../../types/commonTypes.ts";
@ -39,6 +39,7 @@ import { Types } from "mongoose";
export const nemesisController: RequestHandler = async (req, res) => {
const account = await getAccountForRequest(req);
const accountCheats = await getAccountCheats(account._id.toString());
if ((req.query.mode as string) == "f") {
const body = getJSONfromString<IValenceFusionRequest>(String(req.body));
const inventory = await getInventory(account._id.toString(), body.Category + " WeaponBin");
@ -55,7 +56,8 @@ export const nemesisController: RequestHandler = async (req, res) => {
// Upgrade destination damage value
const destDamage = 0.25 + (destFingerprint.buffs[0].Value / 0x3fffffff) * (0.6 - 0.25);
const sourceDamage = 0.25 + (sourceFingerprint.buffs[0].Value / 0x3fffffff) * (0.6 - 0.25);
let newDamage = Math.max(destDamage, sourceDamage) * 1.1;
const WeaponFusionMultiplier = accountCheats.nemesisWeaponFusionMultiplier ?? 1;
let newDamage = Math.max(destDamage, sourceDamage) * 1.1 * WeaponFusionMultiplier;
if (newDamage >= 0.5794998) {
newDamage = 0.6;
}
@ -82,14 +84,18 @@ export const nemesisController: RequestHandler = async (req, res) => {
let guessResult = 0;
if (inventory.Nemesis!.Faction == "FC_INFESTATION") {
for (let i = 0; i != 3; ++i) {
if (body.guess[i] == passcode[0]) {
if (body.guess[i] == passcode[0] || accountCheats.nemesisAlwaysCorrect) {
guessResult = 1 + i;
break;
}
}
} else {
for (let i = 0; i != 3; ++i) {
if (body.guess[i] == passcode[i] || body.guess[i] == GUESS_WILDCARD) {
if (
body.guess[i] == passcode[i] ||
body.guess[i] == GUESS_WILDCARD ||
accountCheats.nemesisAlwaysCorrect
) {
++guessResult;
}
}
@ -100,6 +106,7 @@ export const nemesisController: RequestHandler = async (req, res) => {
account._id.toString(),
"Nemesis LoadOutPresets CurrentLoadOutIds DataKnives Upgrades RawUpgrades"
);
const body = getJSONfromString<INemesisRequiemRequest>(String(req.body));
if (inventory.Nemesis!.Faction == "FC_INFESTATION") {
const guess: number[] = [body.guess & 0xf, (body.guess >> 4) & 0xf, (body.guess >> 8) & 0xf];
@ -111,22 +118,27 @@ export const nemesisController: RequestHandler = async (req, res) => {
encodeNemesisGuess([
{
symbol: guess[0],
result: result1
result: accountCheats.nemesisAlwaysCorrect ? GUESS_CORRECT : result1
},
{
symbol: guess[1],
result: result2
result: accountCheats.nemesisAlwaysCorrect ? GUESS_CORRECT : result2
},
{
symbol: guess[2],
result: result3
result: accountCheats.nemesisAlwaysCorrect ? GUESS_CORRECT : result3
}
])
);
// Increase antivirus if correct antivirus mod is installed
const response: IKnifeResponse = {};
if (result1 == GUESS_CORRECT || result2 == GUESS_CORRECT || result3 == GUESS_CORRECT) {
if (
result1 == GUESS_CORRECT ||
result2 == GUESS_CORRECT ||
result3 == GUESS_CORRECT ||
accountCheats.nemesisAlwaysCorrect
) {
let antivirusGain = 5;
const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!;
const dataknifeLoadout = loadout.DATAKNIFE.id(
@ -149,7 +161,8 @@ export const nemesisController: RequestHandler = async (req, res) => {
break;
}
}
inventory.Nemesis!.HenchmenKilled += antivirusGain;
inventory.Nemesis!.HenchmenKilled +=
antivirusGain * (accountCheats.nemesisHenchmenKillsMultiplierInfestation ?? 1);
if (inventory.Nemesis!.HenchmenKilled >= 100) {
inventory.Nemesis!.HenchmenKilled = 100;
@ -192,10 +205,15 @@ export const nemesisController: RequestHandler = async (req, res) => {
])
);
}
if (accountCheats.nemesisAlwaysCorrect) {
body.guess = GUESS_WILDCARD | (GUESS_WILDCARD << 4) | (GUESS_WILDCARD << 8);
}
// Evaluate guess
const correct =
body.guess == GUESS_WILDCARD || getNemesisPasscode(inventory.Nemesis!)[body.position] == body.guess;
body.guess == GUESS_WILDCARD ||
getNemesisPasscode(inventory.Nemesis!)[body.position] == body.guess ||
accountCheats.nemesisAlwaysCorrect;
// Update entry
const guess = decodeNemesisGuess(
@ -232,9 +250,13 @@ export const nemesisController: RequestHandler = async (req, res) => {
}
} else {
// Guess was incorrect, increase rank
const nemesisExtraRank = Math.floor(Math.random() * ((inventory.nemesisGainExtraRank ?? 0) + 1));
response.RankIncrease = 1;
const manifest = getNemesisManifest(inventory.Nemesis!.manifest);
inventory.Nemesis!.Rank = Math.min(inventory.Nemesis!.Rank + 1, manifest.systemIndexes.length - 1);
inventory.Nemesis!.Rank = Math.min(
inventory.Nemesis!.Rank + 1 + nemesisExtraRank,
manifest.systemIndexes.length - 1
);
inventory.Nemesis!.InfNodes = getInfNodes(manifest, inventory.Nemesis!.Rank);
}
await inventory.save();

View File

@ -26,7 +26,8 @@ import type {
INemesisWeaponTargetFingerprint,
INemesisPetTargetFingerprint,
IDialogueDatabase,
IKubrowPetPrintClient
IKubrowPetPrintClient,
IAccountCheats
} from "../types/inventoryTypes/inventoryTypes.ts";
import { InventorySlot, equipmentKeys } from "../types/inventoryTypes/inventoryTypes.ts";
import type { IGenericUpdate, IUpdateNodeIntrosResponse } from "../types/genericUpdate.ts";
@ -266,6 +267,13 @@ export const getInventory = async (
return inventory;
};
export const getAccountCheats = async (accountOwnerId: string): Promise<Partial<IAccountCheats>> => {
const cheatProperties = Object.keys({} as IAccountCheats) as Array<keyof IAccountCheats>;
const inventoryWithCheats = await getInventory(accountOwnerId, cheatProperties.join(" "));
return inventoryWithCheats;
};
export const productCategoryToInventoryBin = (productCategory: string): InventorySlot | undefined => {
switch (productCategory) {
case "Suits":

View File

@ -35,6 +35,7 @@ import {
addStanding,
applyClientEquipmentUpdates,
combineInventoryChanges,
getAccountCheats,
getDialogue,
giveNemesisPetRecipe,
giveNemesisWeaponRecipe,
@ -201,10 +202,33 @@ export const addMissionInventoryUpdates = async (
inventory.NemesisAbandonedRewards = inventoryUpdates.RewardInfo.NemesisAbandonedRewards;
}
if (inventoryUpdates.RewardInfo.NemesisHenchmenKills && inventory.Nemesis) {
inventory.Nemesis.HenchmenKilled += inventoryUpdates.RewardInfo.NemesisHenchmenKills;
let NemesisHenchmenKillsMultiplier = 1;
switch (inventory.Nemesis.Faction) {
case "FC_GRINEER":
NemesisHenchmenKillsMultiplier = inventory.nemesisHenchmenKillsMultiplierGrineer ?? 1;
break;
case "FC_CORPUS":
NemesisHenchmenKillsMultiplier = inventory.nemesisHenchmenKillsMultiplierCorpus ?? 1;
break;
case "FC_INFESTATION":
//antivirus progess is controlled in nemesisController
break;
}
inventory.Nemesis.HenchmenKilled +=
inventoryUpdates.RewardInfo.NemesisHenchmenKills * NemesisHenchmenKillsMultiplier;
}
if (inventoryUpdates.RewardInfo.NemesisHintProgress && inventory.Nemesis) {
inventory.Nemesis.HintProgress += inventoryUpdates.RewardInfo.NemesisHintProgress;
let NemesisHintProgressMultiplier = 1;
switch (inventory.Nemesis.Faction) {
case "FC_GRINEER":
NemesisHintProgressMultiplier = inventory.nemesisHintProgressMultiplierGrineer ?? 1;
break;
case "FC_CORPUS":
NemesisHintProgressMultiplier = inventory.nemesisHintProgressMultiplierCorpus ?? 1;
break;
}
inventory.Nemesis.HintProgress +=
inventoryUpdates.RewardInfo.NemesisHintProgress * NemesisHintProgressMultiplier;
if (inventory.Nemesis.Faction != "FC_INFESTATION" && inventory.Nemesis.Hints.length != 3) {
const progressNeeded = [35, 60, 100][inventory.Nemesis.Hints.length];
if (inventory.Nemesis.HintProgress >= progressNeeded) {
@ -891,10 +915,11 @@ export const addMissionInventoryUpdates = async (
att.push(rotBReward);
if (value.killed) {
const tokenMultiplier = Math.max(1, inventory.nemesisExtraWeaponOnKill ?? 1);
countedAtt = [
{
ItemType: "/Lotus/Types/Items/MiscItems/CodaWeaponBucks",
ItemCount: getKillTokenRewardCount(inventory.Nemesis.fp)
ItemCount: getKillTokenRewardCount(inventory.Nemesis.fp) * tokenMultiplier
}
];
addMiscItems(inventory, countedAtt);

View File

@ -787,6 +787,68 @@
<input class="form-check-input" type="checkbox" id="finishInvasionsInOneMission" />
<label class="form-check-label" for="finishInvasionsInOneMission" data-loc="cheats_finishInvasionsInOneMission"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="nemesisAlwaysCorrect" />
<label class="form-check-label" for="nemesisAlwaysCorrect" data-loc="cheats_nemesisAlwaysCorrect"></label>
</div>
<form class="form-group mt-2">
<label class="form-label" for="nemesisHenchmenKillsMultiplierGrineer" data-loc="cheats_nemesisHenchmenKillsMultiplierGrineer"></label>
<div class="input-group">
<input class="form-control" id="nemesisHenchmenKillsMultiplierGrineer" type="number" min="-1" max="65535" data-default="1" />
<button class="btn btn-secondary" type="button" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2">
<label class="form-label" for="nemesisHenchmenKillsMultiplierCorpus" data-loc="cheats_nemesisHenchmenKillsMultiplierCorpus"></label>
<div class="input-group">
<input class="form-control" id="nemesisHenchmenKillsMultiplierCorpus" type="number" min="-1" max="65535" data-default="1" />
<button class="btn btn-secondary" type="button" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2">
<label class="form-label" for="nemesisHenchmenKillsMultiplierInfestation" data-loc="cheats_nemesisHenchmenKillsMultiplierInfestation"></label>
<div class="input-group">
<input class="form-control" id="nemesisHenchmenKillsMultiplierInfestation" type="number" min="-1" max="65535" data-default="1" />
<button class="btn btn-secondary" type="button" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2">
<label class="form-label" for="nemesisHintProgressMultiplierGrineer" data-loc="cheats_nemesisHintProgressMultiplierGrineer"></label>
<div class="input-group">
<input class="form-control" id="nemesisHintProgressMultiplierGrineer" type="number" min="-1" max="65535" data-default="1" />
<button class="btn btn-secondary" type="button" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2">
<label class="form-label" for="nemesisHintProgressMultiplierCorpus" data-loc="cheats_nemesisHintProgressMultiplierCorpus"></label>
<div class="input-group">
<input class="form-control" id="nemesisHintProgressMultiplierCorpus" type="number" min="-1" max="65535" data-default="1" />
<button class="btn btn-secondary" type="button" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2">
<label class="form-label" for="nemesisWeaponFusionMultiplier" data-loc="cheats_nemesisWeaponFusionMultiplier"></label>
<div class="input-group">
<input class="form-control" id="nemesisWeaponFusionMultiplier" type="number" min="-1" max="65535" data-default="1" />
<button class="btn btn-secondary" type="button" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2">
<label class="form-label" for="nemesisGainExtraRank" data-loc="cheats_nemesisGainExtraRank"></label>
<abbr data-loc-info="cheats_nemesisGainExtraRank_information"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
<div class="input-group">
<input class="form-control" id="nemesisGainExtraRank" type="number" min="0" max="65535" data-default="0" />
<button class="btn btn-secondary" type="button" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2">
<label class="form-label" for="nemesisExtraWeaponOnKill" data-loc="cheats_nemesisExtraWeaponOnKill"></label>
<abbr data-loc-info="cheats_nemesisExtraWeaponOnKill_information"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
<div class="input-group">
<input class="form-control" id="nemesisExtraWeaponOnKill" type="number" min="0" max="65535" data-default="0" />
<button class="btn btn-secondary" type="button" data-loc="cheats_save"></button>
</div>
</form>
<div class="mt-2 mb-2 d-flex flex-wrap gap-2">
<button class="btn btn-primary" onclick="debounce(doUnlockAllMissions);" data-loc="cheats_unlockAllMissions"></button>
<button class="btn btn-primary" onclick="debounce(markAllAsRead);" data-loc="cheats_markAllAsRead"></button>

View File

@ -1502,7 +1502,11 @@ function updateInventory() {
});
for (const elm of accountCheats) {
if (elm.type === "checkbox") {
elm.checked = !!data[elm.id];
} else if (elm.type === "number" || elm.type === "text") {
elm.value = data[elm.id] !== undefined ? data[elm.id] : elm.getAttribute("data-default") || "";
}
}
});
});
@ -2337,15 +2341,16 @@ function doIntrinsicsUnlockAll() {
});
}
document.querySelectorAll("#account-cheats input[type=checkbox]").forEach(elm => {
document.querySelectorAll("#account-cheats input[type=checkbox], #account-cheats input[type=number]").forEach(elm => {
elm.onchange = function () {
revalidateAuthz().then(() => {
const value = elm.type === "checkbox" ? elm.checked : elm.value;
$.post({
url: "/custom/setAccountCheat?" + window.authz /*+ "&wsid=" + wsid*/,
contentType: "application/json",
data: JSON.stringify({
key: elm.id,
value: elm.checked
value: value
})
});
});