feat: complete Rising Tide with buying railjack #2922

Merged
Sainan merged 6 commits from AMelonInsideLemon/SpaceNinjaServer:complete-rising-tide into main 2025-10-21 23:50:05 -07:00
6 changed files with 49 additions and 27 deletions

View File

@ -1,11 +1,20 @@
import type { RequestHandler } from "express"; import type { RequestHandler } from "express";
import { updateShipFeature } from "../../services/personalRoomsService.ts"; import { getAccountIdForRequest } from "../../services/loginService.ts";
import type { IUnlockShipFeatureRequest } from "../../types/requestTypes.ts"; import { getInventory } from "../../services/inventoryService.ts";
import { parseString } from "../../helpers/general.ts"; import { getJSONfromString } from "../../helpers/stringHelpers.ts";
import { unlockShipFeature } from "../../services/personalRoomsService.ts";
export const unlockShipFeatureController: RequestHandler = async (req, res) => { export const unlockShipFeatureController: RequestHandler = async (req, res) => {
const accountId = parseString(req.query.accountId); const accountId = await getAccountIdForRequest(req);
const shipFeatureRequest = JSON.parse((req.body as string).toString()) as IUnlockShipFeatureRequest; const inventory = await getInventory(accountId, "MiscItems accountOwnerId");
await updateShipFeature(accountId, shipFeatureRequest.Feature); const request = getJSONfromString<IUnlockShipFeatureRequest>(String(req.body));
await unlockShipFeature(inventory, request.Feature);
await inventory.save();
res.send([]); res.send([]);
}; };
interface IUnlockShipFeatureRequest {
Feature: string;
KeyChain: string;
ChainStage: number;
}

View File

@ -389,7 +389,7 @@ export const addItem = async (
}; };
} else if (ExportResources[typeName].productCategory == "CrewShips") { } else if (ExportResources[typeName].productCategory == "CrewShips") {
return { return {
...addCrewShip(inventory, typeName), ...(await addCrewShip(inventory, typeName)),
// fix to unlock railjack modding, item bellow supposed to be obtained from archwing quest // fix to unlock railjack modding, item bellow supposed to be obtained from archwing quest
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
...(!inventory.CrewShipHarnesses?.length ...(!inventory.CrewShipHarnesses?.length
@ -1544,17 +1544,31 @@ export const addCrewShipSalvagedWeaponSkin = (
return inventoryChanges; return inventoryChanges;
}; };
const addCrewShip = ( const addCrewShip = async (
inventory: TInventoryDatabaseDocument, inventory: TInventoryDatabaseDocument,
typeName: string, typeName: string,
inventoryChanges: IInventoryChanges = {} inventoryChanges: IInventoryChanges = {}
): IInventoryChanges => { ): Promise<IInventoryChanges> => {
if (inventory.CrewShips.length != 0) { if (inventory.CrewShips.length != 0) {
logger.warn("refusing to add CrewShip because account already has one"); logger.warn("refusing to add CrewShip because account already has one");
} else { } else {
const index = inventory.CrewShips.push({ ItemType: typeName }) - 1; const index = inventory.CrewShips.push({ ItemType: typeName }) - 1;
inventoryChanges.CrewShips ??= []; inventoryChanges.CrewShips ??= [];
inventoryChanges.CrewShips.push(inventory.CrewShips[index].toJSON<IEquipmentClient>()); inventoryChanges.CrewShips.push(inventory.CrewShips[index].toJSON<IEquipmentClient>());
const railjackQuest = inventory.QuestKeys.find(
qk => qk.ItemType === "/Lotus/Types/Keys/RailJackBuildQuest/RailjackBuildQuestKeyChain"
);
if (!railjackQuest || !railjackQuest.Completed) {
const questChanges = await completeQuest(
inventory,
"/Lotus/Types/Keys/RailJackBuildQuest/RailjackBuildQuestKeyChain",
false
);
if (questChanges) {
inventoryChanges.QuestKeys ??= [];
inventoryChanges.QuestKeys.push(questChanges);
}
}
} }
return inventoryChanges; return inventoryChanges;
}; };

View File

@ -1,7 +1,9 @@
import { PersonalRooms } from "../models/personalRoomsModel.ts"; import { PersonalRooms } from "../models/personalRoomsModel.ts";
import { addItem, getInventory } from "./inventoryService.ts"; import { addItem } from "./inventoryService.ts";
import type { IGardeningDatabase, TPersonalRoomsDatabaseDocument } from "../types/personalRoomsTypes.ts"; import type { IGardeningDatabase, TPersonalRoomsDatabaseDocument } from "../types/personalRoomsTypes.ts";
import { getRandomElement } from "./rngService.ts"; import { getRandomElement } from "./rngService.ts";
import type { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel.ts";
import { logger } from "../utils/logger.ts";
export const getPersonalRooms = async ( export const getPersonalRooms = async (
accountId: string, accountId: string,
@ -15,19 +17,17 @@ export const getPersonalRooms = async (
return personalRooms; return personalRooms;
}; };
export const updateShipFeature = async (accountId: string, shipFeature: string): Promise<void> => { export const unlockShipFeature = async (inventory: TInventoryDatabaseDocument, shipFeature: string): Promise<void> => {
const personalRooms = await getPersonalRooms(accountId); const personalRooms = await getPersonalRooms(inventory.accountOwnerId.toString());
if (personalRooms.Ship.Features.includes(shipFeature)) { if (personalRooms.Ship.Features.includes(shipFeature)) {
throw new Error(`ship feature ${shipFeature} already unlocked`); logger.warn(`ship feature ${shipFeature} already unlocked`);
} else {
personalRooms.Ship.Features.push(shipFeature);
await personalRooms.save();
} }
const miscItem = inventory.MiscItems.find(x => x.ItemType === shipFeature);
personalRooms.Ship.Features.push(shipFeature); if (miscItem && miscItem.ItemCount > 0) await addItem(inventory, shipFeature, miscItem.ItemCount * -1);
await personalRooms.save();
const inventory = await getInventory(accountId);
await addItem(inventory, shipFeature, -1);
await inventory.save();
}; };
export const createGarden = (): IGardeningDatabase => { export const createGarden = (): IGardeningDatabase => {

View File

@ -120,7 +120,7 @@ export const completeQuest = async (
inventory: TInventoryDatabaseDocument, inventory: TInventoryDatabaseDocument,
questKey: string, questKey: string,
sendMessages: boolean = false sendMessages: boolean = false
): Promise<void> => { ): Promise<void | IQuestKeyClient> => {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
const chainStages = ExportKeys[questKey]?.chainStages; const chainStages = ExportKeys[questKey]?.chainStages;
@ -176,6 +176,8 @@ export const completeQuest = async (
existingQuestKey.CompletionDate = new Date(); existingQuestKey.CompletionDate = new Date();
await handleQuestCompletion(inventory, questKey, undefined, run > 0); await handleQuestCompletion(inventory, questKey, undefined, run > 0);
} }
return existingQuestKey.toJSON<IQuestKeyClient>();
}; };
const getQuestCompletionItems = (questKey: string): ITypeCount[] | undefined => { const getQuestCompletionItems = (questKey: string): ITypeCount[] | undefined => {

View File

@ -9,7 +9,8 @@ import type {
TEquipmentKey, TEquipmentKey,
ICrewMemberClient, ICrewMemberClient,
IKubrowPetPrintClient, IKubrowPetPrintClient,
IUpgradeClient IUpgradeClient,
IQuestKeyClient
} from "./inventoryTypes/inventoryTypes.ts"; } from "./inventoryTypes/inventoryTypes.ts";
export enum PurchaseSource { export enum PurchaseSource {
@ -83,6 +84,7 @@ export type IInventoryChanges = {
CrewMembers?: ICrewMemberClient[]; CrewMembers?: ICrewMemberClient[];
KubrowPetPrints?: IKubrowPetPrintClient[]; KubrowPetPrints?: IKubrowPetPrintClient[];
Upgrades?: IUpgradeClient[]; // TOVERIFY Upgrades?: IUpgradeClient[]; // TOVERIFY
QuestKeys?: IQuestKeyClient[];
} & Record< } & Record<
Exclude< Exclude<
string, string,

View File

@ -234,11 +234,6 @@ export interface IUpgradeOperation {
PolarizeValue: ArtifactPolarity; PolarizeValue: ArtifactPolarity;
PolarityRemap: IPolarity[]; PolarityRemap: IPolarity[];
} }
export interface IUnlockShipFeatureRequest {
Feature: string;
KeyChain: string;
ChainStage: number;
}
export interface IVoidTearParticipantInfo { export interface IVoidTearParticipantInfo {
AccountId: string; AccountId: string;