forked from OpenWF/SpaceNinjaServer
		
	Compare commits
	
		
			No commits in common. "b56c79d9f45d79dc5ba2a89b36568d3e2948a1af" and "18fafc38b500eb5ef162b9a3408e4368fc9e62d6" have entirely different histories.
		
	
	
		
			b56c79d9f4
			...
			18fafc38b5
		
	
		
@ -1,62 +0,0 @@
 | 
			
		||||
import type { RequestHandler } from "express";
 | 
			
		||||
import { getAccountIdForRequest } from "../../services/loginService.ts";
 | 
			
		||||
import { addMiscItem, getInventory } from "../../services/inventoryService.ts";
 | 
			
		||||
import { getJSONfromString } from "../../helpers/stringHelpers.ts";
 | 
			
		||||
import { logger } from "../../utils/logger.ts";
 | 
			
		||||
import type { IInventoryChanges } from "../../types/purchaseTypes.ts";
 | 
			
		||||
 | 
			
		||||
export const feedPrinceController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
    const inventory = await getInventory(accountId, "MiscItems NokkoColony NodeIntrosCompleted");
 | 
			
		||||
    const payload = getJSONfromString<IFeedPrinceRequest>(String(req.body));
 | 
			
		||||
 | 
			
		||||
    switch (payload.Mode) {
 | 
			
		||||
        case "r": {
 | 
			
		||||
            inventory.NokkoColony ??= {
 | 
			
		||||
                FeedLevel: 0,
 | 
			
		||||
                JournalEntries: []
 | 
			
		||||
            };
 | 
			
		||||
            const InventoryChanges: IInventoryChanges = {};
 | 
			
		||||
            inventory.NokkoColony.FeedLevel += payload.Amount;
 | 
			
		||||
            if (
 | 
			
		||||
                (!inventory.NodeIntrosCompleted.includes("CompletedVision1") && inventory.NokkoColony.FeedLevel > 20) ||
 | 
			
		||||
                (!inventory.NodeIntrosCompleted.includes("CompletedVision2") && inventory.NokkoColony.FeedLevel > 60)
 | 
			
		||||
            ) {
 | 
			
		||||
                res.json({
 | 
			
		||||
                    FeedSucceeded: false,
 | 
			
		||||
                    FeedLevel: inventory.NokkoColony.FeedLevel - payload.Amount,
 | 
			
		||||
                    InventoryChanges
 | 
			
		||||
                } satisfies IFeedPrinceResponse);
 | 
			
		||||
            } else {
 | 
			
		||||
                addMiscItem(
 | 
			
		||||
                    inventory,
 | 
			
		||||
                    "/Lotus/Types/Items/MiscItems/MushroomFood",
 | 
			
		||||
                    payload.Amount * -1,
 | 
			
		||||
                    InventoryChanges
 | 
			
		||||
                );
 | 
			
		||||
                await inventory.save();
 | 
			
		||||
                res.json({
 | 
			
		||||
                    FeedSucceeded: true,
 | 
			
		||||
                    FeedLevel: inventory.NokkoColony.FeedLevel,
 | 
			
		||||
                    InventoryChanges
 | 
			
		||||
                } satisfies IFeedPrinceResponse);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            logger.debug(`data provided to ${req.path}: ${String(req.body)}`);
 | 
			
		||||
            throw new Error(`unknown feedPrince mode: ${payload.Mode}`);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface IFeedPrinceRequest {
 | 
			
		||||
    Mode: string; // r
 | 
			
		||||
    Amount: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface IFeedPrinceResponse {
 | 
			
		||||
    FeedSucceeded: boolean;
 | 
			
		||||
    FeedLevel: number;
 | 
			
		||||
    InventoryChanges: IInventoryChanges;
 | 
			
		||||
}
 | 
			
		||||
@ -1,117 +0,0 @@
 | 
			
		||||
import type { RequestHandler } from "express";
 | 
			
		||||
import { getAccountIdForRequest } from "../../services/loginService.ts";
 | 
			
		||||
import { addMiscItem, getInventory } from "../../services/inventoryService.ts";
 | 
			
		||||
import { getJSONfromString } from "../../helpers/stringHelpers.ts";
 | 
			
		||||
import { logger } from "../../utils/logger.ts";
 | 
			
		||||
import type { IJournalEntry } from "../../types/inventoryTypes/inventoryTypes.ts";
 | 
			
		||||
import type { IAffiliationMods } from "../../types/purchaseTypes.ts";
 | 
			
		||||
 | 
			
		||||
export const researchMushroomController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
    const inventory = await getInventory(accountId, "MiscItems NokkoColony Affiliations");
 | 
			
		||||
    const payload = getJSONfromString<IResearchMushroom>(String(req.body));
 | 
			
		||||
    switch (payload.Mode) {
 | 
			
		||||
        case "r": {
 | 
			
		||||
            const InventoryChanges = {};
 | 
			
		||||
            const AffiliationMods: IAffiliationMods[] = [];
 | 
			
		||||
 | 
			
		||||
            addMiscItem(inventory, payload.MushroomItem, payload.Amount * -1, InventoryChanges);
 | 
			
		||||
            if (payload.Convert) {
 | 
			
		||||
                addMiscItem(inventory, "/Lotus/Types/Items/MiscItems/MushroomFood", payload.Amount, InventoryChanges);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            inventory.NokkoColony ??= {
 | 
			
		||||
                FeedLevel: 0,
 | 
			
		||||
                JournalEntries: []
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            let journalEntry = inventory.NokkoColony.JournalEntries.find(x => x.EntryType == payload.MushroomItem);
 | 
			
		||||
            if (!journalEntry) {
 | 
			
		||||
                journalEntry = { EntryType: payload.MushroomItem, Progress: 0 };
 | 
			
		||||
                inventory.NokkoColony.JournalEntries.push(journalEntry);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let syndicate = inventory.Affiliations.find(x => x.Tag == "NightcapJournalSyndicate");
 | 
			
		||||
            if (!syndicate) {
 | 
			
		||||
                syndicate = { Tag: "NightcapJournalSyndicate", Title: 0, Standing: 0 };
 | 
			
		||||
                inventory.Affiliations.push(syndicate);
 | 
			
		||||
            }
 | 
			
		||||
            const completedBefore = inventory.NokkoColony.JournalEntries.filter(
 | 
			
		||||
                entry => getJournalRank(entry) === 3
 | 
			
		||||
            ).length;
 | 
			
		||||
            const PrevRank = syndicateTitleThresholds.reduce(
 | 
			
		||||
                (rank, threshold, i) => (completedBefore >= threshold ? i : rank),
 | 
			
		||||
                0
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            if (getJournalRank(journalEntry) < 3) journalEntry.Progress += payload.Amount;
 | 
			
		||||
 | 
			
		||||
            const completedAfter = inventory.NokkoColony.JournalEntries.filter(
 | 
			
		||||
                entry => getJournalRank(entry) === 3
 | 
			
		||||
            ).length;
 | 
			
		||||
            const NewRank = syndicateTitleThresholds.reduce(
 | 
			
		||||
                (rank, threshold, i) => (completedAfter >= threshold ? i : rank),
 | 
			
		||||
                0
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            if (NewRank > (syndicate.Title ?? 0)) {
 | 
			
		||||
                syndicate.Title = NewRank;
 | 
			
		||||
                AffiliationMods.push({ Tag: "NightcapJournalSyndicate", Title: NewRank });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await inventory.save();
 | 
			
		||||
            res.json({
 | 
			
		||||
                PrevRank,
 | 
			
		||||
                NewRank,
 | 
			
		||||
                Progress: journalEntry.Progress,
 | 
			
		||||
                InventoryChanges,
 | 
			
		||||
                AffiliationMods
 | 
			
		||||
            });
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            logger.debug(`data provided to ${req.path}: ${String(req.body)}`);
 | 
			
		||||
            throw new Error(`unknown researchMushroom mode: ${payload.Mode}`);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface IResearchMushroom {
 | 
			
		||||
    Mode: string; // r
 | 
			
		||||
    MushroomItem: string;
 | 
			
		||||
    Amount: number;
 | 
			
		||||
    Convert: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const journalEntriesRank: Record<string, number> = {
 | 
			
		||||
    "/Lotus/Types/Items/MushroomJournal/PlainMushroomJournalItem": 1,
 | 
			
		||||
    "/Lotus/Types/Items/MushroomJournal/GasMushroomJournalItem": 4,
 | 
			
		||||
    "/Lotus/Types/Items/MushroomJournal/ToxinMushroomJournalItem": 3,
 | 
			
		||||
    "/Lotus/Types/Items/MushroomJournal/ViralMushroomJournalItem": 4,
 | 
			
		||||
    "/Lotus/Types/Items/MushroomJournal/MagneticMushroomJournalItem": 4,
 | 
			
		||||
    "/Lotus/Types/Items/MushroomJournal/ElectricMushroomJournalItem": 3,
 | 
			
		||||
    "/Lotus/Types/Items/MushroomJournal/TauMushroomJournalItem": 5,
 | 
			
		||||
    "/Lotus/Types/Items/MushroomJournal/SlashMushroomJournalItem": 3,
 | 
			
		||||
    "/Lotus/Types/Items/MushroomJournal/BlastMushroomJournalItem": 4,
 | 
			
		||||
    "/Lotus/Types/Items/MushroomJournal/ImpactMushroomJournalItem": 3,
 | 
			
		||||
    "/Lotus/Types/Items/MushroomJournal/ColdMushroomJournalItem": 3,
 | 
			
		||||
    "/Lotus/Types/Items/MushroomJournal/CorrosiveMushroomJournalItem": 4,
 | 
			
		||||
    "/Lotus/Types/Items/MushroomJournal/PunctureMushroomJournalItem": 3,
 | 
			
		||||
    "/Lotus/Types/Items/MushroomJournal/HeatMushroomJournalItem": 3,
 | 
			
		||||
    "/Lotus/Types/Items/MushroomJournal/RadiationMushroomJournalItem": 4,
 | 
			
		||||
    "/Lotus/Types/Items/MushroomJournal/VoidMushroomJournalItem": 5
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const syndicateTitleThresholds = [0, 1, 2, 6, 12, 16];
 | 
			
		||||
 | 
			
		||||
const getJournalRank = (journalEntry: IJournalEntry): number => {
 | 
			
		||||
    const k = journalEntriesRank[journalEntry.EntryType];
 | 
			
		||||
    if (!k) return 0;
 | 
			
		||||
 | 
			
		||||
    const thresholds = [k * 1, k * 3, k * 6];
 | 
			
		||||
 | 
			
		||||
    if (journalEntry.Progress >= thresholds[2]) return 3;
 | 
			
		||||
    if (journalEntry.Progress >= thresholds[1]) return 2;
 | 
			
		||||
    if (journalEntry.Progress >= thresholds[0]) return 1;
 | 
			
		||||
    return 0;
 | 
			
		||||
};
 | 
			
		||||
@ -96,15 +96,10 @@ export const upgradesController: RequestHandler = async (req, res) => {
 | 
			
		||||
                case "/Lotus/Types/Items/MiscItems/WeaponPrimaryArcaneUnlocker":
 | 
			
		||||
                case "/Lotus/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker":
 | 
			
		||||
                case "/Lotus/Types/Items/MiscItems/WeaponMeleeArcaneUnlocker":
 | 
			
		||||
                case "/Lotus/Types/Items/MiscItems/WeaponAmpArcaneUnlocker":
 | 
			
		||||
                case "/Lotus/Types/Items/MiscItems/WeaponArchGunArcaneUnlocker": {
 | 
			
		||||
                case "/Lotus/Types/Items/MiscItems/WeaponAmpArcaneUnlocker": {
 | 
			
		||||
                    const item = inventory[payload.ItemCategory].id(payload.ItemId.$oid)!;
 | 
			
		||||
                    item.Features ??= 0;
 | 
			
		||||
                    if (operation.OperationType == "UOT_ARCANE_UNLOCK_1") {
 | 
			
		||||
                        item.Features |= EquipmentFeatures.SECOND_ARCANE_SLOT;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        item.Features |= EquipmentFeatures.ARCANE_SLOT;
 | 
			
		||||
                    }
 | 
			
		||||
                    item.Features |= EquipmentFeatures.ARCANE_SLOT;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case "/Lotus/Types/Items/MiscItems/ValenceAdapter": {
 | 
			
		||||
 | 
			
		||||
@ -1,24 +0,0 @@
 | 
			
		||||
import { getInventory } from "../../services/inventoryService.ts";
 | 
			
		||||
import { getAccountIdForRequest } from "../../services/loginService.ts";
 | 
			
		||||
import type { RequestHandler } from "express";
 | 
			
		||||
import { equipmentKeys } from "../../types/inventoryTypes/inventoryTypes.ts";
 | 
			
		||||
import { broadcastInventoryUpdate } from "../../services/wsService.ts";
 | 
			
		||||
 | 
			
		||||
export const removeIsNewController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
    const filteredEquipmentKeys = equipmentKeys.filter(k => k !== "CrewShipWeapons" && k !== "CrewShipSalvagedWeapons");
 | 
			
		||||
    const inventory = await getInventory(accountId, [...filteredEquipmentKeys, "WeaponSkins"].join(" "));
 | 
			
		||||
    for (const key of filteredEquipmentKeys) {
 | 
			
		||||
        if (key in inventory) {
 | 
			
		||||
            for (const equipment of inventory[key]) {
 | 
			
		||||
                if (equipment.IsNew) equipment.IsNew = false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    for (const equipment of inventory.WeaponSkins) {
 | 
			
		||||
        if (equipment.IsNew) equipment.IsNew = false;
 | 
			
		||||
    }
 | 
			
		||||
    await inventory.save();
 | 
			
		||||
    res.end();
 | 
			
		||||
    broadcastInventoryUpdate(req);
 | 
			
		||||
};
 | 
			
		||||
@ -88,9 +88,7 @@ import type {
 | 
			
		||||
    IGoalProgressDatabase,
 | 
			
		||||
    IGoalProgressClient,
 | 
			
		||||
    IKubrowPetPrintClient,
 | 
			
		||||
    IKubrowPetPrintDatabase,
 | 
			
		||||
    INokkoColony,
 | 
			
		||||
    IJournalEntry
 | 
			
		||||
    IKubrowPetPrintDatabase
 | 
			
		||||
} from "../../types/inventoryTypes/inventoryTypes.ts";
 | 
			
		||||
import { equipmentKeys } from "../../types/inventoryTypes/inventoryTypes.ts";
 | 
			
		||||
import type { IOid, ITypeCount } from "../../types/commonTypes.ts";
 | 
			
		||||
@ -1426,22 +1424,6 @@ const hubNpcCustomizationSchema = new Schema<IHubNpcCustomization>(
 | 
			
		||||
    { _id: false }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const journalEntrySchema = new Schema<IJournalEntry>(
 | 
			
		||||
    {
 | 
			
		||||
        EntryType: String,
 | 
			
		||||
        Progress: Number
 | 
			
		||||
    },
 | 
			
		||||
    { _id: false }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const nokkoColonySchema = new Schema<INokkoColony>(
 | 
			
		||||
    {
 | 
			
		||||
        FeedLevel: Number,
 | 
			
		||||
        JournalEntries: [journalEntrySchema]
 | 
			
		||||
    },
 | 
			
		||||
    { _id: false }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
			
		||||
    {
 | 
			
		||||
        accountOwnerId: Schema.Types.ObjectId,
 | 
			
		||||
@ -1858,9 +1840,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
			
		||||
 | 
			
		||||
        ClaimedJunctionChallengeRewards: { type: [String], default: undefined },
 | 
			
		||||
 | 
			
		||||
        SpecialItemRewardAttenuation: { type: [rewardAttenutationSchema], default: undefined },
 | 
			
		||||
 | 
			
		||||
        NokkoColony: { type: nokkoColonySchema, default: undefined }
 | 
			
		||||
        SpecialItemRewardAttenuation: { type: [rewardAttenutationSchema], default: undefined }
 | 
			
		||||
    },
 | 
			
		||||
    { timestamps: { createdAt: "Created", updatedAt: false } }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
@ -50,7 +50,6 @@ import { dronesController } from "../controllers/api/dronesController.ts";
 | 
			
		||||
import { endlessXpController } from "../controllers/api/endlessXpController.ts";
 | 
			
		||||
import { entratiLabConquestModeController } from "../controllers/api/entratiLabConquestModeController.ts";
 | 
			
		||||
import { evolveWeaponController } from "../controllers/api/evolveWeaponController.ts";
 | 
			
		||||
import { feedPrinceController } from "../controllers/api/feedPrinceController.ts";
 | 
			
		||||
import { findSessionsController } from "../controllers/api/findSessionsController.ts";
 | 
			
		||||
import { fishmongerController } from "../controllers/api/fishmongerController.ts";
 | 
			
		||||
import { focusController } from "../controllers/api/focusController.ts";
 | 
			
		||||
@ -117,7 +116,6 @@ import { removeFromGuildController } from "../controllers/api/removeFromGuildCon
 | 
			
		||||
import { removeIgnoredUserController } from "../controllers/api/removeIgnoredUserController.ts";
 | 
			
		||||
import { renamePetController } from "../controllers/api/renamePetController.ts";
 | 
			
		||||
import { rerollRandomModController } from "../controllers/api/rerollRandomModController.ts";
 | 
			
		||||
import { researchMushroomController } from "../controllers/api/researchMushroomController.ts";
 | 
			
		||||
import { resetQuestProgressController } from "../controllers/api/resetQuestProgressController.ts";
 | 
			
		||||
import { retrievePetFromStasisController } from "../controllers/api/retrievePetFromStasisController.ts";
 | 
			
		||||
import { saveDialogueController } from "../controllers/api/saveDialogueController.ts";
 | 
			
		||||
@ -273,7 +271,6 @@ apiRouter.post("/drones.php", dronesController);
 | 
			
		||||
apiRouter.post("/endlessXp.php", endlessXpController);
 | 
			
		||||
apiRouter.post("/entratiLabConquestMode.php", entratiLabConquestModeController);
 | 
			
		||||
apiRouter.post("/evolveWeapon.php", evolveWeaponController);
 | 
			
		||||
apiRouter.post("/feedPrince.php", feedPrinceController);
 | 
			
		||||
apiRouter.post("/findSessions.php", findSessionsController);
 | 
			
		||||
apiRouter.post("/fishmonger.php", fishmongerController);
 | 
			
		||||
apiRouter.post("/focus.php", focusController);
 | 
			
		||||
@ -321,7 +318,6 @@ apiRouter.post("/removeFromGuild.php", removeFromGuildController);
 | 
			
		||||
apiRouter.post("/removeIgnoredUser.php", removeIgnoredUserController);
 | 
			
		||||
apiRouter.post("/renamePet.php", renamePetController);
 | 
			
		||||
apiRouter.post("/rerollRandomMod.php", rerollRandomModController);
 | 
			
		||||
apiRouter.post("/researchMushroom.php", researchMushroomController);
 | 
			
		||||
apiRouter.post("/retrievePetFromStasis.php", retrievePetFromStasisController);
 | 
			
		||||
apiRouter.post("/saveDialogue.php", saveDialogueController);
 | 
			
		||||
apiRouter.post("/saveLoadout.php", saveLoadoutController);
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,6 @@ import { unlockAllScansController } from "../controllers/custom/unlockAllScansCo
 | 
			
		||||
import { unlockAllShipFeaturesController } from "../controllers/custom/unlockAllShipFeaturesController.ts";
 | 
			
		||||
import { unlockAllCapturaScenesController } from "../controllers/custom/unlockAllCapturaScenesController.ts";
 | 
			
		||||
import { removeCustomizationController } from "../controllers/custom/removeCustomizationController.ts";
 | 
			
		||||
import { removeIsNewController } from "../controllers/custom/removeIsNewController.ts";
 | 
			
		||||
 | 
			
		||||
import { abilityOverrideController } from "../controllers/custom/abilityOverrideController.ts";
 | 
			
		||||
import { createAccountController } from "../controllers/custom/createAccountController.ts";
 | 
			
		||||
@ -74,7 +73,6 @@ customRouter.get("/unlockAllScans", unlockAllScansController);
 | 
			
		||||
customRouter.get("/unlockAllShipFeatures", unlockAllShipFeaturesController);
 | 
			
		||||
customRouter.get("/unlockAllCapturaScenes", unlockAllCapturaScenesController);
 | 
			
		||||
customRouter.get("/removeCustomization", removeCustomizationController);
 | 
			
		||||
customRouter.get("/removeIsNew", removeIsNewController);
 | 
			
		||||
 | 
			
		||||
customRouter.post("/abilityOverride", abilityOverrideController);
 | 
			
		||||
customRouter.post("/createAccount", createAccountController);
 | 
			
		||||
 | 
			
		||||
@ -1391,10 +1391,7 @@ export const addStanding = (
 | 
			
		||||
 | 
			
		||||
// TODO: AffiliationMods support (Nightwave).
 | 
			
		||||
export const updateGeneric = async (data: IGenericUpdate, accountId: string): Promise<IUpdateNodeIntrosResponse> => {
 | 
			
		||||
    const inventory = await getInventory(
 | 
			
		||||
        accountId,
 | 
			
		||||
        "NodeIntrosCompleted MiscItems ShipDecorations FlavourItems WeaponSkins"
 | 
			
		||||
    );
 | 
			
		||||
    const inventory = await getInventory(accountId, "NodeIntrosCompleted MiscItems ShipDecorations");
 | 
			
		||||
 | 
			
		||||
    // Make it an array for easier parsing.
 | 
			
		||||
    if (typeof data.NodeIntrosCompleted === "string") {
 | 
			
		||||
@ -1403,12 +1400,6 @@ export const updateGeneric = async (data: IGenericUpdate, accountId: string): Pr
 | 
			
		||||
 | 
			
		||||
    const inventoryChanges: IInventoryChanges = {};
 | 
			
		||||
    for (const node of data.NodeIntrosCompleted) {
 | 
			
		||||
        if (inventory.NodeIntrosCompleted.indexOf(node) != -1) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        inventory.NodeIntrosCompleted.push(node);
 | 
			
		||||
        logger.debug(`completed dialogue/cutscene for ${node}`);
 | 
			
		||||
 | 
			
		||||
        if (node == "TC2025") {
 | 
			
		||||
            inventoryChanges.ShipDecorations = [
 | 
			
		||||
                {
 | 
			
		||||
@ -1429,15 +1420,16 @@ export const updateGeneric = async (data: IGenericUpdate, accountId: string): Pr
 | 
			
		||||
            await addEmailItem(inventory, "/Lotus/Types/Items/EmailItems/BeatCaliberChicksEmailItem", inventoryChanges);
 | 
			
		||||
        } else if (node == "ClearedFiveLoops") {
 | 
			
		||||
            await addEmailItem(inventory, "/Lotus/Types/Items/EmailItems/ClearedFiveLoopsEmailItem", inventoryChanges);
 | 
			
		||||
        } else if (node == "NokkoVisions_AllCompleted") {
 | 
			
		||||
            addCustomization(
 | 
			
		||||
                inventory,
 | 
			
		||||
                "/Lotus/Types/StoreItems/AvatarImages/Warframes/NokkoBabySecretGlyph",
 | 
			
		||||
                inventoryChanges
 | 
			
		||||
            );
 | 
			
		||||
            addSkin(inventory, "/Lotus/Upgrades/Skins/Clan/NokkoBabySecretEmblemItem", inventoryChanges);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Combine the two arrays into one.
 | 
			
		||||
    data.NodeIntrosCompleted = inventory.NodeIntrosCompleted.concat(data.NodeIntrosCompleted);
 | 
			
		||||
 | 
			
		||||
    // Remove duplicate entries.
 | 
			
		||||
    const nodes = [...new Set(data.NodeIntrosCompleted)];
 | 
			
		||||
 | 
			
		||||
    inventory.NodeIntrosCompleted = nodes;
 | 
			
		||||
    await inventory.save();
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
@ -2180,7 +2172,7 @@ export const addMissionComplete = (inventory: TInventoryDatabaseDocument, { Tag,
 | 
			
		||||
 | 
			
		||||
    if (itemIndex !== -1) {
 | 
			
		||||
        Missions[itemIndex].Completes += Completes;
 | 
			
		||||
        if (Completes && Tier) {
 | 
			
		||||
        if (Tier) {
 | 
			
		||||
            Missions[itemIndex].Tier = Tier;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
@ -310,9 +310,6 @@ export const addMissionInventoryUpdates = async (
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case "Missions":
 | 
			
		||||
                addMissionComplete(inventory, value);
 | 
			
		||||
                break;
 | 
			
		||||
            case "LastRegionPlayed":
 | 
			
		||||
                if (!(config.unfaithfulBugFixes?.ignore1999LastRegionPlayed && value === "1999MapName")) {
 | 
			
		||||
                    inventory.LastRegionPlayed = value;
 | 
			
		||||
@ -1245,6 +1242,9 @@ export const addMissionRewards = async (
 | 
			
		||||
    if (missions && missions.Tag in ExportRegions) {
 | 
			
		||||
        const node = ExportRegions[missions.Tag];
 | 
			
		||||
 | 
			
		||||
        // cannot add this with normal updates because { Tier: 1 } would mark the SP node as completed even on a failure
 | 
			
		||||
        addMissionComplete(inventory, missions);
 | 
			
		||||
 | 
			
		||||
        //node based credit rewards for mission completion
 | 
			
		||||
        if (isEligibleForCreditReward(rewardInfo, missions, node)) {
 | 
			
		||||
            const levelCreditReward = getLevelCreditRewards(node);
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,6 @@ import { addFixedLevelRewards } from "./missionInventoryUpdateService.ts";
 | 
			
		||||
import type { IInventoryChanges } from "../types/purchaseTypes.ts";
 | 
			
		||||
import questCompletionItems from "../../static/fixed_responses/questCompletionRewards.json" with { type: "json" };
 | 
			
		||||
import type { ITypeCount } from "../types/commonTypes.ts";
 | 
			
		||||
import { addString } from "../helpers/stringHelpers.ts";
 | 
			
		||||
 | 
			
		||||
export interface IUpdateQuestRequest {
 | 
			
		||||
    QuestKeys: IQuestKeyClient[];
 | 
			
		||||
@ -176,11 +175,6 @@ export const completeQuest = async (
 | 
			
		||||
        existingQuestKey.Completed = true;
 | 
			
		||||
        existingQuestKey.CompletionDate = new Date();
 | 
			
		||||
        await handleQuestCompletion(inventory, questKey, undefined, run > 0);
 | 
			
		||||
 | 
			
		||||
        if (questKey == "/Lotus/Types/Keys/ModQuest/ModQuestKeyChain") {
 | 
			
		||||
            // This would be set by the client during the equilogue, but since we're cheating through, we have to do it ourselves.
 | 
			
		||||
            addString(inventory.NodeIntrosCompleted, "ModQuestTeshinAccess");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return existingQuestKey.toJSON<IQuestKeyClient>();
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,6 @@ export enum EquipmentFeatures {
 | 
			
		||||
    GRAVIMAG_INSTALLED = 4,
 | 
			
		||||
    GILDED = 8,
 | 
			
		||||
    ARCANE_SLOT = 32,
 | 
			
		||||
    SECOND_ARCANE_SLOT = 64,
 | 
			
		||||
    INCARNON_GENESIS = 512,
 | 
			
		||||
    VALENCE_SWAP = 1024
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -436,7 +436,6 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
 | 
			
		||||
    Ship?: IOrbiterClient; // U22 and below, response only
 | 
			
		||||
    ClaimedJunctionChallengeRewards?: string[]; // U39
 | 
			
		||||
    SpecialItemRewardAttenuation?: IRewardAttenuation[]; // Baro's Void Surplus
 | 
			
		||||
    NokkoColony?: INokkoColony; // Field Guide
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IAffiliation {
 | 
			
		||||
@ -1221,13 +1220,3 @@ export interface IHubNpcCustomization {
 | 
			
		||||
    Pattern: string;
 | 
			
		||||
    Tag: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IJournalEntry {
 | 
			
		||||
    EntryType: string;
 | 
			
		||||
    Progress: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface INokkoColony {
 | 
			
		||||
    FeedLevel: number;
 | 
			
		||||
    JournalEntries: IJournalEntry[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -136,7 +136,5 @@
 | 
			
		||||
  "ConquestSetupIntro",
 | 
			
		||||
  "EntratiLabConquestHardModeUnlocked",
 | 
			
		||||
  "/Lotus/Language/Npcs/KonzuPostNewWar",
 | 
			
		||||
  "/Lotus/Language/SolarisVenus/EudicoPostNewWar",
 | 
			
		||||
  "/Lotus/Language/NokkoColony/NokkoVendorName",
 | 
			
		||||
  "NokkoVisions_FirstVisit"
 | 
			
		||||
  "/Lotus/Language/SolarisVenus/EudicoPostNewWar"
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@ -558,7 +558,6 @@
 | 
			
		||||
                            <button class="btn btn-primary" onclick="debounce(addMissingEquipment, ['ShipDecorations']);" data-loc="inventory_bulkAddShipDecorations"></button>
 | 
			
		||||
                            <button class="btn btn-primary" onclick="debounce(addMissingEquipment, ['WeaponSkins']);" data-loc="inventory_bulkAddWeaponSkins"></button>
 | 
			
		||||
                            <button class="btn btn-primary" onclick="debounce(addMissingEvolutionProgress);" data-loc="inventory_bulkAddEvolutionProgress"></button>
 | 
			
		||||
                            <button class="btn btn-primary" onclick="removeIsNew();" data-loc="inventory_removeIsNew"></button>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="mb-2 d-flex flex-wrap gap-2">
 | 
			
		||||
                            <button class="btn btn-success" onclick="debounce(maxRankAllEquipment, ['Suits']);" data-loc="inventory_bulkRankUpSuits"></button>
 | 
			
		||||
 | 
			
		||||
@ -559,7 +559,7 @@ function fetchItemList() {
 | 
			
		||||
                    });
 | 
			
		||||
                } else if (type == "Syndicates") {
 | 
			
		||||
                    items.forEach(item => {
 | 
			
		||||
                        if (["ConclaveSyndicate", "NightcapJournalSyndicate"].includes(item.uniqueName)) {
 | 
			
		||||
                        if (item.uniqueName === "ConclaveSyndicate") {
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                        if (item.uniqueName.startsWith("RadioLegion")) {
 | 
			
		||||
@ -2177,15 +2177,6 @@ function removeCustomization(uniqueName) {
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function removeIsNew() {
 | 
			
		||||
    revalidateAuthz().then(() => {
 | 
			
		||||
        const req = $.get("/custom/removeIsNew?" + window.authz);
 | 
			
		||||
        req.done(() => {
 | 
			
		||||
            updateInventory();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getRequiredParts(category, WeaponType) {
 | 
			
		||||
    switch (category) {
 | 
			
		||||
        case "Hoverboards":
 | 
			
		||||
 | 
			
		||||
@ -135,7 +135,6 @@ dict = {
 | 
			
		||||
    inventory_bulkRankUpSentinelWeapons: `Alle Wächter-Waffen auf Max. Rang`,
 | 
			
		||||
    inventory_bulkRankUpEvolutionProgress: `Alle Incarnon-Entwicklungsfortschritte auf Max. Rang`,
 | 
			
		||||
    inventory_maxPlexus: `Plexus auf Max. Rang`,
 | 
			
		||||
    inventory_removeIsNew: `[UNTRANSLATED] Remove New Equipment Exclamation Icon`,
 | 
			
		||||
 | 
			
		||||
    quests_list: `Quests`,
 | 
			
		||||
    quests_completeAll: `Alle Quests abschließen`,
 | 
			
		||||
 | 
			
		||||
@ -134,7 +134,6 @@ dict = {
 | 
			
		||||
    inventory_bulkRankUpSentinelWeapons: `Max Rank All Sentinel Weapons`,
 | 
			
		||||
    inventory_bulkRankUpEvolutionProgress: `Max Rank All Incarnon Evolution Progress`,
 | 
			
		||||
    inventory_maxPlexus: `Max Rank Plexus`,
 | 
			
		||||
    inventory_removeIsNew: `Remove New Equipment Exclamation Icon`,
 | 
			
		||||
 | 
			
		||||
    quests_list: `Quests`,
 | 
			
		||||
    quests_completeAll: `Complete All Quests`,
 | 
			
		||||
 | 
			
		||||
@ -135,7 +135,6 @@ dict = {
 | 
			
		||||
    inventory_bulkRankUpSentinelWeapons: `Maximizar rango de todas las armas de centinela`,
 | 
			
		||||
    inventory_bulkRankUpEvolutionProgress: `Maximizar todo el progreso de evolución Incarnon`,
 | 
			
		||||
    inventory_maxPlexus: `Rango máximo de Plexus`,
 | 
			
		||||
    inventory_removeIsNew: `[UNTRANSLATED] Remove New Equipment Exclamation Icon`,
 | 
			
		||||
 | 
			
		||||
    quests_list: `Misiones`,
 | 
			
		||||
    quests_completeAll: `Completar todas las misiones`,
 | 
			
		||||
 | 
			
		||||
@ -135,7 +135,6 @@ dict = {
 | 
			
		||||
    inventory_bulkRankUpSentinelWeapons: `Toutes les armes de Sentinelles au rang max`,
 | 
			
		||||
    inventory_bulkRankUpEvolutionProgress: `Toutes les évolutions Incarnon au rang max`,
 | 
			
		||||
    inventory_maxPlexus: `Plexus au rang max`,
 | 
			
		||||
    inventory_removeIsNew: `[UNTRANSLATED] Remove New Equipment Exclamation Icon`,
 | 
			
		||||
 | 
			
		||||
    quests_list: `Quêtes`,
 | 
			
		||||
    quests_completeAll: `Compléter toutes les quêtes`,
 | 
			
		||||
 | 
			
		||||
@ -135,7 +135,6 @@ dict = {
 | 
			
		||||
    inventory_bulkRankUpSentinelWeapons: `Макс. ранг всего оружия Стражей`,
 | 
			
		||||
    inventory_bulkRankUpEvolutionProgress: `Макс. ранг всех эволюций Инкарнонов`,
 | 
			
		||||
    inventory_maxPlexus: `Макс. ранг Плексуса`,
 | 
			
		||||
    inventory_removeIsNew: `Удалить значок восклицательного знака нового снаряжения`,
 | 
			
		||||
 | 
			
		||||
    quests_list: `Квесты`,
 | 
			
		||||
    quests_completeAll: `Завершить все квесты`,
 | 
			
		||||
 | 
			
		||||
@ -135,7 +135,6 @@ dict = {
 | 
			
		||||
    inventory_bulkRankUpSentinelWeapons: `Макс. рівень всієї зброї Вартових`,
 | 
			
		||||
    inventory_bulkRankUpEvolutionProgress: `Макс. рівень всіх еволюцій Інкарнонів`,
 | 
			
		||||
    inventory_maxPlexus: `Макс. рівень Плексу`,
 | 
			
		||||
    inventory_removeIsNew: `[UNTRANSLATED] Remove New Equipment Exclamation Icon`,
 | 
			
		||||
 | 
			
		||||
    quests_list: `Пригоди`,
 | 
			
		||||
    quests_completeAll: `Закінчити всі пригоди`,
 | 
			
		||||
 | 
			
		||||
@ -135,7 +135,6 @@ dict = {
 | 
			
		||||
    inventory_bulkRankUpSentinelWeapons: `所有守护武器升满级`,
 | 
			
		||||
    inventory_bulkRankUpEvolutionProgress: `所有灵化之源进度最大等级`,
 | 
			
		||||
    inventory_maxPlexus: `最大深控等级`,
 | 
			
		||||
    inventory_removeIsNew: `[UNTRANSLATED] Remove New Equipment Exclamation Icon`,
 | 
			
		||||
 | 
			
		||||
    quests_list: `系列任务`,
 | 
			
		||||
    quests_completeAll: `完成所有任务`,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user