XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

SpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 1 Star 0
返回提交历史

XFEstudio/SpaceNinjaServer

feat: dojo decorations (#1079)

Closes #525 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1079

c4ab496a
Sainan <sainan@calamity.inc>
提交于

代码差异

12 个文件 +260 -68
Modified src/controllers/api/abortDojoComponentController.ts +12 -4
@@ -1,4 +1,4 @@
1 import { getDojoClient, getGuildForRequestEx } from "@/src/services/guildService";
1 import { getDojoClient, getGuildForRequestEx, removeDojoDeco, removeDojoRoom } from "@/src/services/guildService";
2 2 import { getInventory } from "@/src/services/inventoryService";
3 3 import { getAccountIdForRequest } from "@/src/services/loginService";
4 4 import { RequestHandler } from "express";
@@ -8,12 +8,20 @@ export const abortDojoComponentController: RequestHandler = async (req, res) =>
8 8 const inventory = await getInventory(accountId);
9 9 const guild = await getGuildForRequestEx(req, inventory);
10 10 const request = JSON.parse(String(req.body)) as IAbortDojoComponentRequest;
11
11 12 // TODO: Move already-contributed credits & items to the clan vault
12 guild.DojoComponents.pull({ _id: request.ComponentId });
13 if (request.DecoId) {
14 removeDojoDeco(guild, request.ComponentId, request.DecoId);
15 } else {
16 removeDojoRoom(guild, request.ComponentId);
17 }
18
13 19 await guild.save();
14 res.json(getDojoClient(guild, 0));
20 res.json(getDojoClient(guild, 0, request.ComponentId));
15 21 };
16 22
17 export interface IAbortDojoComponentRequest {
23 interface IAbortDojoComponentRequest {
24 DecoType?: string;
18 25 ComponentId: string;
26 DecoId?: string;
19 27 }
Modified src/controllers/api/contributeToDojoComponentController.ts +62 -27
@@ -1,10 +1,26 @@
1 import { TGuildDatabaseDocument } from "@/src/models/guildModel";
2 import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
1 3 import { getDojoClient, getGuildForRequestEx, scaleRequiredCount } from "@/src/services/guildService";
2 4 import { addMiscItems, getInventory, updateCurrency } from "@/src/services/inventoryService";
3 5 import { getAccountIdForRequest } from "@/src/services/loginService";
6 import { IDojoContributable } from "@/src/types/guildTypes";
4 7 import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
5 8 import { IInventoryChanges } from "@/src/types/purchaseTypes";
6 9 import { RequestHandler } from "express";
7 import { ExportDojoRecipes } from "warframe-public-export-plus";
10 import { ExportDojoRecipes, IDojoRecipe } from "warframe-public-export-plus";
11
12 interface IContributeToDojoComponentRequest {
13 ComponentId: string;
14 DecoId?: string;
15 DecoType?: string;
16 IngredientContributions: {
17 ItemType: string;
18 ItemCount: number;
19 }[];
20 RegularCredits: number;
21 VaultIngredientContributions: [];
22 VaultCredits: number;
23 }
8 24
9 25 export const contributeToDojoComponentController: RequestHandler = async (req, res) => {
10 26 const accountId = await getAccountIdForRequest(req);
@@ -13,21 +29,54 @@ export const contributeToDojoComponentController: RequestHandler = async (req, r
13 29 // 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.
14 30 const request = JSON.parse(String(req.body)) as IContributeToDojoComponentRequest;
15 31 const component = guild.DojoComponents.id(request.ComponentId)!;
16 const componentMeta = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == component.pf)!;
17 32
33 const inventoryChanges: IInventoryChanges = {};
34 if (!component.CompletionTime) {
35 // Room is in "Collecting Materials" state
36 if (request.DecoId) {
37 throw new Error("attempt to contribute to a deco in an unfinished room?!");
38 }
39 const meta = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == component.pf)!;
40 await processContribution(guild, request, inventory, inventoryChanges, meta, component);
41 } else {
42 // Room is past "Collecting Materials"
43 if (request.DecoId) {
44 const deco = component.Decos!.find(x => x._id.equals(request.DecoId))!;
45 const meta = Object.values(ExportDojoRecipes.decos).find(x => x.resultType == deco.Type)!;
46 await processContribution(guild, request, inventory, inventoryChanges, meta, deco);
47 }
48 }
49
50 await guild.save();
51 await inventory.save();
52 res.json({
53 ...getDojoClient(guild, 0, component._id),
54 InventoryChanges: inventoryChanges
55 });
56 };
57
58 const processContribution = async (
59 guild: TGuildDatabaseDocument,
60 request: IContributeToDojoComponentRequest,
61 inventory: TInventoryDatabaseDocument,
62 inventoryChanges: IInventoryChanges,
63 meta: IDojoRecipe,
64 component: IDojoContributable
65 ): Promise<void> => {
18 66 component.RegularCredits ??= 0;
19 if (component.RegularCredits + request.RegularCredits > scaleRequiredCount(componentMeta.price)) {
20 request.RegularCredits = scaleRequiredCount(componentMeta.price) - component.RegularCredits;
67 if (component.RegularCredits + request.RegularCredits > scaleRequiredCount(meta.price)) {
68 request.RegularCredits = scaleRequiredCount(meta.price) - component.RegularCredits;
21 69 }
22 70 component.RegularCredits += request.RegularCredits;
23 const inventoryChanges: IInventoryChanges = updateCurrency(inventory, request.RegularCredits, false);
71 inventoryChanges.RegularCredits = -request.RegularCredits;
72 updateCurrency(inventory, request.RegularCredits, false);
24 73
25 74 component.MiscItems ??= [];
26 75 const miscItemChanges: IMiscItem[] = [];
27 76 for (const ingredientContribution of request.IngredientContributions) {
28 77 const componentMiscItem = component.MiscItems.find(x => x.ItemType == ingredientContribution.ItemType);
29 78 if (componentMiscItem) {
30 const ingredientMeta = componentMeta.ingredients.find(x => x.ItemType == ingredientContribution.ItemType)!;
79 const ingredientMeta = meta.ingredients.find(x => x.ItemType == ingredientContribution.ItemType)!;
31 80 if (
32 81 componentMiscItem.ItemCount + ingredientContribution.ItemCount >
33 82 scaleRequiredCount(ingredientMeta.ItemCount)
@@ -47,9 +96,9 @@ export const contributeToDojoComponentController: RequestHandler = async (req, r
47 96 addMiscItems(inventory, miscItemChanges);
48 97 inventoryChanges.MiscItems = miscItemChanges;
49 98
50 if (component.RegularCredits >= scaleRequiredCount(componentMeta.price)) {
99 if (component.RegularCredits >= scaleRequiredCount(meta.price)) {
51 100 let fullyFunded = true;
52 for (const ingredient of componentMeta.ingredients) {
101 for (const ingredient of meta.ingredients) {
53 102 const componentMiscItem = component.MiscItems.find(x => x.ItemType == ingredient.ItemType);
54 103 if (!componentMiscItem || componentMiscItem.ItemCount < scaleRequiredCount(ingredient.ItemCount)) {
55 104 fullyFunded = false;
@@ -57,27 +106,13 @@ export const contributeToDojoComponentController: RequestHandler = async (req, r
57 106 }
58 107 }
59 108 if (fullyFunded) {
109 if (request.IngredientContributions.length) {
110 // We've already updated subpaths of MiscItems, we need to allow MongoDB to save this before we remove MiscItems.
111 await guild.save();
112 }
60 113 component.RegularCredits = undefined;
61 114 component.MiscItems = undefined;
62 component.CompletionTime = new Date(Date.now() + componentMeta.time * 1000);
115 component.CompletionTime = new Date(Date.now() + meta.time * 1000);
63 116 }
64 117 }
65
66 await guild.save();
67 await inventory.save();
68 res.json({
69 ...getDojoClient(guild, 0, component._id),
70 InventoryChanges: inventoryChanges
71 });
72 118 };
73
74 export interface IContributeToDojoComponentRequest {
75 ComponentId: string;
76 IngredientContributions: {
77 ItemType: string;
78 ItemCount: number;
79 }[];
80 RegularCredits: number;
81 VaultIngredientContributions: [];
82 VaultCredits: number;
83 }
Added src/controllers/api/destroyDojoDecoController.ts +19 -0
@@ -0,0 +1,19 @@
1 import { getDojoClient, getGuildForRequest, removeDojoDeco } from "@/src/services/guildService";
2 import { RequestHandler } from "express";
3
4 export const destroyDojoDecoController: RequestHandler = async (req, res) => {
5 const guild = await getGuildForRequest(req);
6 const request = JSON.parse(String(req.body)) as IDestroyDojoDecoRequest;
7
8 removeDojoDeco(guild, request.ComponentId, request.DecoId);
9 // TODO: The client says this is supposed to refund the resources to the clan vault, so we should probably do that.
10
11 await guild.save();
12 res.json(getDojoClient(guild, 0, request.ComponentId));
13 };
14
15 interface IDestroyDojoDecoRequest {
16 DecoType: string;
17 ComponentId: string;
18 DecoId: string;
19 }
Modified src/controllers/api/dojoComponentRushController.ts +28 -14
@@ -1,8 +1,18 @@
1 1 import { getDojoClient, getGuildForRequestEx, scaleRequiredCount } from "@/src/services/guildService";
2 2 import { getInventory, updateCurrency } from "@/src/services/inventoryService";
3 3 import { getAccountIdForRequest } from "@/src/services/loginService";
4 import { IDojoContributable } from "@/src/types/guildTypes";
4 5 import { RequestHandler } from "express";
5 import { ExportDojoRecipes } from "warframe-public-export-plus";
6 import { ExportDojoRecipes, IDojoRecipe } from "warframe-public-export-plus";
7
8 interface IDojoComponentRushRequest {
9 DecoType?: string;
10 DecoId?: string;
11 ComponentId: string;
12 Amount: number;
13 VaultAmount: number;
14 AllianceVaultAmount: number;
15 }
6 16
7 17 export const dojoComponentRushController: RequestHandler = async (req, res) => {
8 18 const accountId = await getAccountIdForRequest(req);
@@ -10,14 +20,16 @@ export const dojoComponentRushController: RequestHandler = async (req, res) => {
10 20 const guild = await getGuildForRequestEx(req, inventory);
11 21 const request = JSON.parse(String(req.body)) as IDojoComponentRushRequest;
12 22 const component = guild.DojoComponents.id(request.ComponentId)!;
13 const componentMeta = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == component.pf)!;
14 23
15 const fullPlatinumCost = scaleRequiredCount(componentMeta.skipTimePrice);
16 const fullDurationSeconds = componentMeta.time;
17 const secondsPerPlatinum = fullDurationSeconds / fullPlatinumCost;
18 component.CompletionTime = new Date(
19 component.CompletionTime!.getTime() - secondsPerPlatinum * request.Amount * 1000
20 );
24 if (request.DecoId) {
25 const deco = component.Decos!.find(x => x._id.equals(request.DecoId))!;
26 const meta = Object.values(ExportDojoRecipes.decos).find(x => x.resultType == deco.Type)!;
27 processContribution(deco, meta, request.Amount);
28 } else {
29 const meta = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == component.pf)!;
30 processContribution(component, meta, request.Amount);
31 }
32
21 33 const inventoryChanges = updateCurrency(inventory, request.Amount, true);
22 34
23 35 await guild.save();
@@ -28,9 +40,11 @@ export const dojoComponentRushController: RequestHandler = async (req, res) => {
28 40 });
29 41 };
30 42
31 interface IDojoComponentRushRequest {
32 ComponentId: string;
33 Amount: number;
34 VaultAmount: number;
35 AllianceVaultAmount: number;
36 }
43 const processContribution = (component: IDojoContributable, meta: IDojoRecipe, platinumDonated: number): void => {
44 const fullPlatinumCost = scaleRequiredCount(meta.skipTimePrice);
45 const fullDurationSeconds = meta.time;
46 const secondsPerPlatinum = fullDurationSeconds / fullPlatinumCost;
47 component.CompletionTime = new Date(
48 component.CompletionTime!.getTime() - secondsPerPlatinum * platinumDonated * 1000
49 );
50 };
Modified src/controllers/api/getGuildDojoController.ts +2 -1
@@ -18,7 +18,8 @@ export const getGuildDojoController: RequestHandler = async (req, res) => {
18 18 _id: new Types.ObjectId(),
19 19 pf: "/Lotus/Levels/ClanDojo/DojoHall.level",
20 20 ppf: "",
21 CompletionTime: new Date(Date.now())
21 CompletionTime: new Date(Date.now()),
22 DecoCapacity: 600
22 23 });
23 24 await guild.save();
24 25 }
Added src/controllers/api/placeDecoInComponentController.ts +43 -0
@@ -0,0 +1,43 @@
1 import { getDojoClient, getGuildForRequest } from "@/src/services/guildService";
2 import { RequestHandler } from "express";
3 import { Types } from "mongoose";
4 import { ExportDojoRecipes } from "warframe-public-export-plus";
5
6 export const placeDecoInComponentController: RequestHandler = async (req, res) => {
7 const guild = await getGuildForRequest(req);
8 const request = JSON.parse(String(req.body)) as IPlaceDecoInComponentRequest;
9 // At this point, we know that a member of the guild is making this request. Assuming they are allowed to place decorations.
10 const component = guild.DojoComponents.id(request.ComponentId)!;
11
12 if (component.DecoCapacity === undefined) {
13 component.DecoCapacity = Object.values(ExportDojoRecipes.rooms).find(
14 x => x.resultType == component.pf
15 )!.decoCapacity;
16 }
17
18 component.Decos ??= [];
19 component.Decos.push({
20 _id: new Types.ObjectId(),
21 Type: request.Type,
22 Pos: request.Pos,
23 Rot: request.Rot,
24 Name: request.Name
25 });
26
27 const meta = Object.values(ExportDojoRecipes.decos).find(x => x.resultType == request.Type);
28 if (meta && meta.capacityCost) {
29 component.DecoCapacity -= meta.capacityCost;
30 }
31
32 await guild.save();
33 res.json(getDojoClient(guild, 0, component._id));
34 };
35
36 interface IPlaceDecoInComponentRequest {
37 ComponentId: string;
38 Revision: number;
39 Type: string;
40 Pos: number[];
41 Rot: number[];
42 Name?: string;
43 }
Modified src/controllers/api/queueDojoComponentDestructionController.ts +4 -11
@@ -1,19 +1,12 @@
1 import { getDojoClient, getGuildForRequest } from "@/src/services/guildService";
1 import { getDojoClient, getGuildForRequest, removeDojoRoom } from "@/src/services/guildService";
2 2 import { RequestHandler } from "express";
3 import { ExportDojoRecipes } from "warframe-public-export-plus";
4 3
5 4 export const queueDojoComponentDestructionController: RequestHandler = async (req, res) => {
6 5 const guild = await getGuildForRequest(req);
7 6 const componentId = req.query.componentId as string;
8 const component = guild.DojoComponents.splice(
9 guild.DojoComponents.findIndex(x => x._id.toString() === componentId),
10 1
11 )[0];
12 const room = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == component.pf);
13 if (room) {
14 guild.DojoCapacity -= room.capacity;
15 guild.DojoEnergy -= room.energy;
16 }
7
8 removeDojoRoom(guild, componentId);
9
17 10 await guild.save();
18 11 res.json(getDojoClient(guild, 1));
19 12 };
Modified src/controllers/api/startDojoRecipeController.ts +2 -1
@@ -29,7 +29,8 @@ export const startDojoRecipeController: RequestHandler = async (req, res) => {
29 29 ppf: request.PlacedComponent.ppf,
30 30 pi: new Types.ObjectId(request.PlacedComponent.pi!.$oid),
31 31 op: request.PlacedComponent.op,
32 pp: request.PlacedComponent.pp
32 pp: request.PlacedComponent.pp,
33 DecoCapacity: room?.decoCapacity
33 34 }) - 1
34 35 ];
35 36 if (config.noDojoRoomBuildStage) {
Modified src/models/guildModel.ts +16 -2
@@ -2,12 +2,23 @@ import {
2 2 IGuildDatabase,
3 3 IDojoComponentDatabase,
4 4 ITechProjectDatabase,
5 ITechProjectClient
5 ITechProjectClient,
6 IDojoDecoDatabase
6 7 } from "@/src/types/guildTypes";
7 8 import { Document, Model, model, Schema, Types } from "mongoose";
8 9 import { typeCountSchema } from "./inventoryModels/inventoryModel";
9 10 import { toMongoDate } from "../helpers/inventoryHelpers";
10 11
12 const dojoDecoSchema = new Schema<IDojoDecoDatabase>({
13 Type: String,
14 Pos: [Number],
15 Rot: [Number],
16 Name: String,
17 RegularCredits: Number,
18 MiscItems: { type: [typeCountSchema], default: undefined },
19 CompletionTime: Date
20 });
21
11 22 const dojoComponentSchema = new Schema<IDojoComponentDatabase>({
12 23 pf: { type: String, required: true },
13 24 ppf: String,
@@ -18,7 +29,10 @@ const dojoComponentSchema = new Schema<IDojoComponentDatabase>({
18 29 Message: String,
19 30 RegularCredits: Number,
20 31 MiscItems: { type: [typeCountSchema], default: undefined },
21 CompletionTime: Date
32 CompletionTime: Date,
33 DestructionTime: Date,
34 Decos: [dojoDecoSchema],
35 DecoCapacity: Number
22 36 });
23 37
24 38 const techProjectSchema = new Schema<ITechProjectDatabase>(
Modified src/routes/api.ts +4 -0
@@ -16,6 +16,7 @@ import { contributeToDojoComponentController } from "@/src/controllers/api/contr
16 16 import { createGuildController } from "@/src/controllers/api/createGuildController";
17 17 import { creditsController } from "@/src/controllers/api/creditsController";
18 18 import { deleteSessionController } from "@/src/controllers/api/deleteSessionController";
19 import { destroyDojoDecoController } from "@/src/controllers/api/destroyDojoDecoController";
19 20 import { dojoComponentRushController } from "@/src/controllers/api/dojoComponentRushController";
20 21 import { dojoController } from "@/src/controllers/api/dojoController";
21 22 import { dronesController } from "@/src/controllers/api/dronesController";
@@ -59,6 +60,7 @@ import { missionInventoryUpdateController } from "@/src/controllers/api/missionI
59 60 import { modularWeaponCraftingController } from "@/src/controllers/api/modularWeaponCraftingController";
60 61 import { modularWeaponSaleController } from "@/src/controllers/api/modularWeaponSaleController";
61 62 import { nameWeaponController } from "@/src/controllers/api/nameWeaponController";
63 import { placeDecoInComponentController } from "@/src/controllers/api/placeDecoInComponentController";
62 64 import { playerSkillsController } from "@/src/controllers/api/playerSkillsController";
63 65 import { projectionManagerController } from "@/src/controllers/api/projectionManagerController";
64 66 import { purchaseController } from "@/src/controllers/api/purchaseController";
@@ -150,6 +152,7 @@ apiRouter.post("/clearDialogueHistory.php", clearDialogueHistoryController);
150 152 apiRouter.post("/completeRandomModChallenge.php", completeRandomModChallengeController);
151 153 apiRouter.post("/contributeToDojoComponent.php", contributeToDojoComponentController);
152 154 apiRouter.post("/createGuild.php", createGuildController);
155 apiRouter.post("/destroyDojoDeco.php", destroyDojoDecoController);
153 156 apiRouter.post("/dojoComponentRush.php", dojoComponentRushController);
154 157 apiRouter.post("/drones.php", dronesController);
155 158 apiRouter.post("/endlessXp.php", endlessXpController);
@@ -175,6 +178,7 @@ apiRouter.post("/login.php", loginController);
175 178 apiRouter.post("/missionInventoryUpdate.php", missionInventoryUpdateController);
176 179 apiRouter.post("/modularWeaponCrafting.php", modularWeaponCraftingController);
177 180 apiRouter.post("/nameWeapon.php", nameWeaponController);
181 apiRouter.post("/placeDecoInComponent.php", placeDecoInComponentController);
178 182 apiRouter.post("/playerSkills.php", playerSkillsController);
179 183 apiRouter.post("/projectionManager.php", projectionManagerController);
180 184 apiRouter.post("/purchase.php", purchaseController);
Modified src/services/guildService.ts +42 -3
@@ -6,6 +6,7 @@ import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/invento
6 6 import { IDojoClient, IDojoComponentClient } from "@/src/types/guildTypes";
7 7 import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers";
8 8 import { Types } from "mongoose";
9 import { ExportDojoRecipes } from "warframe-public-export-plus";
9 10
10 11 export const getGuildForRequest = async (req: Request): Promise<TGuildDatabaseDocument> => {
11 12 const accountId = await getAccountIdForRequest(req);
@@ -31,7 +32,7 @@ export const getGuildForRequestEx = async (
31 32 export const getDojoClient = (
32 33 guild: TGuildDatabaseDocument,
33 34 status: number,
34 componentId: Types.ObjectId | undefined = undefined
35 componentId: Types.ObjectId | string | undefined = undefined
35 36 ): IDojoClient => {
36 37 const dojo: IDojoClient = {
37 38 _id: { $oid: guild._id.toString() },
@@ -46,14 +47,14 @@ export const getDojoClient = (
46 47 DojoComponents: []
47 48 };
48 49 guild.DojoComponents.forEach(dojoComponent => {
49 if (!componentId || componentId == dojoComponent._id) {
50 if (!componentId || dojoComponent._id.equals(componentId)) {
50 51 const clientComponent: IDojoComponentClient = {
51 52 id: toOid(dojoComponent._id),
52 53 pf: dojoComponent.pf,
53 54 ppf: dojoComponent.ppf,
54 55 Name: dojoComponent.Name,
55 56 Message: dojoComponent.Message,
56 DecoCapacity: 600
57 DecoCapacity: dojoComponent.DecoCapacity ?? 600
57 58 };
58 59 if (dojoComponent.pi) {
59 60 clientComponent.pi = toOid(dojoComponent.pi);
@@ -66,6 +67,20 @@ export const getDojoClient = (
66 67 clientComponent.RegularCredits = dojoComponent.RegularCredits;
67 68 clientComponent.MiscItems = dojoComponent.MiscItems;
68 69 }
70 if (dojoComponent.Decos) {
71 clientComponent.Decos = [];
72 for (const deco of dojoComponent.Decos) {
73 clientComponent.Decos.push({
74 id: toOid(deco._id),
75 Type: deco.Type,
76 Pos: deco.Pos,
77 Rot: deco.Rot,
78 CompletionTime: deco.CompletionTime ? toMongoDate(deco.CompletionTime) : undefined,
79 RegularCredits: deco.RegularCredits,
80 MiscItems: deco.MiscItems
81 });
82 }
83 }
69 84 dojo.DojoComponents.push(clientComponent);
70 85 }
71 86 });
@@ -76,3 +91,27 @@ export const scaleRequiredCount = (count: number): number => {
76 91 // The recipes in the export are for Moon clans. For now we'll just assume we only have Ghost clans.
77 92 return Math.max(1, Math.trunc(count / 100));
78 93 };
94
95 export const removeDojoRoom = (guild: TGuildDatabaseDocument, componentId: string): void => {
96 const component = guild.DojoComponents.splice(
97 guild.DojoComponents.findIndex(x => x._id.equals(componentId)),
98 1
99 )[0];
100 const meta = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == component.pf);
101 if (meta) {
102 guild.DojoCapacity -= meta.capacity;
103 guild.DojoEnergy -= meta.energy;
104 }
105 };
106
107 export const removeDojoDeco = (guild: TGuildDatabaseDocument, componentId: string, decoId: string): void => {
108 const component = guild.DojoComponents.id(componentId)!;
109 const deco = component.Decos!.splice(
110 component.Decos!.findIndex(x => x._id.equals(decoId)),
111 1
112 )[0];
113 const meta = Object.values(ExportDojoRecipes.decos).find(x => x.resultType == deco.Type);
114 if (meta && meta.capacityCost) {
115 component.DecoCapacity! += meta.capacityCost;
116 }
117 };
Modified src/types/guildTypes.ts +26 -5
@@ -41,18 +41,33 @@ export interface IDojoComponentClient {
41 41 CompletionTime?: IMongoDate;
42 42 RushPlatinum?: number;
43 43 DestructionTime?: IMongoDate;
44 Decos?: IDojoDecoClient[];
44 45 DecoCapacity?: number;
45 46 }
46 47
47 48 export interface IDojoComponentDatabase
48 extends Omit<
49 IDojoComponentClient,
50 "id" | "pi" | "CompletionTime" | "RushPlatinum" | "DestructionTime" | "DecoCapacity"
51 > {
49 extends Omit<IDojoComponentClient, "id" | "pi" | "CompletionTime" | "RushPlatinum" | "DestructionTime" | "Decos"> {
52 50 _id: Types.ObjectId;
53 51 pi?: Types.ObjectId;
54 52 CompletionTime?: Date;
55 //DestructionTime?: Date;
53 DestructionTime?: Date;
54 Decos?: IDojoDecoDatabase[];
55 }
56
57 export interface IDojoDecoClient {
58 id: IOid;
59 Type: string;
60 Pos: number[];
61 Rot: number[];
62 Name?: string; // for teleporters
63 RegularCredits?: number;
64 MiscItems?: IMiscItem[];
65 CompletionTime?: IMongoDate;
66 }
67
68 export interface IDojoDecoDatabase extends Omit<IDojoDecoClient, "id" | "CompletionTime"> {
69 _id: Types.ObjectId;
70 CompletionTime?: Date;
56 71 }
57 72
58 73 export interface ITechProjectClient {
@@ -66,3 +81,9 @@ export interface ITechProjectClient {
66 81 export interface ITechProjectDatabase extends Omit<ITechProjectClient, "CompletionDate"> {
67 82 CompletionDate?: Date;
68 83 }
84
85 export interface IDojoContributable {
86 RegularCredits?: number;
87 MiscItems?: IMiscItem[];
88 CompletionTime?: Date;
89 }