feat: dojo decorations #1079
@ -1,4 +1,4 @@
|
||||
import { getDojoClient, getGuildForRequestEx } from "@/src/services/guildService";
|
||||
import { getDojoClient, getGuildForRequestEx, removeDojoDeco, removeDojoRoom } from "@/src/services/guildService";
|
||||
import { getInventory } from "@/src/services/inventoryService";
|
||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||
import { RequestHandler } from "express";
|
||||
@ -8,12 +8,20 @@ export const abortDojoComponentController: RequestHandler = async (req, res) =>
|
||||
const inventory = await getInventory(accountId);
|
||||
const guild = await getGuildForRequestEx(req, inventory);
|
||||
const request = JSON.parse(String(req.body)) as IAbortDojoComponentRequest;
|
||||
|
||||
// TODO: Move already-contributed credits & items to the clan vault
|
||||
guild.DojoComponents.pull({ _id: request.ComponentId });
|
||||
if (request.DecoId) {
|
||||
removeDojoDeco(guild, request.ComponentId, request.DecoId);
|
||||
} else {
|
||||
removeDojoRoom(guild, request.ComponentId);
|
||||
}
|
||||
|
||||
await guild.save();
|
||||
res.json(getDojoClient(guild, 0));
|
||||
res.json(getDojoClient(guild, 0, request.ComponentId));
|
||||
};
|
||||
|
||||
export interface IAbortDojoComponentRequest {
|
||||
interface IAbortDojoComponentRequest {
|
||||
DecoType?: string;
|
||||
ComponentId: string;
|
||||
DecoId?: string;
|
||||
}
|
||||
|
@ -1,10 +1,26 @@
|
||||
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";
|
||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||
import { IDojoContributable } from "@/src/types/guildTypes";
|
||||
import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
|
||||
import { RequestHandler } from "express";
|
||||
import { ExportDojoRecipes } from "warframe-public-export-plus";
|
||||
import { ExportDojoRecipes, IDojoRecipe } from "warframe-public-export-plus";
|
||||
|
||||
interface IContributeToDojoComponentRequest {
|
||||
ComponentId: string;
|
||||
DecoId?: string;
|
||||
DecoType?: string;
|
||||
IngredientContributions: {
|
||||
ItemType: string;
|
||||
ItemCount: number;
|
||||
}[];
|
||||
RegularCredits: number;
|
||||
VaultIngredientContributions: [];
|
||||
VaultCredits: number;
|
||||
}
|
||||
|
||||
export const contributeToDojoComponentController: RequestHandler = async (req, res) => {
|
||||
const accountId = await getAccountIdForRequest(req);
|
||||
@ -13,21 +29,54 @@ export const contributeToDojoComponentController: RequestHandler = async (req, r
|
||||
// Any clan member should have permission to contribute although notably permission is denied if they have not crafted the dojo key and were simply invited in.
|
||||
const request = JSON.parse(String(req.body)) as IContributeToDojoComponentRequest;
|
||||
const component = guild.DojoComponents.id(request.ComponentId)!;
|
||||
const componentMeta = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == component.pf)!;
|
||||
|
||||
const inventoryChanges: IInventoryChanges = {};
|
||||
if (!component.CompletionTime) {
|
||||
// Room is in "Collecting Materials" state
|
||||
if (request.DecoId) {
|
||||
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);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
await guild.save();
|
||||
await inventory.save();
|
||||
res.json({
|
||||
...getDojoClient(guild, 0, component._id),
|
||||
InventoryChanges: inventoryChanges
|
||||
});
|
||||
};
|
||||
|
||||
const processContribution = async (
|
||||
guild: TGuildDatabaseDocument,
|
||||
request: IContributeToDojoComponentRequest,
|
||||
inventory: TInventoryDatabaseDocument,
|
||||
inventoryChanges: IInventoryChanges,
|
||||
meta: IDojoRecipe,
|
||||
component: IDojoContributable
|
||||
): Promise<void> => {
|
||||
component.RegularCredits ??= 0;
|
||||
if (component.RegularCredits + request.RegularCredits > scaleRequiredCount(componentMeta.price)) {
|
||||
request.RegularCredits = scaleRequiredCount(componentMeta.price) - component.RegularCredits;
|
||||
if (component.RegularCredits + request.RegularCredits > scaleRequiredCount(meta.price)) {
|
||||
request.RegularCredits = scaleRequiredCount(meta.price) - component.RegularCredits;
|
||||
}
|
||||
component.RegularCredits += request.RegularCredits;
|
||||
const inventoryChanges: IInventoryChanges = updateCurrency(inventory, request.RegularCredits, false);
|
||||
inventoryChanges.RegularCredits = -request.RegularCredits;
|
||||
updateCurrency(inventory, request.RegularCredits, false);
|
||||
|
||||
component.MiscItems ??= [];
|
||||
const miscItemChanges: IMiscItem[] = [];
|
||||
for (const ingredientContribution of request.IngredientContributions) {
|
||||
const componentMiscItem = component.MiscItems.find(x => x.ItemType == ingredientContribution.ItemType);
|
||||
if (componentMiscItem) {
|
||||
const ingredientMeta = componentMeta.ingredients.find(x => x.ItemType == ingredientContribution.ItemType)!;
|
||||
const ingredientMeta = meta.ingredients.find(x => x.ItemType == ingredientContribution.ItemType)!;
|
||||
if (
|
||||
componentMiscItem.ItemCount + ingredientContribution.ItemCount >
|
||||
scaleRequiredCount(ingredientMeta.ItemCount)
|
||||
@ -47,9 +96,9 @@ export const contributeToDojoComponentController: RequestHandler = async (req, r
|
||||
addMiscItems(inventory, miscItemChanges);
|
||||
inventoryChanges.MiscItems = miscItemChanges;
|
||||
|
||||
if (component.RegularCredits >= scaleRequiredCount(componentMeta.price)) {
|
||||
if (component.RegularCredits >= scaleRequiredCount(meta.price)) {
|
||||
let fullyFunded = true;
|
||||
for (const ingredient of componentMeta.ingredients) {
|
||||
for (const ingredient of meta.ingredients) {
|
||||
const componentMiscItem = component.MiscItems.find(x => x.ItemType == ingredient.ItemType);
|
||||
if (!componentMiscItem || componentMiscItem.ItemCount < scaleRequiredCount(ingredient.ItemCount)) {
|
||||
fullyFunded = false;
|
||||
@ -57,27 +106,13 @@ export const contributeToDojoComponentController: RequestHandler = async (req, r
|
||||
}
|
||||
}
|
||||
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() + componentMeta.time * 1000);
|
||||
component.CompletionTime = new Date(Date.now() + meta.time * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
await guild.save();
|
||||
await inventory.save();
|
||||
res.json({
|
||||
...getDojoClient(guild, 0, component._id),
|
||||
InventoryChanges: inventoryChanges
|
||||
});
|
||||
};
|
||||
|
||||
export interface IContributeToDojoComponentRequest {
|
||||
ComponentId: string;
|
||||
IngredientContributions: {
|
||||
ItemType: string;
|
||||
ItemCount: number;
|
||||
}[];
|
||||
RegularCredits: number;
|
||||
VaultIngredientContributions: [];
|
||||
VaultCredits: number;
|
||||
}
|
||||
|
19
src/controllers/api/destroyDojoDecoController.ts
Normal file
19
src/controllers/api/destroyDojoDecoController.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { getDojoClient, getGuildForRequest, removeDojoDeco } from "@/src/services/guildService";
|
||||
import { RequestHandler } from "express";
|
||||
|
||||
export const destroyDojoDecoController: RequestHandler = async (req, res) => {
|
||||
const guild = await getGuildForRequest(req);
|
||||
const request = JSON.parse(String(req.body)) as IDestroyDojoDecoRequest;
|
||||
|
||||
removeDojoDeco(guild, request.ComponentId, request.DecoId);
|
||||
// TODO: The client says this is supposed to refund the resources to the clan vault, so we should probably do that.
|
||||
|
||||
await guild.save();
|
||||
res.json(getDojoClient(guild, 0, request.ComponentId));
|
||||
};
|
||||
|
||||
interface IDestroyDojoDecoRequest {
|
||||
DecoType: string;
|
||||
ComponentId: string;
|
||||
DecoId: string;
|
||||
}
|
@ -1,8 +1,18 @@
|
||||
import { getDojoClient, getGuildForRequestEx, scaleRequiredCount } from "@/src/services/guildService";
|
||||
import { getInventory, updateCurrency } from "@/src/services/inventoryService";
|
||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||
import { IDojoContributable } from "@/src/types/guildTypes";
|
||||
import { RequestHandler } from "express";
|
||||
import { ExportDojoRecipes } from "warframe-public-export-plus";
|
||||
import { ExportDojoRecipes, IDojoRecipe } from "warframe-public-export-plus";
|
||||
|
||||
interface IDojoComponentRushRequest {
|
||||
DecoType?: string;
|
||||
DecoId?: string;
|
||||
ComponentId: string;
|
||||
Amount: number;
|
||||
VaultAmount: number;
|
||||
AllianceVaultAmount: number;
|
||||
}
|
||||
|
||||
export const dojoComponentRushController: RequestHandler = async (req, res) => {
|
||||
const accountId = await getAccountIdForRequest(req);
|
||||
@ -10,14 +20,16 @@ export const dojoComponentRushController: RequestHandler = async (req, res) => {
|
||||
const guild = await getGuildForRequestEx(req, inventory);
|
||||
const request = JSON.parse(String(req.body)) as IDojoComponentRushRequest;
|
||||
const component = guild.DojoComponents.id(request.ComponentId)!;
|
||||
const componentMeta = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == component.pf)!;
|
||||
|
||||
const fullPlatinumCost = scaleRequiredCount(componentMeta.skipTimePrice);
|
||||
const fullDurationSeconds = componentMeta.time;
|
||||
const secondsPerPlatinum = fullDurationSeconds / fullPlatinumCost;
|
||||
component.CompletionTime = new Date(
|
||||
component.CompletionTime!.getTime() - secondsPerPlatinum * request.Amount * 1000
|
||||
);
|
||||
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)!;
|
||||
processContribution(deco, meta, request.Amount);
|
||||
} else {
|
||||
const meta = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == component.pf)!;
|
||||
processContribution(component, meta, request.Amount);
|
||||
}
|
||||
|
||||
const inventoryChanges = updateCurrency(inventory, request.Amount, true);
|
||||
|
||||
await guild.save();
|
||||
@ -28,9 +40,11 @@ export const dojoComponentRushController: RequestHandler = async (req, res) => {
|
||||
});
|
||||
};
|
||||
|
||||
interface IDojoComponentRushRequest {
|
||||
ComponentId: string;
|
||||
Amount: number;
|
||||
VaultAmount: number;
|
||||
AllianceVaultAmount: number;
|
||||
}
|
||||
const processContribution = (component: IDojoContributable, meta: IDojoRecipe, platinumDonated: number): void => {
|
||||
const fullPlatinumCost = scaleRequiredCount(meta.skipTimePrice);
|
||||
const fullDurationSeconds = meta.time;
|
||||
const secondsPerPlatinum = fullDurationSeconds / fullPlatinumCost;
|
||||
component.CompletionTime = new Date(
|
||||
component.CompletionTime!.getTime() - secondsPerPlatinum * platinumDonated * 1000
|
||||
);
|
||||
};
|
||||
|
@ -18,7 +18,8 @@ export const getGuildDojoController: RequestHandler = async (req, res) => {
|
||||
_id: new Types.ObjectId(),
|
||||
pf: "/Lotus/Levels/ClanDojo/DojoHall.level",
|
||||
ppf: "",
|
||||
CompletionTime: new Date(Date.now())
|
||||
CompletionTime: new Date(Date.now()),
|
||||
DecoCapacity: 600
|
||||
});
|
||||
await guild.save();
|
||||
}
|
||||
|
43
src/controllers/api/placeDecoInComponentController.ts
Normal file
43
src/controllers/api/placeDecoInComponentController.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { getDojoClient, getGuildForRequest } from "@/src/services/guildService";
|
||||
import { RequestHandler } from "express";
|
||||
import { Types } from "mongoose";
|
||||
import { ExportDojoRecipes } from "warframe-public-export-plus";
|
||||
|
||||
export const placeDecoInComponentController: RequestHandler = async (req, res) => {
|
||||
const guild = await getGuildForRequest(req);
|
||||
const request = JSON.parse(String(req.body)) as IPlaceDecoInComponentRequest;
|
||||
// At this point, we know that a member of the guild is making this request. Assuming they are allowed to place decorations.
|
||||
const component = guild.DojoComponents.id(request.ComponentId)!;
|
||||
|
||||
if (component.DecoCapacity === undefined) {
|
||||
component.DecoCapacity = Object.values(ExportDojoRecipes.rooms).find(
|
||||
x => x.resultType == component.pf
|
||||
)!.decoCapacity;
|
||||
}
|
||||
|
||||
component.Decos ??= [];
|
||||
component.Decos.push({
|
||||
_id: new Types.ObjectId(),
|
||||
Type: request.Type,
|
||||
Pos: request.Pos,
|
||||
Rot: request.Rot,
|
||||
Name: request.Name
|
||||
});
|
||||
|
||||
const meta = Object.values(ExportDojoRecipes.decos).find(x => x.resultType == request.Type);
|
||||
if (meta && meta.capacityCost) {
|
||||
component.DecoCapacity -= meta.capacityCost;
|
||||
}
|
||||
|
||||
await guild.save();
|
||||
res.json(getDojoClient(guild, 0, component._id));
|
||||
};
|
||||
|
||||
interface IPlaceDecoInComponentRequest {
|
||||
ComponentId: string;
|
||||
Revision: number;
|
||||
Type: string;
|
||||
Pos: number[];
|
||||
Rot: number[];
|
||||
Name?: string;
|
||||
}
|
@ -1,19 +1,12 @@
|
||||
import { getDojoClient, getGuildForRequest } from "@/src/services/guildService";
|
||||
import { getDojoClient, getGuildForRequest, removeDojoRoom } from "@/src/services/guildService";
|
||||
import { RequestHandler } from "express";
|
||||
import { ExportDojoRecipes } from "warframe-public-export-plus";
|
||||
|
||||
export const queueDojoComponentDestructionController: RequestHandler = async (req, res) => {
|
||||
const guild = await getGuildForRequest(req);
|
||||
const componentId = req.query.componentId as string;
|
||||
const component = guild.DojoComponents.splice(
|
||||
guild.DojoComponents.findIndex(x => x._id.toString() === componentId),
|
||||
1
|
||||
)[0];
|
||||
const room = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == component.pf);
|
||||
if (room) {
|
||||
guild.DojoCapacity -= room.capacity;
|
||||
guild.DojoEnergy -= room.energy;
|
||||
}
|
||||
|
||||
removeDojoRoom(guild, componentId);
|
||||
|
||||
await guild.save();
|
||||
res.json(getDojoClient(guild, 1));
|
||||
};
|
||||
|
@ -29,7 +29,8 @@ export const startDojoRecipeController: RequestHandler = async (req, res) => {
|
||||
ppf: request.PlacedComponent.ppf,
|
||||
pi: new Types.ObjectId(request.PlacedComponent.pi!.$oid),
|
||||
op: request.PlacedComponent.op,
|
||||
pp: request.PlacedComponent.pp
|
||||
pp: request.PlacedComponent.pp,
|
||||
DecoCapacity: room?.decoCapacity
|
||||
}) - 1
|
||||
];
|
||||
if (config.noDojoRoomBuildStage) {
|
||||
|
@ -2,12 +2,23 @@ import {
|
||||
IGuildDatabase,
|
||||
IDojoComponentDatabase,
|
||||
ITechProjectDatabase,
|
||||
ITechProjectClient
|
||||
ITechProjectClient,
|
||||
IDojoDecoDatabase
|
||||
} from "@/src/types/guildTypes";
|
||||
import { Document, Model, model, Schema, Types } from "mongoose";
|
||||
import { typeCountSchema } from "./inventoryModels/inventoryModel";
|
||||
import { toMongoDate } from "../helpers/inventoryHelpers";
|
||||
|
||||
const dojoDecoSchema = new Schema<IDojoDecoDatabase>({
|
||||
Type: String,
|
||||
Pos: [Number],
|
||||
Rot: [Number],
|
||||
Name: String,
|
||||
RegularCredits: Number,
|
||||
MiscItems: { type: [typeCountSchema], default: undefined },
|
||||
CompletionTime: Date
|
||||
});
|
||||
|
||||
const dojoComponentSchema = new Schema<IDojoComponentDatabase>({
|
||||
pf: { type: String, required: true },
|
||||
ppf: String,
|
||||
@ -18,7 +29,10 @@ const dojoComponentSchema = new Schema<IDojoComponentDatabase>({
|
||||
Message: String,
|
||||
RegularCredits: Number,
|
||||
MiscItems: { type: [typeCountSchema], default: undefined },
|
||||
CompletionTime: Date
|
||||
CompletionTime: Date,
|
||||
DestructionTime: Date,
|
||||
Decos: [dojoDecoSchema],
|
||||
DecoCapacity: Number
|
||||
});
|
||||
|
||||
const techProjectSchema = new Schema<ITechProjectDatabase>(
|
||||
|
@ -16,6 +16,7 @@ import { contributeToDojoComponentController } from "@/src/controllers/api/contr
|
||||
import { createGuildController } from "@/src/controllers/api/createGuildController";
|
||||
import { creditsController } from "@/src/controllers/api/creditsController";
|
||||
import { deleteSessionController } from "@/src/controllers/api/deleteSessionController";
|
||||
import { destroyDojoDecoController } from "@/src/controllers/api/destroyDojoDecoController";
|
||||
import { dojoComponentRushController } from "@/src/controllers/api/dojoComponentRushController";
|
||||
import { dojoController } from "@/src/controllers/api/dojoController";
|
||||
import { dronesController } from "@/src/controllers/api/dronesController";
|
||||
@ -59,6 +60,7 @@ import { missionInventoryUpdateController } from "@/src/controllers/api/missionI
|
||||
import { modularWeaponCraftingController } from "@/src/controllers/api/modularWeaponCraftingController";
|
||||
import { modularWeaponSaleController } from "@/src/controllers/api/modularWeaponSaleController";
|
||||
import { nameWeaponController } from "@/src/controllers/api/nameWeaponController";
|
||||
import { placeDecoInComponentController } from "@/src/controllers/api/placeDecoInComponentController";
|
||||
import { playerSkillsController } from "@/src/controllers/api/playerSkillsController";
|
||||
import { projectionManagerController } from "@/src/controllers/api/projectionManagerController";
|
||||
import { purchaseController } from "@/src/controllers/api/purchaseController";
|
||||
@ -150,6 +152,7 @@ apiRouter.post("/clearDialogueHistory.php", clearDialogueHistoryController);
|
||||
apiRouter.post("/completeRandomModChallenge.php", completeRandomModChallengeController);
|
||||
apiRouter.post("/contributeToDojoComponent.php", contributeToDojoComponentController);
|
||||
apiRouter.post("/createGuild.php", createGuildController);
|
||||
apiRouter.post("/destroyDojoDeco.php", destroyDojoDecoController);
|
||||
apiRouter.post("/dojoComponentRush.php", dojoComponentRushController);
|
||||
apiRouter.post("/drones.php", dronesController);
|
||||
apiRouter.post("/endlessXp.php", endlessXpController);
|
||||
@ -175,6 +178,7 @@ apiRouter.post("/login.php", loginController);
|
||||
apiRouter.post("/missionInventoryUpdate.php", missionInventoryUpdateController);
|
||||
apiRouter.post("/modularWeaponCrafting.php", modularWeaponCraftingController);
|
||||
apiRouter.post("/nameWeapon.php", nameWeaponController);
|
||||
apiRouter.post("/placeDecoInComponent.php", placeDecoInComponentController);
|
||||
apiRouter.post("/playerSkills.php", playerSkillsController);
|
||||
apiRouter.post("/projectionManager.php", projectionManagerController);
|
||||
apiRouter.post("/purchase.php", purchaseController);
|
||||
|
@ -6,6 +6,7 @@ import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/invento
|
||||
import { IDojoClient, IDojoComponentClient } from "@/src/types/guildTypes";
|
||||
import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers";
|
||||
import { Types } from "mongoose";
|
||||
import { ExportDojoRecipes } from "warframe-public-export-plus";
|
||||
|
||||
export const getGuildForRequest = async (req: Request): Promise<TGuildDatabaseDocument> => {
|
||||
const accountId = await getAccountIdForRequest(req);
|
||||
@ -31,7 +32,7 @@ export const getGuildForRequestEx = async (
|
||||
export const getDojoClient = (
|
||||
guild: TGuildDatabaseDocument,
|
||||
status: number,
|
||||
componentId: Types.ObjectId | undefined = undefined
|
||||
componentId: Types.ObjectId | string | undefined = undefined
|
||||
): IDojoClient => {
|
||||
const dojo: IDojoClient = {
|
||||
_id: { $oid: guild._id.toString() },
|
||||
@ -46,14 +47,14 @@ export const getDojoClient = (
|
||||
DojoComponents: []
|
||||
};
|
||||
guild.DojoComponents.forEach(dojoComponent => {
|
||||
if (!componentId || componentId == dojoComponent._id) {
|
||||
if (!componentId || dojoComponent._id.equals(componentId)) {
|
||||
const clientComponent: IDojoComponentClient = {
|
||||
id: toOid(dojoComponent._id),
|
||||
pf: dojoComponent.pf,
|
||||
ppf: dojoComponent.ppf,
|
||||
Name: dojoComponent.Name,
|
||||
Message: dojoComponent.Message,
|
||||
DecoCapacity: 600
|
||||
DecoCapacity: dojoComponent.DecoCapacity ?? 600
|
||||
};
|
||||
if (dojoComponent.pi) {
|
||||
clientComponent.pi = toOid(dojoComponent.pi);
|
||||
@ -66,6 +67,20 @@ export const getDojoClient = (
|
||||
clientComponent.RegularCredits = dojoComponent.RegularCredits;
|
||||
clientComponent.MiscItems = dojoComponent.MiscItems;
|
||||
}
|
||||
if (dojoComponent.Decos) {
|
||||
clientComponent.Decos = [];
|
||||
for (const deco of dojoComponent.Decos) {
|
||||
clientComponent.Decos.push({
|
||||
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
|
||||
});
|
||||
}
|
||||
}
|
||||
dojo.DojoComponents.push(clientComponent);
|
||||
}
|
||||
});
|
||||
@ -76,3 +91,27 @@ export const scaleRequiredCount = (count: number): number => {
|
||||
// The recipes in the export are for Moon clans. For now we'll just assume we only have Ghost clans.
|
||||
return Math.max(1, Math.trunc(count / 100));
|
||||
};
|
||||
|
||||
export const removeDojoRoom = (guild: TGuildDatabaseDocument, componentId: string): void => {
|
||||
const component = guild.DojoComponents.splice(
|
||||
guild.DojoComponents.findIndex(x => x._id.equals(componentId)),
|
||||
1
|
||||
)[0];
|
||||
const meta = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == component.pf);
|
||||
if (meta) {
|
||||
guild.DojoCapacity -= meta.capacity;
|
||||
guild.DojoEnergy -= meta.energy;
|
||||
}
|
||||
};
|
||||
|
||||
export const removeDojoDeco = (guild: TGuildDatabaseDocument, componentId: string, decoId: string): void => {
|
||||
const component = guild.DojoComponents.id(componentId)!;
|
||||
const deco = component.Decos!.splice(
|
||||
component.Decos!.findIndex(x => x._id.equals(decoId)),
|
||||
1
|
||||
)[0];
|
||||
const meta = Object.values(ExportDojoRecipes.decos).find(x => x.resultType == deco.Type);
|
||||
if (meta && meta.capacityCost) {
|
||||
component.DecoCapacity! += meta.capacityCost;
|
||||
}
|
||||
};
|
||||
|
@ -41,18 +41,33 @@ export interface IDojoComponentClient {
|
||||
CompletionTime?: IMongoDate;
|
||||
RushPlatinum?: number;
|
||||
DestructionTime?: IMongoDate;
|
||||
Decos?: IDojoDecoClient[];
|
||||
DecoCapacity?: number;
|
||||
}
|
||||
|
||||
export interface IDojoComponentDatabase
|
||||
extends Omit<
|
||||
IDojoComponentClient,
|
||||
"id" | "pi" | "CompletionTime" | "RushPlatinum" | "DestructionTime" | "DecoCapacity"
|
||||
> {
|
||||
extends Omit<IDojoComponentClient, "id" | "pi" | "CompletionTime" | "RushPlatinum" | "DestructionTime" | "Decos"> {
|
||||
_id: Types.ObjectId;
|
||||
pi?: Types.ObjectId;
|
||||
CompletionTime?: Date;
|
||||
//DestructionTime?: Date;
|
||||
DestructionTime?: Date;
|
||||
Decos?: IDojoDecoDatabase[];
|
||||
}
|
||||
|
||||
export interface IDojoDecoClient {
|
||||
id: IOid;
|
||||
Type: string;
|
||||
Pos: number[];
|
||||
Rot: number[];
|
||||
Name?: string; // for teleporters
|
||||
RegularCredits?: number;
|
||||
MiscItems?: IMiscItem[];
|
||||
CompletionTime?: IMongoDate;
|
||||
}
|
||||
|
||||
export interface IDojoDecoDatabase extends Omit<IDojoDecoClient, "id" | "CompletionTime"> {
|
||||
_id: Types.ObjectId;
|
||||
CompletionTime?: Date;
|
||||
}
|
||||
|
||||
export interface ITechProjectClient {
|
||||
@ -66,3 +81,9 @@ 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