返回提交历史
Added
src/constants/suitDefaultUpgrades.ts
+690
-0
Modified
src/controllers/api/claimCompletedRecipeController.ts
+4
-1
Modified
src/controllers/api/giveStartingGearController.ts
+7
-5
Modified
src/controllers/custom/getItemListsController.ts
+55
-0
Modified
src/services/inventoryService.ts
+21
-6
Modified
src/services/purchaseService.ts
+2
-1
Modified
static/webui/script.js
+4
-1
Modified
static/webui/translations/de.js
+1
-0
Modified
static/webui/translations/en.js
+1
-0
Modified
static/webui/translations/es.js
+1
-0
Modified
static/webui/translations/fr.js
+1
-0
Modified
static/webui/translations/ru.js
+1
-0
Modified
static/webui/translations/uk.js
+1
-0
Modified
static/webui/translations/zh.js
+1
-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
代码差异
14 个文件
+790
-14
@@ -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
}
@@ -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),
@@ -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,
@@ -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
@@ -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;
@@ -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
}
@@ -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:`,
@@ -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:`,
@@ -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:`,
@@ -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 :`,
@@ -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: `Введите новое имя:`,
@@ -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: `Введіть нове ім'я:`,