forked from OpenWF/SpaceNinjaServer
feat: classic lich guess history (#2129)
Closes #2123 Reviewed-on: OpenWF/SpaceNinjaServer#2129 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
parent
b7c47b91ff
commit
135b1e54fe
@ -1,12 +1,17 @@
|
|||||||
import { version_compare } from "@/src/helpers/inventoryHelpers";
|
import { version_compare } from "@/src/helpers/inventoryHelpers";
|
||||||
import {
|
import {
|
||||||
consumeModCharge,
|
consumeModCharge,
|
||||||
|
decodeNemesisGuess,
|
||||||
encodeNemesisGuess,
|
encodeNemesisGuess,
|
||||||
getInfNodes,
|
getInfNodes,
|
||||||
getKnifeUpgrade,
|
getKnifeUpgrade,
|
||||||
getNemesisManifest,
|
getNemesisManifest,
|
||||||
getNemesisPasscode,
|
getNemesisPasscode,
|
||||||
getNemesisPasscodeModTypes,
|
getNemesisPasscodeModTypes,
|
||||||
|
GUESS_CORRECT,
|
||||||
|
GUESS_INCORRECT,
|
||||||
|
GUESS_NEUTRAL,
|
||||||
|
GUESS_NONE,
|
||||||
GUESS_WILDCARD,
|
GUESS_WILDCARD,
|
||||||
IKnifeResponse
|
IKnifeResponse
|
||||||
} from "@/src/helpers/nemesisHelpers";
|
} from "@/src/helpers/nemesisHelpers";
|
||||||
@ -98,18 +103,29 @@ export const nemesisController: RequestHandler = async (req, res) => {
|
|||||||
if (inventory.Nemesis!.Faction == "FC_INFESTATION") {
|
if (inventory.Nemesis!.Faction == "FC_INFESTATION") {
|
||||||
const guess: number[] = [body.guess & 0xf, (body.guess >> 4) & 0xf, (body.guess >> 8) & 0xf];
|
const guess: number[] = [body.guess & 0xf, (body.guess >> 4) & 0xf, (body.guess >> 8) & 0xf];
|
||||||
const passcode = getNemesisPasscode(inventory.Nemesis!)[0];
|
const passcode = getNemesisPasscode(inventory.Nemesis!)[0];
|
||||||
|
const result1 = passcode == guess[0] ? GUESS_CORRECT : GUESS_INCORRECT;
|
||||||
// Add to GuessHistory
|
const result2 = passcode == guess[1] ? GUESS_CORRECT : GUESS_INCORRECT;
|
||||||
const result1 = passcode == guess[0] ? 0 : 1;
|
const result3 = passcode == guess[2] ? GUESS_CORRECT : GUESS_INCORRECT;
|
||||||
const result2 = passcode == guess[1] ? 0 : 1;
|
|
||||||
const result3 = passcode == guess[2] ? 0 : 1;
|
|
||||||
inventory.Nemesis!.GuessHistory.push(
|
inventory.Nemesis!.GuessHistory.push(
|
||||||
encodeNemesisGuess(guess[0], result1, guess[1], result2, guess[2], result3)
|
encodeNemesisGuess([
|
||||||
|
{
|
||||||
|
symbol: guess[0],
|
||||||
|
result: result1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symbol: guess[1],
|
||||||
|
result: result2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symbol: guess[2],
|
||||||
|
result: result3
|
||||||
|
}
|
||||||
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
// Increase antivirus if correct antivirus mod is installed
|
// Increase antivirus if correct antivirus mod is installed
|
||||||
const response: IKnifeResponse = {};
|
const response: IKnifeResponse = {};
|
||||||
if (result1 == 0 || result2 == 0 || result3 == 0) {
|
if (result1 == GUESS_CORRECT || result2 == GUESS_CORRECT || result3 == GUESS_CORRECT) {
|
||||||
let antivirusGain = 5;
|
let antivirusGain = 5;
|
||||||
const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!;
|
const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!;
|
||||||
const dataknifeLoadout = loadout.DATAKNIFE.id(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid);
|
const dataknifeLoadout = loadout.DATAKNIFE.id(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid);
|
||||||
@ -150,19 +166,47 @@ export const nemesisController: RequestHandler = async (req, res) => {
|
|||||||
await inventory.save();
|
await inventory.save();
|
||||||
res.json(response);
|
res.json(response);
|
||||||
} else {
|
} else {
|
||||||
let RankIncrease: number | undefined;
|
// For first guess, create a new entry.
|
||||||
if (body.guess != GUESS_WILDCARD) {
|
if (body.position == 0) {
|
||||||
const passcode = getNemesisPasscode(inventory.Nemesis!);
|
inventory.Nemesis!.GuessHistory.push(
|
||||||
if (passcode[body.position] != body.guess) {
|
encodeNemesisGuess([
|
||||||
const manifest = getNemesisManifest(inventory.Nemesis!.manifest);
|
{
|
||||||
if (inventory.Nemesis!.Rank + 1 < manifest.systemIndexes.length) {
|
symbol: GUESS_NONE,
|
||||||
inventory.Nemesis!.Rank += 1;
|
result: GUESS_NEUTRAL
|
||||||
RankIncrease = 1;
|
},
|
||||||
}
|
{
|
||||||
inventory.Nemesis!.InfNodes = getInfNodes(manifest, inventory.Nemesis!.Rank);
|
symbol: GUESS_NONE,
|
||||||
await inventory.save();
|
result: GUESS_NEUTRAL
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
symbol: GUESS_NONE,
|
||||||
|
result: GUESS_NEUTRAL
|
||||||
|
}
|
||||||
|
])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Evaluate guess
|
||||||
|
const correct =
|
||||||
|
body.guess == GUESS_WILDCARD || getNemesisPasscode(inventory.Nemesis!)[body.position] == body.guess;
|
||||||
|
|
||||||
|
// Update entry
|
||||||
|
const guess = decodeNemesisGuess(
|
||||||
|
inventory.Nemesis!.GuessHistory[inventory.Nemesis!.GuessHistory.length - 1]
|
||||||
|
);
|
||||||
|
guess[body.position].symbol = body.guess;
|
||||||
|
guess[body.position].result = correct ? GUESS_CORRECT : GUESS_INCORRECT;
|
||||||
|
inventory.Nemesis!.GuessHistory[inventory.Nemesis!.GuessHistory.length - 1] = encodeNemesisGuess(guess);
|
||||||
|
|
||||||
|
// Increase rank if incorrect
|
||||||
|
let RankIncrease: number | undefined;
|
||||||
|
if (!correct) {
|
||||||
|
RankIncrease = 1;
|
||||||
|
const manifest = getNemesisManifest(inventory.Nemesis!.manifest);
|
||||||
|
inventory.Nemesis!.Rank = Math.min(inventory.Nemesis!.Rank + 1, manifest.systemIndexes.length - 1);
|
||||||
|
inventory.Nemesis!.InfNodes = getInfNodes(manifest, inventory.Nemesis!.Rank);
|
||||||
|
}
|
||||||
|
await inventory.save();
|
||||||
res.json({ RankIncrease });
|
res.json({ RankIncrease });
|
||||||
}
|
}
|
||||||
} else if ((req.query.mode as string) == "rs") {
|
} else if ((req.query.mode as string) == "rs") {
|
||||||
|
@ -237,7 +237,7 @@ export const getNemesisPasscode = (nemesis: { fp: bigint; Faction: TNemesisFacti
|
|||||||
return passcode;
|
return passcode;
|
||||||
};
|
};
|
||||||
|
|
||||||
const reqiuemMods: readonly string[] = [
|
const requiemMods: readonly string[] = [
|
||||||
"/Lotus/Upgrades/Mods/Immortal/ImmortalOneMod",
|
"/Lotus/Upgrades/Mods/Immortal/ImmortalOneMod",
|
||||||
"/Lotus/Upgrades/Mods/Immortal/ImmortalTwoMod",
|
"/Lotus/Upgrades/Mods/Immortal/ImmortalTwoMod",
|
||||||
"/Lotus/Upgrades/Mods/Immortal/ImmortalThreeMod",
|
"/Lotus/Upgrades/Mods/Immortal/ImmortalThreeMod",
|
||||||
@ -263,32 +263,51 @@ export const getNemesisPasscodeModTypes = (nemesis: { fp: bigint; Faction: TNeme
|
|||||||
const passcode = getNemesisPasscode(nemesis);
|
const passcode = getNemesisPasscode(nemesis);
|
||||||
return nemesis.Faction == "FC_INFESTATION"
|
return nemesis.Faction == "FC_INFESTATION"
|
||||||
? passcode.map(i => antivirusMods[i])
|
? passcode.map(i => antivirusMods[i])
|
||||||
: passcode.map(i => reqiuemMods[i]);
|
: passcode.map(i => requiemMods[i]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Symbols; 0-7 are the normal requiem mods.
|
||||||
export const GUESS_NONE = 8;
|
export const GUESS_NONE = 8;
|
||||||
export const GUESS_WILDCARD = 9;
|
export const GUESS_WILDCARD = 9;
|
||||||
|
|
||||||
export const encodeNemesisGuess = (
|
// Results; there are 3, 4, 5 as well which are more muted versions but unused afaik.
|
||||||
symbol1: number,
|
export const GUESS_NEUTRAL = 0;
|
||||||
result1: number,
|
export const GUESS_INCORRECT = 1;
|
||||||
symbol2: number,
|
export const GUESS_CORRECT = 2;
|
||||||
result2: number,
|
|
||||||
symbol3: number,
|
interface NemesisPositionGuess {
|
||||||
result3: number
|
symbol: number;
|
||||||
): number => {
|
result: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NemesisGuess = [NemesisPositionGuess, NemesisPositionGuess, NemesisPositionGuess];
|
||||||
|
|
||||||
|
export const encodeNemesisGuess = (guess: NemesisGuess): number => {
|
||||||
return (
|
return (
|
||||||
(symbol1 & 0xf) |
|
(guess[0].symbol & 0xf) |
|
||||||
((result1 & 3) << 12) |
|
((guess[0].result & 3) << 12) |
|
||||||
((symbol2 << 4) & 0xff) |
|
((guess[1].symbol << 4) & 0xff) |
|
||||||
((result2 << 14) & 0xffff) |
|
((guess[1].result << 14) & 0xffff) |
|
||||||
((symbol3 & 0xf) << 8) |
|
((guess[2].symbol & 0xf) << 8) |
|
||||||
((result3 & 3) << 16)
|
((guess[2].result & 3) << 16)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const decodeNemesisGuess = (val: number): number[] => {
|
export const decodeNemesisGuess = (val: number): NemesisGuess => {
|
||||||
return [val & 0xf, (val >> 12) & 3, (val & 0xff) >> 4, (val & 0xffff) >> 14, (val >> 8) & 0xf, (val >> 16) & 3];
|
return [
|
||||||
|
{
|
||||||
|
symbol: val & 0xf,
|
||||||
|
result: (val >> 12) & 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symbol: (val & 0xff) >> 4,
|
||||||
|
result: (val & 0xffff) >> 14
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symbol: (val >> 8) & 0xf,
|
||||||
|
result: (val >> 16) & 3
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface IKnifeResponse {
|
export interface IKnifeResponse {
|
||||||
|
@ -1182,14 +1182,12 @@ export const addMissionRewards = async (
|
|||||||
if (nodeIndex !== -1) inventory.Nemesis.InfNodes.splice(nodeIndex, 1);
|
if (nodeIndex !== -1) inventory.Nemesis.InfNodes.splice(nodeIndex, 1);
|
||||||
|
|
||||||
if (inventory.Nemesis.InfNodes.length <= 0) {
|
if (inventory.Nemesis.InfNodes.length <= 0) {
|
||||||
|
const manifest = getNemesisManifest(inventory.Nemesis.manifest);
|
||||||
if (inventory.Nemesis.Faction != "FC_INFESTATION") {
|
if (inventory.Nemesis.Faction != "FC_INFESTATION") {
|
||||||
inventory.Nemesis.Rank = Math.min(inventory.Nemesis.Rank + 1, 4);
|
inventory.Nemesis.Rank = Math.min(inventory.Nemesis.Rank + 1, manifest.systemIndexes.length - 1);
|
||||||
inventoryChanges.Nemesis.Rank = inventory.Nemesis.Rank;
|
inventoryChanges.Nemesis.Rank = inventory.Nemesis.Rank;
|
||||||
}
|
}
|
||||||
inventory.Nemesis.InfNodes = getInfNodes(
|
inventory.Nemesis.InfNodes = getInfNodes(manifest, inventory.Nemesis.Rank);
|
||||||
getNemesisManifest(inventory.Nemesis.manifest),
|
|
||||||
inventory.Nemesis.Rank
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inventory.Nemesis.Faction == "FC_INFESTATION") {
|
if (inventory.Nemesis.Faction == "FC_INFESTATION") {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user