feat: handle railjack armaments, crew, & customizations in saveLoadout (#1706)

Closes #467

Reviewed-on: OpenWF/SpaceNinjaServer#1706
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:
Sainan 2025-04-18 11:15:50 -07:00 committed by Sainan
parent 196182f9a8
commit 3baf6ad015
5 changed files with 72 additions and 37 deletions

View File

@ -39,10 +39,9 @@ import {
ILoreFragmentScan,
IEvolutionProgress,
IEndlessXpProgress,
ICrewShipPortGuns,
ICrewShipCustomization,
ICrewShipWeapon,
ICrewShipPilotWeapon,
ICrewShipWeaponEmplacements,
IShipExterior,
IHelminthFoodRecord,
ICrewShipMembersDatabase,
@ -772,25 +771,23 @@ const endlessXpProgressSchema = new Schema<IEndlessXpProgress>(
{ _id: false }
);
const crewShipPilotWeaponSchema = new Schema<ICrewShipPilotWeapon>(
const crewShipWeaponEmplacementsSchema = new Schema<ICrewShipWeaponEmplacements>(
{
PRIMARY_A: EquipmentSelectionSchema,
SECONDARY_A: EquipmentSelectionSchema
},
{ _id: false }
);
const crewShipPortGunsSchema = new Schema<ICrewShipPortGuns>(
{
PRIMARY_A: EquipmentSelectionSchema
PRIMARY_B: EquipmentSelectionSchema,
SECONDARY_A: EquipmentSelectionSchema,
SECONDARY_B: EquipmentSelectionSchema
},
{ _id: false }
);
const crewShipWeaponSchema = new Schema<ICrewShipWeapon>(
{
PILOT: crewShipPilotWeaponSchema,
PORT_GUNS: crewShipPortGunsSchema
PILOT: crewShipWeaponEmplacementsSchema,
PORT_GUNS: crewShipWeaponEmplacementsSchema,
STARBOARD_GUNS: crewShipWeaponEmplacementsSchema,
ARTILLERY: crewShipWeaponEmplacementsSchema,
SCANNER: crewShipWeaponEmplacementsSchema
},
{ _id: false }
);
@ -814,7 +811,7 @@ const crewShipCustomizationSchema = new Schema<ICrewShipCustomization>(
const crewShipMemberSchema = new Schema<ICrewShipMemberDatabase>(
{
ItemId: { type: Schema.Types.ObjectId, required: false },
NemesisFingerprint: { type: Number, required: false }
NemesisFingerprint: { type: BigInt, required: false }
},
{ _id: false }
);

View File

@ -104,18 +104,18 @@ const replaceSlots = (db: ISlots, client: ISlots): void => {
db.Slots = client.Slots;
};
const convertCrewShipMember = (client: ICrewShipMemberClient): ICrewShipMemberDatabase => {
return {
...client,
ItemId: client.ItemId ? new Types.ObjectId(client.ItemId.$oid) : undefined
};
export const importCrewMemberId = (crewMemberId: ICrewShipMemberClient): ICrewShipMemberDatabase => {
if (crewMemberId.ItemId) {
return { ItemId: new Types.ObjectId(crewMemberId.ItemId.$oid) };
}
return { NemesisFingerprint: BigInt(crewMemberId.NemesisFingerprint ?? 0) };
};
const convertCrewShipMembers = (client: ICrewShipMembersClient): ICrewShipMembersDatabase => {
return {
SLOT_A: client.SLOT_A ? convertCrewShipMember(client.SLOT_A) : undefined,
SLOT_B: client.SLOT_B ? convertCrewShipMember(client.SLOT_B) : undefined,
SLOT_C: client.SLOT_C ? convertCrewShipMember(client.SLOT_C) : undefined
SLOT_A: client.SLOT_A ? importCrewMemberId(client.SLOT_A) : undefined,
SLOT_B: client.SLOT_B ? importCrewMemberId(client.SLOT_B) : undefined,
SLOT_C: client.SLOT_C ? importCrewMemberId(client.SLOT_C) : undefined
};
};

View File

@ -13,6 +13,8 @@ import { Types } from "mongoose";
import { isEmptyObject } from "@/src/helpers/general";
import { logger } from "@/src/utils/logger";
import { equipmentKeys, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
import { IItemConfig } from "../types/inventoryTypes/commonInventoryTypes";
import { importCrewMemberId } from "./importService";
//TODO: setup default items on account creation or like originally in giveStartingItems.php
@ -174,8 +176,8 @@ export const handleInventoryItemConfigChange = async (
}
for (const [configId, config] of Object.entries(itemConfigEntries)) {
if (typeof config !== "boolean") {
inventoryItem.Configs[parseInt(configId)] = config;
if (/^[0-9]+$/.test(configId)) {
inventoryItem.Configs[parseInt(configId)] = config as IItemConfig;
}
}
if ("Favorite" in itemConfigEntries) {
@ -184,6 +186,26 @@ export const handleInventoryItemConfigChange = async (
if ("IsNew" in itemConfigEntries) {
inventoryItem.IsNew = itemConfigEntries.IsNew;
}
if ("ItemName" in itemConfigEntries) {
inventoryItem.ItemName = itemConfigEntries.ItemName;
}
if ("RailjackImage" in itemConfigEntries) {
inventoryItem.RailjackImage = itemConfigEntries.RailjackImage;
}
if ("Customization" in itemConfigEntries) {
inventoryItem.Customization = itemConfigEntries.Customization;
}
if ("Weapon" in itemConfigEntries) {
inventoryItem.Weapon = itemConfigEntries.Weapon;
}
if (itemConfigEntries.CrewMembers) {
inventoryItem.CrewMembers = {
SLOT_A: importCrewMemberId(itemConfigEntries.CrewMembers.SLOT_A ?? {}),
SLOT_B: importCrewMemberId(itemConfigEntries.CrewMembers.SLOT_B ?? {}),
SLOT_C: importCrewMemberId(itemConfigEntries.CrewMembers.SLOT_C ?? {})
};
}
}
break;
} else {

View File

@ -538,12 +538,12 @@ export interface ICrewShipMembersDatabase {
export interface ICrewShipMemberClient {
ItemId?: IOid;
NemesisFingerprint?: number;
NemesisFingerprint?: number | bigint;
}
export interface ICrewShipMemberDatabase {
ItemId?: Types.ObjectId;
NemesisFingerprint?: number;
NemesisFingerprint?: bigint;
}
export interface ICrewShipCustomization {
@ -568,17 +568,18 @@ export type IMiscItem = ITypeCount;
// inventory.CrewShips[0].Weapon
export interface ICrewShipWeapon {
PILOT: ICrewShipPilotWeapon;
PORT_GUNS: ICrewShipPortGuns;
PILOT?: ICrewShipWeaponEmplacements;
PORT_GUNS?: ICrewShipWeaponEmplacements;
STARBOARD_GUNS?: ICrewShipWeaponEmplacements;
ARTILLERY?: ICrewShipWeaponEmplacements;
SCANNER?: ICrewShipWeaponEmplacements;
}
export interface ICrewShipPilotWeapon {
PRIMARY_A: IEquipmentSelection;
SECONDARY_A: IEquipmentSelection;
}
export interface ICrewShipPortGuns {
PRIMARY_A: IEquipmentSelection;
export interface ICrewShipWeaponEmplacements {
PRIMARY_A?: IEquipmentSelection;
PRIMARY_B?: IEquipmentSelection;
SECONDARY_A?: IEquipmentSelection;
SECONDARY_B?: IEquipmentSelection;
}
export interface IDiscoveredMarker {

View File

@ -1,7 +1,13 @@
import { IOid } from "@/src/types/commonTypes";
import { IItemConfig, IOperatorConfigClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
import { Types } from "mongoose";
import { ILoadoutConfigClient } from "./inventoryTypes/inventoryTypes";
import {
ICrewShipCustomization,
ICrewShipMembersClient,
ICrewShipWeapon,
IFlavourItem,
ILoadoutConfigClient
} from "./inventoryTypes/inventoryTypes";
export interface ISaveLoadoutRequest {
LoadOuts: ILoadoutClient;
@ -51,7 +57,16 @@ export interface IItemEntry {
export type IConfigEntry = {
[configId in "0" | "1" | "2" | "3" | "4" | "5"]: IItemConfig;
} & { Favorite?: boolean; IsNew?: boolean };
} & {
Favorite?: boolean;
IsNew?: boolean;
// Railjack
ItemName?: string;
RailjackImage?: IFlavourItem;
Customization?: ICrewShipCustomization;
Weapon?: ICrewShipWeapon;
CrewMembers?: ICrewShipMembersClient;
};
export type ILoadoutClient = Omit<ILoadoutDatabase, "_id" | "loadoutOwnerId">;