XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

SpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 1 Star 0
返回提交历史

XFEstudio/SpaceNinjaServer

feat: weaken nemesis (#1893)

Closes #1885 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1893 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>

88d00eaa
Sainan <63328889+Sainan@users.noreply.github.com>
提交于

代码差异

2 个文件 +156 -50
Modified src/controllers/api/nemesisController.ts +86 -47
@@ -2,9 +2,12 @@ import {
2 2 consumeModCharge,
3 3 encodeNemesisGuess,
4 4 getInfNodes,
5 getKnifeUpgrade,
5 6 getNemesisPasscode,
7 getNemesisPasscodeModTypes,
6 8 getWeaponsForManifest,
7 IKnifeResponse
9 IKnifeResponse,
10 showdownNodes
8 11 } from "@/src/helpers/nemesisHelpers";
9 12 import { getJSONfromString } from "@/src/helpers/stringHelpers";
10 13 import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
@@ -15,6 +18,8 @@ import { IMongoDate, IOid } from "@/src/types/commonTypes";
15 18 import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
16 19 import {
17 20 IInnateDamageFingerprint,
21 IInventoryClient,
22 INemesisClient,
18 23 InventorySlot,
19 24 IUpgradeClient,
20 25 IWeaponSkinClient,
@@ -100,50 +105,45 @@ export const nemesisController: RequestHandler = async (req, res) => {
100 105 encodeNemesisGuess(guess[0], result1, guess[1], result2, guess[2], result3)
101 106 );
102 107
103 // Increase antivirus
104 let antivirusGain = 5;
105 const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!;
106 const dataknifeLoadout = loadout.DATAKNIFE.id(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid);
107 const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0;
108 const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!;
108 // Increase antivirus if correct antivirus mod is installed
109 109 const response: IKnifeResponse = {};
110 for (const upgrade of body.knife!.AttachedUpgrades) {
111 switch (upgrade.ItemType) {
112 case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusAndSpeedOnUseMod":
113 antivirusGain += 10;
114 consumeModCharge(response, inventory, upgrade, dataknifeUpgrades);
115 break;
116 case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusAndWeaponDamageOnUseMod":
117 antivirusGain += 10;
118 consumeModCharge(response, inventory, upgrade, dataknifeUpgrades);
119 break;
120 case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusLargeOnSingleUseMod": // Instant Secure
121 antivirusGain += 15;
122 consumeModCharge(response, inventory, upgrade, dataknifeUpgrades);
123 break;
124 case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusOnUseMod": // Immuno Shield
125 antivirusGain += 15;
126 consumeModCharge(response, inventory, upgrade, dataknifeUpgrades);
127 break;
128 case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusSmallOnSingleUseMod":
129 antivirusGain += 10;
130 consumeModCharge(response, inventory, upgrade, dataknifeUpgrades);
131 break;
110 if (result1 == 0 || result2 == 0 || result3 == 0) {
111 let antivirusGain = 5;
112 const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!;
113 const dataknifeLoadout = loadout.DATAKNIFE.id(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid);
114 const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0;
115 const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!;
116 for (const upgrade of body.knife!.AttachedUpgrades) {
117 switch (upgrade.ItemType) {
118 case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusAndSpeedOnUseMod":
119 antivirusGain += 10;
120 consumeModCharge(response, inventory, upgrade, dataknifeUpgrades);
121 break;
122 case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusAndWeaponDamageOnUseMod":
123 antivirusGain += 10;
124 consumeModCharge(response, inventory, upgrade, dataknifeUpgrades);
125 break;
126 case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusLargeOnSingleUseMod": // Instant Secure
127 antivirusGain += 15;
128 consumeModCharge(response, inventory, upgrade, dataknifeUpgrades);
129 break;
130 case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusOnUseMod": // Immuno Shield
131 antivirusGain += 15;
132 consumeModCharge(response, inventory, upgrade, dataknifeUpgrades);
133 break;
134 case "/Lotus/Upgrades/Mods/DataSpike/Potency/GainAntivirusSmallOnSingleUseMod":
135 antivirusGain += 10;
136 consumeModCharge(response, inventory, upgrade, dataknifeUpgrades);
137 break;
138 }
132 139 }
140 inventory.Nemesis!.HenchmenKilled += antivirusGain;
133 141 }
134 inventory.Nemesis!.HenchmenKilled += antivirusGain;
142
135 143 if (inventory.Nemesis!.HenchmenKilled >= 100) {
136 144 inventory.Nemesis!.HenchmenKilled = 100;
137 inventory.Nemesis!.InfNodes = [
138 {
139 Node: "CrewBattleNode559",
140 Influence: 1
141 }
142 ];
143 inventory.Nemesis!.Weakened = true;
144 } else {
145 inventory.Nemesis!.InfNodes = getInfNodes("FC_INFESTATION", 0);
146 145 }
146 inventory.Nemesis!.InfNodes = getInfNodes("FC_INFESTATION", 0);
147 147
148 148 await inventory.save();
149 149 res.json(response);
@@ -213,6 +213,38 @@ export const nemesisController: RequestHandler = async (req, res) => {
213 213 res.json({
214 214 target: inventory.toJSON().Nemesis
215 215 });
216 } else if ((req.query.mode as string) == "w") {
217 const inventory = await getInventory(
218 accountId,
219 "Nemesis LoadOutPresets CurrentLoadOutIds DataKnives Upgrades RawUpgrades"
220 );
221 //const body = getJSONfromString<INemesisWeakenRequest>(String(req.body));
222
223 inventory.Nemesis!.InfNodes = [
224 {
225 Node: showdownNodes[inventory.Nemesis!.Faction],
226 Influence: 1
227 }
228 ];
229 inventory.Nemesis!.Weakened = true;
230
231 const response: IKnifeResponse & { target: INemesisClient } = {
232 target: inventory.toJSON<IInventoryClient>().Nemesis!
233 };
234
235 // Consume charge of the correct requiem mod(s)
236 const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!;
237 const dataknifeLoadout = loadout.DATAKNIFE.id(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid);
238 const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0;
239 const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!;
240 const modTypes = getNemesisPasscodeModTypes(inventory.Nemesis!);
241 for (const modType of modTypes) {
242 const upgrade = getKnifeUpgrade(inventory, dataknifeUpgrades, modType);
243 consumeModCharge(response, inventory, upgrade, dataknifeUpgrades);
244 }
245
246 await inventory.save();
247 res.json(response);
216 248 } else {
217 249 logger.debug(`data provided to ${req.path}: ${String(req.body)}`);
218 250 throw new Error(`unknown nemesis mode: ${String(req.query.mode)}`);
@@ -264,12 +296,19 @@ interface INemesisRequiemRequest {
264 296 guess: number; // grn/crp: 4 bits | coda: 3x 4 bits
265 297 position: number; // grn/crp: 0-2 | coda: 0
266 298 // knife field provided for coda only
267 knife?: {
268 Item: IEquipmentClient;
269 Skins: IWeaponSkinClient[];
270 ModSlot: number;
271 CustSlot: number;
272 AttachedUpgrades: IUpgradeClient[];
273 HiddenWhenHolstered: boolean;
274 };
299 knife?: IKnife;
300 }
301
302 // interface INemesisWeakenRequest {
303 // target: INemesisClient;
304 // knife: IKnife;
305 // }
306
307 interface IKnife {
308 Item: IEquipmentClient;
309 Skins: IWeaponSkinClient[];
310 ModSlot: number;
311 CustSlot: number;
312 AttachedUpgrades: IUpgradeClient[];
313 HiddenWhenHolstered: boolean;
275 314 }
Modified src/helpers/nemesisHelpers.ts +70 -3
@@ -38,17 +38,59 @@ const systemIndexes: Record<string, number[]> = {
38 38 FC_INFESTATION: [23]
39 39 };
40 40
41 export const showdownNodes: Record<string, string> = {
42 FC_GRINEER: "CrewBattleNode557",
43 FC_CORPUS: "CrewBattleNode558",
44 FC_INFESTATION: "CrewBattleNode559"
45 };
46
41 47 // Get a parazon 'passcode' based on the nemesis fingerprint so it's always the same for the same nemesis.
42 48 export const getNemesisPasscode = (nemesis: { fp: bigint; Faction: string }): number[] => {
43 49 const rng = new SRng(nemesis.fp);
44 const passcode = [rng.randomInt(0, 7)];
50 const choices = [0, 1, 2, 3, 5, 6, 7];
51 let choiceIndex = rng.randomInt(0, choices.length - 1);
52 const passcode = [choices[choiceIndex]];
45 53 if (nemesis.Faction != "FC_INFESTATION") {
46 passcode.push(rng.randomInt(0, 7));
47 passcode.push(rng.randomInt(0, 7));
54 choices.splice(choiceIndex, 1);
55 choiceIndex = rng.randomInt(0, choices.length - 1);
56 passcode.push(choices[choiceIndex]);
57
58 choices.splice(choiceIndex, 1);
59 choiceIndex = rng.randomInt(0, choices.length - 1);
60 passcode.push(choices[choiceIndex]);
48 61 }
49 62 return passcode;
50 63 };
51 64
65 const reqiuemMods: readonly string[] = [
66 "/Lotus/Upgrades/Mods/Immortal/ImmortalOneMod",
67 "/Lotus/Upgrades/Mods/Immortal/ImmortalTwoMod",
68 "/Lotus/Upgrades/Mods/Immortal/ImmortalThreeMod",
69 "/Lotus/Upgrades/Mods/Immortal/ImmortalFourMod",
70 "/Lotus/Upgrades/Mods/Immortal/ImmortalFiveMod",
71 "/Lotus/Upgrades/Mods/Immortal/ImmortalSixMod",
72 "/Lotus/Upgrades/Mods/Immortal/ImmortalSevenMod",
73 "/Lotus/Upgrades/Mods/Immortal/ImmortalEightMod"
74 ];
75
76 const antivirusMods: readonly string[] = [
77 "/Lotus/Upgrades/Mods/Immortal/AntivirusOneMod",
78 "/Lotus/Upgrades/Mods/Immortal/AntivirusTwoMod",
79 "/Lotus/Upgrades/Mods/Immortal/AntivirusThreeMod",
80 "/Lotus/Upgrades/Mods/Immortal/AntivirusFourMod",
81 "/Lotus/Upgrades/Mods/Immortal/AntivirusFiveMod",
82 "/Lotus/Upgrades/Mods/Immortal/AntivirusSixMod",
83 "/Lotus/Upgrades/Mods/Immortal/AntivirusSevenMod",
84 "/Lotus/Upgrades/Mods/Immortal/AntivirusEightMod"
85 ];
86
87 export const getNemesisPasscodeModTypes = (nemesis: { fp: bigint; Faction: string }): string[] => {
88 const passcode = getNemesisPasscode(nemesis);
89 return nemesis.Faction == "FC_INFESTATION"
90 ? passcode.map(i => antivirusMods[i])
91 : passcode.map(i => reqiuemMods[i]);
92 };
93
52 94 export const encodeNemesisGuess = (
53 95 symbol1: number,
54 96 result1: number,
@@ -79,6 +121,31 @@ export interface IKnifeResponse {
79 121 HasKnife?: boolean;
80 122 }
81 123
124 export const getKnifeUpgrade = (
125 inventory: TInventoryDatabaseDocument,
126 dataknifeUpgrades: string[],
127 type: string
128 ): { ItemId: IOid; ItemType: string } => {
129 if (dataknifeUpgrades.indexOf(type) != -1) {
130 return {
131 ItemId: { $oid: "000000000000000000000000" },
132 ItemType: type
133 };
134 }
135 for (const upgradeId of dataknifeUpgrades) {
136 if (upgradeId.length == 24) {
137 const upgrade = inventory.Upgrades.id(upgradeId);
138 if (upgrade && upgrade.ItemType == type) {
139 return {
140 ItemId: { $oid: upgradeId },
141 ItemType: type
142 };
143 }
144 }
145 }
146 throw new Error(`${type} does not seem to be installed on parazon?!`);
147 };
148
82 149 export const consumeModCharge = (
83 150 response: IKnifeResponse,
84 151 inventory: TInventoryDatabaseDocument,