feat: fabricate research (#1150)
Closes #910 Reviewed-on: OpenWF/SpaceNinjaServer#1150
This commit is contained in:
parent
ead7b67efc
commit
38dfe14776
8
package-lock.json
generated
8
package-lock.json
generated
@ -17,7 +17,7 @@
|
|||||||
"mongoose": "^8.11.0",
|
"mongoose": "^8.11.0",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"typescript": ">=4.7.4 <5.6.0",
|
"typescript": ">=4.7.4 <5.6.0",
|
||||||
"warframe-public-export-plus": "^0.5.42",
|
"warframe-public-export-plus": "^0.5.43",
|
||||||
"warframe-riven-info": "^0.1.2",
|
"warframe-riven-info": "^0.1.2",
|
||||||
"winston": "^3.17.0",
|
"winston": "^3.17.0",
|
||||||
"winston-daily-rotate-file": "^5.0.0"
|
"winston-daily-rotate-file": "^5.0.0"
|
||||||
@ -4073,9 +4073,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/warframe-public-export-plus": {
|
"node_modules/warframe-public-export-plus": {
|
||||||
"version": "0.5.42",
|
"version": "0.5.43",
|
||||||
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.42.tgz",
|
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.43.tgz",
|
||||||
"integrity": "sha512-up3P5bLKD42Xkr3o7TX9WUwvpJzK88aQTLZ2bB6QWUHdsJxl/Z3TBn+HSd3eouIDTMVUzbTDeDPosSw7TcLegA=="
|
"integrity": "sha512-LeF7HmsjOPsJDtgr66x3iMEIAQgcxKNM54VG895FTemgHLLo34UGDyeS1yIfY67WxxbTUgW3MkHQLlCEJXD14w=="
|
||||||
},
|
},
|
||||||
"node_modules/warframe-riven-info": {
|
"node_modules/warframe-riven-info": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
"mongoose": "^8.11.0",
|
"mongoose": "^8.11.0",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"typescript": ">=4.7.4 <5.6.0",
|
"typescript": ">=4.7.4 <5.6.0",
|
||||||
"warframe-public-export-plus": "^0.5.42",
|
"warframe-public-export-plus": "^0.5.43",
|
||||||
"warframe-riven-info": "^0.1.2",
|
"warframe-riven-info": "^0.1.2",
|
||||||
"winston": "^3.17.0",
|
"winston": "^3.17.0",
|
||||||
"winston-daily-rotate-file": "^5.0.0"
|
"winston-daily-rotate-file": "^5.0.0"
|
||||||
|
@ -2,7 +2,14 @@ import { RequestHandler } from "express";
|
|||||||
import { getGuildForRequestEx, getGuildVault, scaleRequiredCount } from "@/src/services/guildService";
|
import { getGuildForRequestEx, getGuildVault, scaleRequiredCount } from "@/src/services/guildService";
|
||||||
import { ExportDojoRecipes, IDojoResearch } from "warframe-public-export-plus";
|
import { ExportDojoRecipes, IDojoResearch } from "warframe-public-export-plus";
|
||||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||||
import { addMiscItems, addRecipes, getInventory, updateCurrency } from "@/src/services/inventoryService";
|
import {
|
||||||
|
addItem,
|
||||||
|
addMiscItems,
|
||||||
|
addRecipes,
|
||||||
|
combineInventoryChanges,
|
||||||
|
getInventory,
|
||||||
|
updateCurrency
|
||||||
|
} from "@/src/services/inventoryService";
|
||||||
import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
|
import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||||
import { config } from "@/src/services/configService";
|
import { config } from "@/src/services/configService";
|
||||||
@ -127,6 +134,20 @@ export const guildTechController: RequestHandler = async (req, res) => {
|
|||||||
Recipes: recipeChanges
|
Recipes: recipeChanges
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else if (action == "Fabricate") {
|
||||||
|
const payload = data as IGuildTechFabricateRequest;
|
||||||
|
const recipe = ExportDojoRecipes.fabrications[payload.RecipeType];
|
||||||
|
const inventory = await getInventory(accountId);
|
||||||
|
const inventoryChanges: IInventoryChanges = updateCurrency(inventory, recipe.price, false);
|
||||||
|
inventoryChanges.MiscItems = recipe.ingredients.map(x => ({
|
||||||
|
ItemType: x.ItemType,
|
||||||
|
ItemCount: x.ItemCount * -1
|
||||||
|
}));
|
||||||
|
addMiscItems(inventory, inventoryChanges.MiscItems);
|
||||||
|
combineInventoryChanges(inventoryChanges, (await addItem(inventory, recipe.resultType)).InventoryChanges);
|
||||||
|
await inventory.save();
|
||||||
|
// Not a mistake: This response uses `inventoryChanges` instead of `InventoryChanges`.
|
||||||
|
res.json({ inventoryChanges: inventoryChanges });
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`unknown guildTech action: ${data.Action}`);
|
throw new Error(`unknown guildTech action: ${data.Action}`);
|
||||||
}
|
}
|
||||||
@ -144,10 +165,12 @@ const processFundedProject = (
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
type TGuildTechRequest = {
|
type TGuildTechRequest =
|
||||||
Action: string;
|
| ({
|
||||||
} & Partial<IGuildTechStartFields> &
|
Action: string;
|
||||||
Partial<IGuildTechContributeFields>;
|
} & Partial<IGuildTechStartFields> &
|
||||||
|
Partial<IGuildTechContributeFields>)
|
||||||
|
| IGuildTechFabricateRequest;
|
||||||
|
|
||||||
interface IGuildTechStartFields {
|
interface IGuildTechStartFields {
|
||||||
Mode: "Guild";
|
Mode: "Guild";
|
||||||
@ -164,3 +187,9 @@ interface IGuildTechContributeFields {
|
|||||||
VaultCredits: number;
|
VaultCredits: number;
|
||||||
VaultMiscItems: IMiscItem[];
|
VaultMiscItems: IMiscItem[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IGuildTechFabricateRequest {
|
||||||
|
Action: "Fabricate";
|
||||||
|
Mode: "Guild";
|
||||||
|
RecipeType: string;
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
ExportDrones,
|
ExportDrones,
|
||||||
ExportGear,
|
ExportGear,
|
||||||
ExportMisc,
|
ExportMisc,
|
||||||
|
ExportRailjackWeapons,
|
||||||
ExportRecipes,
|
ExportRecipes,
|
||||||
ExportRelics,
|
ExportRelics,
|
||||||
ExportResources,
|
ExportResources,
|
||||||
@ -160,6 +161,12 @@ const getItemListsController: RequestHandler = (req, response) => {
|
|||||||
name: getString(item.name, lang)
|
name: getString(item.name, lang)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
for (const [uniqueName, item] of Object.entries(ExportRailjackWeapons)) {
|
||||||
|
res.miscitems.push({
|
||||||
|
uniqueName: uniqueName,
|
||||||
|
name: getString(item.name, lang)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
res.mods = [];
|
res.mods = [];
|
||||||
for (const [uniqueName, upgrade] of Object.entries(ExportUpgrades)) {
|
for (const [uniqueName, upgrade] of Object.entries(ExportUpgrades)) {
|
||||||
|
@ -75,7 +75,8 @@ import {
|
|||||||
ICollectibleEntry,
|
ICollectibleEntry,
|
||||||
IIncentiveState,
|
IIncentiveState,
|
||||||
ISongChallenge,
|
ISongChallenge,
|
||||||
ILibraryPersonalProgress
|
ILibraryPersonalProgress,
|
||||||
|
ICrewShipWeaponDatabase
|
||||||
} from "../../types/inventoryTypes/inventoryTypes";
|
} from "../../types/inventoryTypes/inventoryTypes";
|
||||||
import { IOid } from "../../types/commonTypes";
|
import { IOid } from "../../types/commonTypes";
|
||||||
import {
|
import {
|
||||||
@ -1037,6 +1038,25 @@ const alignmentSchema = new Schema<IAlignment>(
|
|||||||
{ _id: false }
|
{ _id: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const crewShipWeaponSchema2 = new Schema<ICrewShipWeaponDatabase>(
|
||||||
|
{
|
||||||
|
ItemType: String
|
||||||
|
},
|
||||||
|
{ id: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
crewShipWeaponSchema2.virtual("ItemId").get(function () {
|
||||||
|
return { $oid: this._id.toString() } satisfies IOid;
|
||||||
|
});
|
||||||
|
|
||||||
|
crewShipWeaponSchema2.set("toJSON", {
|
||||||
|
virtuals: true,
|
||||||
|
transform(_document, returnedObject) {
|
||||||
|
delete returnedObject._id;
|
||||||
|
delete returnedObject.__v;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
||||||
{
|
{
|
||||||
accountOwnerId: Schema.Types.ObjectId,
|
accountOwnerId: Schema.Types.ObjectId,
|
||||||
@ -1157,7 +1177,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
|
|
||||||
//Default RailJack
|
//Default RailJack
|
||||||
CrewShipAmmo: [typeCountSchema],
|
CrewShipAmmo: [typeCountSchema],
|
||||||
CrewShipWeapons: [Schema.Types.Mixed],
|
CrewShipWeapons: [crewShipWeaponSchema2],
|
||||||
CrewShipWeaponSkins: [upgradeSchema],
|
CrewShipWeaponSkins: [upgradeSchema],
|
||||||
|
|
||||||
//NPC Crew and weapon
|
//NPC Crew and weapon
|
||||||
@ -1404,6 +1424,7 @@ export type InventoryDocumentProps = {
|
|||||||
WeaponSkins: Types.DocumentArray<IWeaponSkinDatabase>;
|
WeaponSkins: Types.DocumentArray<IWeaponSkinDatabase>;
|
||||||
QuestKeys: Types.DocumentArray<IQuestKeyDatabase>;
|
QuestKeys: Types.DocumentArray<IQuestKeyDatabase>;
|
||||||
Drones: Types.DocumentArray<IDroneDatabase>;
|
Drones: Types.DocumentArray<IDroneDatabase>;
|
||||||
|
CrewShipWeapons: Types.DocumentArray<ICrewShipWeaponDatabase>;
|
||||||
CrewShipWeaponSkins: Types.DocumentArray<IUpgradeDatabase>;
|
CrewShipWeaponSkins: Types.DocumentArray<IUpgradeDatabase>;
|
||||||
} & { [K in TEquipmentKey]: Types.DocumentArray<IEquipmentDatabase> };
|
} & { [K in TEquipmentKey]: Types.DocumentArray<IEquipmentDatabase> };
|
||||||
|
|
||||||
|
@ -26,7 +26,8 @@ import {
|
|||||||
ILibraryDailyTaskInfo,
|
ILibraryDailyTaskInfo,
|
||||||
ICalendarProgress,
|
ICalendarProgress,
|
||||||
IDroneClient,
|
IDroneClient,
|
||||||
IUpgradeClient
|
IUpgradeClient,
|
||||||
|
ICrewShipWeaponClient
|
||||||
} from "@/src/types/inventoryTypes/inventoryTypes";
|
} from "@/src/types/inventoryTypes/inventoryTypes";
|
||||||
import { IGenericUpdate } from "../types/genericUpdate";
|
import { IGenericUpdate } from "../types/genericUpdate";
|
||||||
import {
|
import {
|
||||||
@ -54,6 +55,7 @@ import {
|
|||||||
ExportGear,
|
ExportGear,
|
||||||
ExportKeys,
|
ExportKeys,
|
||||||
ExportMisc,
|
ExportMisc,
|
||||||
|
ExportRailjackWeapons,
|
||||||
ExportRecipes,
|
ExportRecipes,
|
||||||
ExportResources,
|
ExportResources,
|
||||||
ExportSentinels,
|
ExportSentinels,
|
||||||
@ -386,6 +388,14 @@ export const addItem = async (
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (typeName in ExportRailjackWeapons) {
|
||||||
|
return {
|
||||||
|
InventoryChanges: {
|
||||||
|
...addCrewShipWeapon(inventory, typeName),
|
||||||
|
...occupySlot(inventory, InventorySlot.RJ_COMPONENT_AND_ARMAMENTS, premiumPurchase)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
if (typeName in ExportMisc.creditBundles) {
|
if (typeName in ExportMisc.creditBundles) {
|
||||||
const creditsTotal = ExportMisc.creditBundles[typeName] * quantity;
|
const creditsTotal = ExportMisc.creditBundles[typeName] * quantity;
|
||||||
inventory.RegularCredits += creditsTotal;
|
inventory.RegularCredits += creditsTotal;
|
||||||
@ -859,6 +869,7 @@ export const addCustomization = (
|
|||||||
inventoryChanges: IInventoryChanges = {}
|
inventoryChanges: IInventoryChanges = {}
|
||||||
): IInventoryChanges => {
|
): IInventoryChanges => {
|
||||||
const flavourItemIndex = inventory.FlavourItems.push({ ItemType: customizationName }) - 1;
|
const flavourItemIndex = inventory.FlavourItems.push({ ItemType: customizationName }) - 1;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
inventoryChanges.FlavourItems ??= [];
|
inventoryChanges.FlavourItems ??= [];
|
||||||
(inventoryChanges.FlavourItems as IFlavourItem[]).push(
|
(inventoryChanges.FlavourItems as IFlavourItem[]).push(
|
||||||
inventory.FlavourItems[flavourItemIndex].toJSON<IFlavourItem>()
|
inventory.FlavourItems[flavourItemIndex].toJSON<IFlavourItem>()
|
||||||
@ -872,6 +883,7 @@ export const addSkin = (
|
|||||||
inventoryChanges: IInventoryChanges = {}
|
inventoryChanges: IInventoryChanges = {}
|
||||||
): IInventoryChanges => {
|
): IInventoryChanges => {
|
||||||
const index = inventory.WeaponSkins.push({ ItemType: typeName }) - 1;
|
const index = inventory.WeaponSkins.push({ ItemType: typeName }) - 1;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
inventoryChanges.WeaponSkins ??= [];
|
inventoryChanges.WeaponSkins ??= [];
|
||||||
(inventoryChanges.WeaponSkins as IWeaponSkinClient[]).push(
|
(inventoryChanges.WeaponSkins as IWeaponSkinClient[]).push(
|
||||||
inventory.WeaponSkins[index].toJSON<IWeaponSkinClient>()
|
inventory.WeaponSkins[index].toJSON<IWeaponSkinClient>()
|
||||||
@ -879,12 +891,27 @@ export const addSkin = (
|
|||||||
return inventoryChanges;
|
return inventoryChanges;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const addCrewShipWeapon = (
|
||||||
|
inventory: TInventoryDatabaseDocument,
|
||||||
|
typeName: string,
|
||||||
|
inventoryChanges: IInventoryChanges = {}
|
||||||
|
): IInventoryChanges => {
|
||||||
|
const index = inventory.CrewShipWeapons.push({ ItemType: typeName, _id: new Types.ObjectId() }) - 1;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
|
inventoryChanges.CrewShipWeapons ??= [];
|
||||||
|
(inventoryChanges.CrewShipWeapons as ICrewShipWeaponClient[]).push(
|
||||||
|
inventory.CrewShipWeapons[index].toJSON<ICrewShipWeaponClient>()
|
||||||
|
);
|
||||||
|
return inventoryChanges;
|
||||||
|
};
|
||||||
|
|
||||||
const addCrewShipWeaponSkin = (
|
const addCrewShipWeaponSkin = (
|
||||||
inventory: TInventoryDatabaseDocument,
|
inventory: TInventoryDatabaseDocument,
|
||||||
typeName: string,
|
typeName: string,
|
||||||
inventoryChanges: IInventoryChanges = {}
|
inventoryChanges: IInventoryChanges = {}
|
||||||
): IInventoryChanges => {
|
): IInventoryChanges => {
|
||||||
const index = inventory.CrewShipWeaponSkins.push({ ItemType: typeName }) - 1;
|
const index = inventory.CrewShipWeaponSkins.push({ ItemType: typeName }) - 1;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
inventoryChanges.CrewShipWeaponSkins ??= [];
|
inventoryChanges.CrewShipWeaponSkins ??= [];
|
||||||
(inventoryChanges.CrewShipWeaponSkins as IUpgradeClient[]).push(
|
(inventoryChanges.CrewShipWeaponSkins as IUpgradeClient[]).push(
|
||||||
inventory.CrewShipWeaponSkins[index].toJSON<IUpgradeClient>()
|
inventory.CrewShipWeaponSkins[index].toJSON<IUpgradeClient>()
|
||||||
|
@ -31,6 +31,7 @@ export interface IInventoryDatabase
|
|||||||
| "WeaponSkins"
|
| "WeaponSkins"
|
||||||
| "Upgrades"
|
| "Upgrades"
|
||||||
| "CrewShipSalvagedWeaponSkins"
|
| "CrewShipSalvagedWeaponSkins"
|
||||||
|
| "CrewShipWeapons"
|
||||||
| "CrewShipWeaponSkins"
|
| "CrewShipWeaponSkins"
|
||||||
| "AdultOperatorLoadOuts"
|
| "AdultOperatorLoadOuts"
|
||||||
| "OperatorLoadOuts"
|
| "OperatorLoadOuts"
|
||||||
@ -56,6 +57,7 @@ export interface IInventoryDatabase
|
|||||||
WeaponSkins: IWeaponSkinDatabase[];
|
WeaponSkins: IWeaponSkinDatabase[];
|
||||||
Upgrades: IUpgradeDatabase[];
|
Upgrades: IUpgradeDatabase[];
|
||||||
CrewShipSalvagedWeaponSkins: IUpgradeDatabase[];
|
CrewShipSalvagedWeaponSkins: IUpgradeDatabase[];
|
||||||
|
CrewShipWeapons: ICrewShipWeaponDatabase[];
|
||||||
CrewShipWeaponSkins: IUpgradeDatabase[];
|
CrewShipWeaponSkins: IUpgradeDatabase[];
|
||||||
AdultOperatorLoadOuts: IOperatorConfigDatabase[];
|
AdultOperatorLoadOuts: IOperatorConfigDatabase[];
|
||||||
OperatorLoadOuts: IOperatorConfigDatabase[];
|
OperatorLoadOuts: IOperatorConfigDatabase[];
|
||||||
@ -289,8 +291,8 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
PlayerSkills: IPlayerSkills;
|
PlayerSkills: IPlayerSkills;
|
||||||
CrewShipAmmo: IConsumable[];
|
CrewShipAmmo: IConsumable[];
|
||||||
CrewShipSalvagedWeaponSkins: IUpgradeClient[];
|
CrewShipSalvagedWeaponSkins: IUpgradeClient[];
|
||||||
CrewShipWeapons: ICrewShipWeapon[];
|
CrewShipWeapons: ICrewShipWeaponClient[];
|
||||||
CrewShipSalvagedWeapons: ICrewShipWeapon[];
|
CrewShipSalvagedWeapons: IEquipmentClient[];
|
||||||
CrewShipWeaponSkins: IUpgradeClient[];
|
CrewShipWeaponSkins: IUpgradeClient[];
|
||||||
TradeBannedUntil?: IMongoDate;
|
TradeBannedUntil?: IMongoDate;
|
||||||
PlayedParkourTutorial: boolean;
|
PlayedParkourTutorial: boolean;
|
||||||
@ -428,7 +430,8 @@ export enum InventorySlot {
|
|||||||
SPACESUITS = "SpaceSuitBin",
|
SPACESUITS = "SpaceSuitBin",
|
||||||
MECHSUITS = "MechBin",
|
MECHSUITS = "MechBin",
|
||||||
PVE_LOADOUTS = "PveBonusLoadoutBin",
|
PVE_LOADOUTS = "PveBonusLoadoutBin",
|
||||||
SENTINELS = "SentinelBin"
|
SENTINELS = "SentinelBin",
|
||||||
|
RJ_COMPONENT_AND_ARMAMENTS = "CrewShipSalvageBin"
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISlots {
|
export interface ISlots {
|
||||||
@ -489,11 +492,23 @@ export interface IFlavourItem {
|
|||||||
|
|
||||||
export type IMiscItem = ITypeCount;
|
export type IMiscItem = ITypeCount;
|
||||||
|
|
||||||
|
// inventory.CrewShips[0].Weapon
|
||||||
export interface ICrewShipWeapon {
|
export interface ICrewShipWeapon {
|
||||||
PILOT: ICrewShipPilotWeapon;
|
PILOT: ICrewShipPilotWeapon;
|
||||||
PORT_GUNS: ICrewShipPortGuns;
|
PORT_GUNS: ICrewShipPortGuns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// inventory.CrewShipWeapons
|
||||||
|
export interface ICrewShipWeaponClient {
|
||||||
|
ItemType: string;
|
||||||
|
ItemId: IOid;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ICrewShipWeaponDatabase {
|
||||||
|
ItemType: string;
|
||||||
|
_id: Types.ObjectId;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ICrewShipPilotWeapon {
|
export interface ICrewShipPilotWeapon {
|
||||||
PRIMARY_A: IEquipmentSelection;
|
PRIMARY_A: IEquipmentSelection;
|
||||||
SECONDARY_A: IEquipmentSelection;
|
SECONDARY_A: IEquipmentSelection;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user