From a7f252468adbf93387be77063fc17cd91f4a8b1f Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Sun, 30 Mar 2025 13:23:41 +0200 Subject: [PATCH] consider that research may be completed by lowering tier --- .../api/abortDojoComponentController.ts | 2 +- src/controllers/api/guildTechController.ts | 65 +++------------ src/services/guildService.ts | 79 ++++++++++++++++--- 3 files changed, 82 insertions(+), 64 deletions(-) diff --git a/src/controllers/api/abortDojoComponentController.ts b/src/controllers/api/abortDojoComponentController.ts index 0ad1f074..3fcf770c 100644 --- a/src/controllers/api/abortDojoComponentController.ts +++ b/src/controllers/api/abortDojoComponentController.ts @@ -32,7 +32,7 @@ export const abortDojoComponentController: RequestHandler = async (req, res) => if (request.DecoId) { removeDojoDeco(guild, request.ComponentId, request.DecoId); } else { - removeDojoRoom(guild, request.ComponentId); + await removeDojoRoom(guild, request.ComponentId); } await guild.save(); diff --git a/src/controllers/api/guildTechController.ts b/src/controllers/api/guildTechController.ts index ce9ba8e0..35b4d626 100644 --- a/src/controllers/api/guildTechController.ts +++ b/src/controllers/api/guildTechController.ts @@ -4,10 +4,13 @@ import { getGuildVault, hasAccessToDojo, hasGuildPermission, + processFundedGuildTechProject, + processGuildTechProjectContributionsUpdate, removePigmentsFromGuildMembers, - scaleRequiredCount + scaleRequiredCount, + setGuildTechLogState } from "@/src/services/guildService"; -import { ExportDojoRecipes, IDojoResearch } from "warframe-public-export-plus"; +import { ExportDojoRecipes } from "warframe-public-export-plus"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { addItem, @@ -20,8 +23,8 @@ import { import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { config } from "@/src/services/configService"; -import { GuildPermission, ITechProjectClient, ITechProjectDatabase } from "@/src/types/guildTypes"; -import { GuildMember, TGuildDatabaseDocument } from "@/src/models/guildModel"; +import { GuildPermission, ITechProjectClient } from "@/src/types/guildTypes"; +import { GuildMember } from "@/src/models/guildModel"; import { toMongoDate } from "@/src/helpers/inventoryHelpers"; import { logger } from "@/src/utils/logger"; @@ -44,7 +47,7 @@ export const guildTechController: RequestHandler = async (req, res) => { if (project.CompletionDate) { techProject.CompletionDate = toMongoDate(project.CompletionDate); if (Date.now() >= project.CompletionDate.getTime()) { - needSave ||= setTechLogState(guild, project.ItemType, 4, project.CompletionDate); + needSave ||= setGuildTechLogState(guild, project.ItemType, 4, project.CompletionDate); } } techProjects.push(techProject); @@ -74,9 +77,9 @@ export const guildTechController: RequestHandler = async (req, res) => { State: 0 }) - 1 ]; - setTechLogState(guild, techProject.ItemType, 5); + setGuildTechLogState(guild, techProject.ItemType, 5); if (config.noDojoResearchCosts) { - processFundedProject(guild, techProject, recipe); + processFundedGuildTechProject(guild, techProject, recipe); } else { if (data.RecipeType.substring(0, 39) == "/Lotus/Types/Items/Research/DojoColors/") { guild.ActiveDojoColorResearch = data.RecipeType; @@ -151,15 +154,8 @@ export const guildTechController: RequestHandler = async (req, res) => { const inventoryChanges: IInventoryChanges = updateCurrency(inventory, contributions.RegularCredits, false); inventoryChanges.MiscItems = miscItemChanges; - if (techProject.ReqCredits == 0 && !techProject.ReqItems.find(x => x.ItemCount > 0)) { - // This research is now fully funded. - const recipe = ExportDojoRecipes.research[data.RecipeType]; - processFundedProject(guild, techProject, recipe); - if (data.RecipeType.substring(0, 39) == "/Lotus/Types/Items/Research/DojoColors/") { - guild.ActiveDojoColorResearch = ""; - await removePigmentsFromGuildMembers(guild._id); - } - } + // Check if research is fully funded now. + await processGuildTechProjectContributionsUpdate(guild, techProject); await guild.save(); await inventory.save(); @@ -238,43 +234,6 @@ export const guildTechController: RequestHandler = async (req, res) => { } }; -const processFundedProject = ( - guild: TGuildDatabaseDocument, - techProject: ITechProjectDatabase, - recipe: IDojoResearch -): void => { - techProject.State = 1; - techProject.CompletionDate = new Date(Date.now() + (config.noDojoResearchTime ? 0 : recipe.time) * 1000); - if (recipe.guildXpValue) { - guild.XP += recipe.guildXpValue; - } - setTechLogState(guild, techProject.ItemType, config.noDojoResearchTime ? 4 : 3, techProject.CompletionDate); -}; - -const setTechLogState = ( - guild: TGuildDatabaseDocument, - type: string, - state: number, - dateTime: Date | undefined = undefined -): boolean => { - guild.TechChanges ??= []; - const entry = guild.TechChanges.find(x => x.details == type); - if (entry) { - if (entry.entryType == state) { - return false; - } - entry.dateTime = dateTime; - entry.entryType = state; - } else { - guild.TechChanges.push({ - dateTime: dateTime, - entryType: state, - details: type - }); - } - return true; -}; - type TGuildTechRequest = | { Action: "Sync" | "SomethingElseThatWeMightNotKnowAbout" } | IGuildTechBasicRequest diff --git a/src/services/guildService.ts b/src/services/guildService.ts index 8de88d90..4c595afb 100644 --- a/src/services/guildService.ts +++ b/src/services/guildService.ts @@ -13,11 +13,12 @@ import { IGuildClient, IGuildMemberClient, IGuildMemberDatabase, - IGuildVault + IGuildVault, + ITechProjectDatabase } from "@/src/types/guildTypes"; import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; import { Types } from "mongoose"; -import { ExportDojoRecipes, IDojoBuild } from "warframe-public-export-plus"; +import { ExportDojoRecipes, IDojoBuild, IDojoResearch } from "warframe-public-export-plus"; import { logger } from "../utils/logger"; import { config } from "./configService"; import { Account } from "../models/loginModel"; @@ -171,7 +172,7 @@ export const getDojoClient = async ( } if (newTier) { logger.debug(`clan finished building barracks, updating to tier ${newTier}`); - setGuildTier(guild, newTier); + await setGuildTier(guild, newTier); needSave = true; } } @@ -211,7 +212,7 @@ export const getDojoClient = async ( if (roomsToRemove.length) { logger.debug(`removing now-destroyed rooms`, roomsToRemove); for (const id of roomsToRemove) { - removeDojoRoom(guild, id); + await removeDojoRoom(guild, id); } needSave = true; } @@ -227,7 +228,10 @@ export const scaleRequiredCount = (tier: number, count: number): number => { return Math.max(1, Math.trunc(count * guildTierScalingFactors[tier - 1])); }; -export const removeDojoRoom = (guild: TGuildDatabaseDocument, componentId: Types.ObjectId | string): void => { +export const removeDojoRoom = async ( + guild: TGuildDatabaseDocument, + componentId: Types.ObjectId | string +): Promise => { const component = guild.DojoComponents.splice( guild.DojoComponents.findIndex(x => x._id.equals(componentId)), 1 @@ -249,16 +253,16 @@ export const removeDojoRoom = (guild: TGuildDatabaseDocument, componentId: Types switch (component.pf) { case "/Lotus/Levels/ClanDojo/ClanDojoBarracksShadow.level": - setGuildTier(guild, 1); + await setGuildTier(guild, 1); break; case "/Lotus/Levels/ClanDojo/ClanDojoBarracksStorm.level": - setGuildTier(guild, 2); + await setGuildTier(guild, 2); break; case "/Lotus/Levels/ClanDojo/ClanDojoBarracksMountain.level": - setGuildTier(guild, 3); + await setGuildTier(guild, 3); break; case "/Lotus/Levels/ClanDojo/ClanDojoBarracksMoon.level": - setGuildTier(guild, 4); + await setGuildTier(guild, 4); break; } }; @@ -404,7 +408,59 @@ export const removePigmentsFromGuildMembers = async (guildId: string | Types.Obj } }; -const setGuildTier = (guild: TGuildDatabaseDocument, newTier: number): void => { +export const processGuildTechProjectContributionsUpdate = async ( + guild: TGuildDatabaseDocument, + techProject: ITechProjectDatabase +): Promise => { + if (techProject.ReqCredits == 0 && !techProject.ReqItems.find(x => x.ItemCount > 0)) { + // This research is now fully funded. + const recipe = ExportDojoRecipes.research[techProject.ItemType]; + processFundedGuildTechProject(guild, techProject, recipe); + if (techProject.ItemType.substring(0, 39) == "/Lotus/Types/Items/Research/DojoColors/") { + guild.ActiveDojoColorResearch = ""; + await removePigmentsFromGuildMembers(guild._id); + } + } +}; + +export const processFundedGuildTechProject = ( + guild: TGuildDatabaseDocument, + techProject: ITechProjectDatabase, + recipe: IDojoResearch +): void => { + techProject.State = 1; + techProject.CompletionDate = new Date(Date.now() + (config.noDojoResearchTime ? 0 : recipe.time) * 1000); + if (recipe.guildXpValue) { + guild.XP += recipe.guildXpValue; + } + setGuildTechLogState(guild, techProject.ItemType, config.noDojoResearchTime ? 4 : 3, techProject.CompletionDate); +}; + +export const setGuildTechLogState = ( + guild: TGuildDatabaseDocument, + type: string, + state: number, + dateTime: Date | undefined = undefined +): boolean => { + guild.TechChanges ??= []; + const entry = guild.TechChanges.find(x => x.details == type); + if (entry) { + if (entry.entryType == state) { + return false; + } + entry.dateTime = dateTime; + entry.entryType = state; + } else { + guild.TechChanges.push({ + dateTime: dateTime, + entryType: state, + details: type + }); + } + return true; +}; + +const setGuildTier = async (guild: TGuildDatabaseDocument, newTier: number): Promise => { const oldTier = guild.Tier; guild.Tier = newTier; if (guild.TechProjects) { @@ -436,6 +492,9 @@ const setGuildTier = (guild: TGuildDatabaseDocument, newTier: number): void => { project.ReqItems[i].ItemCount = 0; } } + + // Check if research is fully funded now due to lowered requirements. + await processGuildTechProjectContributionsUpdate(guild, project); } } };