forked from OpenWF/SpaceNinjaServer
		
	feat: argon crystal decay (#1195)
Reviewed-on: OpenWF/SpaceNinjaServer#1195
This commit is contained in:
		
							parent
							
								
									2f59b3d775
								
							
						
					
					
						commit
						2d6e096fde
					
				@ -29,6 +29,7 @@
 | 
			
		||||
  "unlockExilusEverywhere": false,
 | 
			
		||||
  "unlockArcanesEverywhere": false,
 | 
			
		||||
  "noDailyStandingLimits": false,
 | 
			
		||||
  "noArgonCrystalDecay": false,
 | 
			
		||||
  "noVendorPurchaseLimits": true,
 | 
			
		||||
  "instantResourceExtractorDrones": false,
 | 
			
		||||
  "noDojoRoomBuildStage": false,
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
import { getAccountForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { Inventory, TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
			
		||||
import { config } from "@/src/services/configService";
 | 
			
		||||
import allDialogue from "@/static/fixed_responses/allDialogue.json";
 | 
			
		||||
@ -14,12 +14,13 @@ import {
 | 
			
		||||
    ExportVirtuals
 | 
			
		||||
} from "warframe-public-export-plus";
 | 
			
		||||
import { applyCheatsToInfestedFoundry, handleSubsumeCompletion } from "./infestedFoundryController";
 | 
			
		||||
import { allDailyAffiliationKeys, createLibraryDailyTask } from "@/src/services/inventoryService";
 | 
			
		||||
import { addMiscItems, allDailyAffiliationKeys, createLibraryDailyTask } from "@/src/services/inventoryService";
 | 
			
		||||
import { logger } from "@/src/utils/logger";
 | 
			
		||||
 | 
			
		||||
export const inventoryController: RequestHandler = async (request, response) => {
 | 
			
		||||
    const account = await getAccountForRequest(request);
 | 
			
		||||
    const accountId = await getAccountIdForRequest(request);
 | 
			
		||||
 | 
			
		||||
    const inventory = await Inventory.findOne({ accountOwnerId: account._id.toString() });
 | 
			
		||||
    const inventory = await Inventory.findOne({ accountOwnerId: accountId });
 | 
			
		||||
 | 
			
		||||
    if (!inventory) {
 | 
			
		||||
        response.status(400).json({ error: "inventory was undefined" });
 | 
			
		||||
@ -27,11 +28,7 @@ export const inventoryController: RequestHandler = async (request, response) =>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Handle daily reset
 | 
			
		||||
    const today: number = Math.trunc(new Date().getTime() / 86400000);
 | 
			
		||||
    if (account.LastLoginDay != today) {
 | 
			
		||||
        account.LastLoginDay = today;
 | 
			
		||||
        await account.save();
 | 
			
		||||
 | 
			
		||||
    if (!inventory.NextRefill || Date.now() >= inventory.NextRefill.getTime()) {
 | 
			
		||||
        for (const key of allDailyAffiliationKeys) {
 | 
			
		||||
            inventory[key] = 16000 + inventory.PlayerLevel * 500;
 | 
			
		||||
        }
 | 
			
		||||
@ -39,6 +36,45 @@ export const inventoryController: RequestHandler = async (request, response) =>
 | 
			
		||||
 | 
			
		||||
        inventory.LibraryAvailableDailyTaskInfo = createLibraryDailyTask();
 | 
			
		||||
 | 
			
		||||
        if (inventory.NextRefill) {
 | 
			
		||||
            if (config.noArgonCrystalDecay) {
 | 
			
		||||
                inventory.FoundToday = undefined;
 | 
			
		||||
            } else {
 | 
			
		||||
                const lastLoginDay = Math.trunc(inventory.NextRefill.getTime() / 86400000) - 1;
 | 
			
		||||
                const today = Math.trunc(Date.now() / 86400000);
 | 
			
		||||
                const daysPassed = today - lastLoginDay;
 | 
			
		||||
                for (let i = 0; i != daysPassed; ++i) {
 | 
			
		||||
                    const numArgonCrystals =
 | 
			
		||||
                        inventory.MiscItems.find(x => x.ItemType == "/Lotus/Types/Items/MiscItems/ArgonCrystal")
 | 
			
		||||
                            ?.ItemCount ?? 0;
 | 
			
		||||
                    if (numArgonCrystals == 0) {
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                    const numStableArgonCrystals =
 | 
			
		||||
                        inventory.FoundToday?.find(x => x.ItemType == "/Lotus/Types/Items/MiscItems/ArgonCrystal")
 | 
			
		||||
                            ?.ItemCount ?? 0;
 | 
			
		||||
                    const numDecayingArgonCrystals = numArgonCrystals - numStableArgonCrystals;
 | 
			
		||||
                    const numDecayingArgonCrystalsToRemove = Math.ceil(numDecayingArgonCrystals / 2);
 | 
			
		||||
                    logger.debug(`ticking argon crystals for day ${i + 1} of ${daysPassed}`, {
 | 
			
		||||
                        numArgonCrystals,
 | 
			
		||||
                        numStableArgonCrystals,
 | 
			
		||||
                        numDecayingArgonCrystals,
 | 
			
		||||
                        numDecayingArgonCrystalsToRemove
 | 
			
		||||
                    });
 | 
			
		||||
                    // Remove half of owned decaying argon crystals
 | 
			
		||||
                    addMiscItems(inventory, [
 | 
			
		||||
                        {
 | 
			
		||||
                            ItemType: "/Lotus/Types/Items/MiscItems/ArgonCrystal",
 | 
			
		||||
                            ItemCount: numDecayingArgonCrystalsToRemove * -1
 | 
			
		||||
                        }
 | 
			
		||||
                    ]);
 | 
			
		||||
                    // All stable argon crystals are now decaying
 | 
			
		||||
                    inventory.FoundToday = undefined;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inventory.NextRefill = new Date((Math.trunc(Date.now() / 86400000) + 1) * 86400000);
 | 
			
		||||
        await inventory.save();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -219,9 +255,6 @@ export const getInventoryResponse = async (
 | 
			
		||||
        applyCheatsToInfestedFoundry(inventoryResponse.InfestedFoundry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Fix for #380
 | 
			
		||||
    inventoryResponse.NextRefill = { $date: { $numberLong: "9999999999999" } };
 | 
			
		||||
 | 
			
		||||
    // This determines if the "void fissures" tab is shown in navigation.
 | 
			
		||||
    inventoryResponse.HasOwnedVoidProjectionsPreviously = true;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1161,7 +1161,8 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
			
		||||
        ChallengeProgress: [challengeProgressSchema],
 | 
			
		||||
 | 
			
		||||
        //Account Item like Ferrite,Form,Kuva etc
 | 
			
		||||
        MiscItems: [typeCountSchema],
 | 
			
		||||
        MiscItems: { type: [typeCountSchema], default: [] },
 | 
			
		||||
        FoundToday: { type: [typeCountSchema], default: undefined },
 | 
			
		||||
 | 
			
		||||
        //Non Upgrade Mods Example:I have 999 item WeaponElectricityDamageMod (only "ItemCount"+"ItemType")
 | 
			
		||||
        RawUpgrades: [RawUpgrades],
 | 
			
		||||
@ -1360,7 +1361,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
 | 
			
		||||
        //https://warframe.fandom.com/wiki/Helminth
 | 
			
		||||
        InfestedFoundry: infestedFoundrySchema,
 | 
			
		||||
 | 
			
		||||
        NextRefill: Schema.Types.Mixed, // Date, convert to IMongoDate
 | 
			
		||||
        NextRefill: { type: Date, default: undefined },
 | 
			
		||||
 | 
			
		||||
        //Purchase this new permanent skin from the Lotus customization options in Personal Quarters located in your Orbiter.
 | 
			
		||||
        //https://warframe.fandom.com/wiki/Lotus#The_New_War
 | 
			
		||||
@ -1435,6 +1436,9 @@ inventorySchema.set("toJSON", {
 | 
			
		||||
        if (inventoryDatabase.BlessingCooldown) {
 | 
			
		||||
            inventoryResponse.BlessingCooldown = toMongoDate(inventoryDatabase.BlessingCooldown);
 | 
			
		||||
        }
 | 
			
		||||
        if (inventoryDatabase.NextRefill) {
 | 
			
		||||
            inventoryResponse.NextRefill = toMongoDate(inventoryDatabase.NextRefill);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,6 @@ const databaseAccountSchema = new Schema<IDatabaseAccountJson>(
 | 
			
		||||
        TrackedSettings: { type: [String], default: [] },
 | 
			
		||||
        Nonce: { type: Number, default: 0 },
 | 
			
		||||
        Dropped: Boolean,
 | 
			
		||||
        LastLoginDay: { type: Number },
 | 
			
		||||
        LatestEventMessageDate: { type: Date, default: 0 }
 | 
			
		||||
    },
 | 
			
		||||
    opts
 | 
			
		||||
 | 
			
		||||
@ -55,6 +55,7 @@ interface IConfig {
 | 
			
		||||
    unlockExilusEverywhere?: boolean;
 | 
			
		||||
    unlockArcanesEverywhere?: boolean;
 | 
			
		||||
    noDailyStandingLimits?: boolean;
 | 
			
		||||
    noArgonCrystalDecay?: boolean;
 | 
			
		||||
    noVendorPurchaseLimits?: boolean;
 | 
			
		||||
    instantResourceExtractorDrones?: boolean;
 | 
			
		||||
    noDojoRoomBuildStage?: boolean;
 | 
			
		||||
 | 
			
		||||
@ -1045,6 +1045,22 @@ export const addMiscItems = (inventory: TInventoryDatabaseDocument, itemsArray:
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        MiscItems[itemIndex].ItemCount += ItemCount;
 | 
			
		||||
 | 
			
		||||
        if (ItemType == "/Lotus/Types/Items/MiscItems/ArgonCrystal") {
 | 
			
		||||
            inventory.FoundToday ??= [];
 | 
			
		||||
            let foundTodayIndex = inventory.FoundToday.findIndex(x => x.ItemType == ItemType);
 | 
			
		||||
            if (foundTodayIndex == -1) {
 | 
			
		||||
                foundTodayIndex = inventory.FoundToday.push({ ItemType, ItemCount: 0 }) - 1;
 | 
			
		||||
            }
 | 
			
		||||
            inventory.FoundToday[foundTodayIndex].ItemCount += ItemCount;
 | 
			
		||||
            if (inventory.FoundToday[foundTodayIndex].ItemCount <= 0) {
 | 
			
		||||
                inventory.FoundToday.splice(foundTodayIndex, 1);
 | 
			
		||||
            }
 | 
			
		||||
            if (inventory.FoundToday.length == 0) {
 | 
			
		||||
                inventory.FoundToday = undefined;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (MiscItems[itemIndex].ItemCount == 0) {
 | 
			
		||||
            MiscItems.splice(itemIndex, 1);
 | 
			
		||||
        } else if (MiscItems[itemIndex].ItemCount <= 0) {
 | 
			
		||||
 | 
			
		||||
@ -42,6 +42,7 @@ export interface IInventoryDatabase
 | 
			
		||||
            | "PendingCoupon"
 | 
			
		||||
            | "Drones"
 | 
			
		||||
            | "RecentVendorPurchases"
 | 
			
		||||
            | "NextRefill"
 | 
			
		||||
            | TEquipmentKey
 | 
			
		||||
        >,
 | 
			
		||||
        InventoryDatabaseEquipment {
 | 
			
		||||
@ -69,6 +70,7 @@ export interface IInventoryDatabase
 | 
			
		||||
    PendingCoupon?: IPendingCouponDatabase;
 | 
			
		||||
    Drones: IDroneDatabase[];
 | 
			
		||||
    RecentVendorPurchases?: IRecentVendorPurchaseDatabase[];
 | 
			
		||||
    NextRefill?: Date;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IQuestKeyDatabase {
 | 
			
		||||
@ -307,7 +309,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
 | 
			
		||||
    UseAdultOperatorLoadout?: boolean;
 | 
			
		||||
    NemesisAbandonedRewards: string[];
 | 
			
		||||
    LastInventorySync: IOid;
 | 
			
		||||
    NextRefill: IMongoDate; // Next time argon crystals will have a decay tick
 | 
			
		||||
    NextRefill?: IMongoDate;
 | 
			
		||||
    FoundToday?: IMiscItem[]; // for Argon Crystals
 | 
			
		||||
    CustomMarkers?: ICustomMarkers[];
 | 
			
		||||
    ActiveLandscapeTraps: any[];
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,6 @@ export interface IDatabaseAccount extends IAccountAndLoginResponseCommons {
 | 
			
		||||
    email: string;
 | 
			
		||||
    password: string;
 | 
			
		||||
    Dropped?: boolean;
 | 
			
		||||
    LastLoginDay?: number;
 | 
			
		||||
    LatestEventMessageDate: Date;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -517,6 +517,10 @@
 | 
			
		||||
                                        <input class="form-check-input" type="checkbox" id="noDailyStandingLimits" />
 | 
			
		||||
                                        <label class="form-check-label" for="noDailyStandingLimits" data-loc="cheats_noDailyStandingLimits"></label>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                    <div class="form-check">
 | 
			
		||||
                                        <input class="form-check-input" type="checkbox" id="noArgonCrystalDecay" />
 | 
			
		||||
                                        <label class="form-check-label" for="noArgonCrystalDecay" data-loc="cheats_noArgonCrystalDecay"></label>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                    <div class="form-check">
 | 
			
		||||
                                        <input class="form-check-input" type="checkbox" id="noVendorPurchaseLimits" />
 | 
			
		||||
                                        <label class="form-check-label" for="noVendorPurchaseLimits" data-loc="cheats_noVendorPurchaseLimits"></label>
 | 
			
		||||
 | 
			
		||||
@ -110,6 +110,7 @@ dict = {
 | 
			
		||||
    cheats_unlockExilusEverywhere: `Exilus-Adapter überall`,
 | 
			
		||||
    cheats_unlockArcanesEverywhere: `Arkana-Adapter überall`,
 | 
			
		||||
    cheats_noDailyStandingLimits: `Kein tägliches Ansehenslimit`,
 | 
			
		||||
    cheats_noArgonCrystalDecay: `[UNTRANSLATED] No Argon Crystal Decay`,
 | 
			
		||||
    cheats_noVendorPurchaseLimits: `Keine Kaufbeschränkungen bei Händlern`,
 | 
			
		||||
    cheats_instantResourceExtractorDrones: `Sofortige Ressourcen-Extraktor-Drohnen`,
 | 
			
		||||
    cheats_noDojoRoomBuildStage: `Kein Dojo-Raum-Bauvorgang`,
 | 
			
		||||
 | 
			
		||||
@ -109,6 +109,7 @@ dict = {
 | 
			
		||||
    cheats_unlockExilusEverywhere: `Exilus Adapters Everywhere`,
 | 
			
		||||
    cheats_unlockArcanesEverywhere: `Arcane Adapters Everywhere`,
 | 
			
		||||
    cheats_noDailyStandingLimits: `No Daily Standing Limits`,
 | 
			
		||||
    cheats_noArgonCrystalDecay: `No Argon Crystal Decay`,
 | 
			
		||||
    cheats_noVendorPurchaseLimits: `No Vendor Purchase Limits`,
 | 
			
		||||
    cheats_instantResourceExtractorDrones: `Instant Resource Extractor Drones`,
 | 
			
		||||
    cheats_noDojoRoomBuildStage: `No Dojo Room Build Stage`,
 | 
			
		||||
 | 
			
		||||
@ -110,6 +110,7 @@ dict = {
 | 
			
		||||
    cheats_unlockExilusEverywhere: `Adaptateurs Exilus partout`,
 | 
			
		||||
    cheats_unlockArcanesEverywhere: `Adaptateur d'Arcanes partout`,
 | 
			
		||||
    cheats_noDailyStandingLimits: `Pas de limite de réputation journalière`,
 | 
			
		||||
    cheats_noArgonCrystalDecay: `[UNTRANSLATED] No Argon Crystal Decay`,
 | 
			
		||||
    cheats_noVendorPurchaseLimits: `[UNTRANSLATED] No Vendor Purchase Limits`,
 | 
			
		||||
    cheats_instantResourceExtractorDrones: `Ressources de drone d'extraction instantannées`,
 | 
			
		||||
    cheats_noDojoRoomBuildStage: `No Dojo Room Build Stage`,
 | 
			
		||||
 | 
			
		||||
@ -110,6 +110,7 @@ dict = {
 | 
			
		||||
    cheats_unlockExilusEverywhere: `Адаптеры Эксилус везде`,
 | 
			
		||||
    cheats_unlockArcanesEverywhere: `Адаптеры для мистификаторов везде`,
 | 
			
		||||
    cheats_noDailyStandingLimits: `Без ежедневных ограничений репутации`,
 | 
			
		||||
    cheats_noArgonCrystalDecay: `[UNTRANSLATED] No Argon Crystal Decay`,
 | 
			
		||||
    cheats_noVendorPurchaseLimits: `[UNTRANSLATED] No Vendor Purchase Limits`,
 | 
			
		||||
    cheats_instantResourceExtractorDrones: `Мгновенные Экстракторы Ресурсов`,
 | 
			
		||||
    cheats_noDojoRoomBuildStage: `Мгновенное Строительтво Комнат Додзё`,
 | 
			
		||||
 | 
			
		||||
@ -110,6 +110,7 @@ dict = {
 | 
			
		||||
    cheats_unlockExilusEverywhere: `全物品自带适配器`,
 | 
			
		||||
    cheats_unlockArcanesEverywhere: `全物品自带赋能适配器`,
 | 
			
		||||
    cheats_noDailyStandingLimits: `无每日声望限制`,
 | 
			
		||||
    cheats_noArgonCrystalDecay: `[UNTRANSLATED] No Argon Crystal Decay`,
 | 
			
		||||
    cheats_noVendorPurchaseLimits: `[UNTRANSLATED] No Vendor Purchase Limits`,
 | 
			
		||||
    cheats_instantResourceExtractorDrones: `即时资源采集无人机`,
 | 
			
		||||
    cheats_noDojoRoomBuildStage: `无视道场房间建造阶段`,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user