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

XFESpaceNinjaServer

A simple server for a small space ninja game

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

XFEstudio/XFESpaceNinjaServer

feat: ability cards (#3395)

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

53092822
AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
提交于

代码差异

14 个文件 +790 -14
Modified src/controllers/api/claimCompletedRecipeController.ts +4 -1
@@ -273,6 +273,7 @@ const claimCompletedRecipe = async (
273 273 XP: 900_000,
274 274 Features: EquipmentFeatures.DOUBLE_CAPACITY
275 275 },
276 account.BuildLabel,
276 277 resp.InventoryChanges
277 278 );
278 279 inventory.XPInfo.push({
@@ -317,7 +318,9 @@ const claimCompletedRecipe = async (
317 318 recipe.num,
318 319 false,
319 320 undefined,
320 pendingRecipe.TargetFingerprint
321 pendingRecipe.TargetFingerprint,
322 undefined,
323 account.BuildLabel
321 324 )
322 325 );
323 326 }
Modified src/controllers/api/giveStartingGearController.ts +7 -5
@@ -1,25 +1,27 @@
1 1 import { getJSONfromString } from "../../helpers/stringHelpers.ts";
2 2 import { addStartingGear, getInventory } from "../../services/inventoryService.ts";
3 import { getAccountIdForRequest } from "../../services/loginService.ts";
3 import { getAccountForRequest } from "../../services/loginService.ts";
4 4 import type { TPartialStartingGear } from "../../types/inventoryTypes/inventoryTypes.ts";
5 5 import type { RequestHandler } from "express";
6 6
7 7 export const giveStartingGearPostController: RequestHandler = async (req, res) => {
8 const accountId = await getAccountIdForRequest(req);
8 const account = await getAccountForRequest(req);
9 const accountId = account._id.toString();
9 10 const startingGear = getJSONfromString<TPartialStartingGear>(String(req.body));
10 11 const inventory = await getInventory(accountId);
11 12
12 const inventoryChanges = await addStartingGear(inventory, startingGear);
13 const inventoryChanges = await addStartingGear(inventory, account.BuildLabel, startingGear);
13 14 await inventory.save();
14 15
15 16 res.send(inventoryChanges);
16 17 };
17 18
18 19 export const giveStartingGearGetController: RequestHandler = async (req, res) => {
19 const accountId = await getAccountIdForRequest(req);
20 const account = await getAccountForRequest(req);
21 const accountId = account._id.toString();
20 22 const inventory = await getInventory(accountId);
21 23
22 const inventoryChanges = await addStartingGear(inventory, {
24 const inventoryChanges = await addStartingGear(inventory, account.BuildLabel, {
23 25 Suits: [
24 26 {
25 27 ItemType: String(req.query.warframeName),
Modified src/controllers/custom/getItemListsController.ts +55 -0
@@ -25,6 +25,7 @@ import {
25 25 } from "warframe-public-export-plus";
26 26 import allIncarnons from "../../../static/fixed_responses/allIncarnonList.json" with { type: "json" };
27 27 import varzia from "../../constants/varzia.ts";
28 import suitDefaultUpgrades from "../../constants/suitDefaultUpgrades.ts";
28 29
29 30 interface ListedItem {
30 31 uniqueName: string;
@@ -342,6 +343,60 @@ const getItemListsController: RequestHandler = (req, response) => {
342 343 }
343 344 res.mods.push(mod);
344 345 }
346 {
347 const uniqueItemTypes = [
348 ...new Set(
349 Object.values(suitDefaultUpgrades)
350 .flat()
351 .map(u => u.ItemType)
352 )
353 ];
354 const abilityNameOverrides: Record<string, string> = {
355 "/Lotus/Powersuits/AntiMatter/AntiMatterDropAbilityCard": "/Lotus/Language/Suits/DropAbilityName",
356 "/Lotus/Powersuits/AntiMatter/NullStarAbilityCard": "/Lotus/Language/Suits/NullstarAbilityName",
357 "/Lotus/Powersuits/Banshee/EarthQuakeAbilityCard": "/Lotus/Language/Suits/SoundquakeAbilityName",
358 "/Lotus/Powersuits/Berserker/GrappleAbilityCard": "/Lotus/Language/Suits/GrappleHookAbilityName",
359 "/Lotus/Powersuits/Berserker/IntimidateAbilityCard": "/Lotus/Language/Suits/BerserkerScreamAbilityName",
360 "/Lotus/Powersuits/Berserker/ShieldBlastAbilityCard": "/Lotus/Language/Suits/ShieldBashAbilityName",
361 "/Lotus/Powersuits/Cowgirl/RicochetArmourAbilityCard": "/Lotus/Language/Suits/RicochetArmorAbilityName",
362 "/Lotus/Powersuits/Ember/FireSkinAbilityCard": "/Lotus/Language/Suits/OverheatAbilityName",
363 "/Lotus/Powersuits/Excalibur/SuperJumpAbilityCard": "/Lotus/Language/Items/SuperJumpAbility",
364 "/Lotus/Powersuits/Frost/IceShieldAbilityCard": "/Lotus/Language/Suits/SnowGlobeAbilityName",
365 "/Lotus/Powersuits/Frost/IceSpikeAbilityCard": "/Lotus/Language/Suits/IceWaveAbilityName",
366 "/Lotus/Powersuits/Frost/IcicleAbilityCard": "/Lotus/Language/Suits/FreezeAbilityName",
367 "/Lotus/Powersuits/Harlequin/LightAbilityCard": "/Lotus/Language/Suits/EclipseAbilityName",
368 "/Lotus/Powersuits/Harlequin/ObjectChangeAbilityCard": "/Lotus/Language/Suits/SleightOfHandAbilityName",
369 "/Lotus/Powersuits/Harlequin/PrismAbilityCard": "/Lotus/Language/Suits/GrandFinaleName",
370 "/Lotus/Powersuits/Jade/DaggerAbilityCard": "/Lotus/Language/Suits/PhysicDaggerAbilityName",
371 "/Lotus/Powersuits/Jade/SelfBulletAttractorAbilityCard": "/Lotus/Language/Suits/AbsorbAbilityName",
372 "/Lotus/Powersuits/Loki/DisarmAbilityCard": "/Lotus/Language/Suits/RadialDisarmAbilityName",
373 "/Lotus/Powersuits/Loki/SwitchAbilityCard": "/Lotus/Language/Suits/SwitchTeleportAbilityName",
374 "/Lotus/Powersuits/Ninja/TelelportToAbilityCard": "/Lotus/Language/Suits/TeleportToAbilityName",
375 "/Lotus/Powersuits/Pirate/LiquifyAbilityCard": "/Lotus/Language/Suits/LiquefyAbilityName",
376 "/Lotus/Powersuits/Rhino/RadialBlastAbilityCard": "/Lotus/Language/Suits/RhinoRoarAbilityName",
377 "/Lotus/Powersuits/Tengu/DiveBombAbilityCard": "/Lotus/Language/Suits/ZephyrDiveBombAbilityName",
378 "/Lotus/Powersuits/Tengu/TailWindAbilityCard": "/Lotus/Language/Suits/ZephyrTailWindAbilityName",
379 "/Lotus/Powersuits/Tengu/TornadoAbilityCard": "/Lotus/Language/Suits/ZephyrTornadoAbilityName",
380 "/Lotus/Powersuits/Tengu/TurbulenceAbilityCard": "/Lotus/Language/Suits/ZephyrTurbulenceAbilityName",
381 "/Lotus/Powersuits/Trapper/BounceTrapAbilityCard": "/Lotus/Language/Suits/TrapperMultinadeAbilityName",
382 "/Lotus/Powersuits/Volt/OverloadAbilityCard": "/Lotus/Language/Suits/OverLoadAbilityName"
383 };
384 for (const uniqueName of uniqueItemTypes) {
385 let locStr: string;
386
387 if (abilityNameOverrides[uniqueName]) {
388 locStr = abilityNameOverrides[uniqueName];
389 } else {
390 const abilityBase = uniqueName.split("/").pop()!.replace(/Card$/, "");
391 locStr = `/Lotus/Language/Suits/${abilityBase}Name`;
392 }
393 res.mods.push({
394 uniqueName,
395 name: getString(locStr, lang),
396 fusionLimit: 3
397 });
398 }
399 }
345 400 for (const [uniqueName, upgrade] of Object.entries(ExportAvionics)) {
346 401 res.mods.push({
347 402 uniqueName,
Modified src/services/inventoryService.ts +21 -6
@@ -96,6 +96,7 @@ import type { ITypeCount } from "../types/commonTypes.ts";
96 96 import { skinLookupTable } from "../helpers/skinLookupTable.ts";
97 97 import type { TLoadoutDatabaseDocument } from "../models/inventoryModels/loadoutModel.ts";
98 98 import gameToBuildVersion from "../constants/gameToBuildVersion.ts";
99 import suitDefaultUpgrades from "../constants/suitDefaultUpgrades.ts";
99 100
100 101 type OperatorAntiqueMeta = {
101 102 focusAbility: string;
@@ -275,6 +276,7 @@ export const createInventory = async (
275 276
276 277 export const addStartingGear = async (
277 278 inventory: TInventoryDatabaseDocument,
279 buildLabel?: string,
278 280 startingGear?: Partial<TPartialStartingGear>
279 281 ): Promise<IInventoryChanges> => {
280 282 if (inventory.ReceivedStartingGear) {
@@ -295,7 +297,7 @@ export const addStartingGear = async (
295 297 addEquipment(inventory, "LongGuns", LongGuns[0].ItemType, { IsNew: false }, inventoryChanges);
296 298 addEquipment(inventory, "Pistols", Pistols[0].ItemType, { IsNew: false }, inventoryChanges);
297 299 combineInventoryChanges(inventoryChanges, await addItem(inventory, Melee[0].ItemType)); // defaultUpgrades need to respected because as of U38.5, Skana & Bo come with stances by default.
298 await addPowerSuit(inventory, Suits[0].ItemType, { IsNew: false }, inventoryChanges);
300 await addPowerSuit(inventory, Suits[0].ItemType, { IsNew: false }, buildLabel, inventoryChanges);
299 301 addEquipment(
300 302 inventory,
301 303 "DataKnives",
@@ -622,7 +624,8 @@ export const addItem = async (
622 624 if (
623 625 typeName in ExportUpgrades ||
624 626 typeName in ExportArcanes ||
625 typeName.startsWith("/Lotus/Upgrades/Mods/Fusers/")
627 typeName.startsWith("/Lotus/Upgrades/Mods/Fusers/") ||
628 (typeName.endsWith("AbilityCard") && typeName.startsWith("/Lotus/Powersuits/"))
626 629 ) {
627 630 if (targetFingerprint && typeName.startsWith("/Lotus/Upgrades/Mods/Randomized/Raw")) {
628 631 logger.debug(`ignoring fingerprint for raw riven mod`);
@@ -879,9 +882,14 @@ export const addItem = async (
879 882 throw new Error(`unexpected acquisition quantity of Suits: got ${quantity}, expected 1`);
880 883 }
881 884 return {
882 ...(await addPowerSuit(inventory, typeName, {
883 Features: premiumPurchase ? EquipmentFeatures.DOUBLE_CAPACITY : undefined
884 })),
885 ...(await addPowerSuit(
886 inventory,
887 typeName,
888 {
889 Features: premiumPurchase ? EquipmentFeatures.DOUBLE_CAPACITY : undefined
890 },
891 buildLabel
892 )),
885 893 ...occupySlot(inventory, InventorySlot.SUITS, premiumPurchase)
886 894 };
887 895 }
@@ -1316,6 +1324,7 @@ export const addPowerSuit = async (
1316 1324 inventory: TInventoryDatabaseDocument,
1317 1325 powersuitName: string,
1318 1326 defaultOverwrites?: Partial<IEquipmentDatabase>,
1327 buildLabel?: string,
1319 1328 inventoryChanges: IInventoryChanges = {}
1320 1329 ): Promise<IInventoryChanges> => {
1321 1330 const powersuit = ExportWarframes[powersuitName] as IPowersuit | undefined;
@@ -1330,10 +1339,16 @@ export const addPowerSuit = async (
1330 1339 }
1331 1340 }
1332 1341 }
1342 let configs: IItemConfig[] = [];
1343 if (buildLabel && version_compare(buildLabel, gameToBuildVersion["15.0.0"]) < 0) {
1344 if (powersuitName in suitDefaultUpgrades) {
1345 configs = applyDefaultUpgrades(inventory, suitDefaultUpgrades[powersuitName], inventoryChanges);
1346 }
1347 }
1333 1348 const suit: Omit<IEquipmentDatabase, "_id"> = Object.assign(
1334 1349 {
1335 1350 ItemType: powersuitName,
1336 Configs: [],
1351 Configs: configs,
1337 1352 UpgradeVer: 101,
1338 1353 XP: 0,
1339 1354 IsNew: true
Modified src/services/purchaseService.ts +2 -1
@@ -526,7 +526,8 @@ export const handleStoreItemAcquisition = async (
526 526 premiumPurchase,
527 527 seed,
528 528 undefined,
529 true
529 true,
530 buildLabel
530 531 )
531 532 };
532 533 break;
Modified static/webui/script.js +4 -1
@@ -683,6 +683,9 @@ function fetchItemList() {
683 683 const nameToItems = {};
684 684 items.forEach(item => {
685 685 item.name = item.name.replace(/<.+>/g, "").trim();
686 if (item.name == "/Lotus/Language/Suits/RiftWalkAbilityName") {
687 item.name = loc("code_RiftWalkAbilityName");
688 }
686 689 if ("badReason" in item) {
687 690 if (item.badReason == "starter") {
688 691 item.name = loc("code_starter").split("|MOD|").join(item.name);
@@ -3523,7 +3526,7 @@ function doRemoveUnrankedMods() {
3523 3526 SellCurrency: "SC_RegularCredits",
3524 3527 SellPrice: 0,
3525 3528 Items: {
3526 Upgrades: inventory.RawUpgrades.filter(
3529 Upgrades: data.RawUpgrades.filter(
3527 3530 x => !itemMap[x.ItemType]?.parazon && x.ItemCount > 0
3528 3531 ).map(x => ({ String: x.ItemType, Count: x.ItemCount }))
3529 3532 }
Modified static/webui/translations/de.js +1 -0
@@ -31,6 +31,7 @@ dict = {
31 31 code_traumaticPeculiar: `Kuriose Mod: Traumatisch`,
32 32 code_starter: `|MOD| (Defekt)`,
33 33 code_badItem: `(Fälschung)`,
34 code_RiftWalkAbilityName: `Riftlauf`,
34 35 code_maxRank: `Max. Rang`,
35 36 code_rename: `Umbenennen`,
36 37 code_renamePrompt: `Neuen benutzerdefinierten Namen eingeben:`,
Modified static/webui/translations/en.js +1 -0
@@ -30,6 +30,7 @@ dict = {
30 30 code_traumaticPeculiar: `Traumatic Peculiar`,
31 31 code_starter: `|MOD| (Flawed)`,
32 32 code_badItem: `(Imposter)`,
33 code_RiftWalkAbilityName: `Rift Walk`,
33 34 code_maxRank: `Max Rank`,
34 35 code_rename: `Rename`,
35 36 code_renamePrompt: `Enter new custom name:`,
Modified static/webui/translations/es.js +1 -0
@@ -31,6 +31,7 @@ dict = {
31 31 code_traumaticPeculiar: `Traumatismo peculiar`,
32 32 code_starter: `|MOD| (Defectuoso)`,
33 33 code_badItem: `(Impostor)`,
34 code_RiftWalkAbilityName: `Paseo dimensional`,
34 35 code_maxRank: `Rango máximo`,
35 36 code_rename: `Renombrar`,
36 37 code_renamePrompt: `Escribe tu nuevo nombre personalizado:`,
Modified static/webui/translations/fr.js +1 -0
@@ -31,6 +31,7 @@ dict = {
31 31 code_traumaticPeculiar: `Traumatisme Atypique`,
32 32 code_starter: `|MOD| (Défectueux)`,
33 33 code_badItem: `(Imposteur)`,
34 code_RiftWalkAbilityName: `Transfert Dimensionnel`,
34 35 code_maxRank: `Rang Max`,
35 36 code_rename: `Renommer`,
36 37 code_renamePrompt: `Nouveau nom :`,
Modified static/webui/translations/ru.js +1 -0
@@ -31,6 +31,7 @@ dict = {
31 31 code_traumaticPeculiar: `Травмирующая Странность`,
32 32 code_starter: `|MOD| (Повреждённый)`,
33 33 code_badItem: `(Самозванец)`,
34 code_RiftWalkAbilityName: `Путь в Разлом`,
34 35 code_maxRank: `Макс. ранг`,
35 36 code_rename: `Переименовать`,
36 37 code_renamePrompt: `Введите новое имя:`,
Modified static/webui/translations/uk.js +1 -0
@@ -31,6 +31,7 @@ dict = {
31 31 code_traumaticPeculiar: `Особливе травмування`,
32 32 code_starter: `|MOD| (Пошкоджений)`,
33 33 code_badItem: `(Самозванець)`,
34 code_RiftWalkAbilityName: `Крок у розлом`,
34 35 code_maxRank: `Макс. рівень`,
35 36 code_rename: `Перейменувати`,
36 37 code_renamePrompt: `Введіть нове ім'я:`,
Modified static/webui/translations/zh.js +1 -0