feat: clan vault #1093
@ -1,4 +1,3 @@
 | 
			
		||||
import { TGuildDatabaseDocument } from "@/src/models/guildModel";
 | 
			
		||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
			
		||||
import { getDojoClient, getGuildForRequestEx, scaleRequiredCount } from "@/src/services/guildService";
 | 
			
		||||
import { addMiscItems, getInventory, updateCurrency } from "@/src/services/inventoryService";
 | 
			
		||||
@ -37,13 +36,13 @@ export const contributeToDojoComponentController: RequestHandler = async (req, r
 | 
			
		||||
            throw new Error("attempt to contribute to a deco in an unfinished room?!");
 | 
			
		||||
        }
 | 
			
		||||
        const meta = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == component.pf)!;
 | 
			
		||||
        await processContribution(guild, request, inventory, inventoryChanges, meta, component);
 | 
			
		||||
        processContribution(request, inventory, inventoryChanges, meta, component);
 | 
			
		||||
    } else {
 | 
			
		||||
        // Room is past "Collecting Materials"
 | 
			
		||||
        if (request.DecoId) {
 | 
			
		||||
            const deco = component.Decos!.find(x => x._id.equals(request.DecoId))!;
 | 
			
		||||
            const meta = Object.values(ExportDojoRecipes.decos).find(x => x.resultType == deco.Type)!;
 | 
			
		||||
            await processContribution(guild, request, inventory, inventoryChanges, meta, deco);
 | 
			
		||||
            processContribution(request, inventory, inventoryChanges, meta, deco);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -55,14 +54,13 @@ export const contributeToDojoComponentController: RequestHandler = async (req, r
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const processContribution = async (
 | 
			
		||||
    guild: TGuildDatabaseDocument,
 | 
			
		||||
const processContribution = (
 | 
			
		||||
    request: IContributeToDojoComponentRequest,
 | 
			
		||||
    inventory: TInventoryDatabaseDocument,
 | 
			
		||||
    inventoryChanges: IInventoryChanges,
 | 
			
		||||
    meta: IDojoRecipe,
 | 
			
		||||
    component: IDojoContributable
 | 
			
		||||
): Promise<void> => {
 | 
			
		||||
): void => {
 | 
			
		||||
    component.RegularCredits ??= 0;
 | 
			
		||||
    if (component.RegularCredits + request.RegularCredits > scaleRequiredCount(meta.price)) {
 | 
			
		||||
        request.RegularCredits = scaleRequiredCount(meta.price) - component.RegularCredits;
 | 
			
		||||
@ -106,12 +104,6 @@ const processContribution = async (
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (fullyFunded) {
 | 
			
		||||
            if (request.IngredientContributions.length) {
 | 
			
		||||
                // We've already updated subpaths of MiscItems, we need to allow MongoDB to save this before we remove MiscItems.
 | 
			
		||||
                await guild.save();
 | 
			
		||||
            }
 | 
			
		||||
            component.RegularCredits = undefined;
 | 
			
		||||
            component.MiscItems = undefined;
 | 
			
		||||
            component.CompletionTime = new Date(Date.now() + meta.time * 1000);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -47,4 +47,6 @@ const processContribution = (component: IDojoContributable, meta: IDojoRecipe, p
 | 
			
		||||
    component.CompletionTime = new Date(
 | 
			
		||||
        component.CompletionTime!.getTime() - secondsPerPlatinum * platinumDonated * 1000
 | 
			
		||||
    );
 | 
			
		||||
    component.RushPlatinum ??= 0;
 | 
			
		||||
    component.RushPlatinum += platinumDonated;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,8 @@ const dojoDecoSchema = new Schema<IDojoDecoDatabase>({
 | 
			
		||||
    Name: String,
 | 
			
		||||
    RegularCredits: Number,
 | 
			
		||||
    MiscItems: { type: [typeCountSchema], default: undefined },
 | 
			
		||||
    CompletionTime: Date
 | 
			
		||||
    CompletionTime: Date,
 | 
			
		||||
    RushPlatinum: Number
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const dojoComponentSchema = new Schema<IDojoComponentDatabase>({
 | 
			
		||||
@ -30,6 +31,7 @@ const dojoComponentSchema = new Schema<IDojoComponentDatabase>({
 | 
			
		||||
    RegularCredits: Number,
 | 
			
		||||
    MiscItems: { type: [typeCountSchema], default: undefined },
 | 
			
		||||
    CompletionTime: Date,
 | 
			
		||||
    RushPlatinum: Number,
 | 
			
		||||
    DestructionTime: Date,
 | 
			
		||||
    Decos: [dojoDecoSchema],
 | 
			
		||||
    DecoCapacity: Number
 | 
			
		||||
@ -63,6 +65,9 @@ const guildSchema = new Schema<IGuildDatabase>(
 | 
			
		||||
        DojoComponents: { type: [dojoComponentSchema], default: [] },
 | 
			
		||||
        DojoCapacity: { type: Number, default: 100 },
 | 
			
		||||
        DojoEnergy: { type: Number, default: 5 },
 | 
			
		||||
        VaultRegularCredits: Number,
 | 
			
		||||
        VaultPremiumCredits: Number,
 | 
			
		||||
        VaultMiscItems: { type: [typeCountSchema], default: undefined },
 | 
			
		||||
        TechProjects: { type: [techProjectSchema], default: undefined }
 | 
			
		||||
    },
 | 
			
		||||
    { id: false }
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { Guild, TGuildDatabaseDocument } from "@/src/models/guildModel";
 | 
			
		||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
			
		||||
import { IDojoClient, IDojoComponentClient } from "@/src/types/guildTypes";
 | 
			
		||||
import { IDojoClient, IDojoComponentClient, IDojoContributable, IDojoDecoClient } from "@/src/types/guildTypes";
 | 
			
		||||
import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers";
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
import { ExportDojoRecipes } from "warframe-public-export-plus";
 | 
			
		||||
@ -41,6 +41,11 @@ export const getDojoClient = async (
 | 
			
		||||
        Tier: 1,
 | 
			
		||||
        FixedContributions: true,
 | 
			
		||||
        DojoRevision: 1,
 | 
			
		||||
        Vault: {
 | 
			
		||||
            DojoRefundRegularCredits: guild.VaultRegularCredits,
 | 
			
		||||
            DojoRefundMiscItems: guild.VaultMiscItems,
 | 
			
		||||
            DojoRefundPremiumCredits: guild.VaultPremiumCredits
 | 
			
		||||
        },
 | 
			
		||||
        RevisionTime: Math.round(Date.now() / 1000),
 | 
			
		||||
        Energy: guild.DojoEnergy,
 | 
			
		||||
        Capacity: guild.DojoCapacity,
 | 
			
		||||
@ -79,15 +84,20 @@ export const getDojoClient = async (
 | 
			
		||||
            if (dojoComponent.Decos) {
 | 
			
		||||
                clientComponent.Decos = [];
 | 
			
		||||
                for (const deco of dojoComponent.Decos) {
 | 
			
		||||
                    clientComponent.Decos.push({
 | 
			
		||||
                    const clientDeco: IDojoDecoClient = {
 | 
			
		||||
                        id: toOid(deco._id),
 | 
			
		||||
                        Type: deco.Type,
 | 
			
		||||
                        Pos: deco.Pos,
 | 
			
		||||
                        Rot: deco.Rot,
 | 
			
		||||
                        CompletionTime: deco.CompletionTime ? toMongoDate(deco.CompletionTime) : undefined,
 | 
			
		||||
                        RegularCredits: deco.RegularCredits,
 | 
			
		||||
                        MiscItems: deco.MiscItems
 | 
			
		||||
                    });
 | 
			
		||||
                        Name: deco.Name
 | 
			
		||||
                    };
 | 
			
		||||
                    if (deco.CompletionTime) {
 | 
			
		||||
                        clientDeco.CompletionTime = toMongoDate(deco.CompletionTime);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        clientDeco.RegularCredits = deco.RegularCredits;
 | 
			
		||||
                        clientDeco.MiscItems = deco.MiscItems;
 | 
			
		||||
                    }
 | 
			
		||||
                    clientComponent.Decos.push(clientDeco);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            dojo.DojoComponents.push(clientComponent);
 | 
			
		||||
@ -118,7 +128,8 @@ export const removeDojoRoom = (guild: TGuildDatabaseDocument, componentId: Types
 | 
			
		||||
        guild.DojoCapacity -= meta.capacity;
 | 
			
		||||
        guild.DojoEnergy -= meta.energy;
 | 
			
		||||
    }
 | 
			
		||||
    // TODO: Add resources spent to the clan vault
 | 
			
		||||
    moveResourcesToVault(guild, component);
 | 
			
		||||
    component.Decos?.forEach(deco => moveResourcesToVault(guild, deco));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const removeDojoDeco = (
 | 
			
		||||
@ -135,5 +146,27 @@ export const removeDojoDeco = (
 | 
			
		||||
    if (meta && meta.capacityCost) {
 | 
			
		||||
        component.DecoCapacity! += meta.capacityCost;
 | 
			
		||||
    }
 | 
			
		||||
    // TODO: Add resources spent to the clan vault
 | 
			
		||||
    moveResourcesToVault(guild, deco);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const moveResourcesToVault = (guild: TGuildDatabaseDocument, component: IDojoContributable): void => {
 | 
			
		||||
    if (component.RegularCredits) {
 | 
			
		||||
        guild.VaultRegularCredits ??= 0;
 | 
			
		||||
        guild.VaultRegularCredits += component.RegularCredits;
 | 
			
		||||
    }
 | 
			
		||||
    if (component.MiscItems) {
 | 
			
		||||
        guild.VaultMiscItems ??= [];
 | 
			
		||||
        for (const componentMiscItem of component.MiscItems) {
 | 
			
		||||
            const vaultMiscItem = guild.VaultMiscItems.find(x => x.ItemType == componentMiscItem.ItemType);
 | 
			
		||||
            if (vaultMiscItem) {
 | 
			
		||||
                vaultMiscItem.ItemCount += componentMiscItem.ItemCount;
 | 
			
		||||
            } else {
 | 
			
		||||
                guild.VaultMiscItems.push(componentMiscItem);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (component.RushPlatinum) {
 | 
			
		||||
        guild.VaultPremiumCredits ??= 0;
 | 
			
		||||
        guild.VaultPremiumCredits += component.RushPlatinum;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
import { IOid, IMongoDate } from "@/src/types/commonTypes";
 | 
			
		||||
import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { IFusionTreasure, IMiscItem, ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
 | 
			
		||||
export interface IGuild {
 | 
			
		||||
    Name: string;
 | 
			
		||||
@ -11,6 +11,9 @@ export interface IGuildDatabase extends IGuild {
 | 
			
		||||
    DojoComponents: IDojoComponentDatabase[];
 | 
			
		||||
    DojoCapacity: number;
 | 
			
		||||
    DojoEnergy: number;
 | 
			
		||||
    VaultRegularCredits?: number;
 | 
			
		||||
    VaultPremiumCredits?: number;
 | 
			
		||||
    VaultMiscItems?: IMiscItem[];
 | 
			
		||||
    TechProjects?: ITechProjectDatabase[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -20,10 +23,22 @@ export interface IDojoClient {
 | 
			
		||||
    Tier: number;
 | 
			
		||||
    FixedContributions: boolean;
 | 
			
		||||
    DojoRevision: number;
 | 
			
		||||
    AllianceId?: IOid;
 | 
			
		||||
    Vault?: {
 | 
			
		||||
        DojoRefundRegularCredits?: number;
 | 
			
		||||
        DojoRefundMiscItems?: IMiscItem[];
 | 
			
		||||
        DojoRefundPremiumCredits?: number;
 | 
			
		||||
        ShipDecorations?: ITypeCount[];
 | 
			
		||||
        FusionTreasures?: IFusionTreasure[];
 | 
			
		||||
        DecoRecipes?: ITypeCount[]; // Event Trophies
 | 
			
		||||
    };
 | 
			
		||||
    Class?: number; // Level
 | 
			
		||||
    RevisionTime: number;
 | 
			
		||||
    Energy: number;
 | 
			
		||||
    Capacity: number;
 | 
			
		||||
    DojoRequestStatus: number;
 | 
			
		||||
    ContentURL?: string;
 | 
			
		||||
    GuildEmblem?: boolean;
 | 
			
		||||
    DojoComponents: IDojoComponentClient[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -46,7 +61,7 @@ export interface IDojoComponentClient {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IDojoComponentDatabase
 | 
			
		||||
    extends Omit<IDojoComponentClient, "id" | "pi" | "CompletionTime" | "RushPlatinum" | "DestructionTime" | "Decos"> {
 | 
			
		||||
    extends Omit<IDojoComponentClient, "id" | "pi" | "CompletionTime" | "DestructionTime" | "Decos"> {
 | 
			
		||||
    _id: Types.ObjectId;
 | 
			
		||||
    pi?: Types.ObjectId;
 | 
			
		||||
    CompletionTime?: Date;
 | 
			
		||||
@ -63,6 +78,7 @@ export interface IDojoDecoClient {
 | 
			
		||||
    RegularCredits?: number;
 | 
			
		||||
    MiscItems?: IMiscItem[];
 | 
			
		||||
    CompletionTime?: IMongoDate;
 | 
			
		||||
    RushPlatinum?: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IDojoDecoDatabase extends Omit<IDojoDecoClient, "id" | "CompletionTime"> {
 | 
			
		||||
@ -70,6 +86,14 @@ export interface IDojoDecoDatabase extends Omit<IDojoDecoClient, "id" | "Complet
 | 
			
		||||
    CompletionTime?: Date;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A common subset of the database representation of rooms & decos.
 | 
			
		||||
export interface IDojoContributable {
 | 
			
		||||
    RegularCredits?: number;
 | 
			
		||||
    MiscItems?: IMiscItem[];
 | 
			
		||||
    CompletionTime?: Date;
 | 
			
		||||
    RushPlatinum?: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ITechProjectClient {
 | 
			
		||||
    ItemType: string;
 | 
			
		||||
    ReqCredits: number;
 | 
			
		||||
@ -81,9 +105,3 @@ export interface ITechProjectClient {
 | 
			
		||||
export interface ITechProjectDatabase extends Omit<ITechProjectClient, "CompletionDate"> {
 | 
			
		||||
    CompletionDate?: Date;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IDojoContributable {
 | 
			
		||||
    RegularCredits?: number;
 | 
			
		||||
    MiscItems?: IMiscItem[];
 | 
			
		||||
    CompletionTime?: Date;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user