From 80e00b8825a51e0229c6f100429ea739c27bd239 Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 3 Jan 2025 00:48:54 +0100 Subject: [PATCH 1/7] fix: consume resources when installing incarnon genesis (#687) --- src/controllers/api/evolveWeaponController.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/controllers/api/evolveWeaponController.ts b/src/controllers/api/evolveWeaponController.ts index ffeab90c..e20ffa8d 100644 --- a/src/controllers/api/evolveWeaponController.ts +++ b/src/controllers/api/evolveWeaponController.ts @@ -1,8 +1,8 @@ import { RequestHandler } from "express"; import { getAccountIdForRequest } from "@/src/services/loginService"; -import { getInventory } from "@/src/services/inventoryService"; +import { addMiscItems, getInventory } from "@/src/services/inventoryService"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; -import { WeaponTypeInternal } from "@/src/services/itemDataService"; +import { getRecipe, WeaponTypeInternal } from "@/src/services/itemDataService"; import { EquipmentFeatures } from "@/src/types/inventoryTypes/commonInventoryTypes"; export const evolveWeaponController: RequestHandler = async (req, res) => { @@ -11,7 +11,11 @@ export const evolveWeaponController: RequestHandler = async (req, res) => { const payload = getJSONfromString(String(req.body)) as IEvolveWeaponRequest; console.assert(payload.Action == "EWA_INSTALL"); - // TODO: We should remove the Genesis item & its resources, but currently we don't know these "recipes". + const recipe = getRecipe(payload.Recipe)!; + addMiscItems( + inventory, + recipe.ingredients.map(x => ({ ItemType: x.ItemType, ItemCount: x.ItemCount * -1 })) + ); const item = inventory[payload.Category].find(item => item._id.toString() == (req.query.ItemId as string))!; item.Features ??= 0; From ff4b1e5c29a4cb23cbd173b4ab99d7d45fdadbb1 Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 3 Jan 2025 00:49:18 +0100 Subject: [PATCH 2/7] fix: enable completeAllQuests in default/example config (#684) --- config.json.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json.example b/config.json.example index 2f8582bf..100dc42d 100644 --- a/config.json.example +++ b/config.json.example @@ -14,7 +14,7 @@ "unlockAllScans": true, "unlockAllMissions": true, "unlockAllQuests": true, - "completeAllQuests": false, + "completeAllQuests": true, "infiniteCredits": true, "infinitePlatinum": true, "unlockAllShipFeatures": true, From f1c0c5a4297affdc1f013aa02486887f2c6fd141 Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 3 Jan 2025 05:22:56 +0100 Subject: [PATCH 3/7] feat: subsuming warframes (#686) --- .../api/infestedFoundryController.ts | 97 ++++++++++++++++++- src/controllers/api/inventoryController.ts | 12 ++- src/models/inventoryModels/inventoryModel.ts | 24 ++++- src/types/inventoryTypes/inventoryTypes.ts | 7 +- 4 files changed, 130 insertions(+), 10 deletions(-) diff --git a/src/controllers/api/infestedFoundryController.ts b/src/controllers/api/infestedFoundryController.ts index b819cf47..a01ae16b 100644 --- a/src/controllers/api/infestedFoundryController.ts +++ b/src/controllers/api/infestedFoundryController.ts @@ -1,10 +1,17 @@ import { RequestHandler } from "express"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; -import { getInventory, addMiscItems } from "@/src/services/inventoryService"; +import { getInventory, addMiscItems, updateCurrency, addRecipes } from "@/src/services/inventoryService"; import { IOid } from "@/src/types/commonTypes"; -import { IInfestedFoundry, IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes"; -import { ExportMisc } from "warframe-public-export-plus"; +import { + IConsumedSuit, + IInfestedFoundry, + IInventoryDatabaseDocument, + IMiscItem, + ITypeCount +} from "@/src/types/inventoryTypes/inventoryTypes"; +import { ExportMisc, ExportRecipes } from "warframe-public-export-plus"; +import { getRecipe } from "@/src/services/itemDataService"; export const infestedFoundryController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); @@ -110,6 +117,67 @@ export const infestedFoundryController: RequestHandler = async (req, res) => { res.status(404).end(); break; + case "a": { + // subsume warframe + const request = getJSONfromString(String(req.body)) as IHelminthSubsumeRequest; + const inventory = await getInventory(accountId); + const recipe = getRecipe(request.Recipe)!; + for (const ingredient of recipe.secretIngredients!) { + const resource = inventory.InfestedFoundry!.Resources!.find(x => x.ItemType == ingredient.ItemType); + if (resource) { + resource.Count -= ingredient.ItemCount; + } + } + const suit = inventory.Suits.find(x => x._id.toString() == request.SuitId.$oid)!; + inventory.Suits.pull(suit); + const consumedSuit: IConsumedSuit = { s: suit.ItemType }; + if (suit.Configs && suit.Configs[0] && suit.Configs[0].pricol) { + consumedSuit.c = suit.Configs[0].pricol; + } + inventory.InfestedFoundry!.Slots!--; + inventory.InfestedFoundry!.ConsumedSuits ??= []; + inventory.InfestedFoundry!.ConsumedSuits?.push(consumedSuit); + inventory.InfestedFoundry!.LastConsumedSuit = suit; + inventory.InfestedFoundry!.AbilityOverrideUnlockCooldown = new Date( + new Date().getTime() + 24 * 60 * 60 * 1000 + ); + addInfestedFoundryXP(inventory.InfestedFoundry!, 1600_00); + await inventory.save(); + console.log(inventory.toJSON().InfestedFoundry); + res.json({ + InventoryChanges: { + RemovedIdItems: [ + { + ItemId: request.SuitId + } + ], + SuitBin: { + count: -1, + platinum: 0, + Slots: 1 + }, + InfestedFoundry: inventory.toJSON().InfestedFoundry + } + }); + break; + } + + case "r": { + // rush subsume + const inventory = await getInventory(accountId); + const currencyChanges = updateCurrency(inventory, 50, true); + const recipeChanges = handleSubsumeCompletion(inventory); + await inventory.save(); + res.json({ + InventoryChanges: { + ...currencyChanges, + Recipes: recipeChanges, + InfestedFoundry: inventory.toJSON().InfestedFoundry + } + }); + break; + } + default: throw new Error(`unhandled infestedFoundry mode: ${String(req.query.mode)}`); } @@ -165,3 +233,26 @@ const addInfestedFoundryXP = (infestedFoundry: IInfestedFoundry, delta: number): infestedFoundry.Slots += 20; } }; + +interface IHelminthSubsumeRequest { + SuitId: IOid; + Recipe: string; +} + +export const handleSubsumeCompletion = (inventory: IInventoryDatabaseDocument): ITypeCount[] => { + const [recipeType] = Object.entries(ExportRecipes).find( + ([_recipeType, recipe]) => + recipe.secretIngredientAction == "SIA_WARFRAME_ABILITY" && + recipe.secretIngredients![0].ItemType == inventory.InfestedFoundry!.LastConsumedSuit!.ItemType + )!; + inventory.InfestedFoundry!.LastConsumedSuit = undefined; + inventory.InfestedFoundry!.AbilityOverrideUnlockCooldown = undefined; + const recipeChanges: ITypeCount[] = [ + { + ItemType: recipeType, + ItemCount: 1 + } + ]; + addRecipes(inventory, recipeChanges); + return recipeChanges; +}; diff --git a/src/controllers/api/inventoryController.ts b/src/controllers/api/inventoryController.ts index 59b3af5c..f38fe0ec 100644 --- a/src/controllers/api/inventoryController.ts +++ b/src/controllers/api/inventoryController.ts @@ -5,7 +5,7 @@ import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { config } from "@/src/services/configService"; import allDialogue from "@/static/fixed_responses/allDialogue.json"; import { ILoadoutDatabase } from "@/src/types/saveLoadoutTypes"; -import { IShipInventory, equipmentKeys } from "@/src/types/inventoryTypes/inventoryTypes"; +import { IInventoryDatabaseDocument, IShipInventory, equipmentKeys } from "@/src/types/inventoryTypes/inventoryTypes"; import { IPolarity, ArtifactPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { ExportCustoms, @@ -15,6 +15,7 @@ import { ExportResources, ExportVirtuals } from "warframe-public-export-plus"; +import { handleSubsumeCompletion } from "./infestedFoundryController"; export const inventoryController: RequestHandler = async (request, response) => { let account; @@ -57,6 +58,15 @@ export const inventoryController: RequestHandler = async (request, response) => await inventory.save(); } + if ( + inventory.InfestedFoundry && + inventory.InfestedFoundry.AbilityOverrideUnlockCooldown && + new Date() >= inventory.InfestedFoundry.AbilityOverrideUnlockCooldown + ) { + handleSubsumeCompletion(inventory as unknown as IInventoryDatabaseDocument); + await inventory.save(); + } + //TODO: make a function that converts from database representation to client const inventoryJSON = inventory.toJSON(); diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index 5e5a1680..ee2b7a88 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -459,10 +459,13 @@ const settingsSchema = new Schema({ TradingRulesConfirmed: Boolean }); -const consumedSchuitsSchema = new Schema({ - s: String, - c: colorSchema -}); +const consumedSchuitsSchema = new Schema( + { + s: String, + c: colorSchema + }, + { _id: false } +); const helminthResourceSchema = new Schema({ ItemType: String, Count: Number }, { _id: false }); @@ -475,11 +478,22 @@ const infestedFoundrySchema = new Schema( ConsumedSuits: { type: [consumedSchuitsSchema], default: undefined }, InvigorationIndex: Number, InvigorationSuitOfferings: { type: [String], default: undefined }, - InvigorationsApplied: Number + InvigorationsApplied: Number, + LastConsumedSuit: { type: EquipmentSchema, default: undefined }, + AbilityOverrideUnlockCooldown: Date }, { _id: false } ); +infestedFoundrySchema.set("toJSON", { + transform(_doc, ret, _options) { + if (ret.AbilityOverrideUnlockCooldown) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + ret.AbilityOverrideUnlockCooldown = toMongoDate(ret.AbilityOverrideUnlockCooldown); + } + } +}); + const questProgressSchema = new Schema({ c: Number, i: Boolean, diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index 94a46650..d4f33cf9 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -518,10 +518,13 @@ export interface IFusionTreasure { Sockets: number; } -// Like ITypeCount except 'Count' instead of 'ItemCount' export interface IHelminthResource { ItemType: string; Count: number; + RecentlyConvertedResources?: { + ItemType: string; + Date: number; + }[]; } export interface IInfestedFoundry { @@ -533,6 +536,8 @@ export interface IInfestedFoundry { InvigorationIndex?: number; InvigorationSuitOfferings?: string[]; InvigorationsApplied?: number; + LastConsumedSuit?: IEquipmentDatabase; + AbilityOverrideUnlockCooldown?: Date; } export interface IConsumedSuit { From c80dd1bbd0239021aa66d53814dd7cb1231bfda0 Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 3 Jan 2025 09:06:34 +0100 Subject: [PATCH 4/7] feat: remove incarnon (#688) --- src/controllers/api/evolveWeaponController.ts | 47 ++++++++++++------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/src/controllers/api/evolveWeaponController.ts b/src/controllers/api/evolveWeaponController.ts index e20ffa8d..3e70922c 100644 --- a/src/controllers/api/evolveWeaponController.ts +++ b/src/controllers/api/evolveWeaponController.ts @@ -9,27 +9,40 @@ export const evolveWeaponController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); const inventory = await getInventory(accountId); const payload = getJSONfromString(String(req.body)) as IEvolveWeaponRequest; - console.assert(payload.Action == "EWA_INSTALL"); const recipe = getRecipe(payload.Recipe)!; - addMiscItems( - inventory, - recipe.ingredients.map(x => ({ ItemType: x.ItemType, ItemCount: x.ItemCount * -1 })) - ); + if (payload.Action == "EWA_INSTALL") { + addMiscItems( + inventory, + recipe.ingredients.map(x => ({ ItemType: x.ItemType, ItemCount: x.ItemCount * -1 })) + ); - const item = inventory[payload.Category].find(item => item._id.toString() == (req.query.ItemId as string))!; - item.Features ??= 0; - item.Features |= EquipmentFeatures.INCARNON_GENESIS; + const item = inventory[payload.Category].find(item => item._id.toString() == (req.query.ItemId as string))!; + item.Features ??= 0; + item.Features |= EquipmentFeatures.INCARNON_GENESIS; - item.SkillTree = "0"; + item.SkillTree = "0"; - inventory.EvolutionProgress ??= []; - if (!inventory.EvolutionProgress.find(entry => entry.ItemType == payload.EvoType)) { - inventory.EvolutionProgress.push({ - Progress: 0, - Rank: 1, - ItemType: payload.EvoType - }); + inventory.EvolutionProgress ??= []; + if (!inventory.EvolutionProgress.find(entry => entry.ItemType == payload.EvoType)) { + inventory.EvolutionProgress.push({ + Progress: 0, + Rank: 1, + ItemType: payload.EvoType + }); + } + } else if (payload.Action == "EWA_UNINSTALL") { + addMiscItems(inventory, [ + { + ItemType: recipe.resultType, + ItemCount: 1 + } + ]); + + const item = inventory[payload.Category].find(item => item._id.toString() == (req.query.ItemId as string))!; + item.Features! &= ~EquipmentFeatures.INCARNON_GENESIS; + } else { + throw new Error(`unexpected evolve weapon action: ${payload.Action}`); } await inventory.save(); @@ -37,7 +50,7 @@ export const evolveWeaponController: RequestHandler = async (req, res) => { }; interface IEvolveWeaponRequest { - Action: "EWA_INSTALL"; + Action: string; Category: WeaponTypeInternal; Recipe: string; // e.g. "/Lotus/Types/Items/MiscItems/IncarnonAdapters/UnlockerBlueprints/DespairIncarnonBlueprint" UninstallRecipe: ""; From e0ff240d605f5d4951acd5f011c1c097df2113d7 Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 3 Jan 2025 09:06:50 +0100 Subject: [PATCH 5/7] feat: dojo research (#689) --- src/controllers/api/createGuildController.ts | 7 +- src/controllers/api/guildTechController.ts | 99 +++++++++++++++++++- src/models/guildModel.ts | 34 ++++++- src/models/inventoryModels/inventoryModel.ts | 2 +- src/services/guildService.ts | 7 +- src/types/guildTypes.ts | 17 +++- src/types/inventoryTypes/inventoryTypes.ts | 5 +- 7 files changed, 154 insertions(+), 17 deletions(-) diff --git a/src/controllers/api/createGuildController.ts b/src/controllers/api/createGuildController.ts index 2e73d7a2..2c698995 100644 --- a/src/controllers/api/createGuildController.ts +++ b/src/controllers/api/createGuildController.ts @@ -3,9 +3,8 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { Guild } from "@/src/models/guildModel"; -import { ICreateGuildRequest } from "@/src/types/guildTypes"; -const createGuildController: RequestHandler = async (req, res) => { +export const createGuildController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); const payload = getJSONfromString(String(req.body)) as ICreateGuildRequest; @@ -34,4 +33,6 @@ const createGuildController: RequestHandler = async (req, res) => { res.json(guild); }; -export { createGuildController }; +interface ICreateGuildRequest { + guildName: string; +} diff --git a/src/controllers/api/guildTechController.ts b/src/controllers/api/guildTechController.ts index 9e4243da..7d27267b 100644 --- a/src/controllers/api/guildTechController.ts +++ b/src/controllers/api/guildTechController.ts @@ -1,5 +1,100 @@ import { RequestHandler } from "express"; +import { getGuildForRequestEx } from "@/src/services/guildService"; +import { ExportDojoRecipes } from "warframe-public-export-plus"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { addMiscItems, getInventory, updateCurrency } from "@/src/services/inventoryService"; +import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes"; +import { IInventoryChanges } from "@/src/types/purchaseTypes"; -export const guildTechController: RequestHandler = (_req, res) => { - res.status(500).end(); // This is what I got for a fresh clan. +export const guildTechController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const inventory = await getInventory(accountId); + const guild = await getGuildForRequestEx(req, inventory); + const data = JSON.parse(String(req.body)) as TGuildTechRequest; + if (data.Action == "Sync") { + res.json({ + TechProjects: guild.toJSON().TechProjects + }); + } else if (data.Action == "Start") { + const recipe = ExportDojoRecipes.research[data.RecipeType!]; + guild.TechProjects ??= []; + if (!guild.TechProjects.find(x => x.ItemType == data.RecipeType)) { + guild.TechProjects.push({ + ItemType: data.RecipeType!, + ReqCredits: scaleRequiredCount(recipe.price), + ReqItems: recipe.ingredients.map(x => ({ + ItemType: x.ItemType, + ItemCount: scaleRequiredCount(x.ItemCount) + })), + State: 0 + }); + } + await guild.save(); + res.end(); + } else if (data.Action == "Contribute") { + const contributions = data as IGuildTechContributeFields; + const techProject = guild.TechProjects!.find(x => x.ItemType == contributions.RecipeType)!; + if (contributions.RegularCredits > techProject.ReqCredits) { + contributions.RegularCredits = techProject.ReqCredits; + } + techProject.ReqCredits -= contributions.RegularCredits; + const miscItemChanges = []; + for (const miscItem of contributions.MiscItems) { + const reqItem = techProject.ReqItems.find(x => x.ItemType == miscItem.ItemType); + if (reqItem) { + if (miscItem.ItemCount > reqItem.ItemCount) { + miscItem.ItemCount = reqItem.ItemCount; + } + reqItem.ItemCount -= miscItem.ItemCount; + miscItemChanges.push({ + ItemType: miscItem.ItemType, + ItemCount: miscItem.ItemCount * -1 + }); + } + } + addMiscItems(inventory, miscItemChanges); + const inventoryChanges: IInventoryChanges = { + ...updateCurrency(inventory, contributions.RegularCredits, false), + MiscItems: miscItemChanges + }; + + if (techProject.ReqCredits == 0 && !techProject.ReqItems.find(x => x.ItemCount > 0)) { + // This research is now fully funded. + techProject.State = 1; + const recipe = ExportDojoRecipes.research[data.RecipeType!]; + techProject.CompletionDate = new Date(new Date().getTime() + recipe.time * 1000); + } + + await guild.save(); + await inventory.save(); + res.json({ + InventoryChanges: inventoryChanges + }); + } else { + throw new Error(`unknown guildTech action: ${data.Action}`); + } +}; + +type TGuildTechRequest = { + Action: string; +} & Partial & + Partial; + +interface IGuildTechStartFields { + Mode: "Guild"; + RecipeType: string; +} + +interface IGuildTechContributeFields { + ResearchId: ""; + RecipeType: string; + RegularCredits: number; + MiscItems: IMiscItem[]; + VaultCredits: number; + VaultMiscItems: IMiscItem[]; +} + +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)); }; diff --git a/src/models/guildModel.ts b/src/models/guildModel.ts index 22269ec8..ab87e719 100644 --- a/src/models/guildModel.ts +++ b/src/models/guildModel.ts @@ -1,5 +1,12 @@ -import { IGuildDatabase, IDojoComponentDatabase } from "@/src/types/guildTypes"; +import { + IGuildDatabase, + IDojoComponentDatabase, + ITechProjectDatabase, + ITechProjectClient +} from "@/src/types/guildTypes"; import { model, Schema } from "mongoose"; +import { typeCountSchema } from "./inventoryModels/inventoryModel"; +import { toMongoDate } from "../helpers/inventoryHelpers"; const dojoComponentSchema = new Schema({ pf: { type: String, required: true }, @@ -10,12 +17,35 @@ const dojoComponentSchema = new Schema({ CompletionTime: Date }); +const techProjectSchema = new Schema( + { + ItemType: String, + ReqCredits: Number, + ReqItems: [typeCountSchema], + State: Number, + CompletionDate: Date + }, + { _id: false } +); + +techProjectSchema.set("toJSON", { + virtuals: true, + transform(_doc, obj) { + const db = obj as ITechProjectDatabase; + const client = obj as ITechProjectClient; + if (db.CompletionDate) { + client.CompletionDate = toMongoDate(db.CompletionDate); + } + } +}); + const guildSchema = new Schema( { Name: { type: String, required: true }, DojoComponents: [dojoComponentSchema], DojoCapacity: { type: Number, default: 100 }, - DojoEnergy: { type: Number, default: 5 } + DojoEnergy: { type: Number, default: 5 }, + TechProjects: { type: [techProjectSchema], default: undefined } }, { id: false } ); diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index ee2b7a88..37a674c2 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -61,7 +61,7 @@ import { import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; import { EquipmentSelectionSchema } from "./loadoutModel"; -const typeCountSchema = new Schema({ ItemType: String, ItemCount: Number }, { _id: false }); +export const typeCountSchema = new Schema({ ItemType: String, ItemCount: Number }, { _id: false }); const focusXPSchema = new Schema( { diff --git a/src/services/guildService.ts b/src/services/guildService.ts index 35b697fc..dda01ef8 100644 --- a/src/services/guildService.ts +++ b/src/services/guildService.ts @@ -2,17 +2,22 @@ import { Request } from "express"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { getInventory } from "@/src/services/inventoryService"; import { Guild } from "@/src/models/guildModel"; +import { IInventoryDatabaseDocument } from "../types/inventoryTypes/inventoryTypes"; export const getGuildForRequest = async (req: Request) => { const accountId = await getAccountIdForRequest(req); const inventory = await getInventory(accountId); + return await getGuildForRequestEx(req, inventory); +}; + +export const getGuildForRequestEx = async (req: Request, inventory: IInventoryDatabaseDocument) => { const guildId = req.query.guildId as string; if (!inventory.GuildId || inventory.GuildId.toString() != guildId) { throw new Error("Account is not in the guild that it has sent a request for"); } const guild = await Guild.findOne({ _id: guildId }); if (!guild) { - throw new Error("Account thinks it is a in guild that doesn't exist"); + throw new Error("Account thinks it is in a guild that doesn't exist"); } return guild; }; diff --git a/src/types/guildTypes.ts b/src/types/guildTypes.ts index 54f87c98..1778582f 100644 --- a/src/types/guildTypes.ts +++ b/src/types/guildTypes.ts @@ -11,10 +11,7 @@ export interface IGuildDatabase extends IGuild { DojoComponents?: IDojoComponentDatabase[]; DojoCapacity: number; DojoEnergy: number; -} - -export interface ICreateGuildRequest { - guildName: string; + TechProjects?: ITechProjectDatabase[]; } export interface IDojoClient { @@ -49,3 +46,15 @@ export interface IDojoComponentDatabase pi?: Types.ObjectId; CompletionTime?: Date; } + +export interface ITechProjectClient { + ItemType: string; + ReqCredits: number; + ReqItems: IMiscItem[]; + State: number; // 0 = pending, 1 = complete + CompletionDate?: IMongoDate; +} + +export interface ITechProjectDatabase extends Omit { + CompletionDate?: Date; +} diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index d4f33cf9..d608a232 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -460,10 +460,7 @@ export interface IFlavourItem { ItemType: string; } -export interface IMiscItem { - ItemCount: number; - ItemType: string; -} +export type IMiscItem = ITypeCount; export interface ICrewShipWeapon { PILOT: ICrewShipPilotWeapon; From 0523fbdaae8da608cf110e7d8680776bc71f8f22 Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 3 Jan 2025 09:09:53 +0100 Subject: [PATCH 6/7] fix: add missing kitgun types for primaries (#694) --- src/controllers/api/modularWeaponCraftingController.ts | 4 ++++ static/webui/script.js | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/controllers/api/modularWeaponCraftingController.ts b/src/controllers/api/modularWeaponCraftingController.ts index f77fc7d9..8d2f83d9 100644 --- a/src/controllers/api/modularWeaponCraftingController.ts +++ b/src/controllers/api/modularWeaponCraftingController.ts @@ -5,7 +5,11 @@ import { TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; import { getInventory, updateCurrency, addEquipment, addMiscItems } from "@/src/services/inventoryService"; const modularWeaponTypes: Record = { + "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimary": "LongGuns", "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimaryBeam": "LongGuns", + "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimaryLauncher": "LongGuns", + "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimaryShotgun": "LongGuns", + "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimarySniper": "LongGuns", "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondary": "Pistols", "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryBeam": "Pistols", "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryShotgun": "Pistols", diff --git a/static/webui/script.js b/static/webui/script.js index 367fbceb..160ccfae 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -140,7 +140,11 @@ function fetchItemList() { "/Lotus/Weapons/Tenno/Rifle/LotusRifle": { name: "Rifle" }, "/Lotus/Weapons/Tenno/Shotgun/LotusShotgun": { name: "Shotgun" }, // Modular weapons + "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimary": { name: "Kitgun" }, "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimaryBeam": { name: "Kitgun" }, + "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimaryLauncher": { name: "Kitgun" }, + "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimaryShotgun": { name: "Kitgun" }, + "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimarySniper": { name: "Kitgun" }, "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondary": { name: "Kitgun" }, "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryBeam": { name: "Kitgun" }, "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryShotgun": { name: "Kitgun" }, From 69734ea101ba9cc1de2c208f5a76c6a56ca30e04 Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 3 Jan 2025 09:19:06 +0100 Subject: [PATCH 7/7] fix: don't say "error" just because a loadout category is unimplemented (#692) --- src/services/saveLoadoutService.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/services/saveLoadoutService.ts b/src/services/saveLoadoutService.ts index 3282b8dd..a50b1434 100644 --- a/src/services/saveLoadoutService.ts +++ b/src/services/saveLoadoutService.ts @@ -178,7 +178,9 @@ export const handleInventoryItemConfigChange = async ( break; } default: { - logger.error(`category not implemented: ${equipmentName}`, { config: equipment }); + logger.warn(`loadout category not implemented, changes may be lost: ${equipmentName}`, { + config: equipment + }); } //case "KahlLoadOuts": not sure yet how to handle kahl: it is not sent in inventory }