consider that research may be completed by lowering tier
All checks were successful
Build / build (18) (push) Successful in 1m18s
Build / build (22) (push) Successful in 1m21s
Build / build (22) (pull_request) Successful in 1m22s
Build / build (20) (push) Successful in 44s
Build / build (18) (pull_request) Successful in 45s
Build / build (20) (pull_request) Successful in 1m14s

This commit is contained in:
Sainan 2025-03-30 13:23:41 +02:00
parent fec842f4f9
commit a7f252468a
3 changed files with 82 additions and 64 deletions

View File

@ -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();

View File

@ -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

View File

@ -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<void> => {
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<void> => {
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<void> => {
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);
}
}
};