2025-03-27 03:33:08 -07:00
import { GuildMember , TGuildDatabaseDocument } from "@/src/models/guildModel" ;
2025-03-05 23:54:47 -08:00
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel" ;
2025-03-08 01:44:30 -08:00
import {
getDojoClient ,
getGuildForRequestEx ,
2025-03-14 07:09:28 -07:00
hasAccessToDojo ,
2025-03-08 01:44:30 -08:00
processDojoBuildMaterialsGathered ,
2025-03-14 02:07:08 -07:00
scaleRequiredCount ,
setDojoRoomLogFunded
2025-03-08 01:44:30 -08:00
} from "@/src/services/guildService" ;
2025-03-03 12:48:39 -08:00
import { addMiscItems , getInventory , updateCurrency } from "@/src/services/inventoryService" ;
import { getAccountIdForRequest } from "@/src/services/loginService" ;
2025-03-27 03:33:08 -07:00
import { IDojoContributable , IGuildMemberDatabase } from "@/src/types/guildTypes" ;
2025-03-03 12:48:39 -08:00
import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes" ;
import { IInventoryChanges } from "@/src/types/purchaseTypes" ;
import { RequestHandler } from "express" ;
2025-03-08 01:44:30 -08:00
import { ExportDojoRecipes , IDojoBuild } from "warframe-public-export-plus" ;
2025-03-05 23:54:47 -08:00
interface IContributeToDojoComponentRequest {
ComponentId : string ;
DecoId? : string ;
DecoType? : string ;
2025-03-06 21:24:25 -08:00
IngredientContributions : IMiscItem [ ] ;
2025-03-05 23:54:47 -08:00
RegularCredits : number ;
2025-03-06 21:24:25 -08:00
VaultIngredientContributions : IMiscItem [ ] ;
2025-03-05 23:54:47 -08:00
VaultCredits : number ;
}
2025-03-03 12:48:39 -08:00
export const contributeToDojoComponentController : RequestHandler = async ( req , res ) = > {
const accountId = await getAccountIdForRequest ( req ) ;
const inventory = await getInventory ( accountId ) ;
2025-03-04 08:34:42 +01:00
// 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.
2025-03-14 07:09:28 -07:00
if ( ! hasAccessToDojo ( inventory ) ) {
res . json ( { DojoRequestStatus : - 1 } ) ;
return ;
}
const guild = await getGuildForRequestEx ( req , inventory ) ;
2025-03-27 03:33:08 -07:00
const guildMember = ( await GuildMember . findOne (
{ accountId , guildId : guild._id } ,
"RegularCreditsContributed MiscItemsContributed"
) ) ! ;
2025-03-03 12:48:39 -08:00
const request = JSON . parse ( String ( req . body ) ) as IContributeToDojoComponentRequest ;
const component = guild . DojoComponents . id ( request . ComponentId ) ! ;
2025-03-05 23:54:47 -08:00
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 ) ! ;
2025-03-27 03:33:08 -07:00
processContribution ( guild , guildMember , request , inventory , inventoryChanges , meta , component ) ;
2025-03-14 02:07:08 -07:00
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if ( component . CompletionTime ) {
setDojoRoomLogFunded ( guild , component ) ;
}
2025-03-05 23:54:47 -08:00
} 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 ) ! ;
2025-03-27 03:33:08 -07:00
processContribution ( guild , guildMember , request , inventory , inventoryChanges , meta , deco ) ;
2025-03-05 23:54:47 -08:00
}
}
await guild . save ( ) ;
await inventory . save ( ) ;
2025-03-27 03:33:08 -07:00
await guildMember . save ( ) ;
2025-03-05 23:54:47 -08:00
res . json ( {
2025-03-06 07:19:01 -08:00
. . . ( await getDojoClient ( guild , 0 , component . _id ) ) ,
2025-03-05 23:54:47 -08:00
InventoryChanges : inventoryChanges
} ) ;
} ;
2025-03-06 21:24:25 -08:00
const processContribution = (
2025-03-05 23:54:47 -08:00
guild : TGuildDatabaseDocument ,
2025-03-27 03:33:08 -07:00
guildMember : IGuildMemberDatabase ,
2025-03-05 23:54:47 -08:00
request : IContributeToDojoComponentRequest ,
inventory : TInventoryDatabaseDocument ,
inventoryChanges : IInventoryChanges ,
2025-03-08 01:44:30 -08:00
meta : IDojoBuild ,
2025-03-05 23:54:47 -08:00
component : IDojoContributable
2025-03-06 21:24:25 -08:00
) : void = > {
2025-03-03 12:48:39 -08:00
component . RegularCredits ? ? = 0 ;
2025-03-06 21:24:25 -08:00
if ( request . RegularCredits ) {
component . RegularCredits += request . RegularCredits ;
inventoryChanges . RegularCredits = - request . RegularCredits ;
updateCurrency ( inventory , request . RegularCredits , false ) ;
2025-03-27 03:33:08 -07:00
guildMember . RegularCreditsContributed ? ? = 0 ;
guildMember . RegularCreditsContributed += request . RegularCredits ;
2025-03-06 21:24:25 -08:00
}
if ( request . VaultCredits ) {
component . RegularCredits += request . VaultCredits ;
guild . VaultRegularCredits ! -= request . VaultCredits ;
}
if ( component . RegularCredits > scaleRequiredCount ( meta . price ) ) {
guild . VaultRegularCredits ? ? = 0 ;
guild . VaultRegularCredits += component . RegularCredits - scaleRequiredCount ( meta . price ) ;
component . RegularCredits = scaleRequiredCount ( meta . price ) ;
2025-03-03 12:48:39 -08:00
}
component . MiscItems ? ? = [ ] ;
2025-03-06 21:24:25 -08:00
if ( request . VaultIngredientContributions . length ) {
for ( const ingredientContribution of request . VaultIngredientContributions ) {
const componentMiscItem = component . MiscItems . find ( x = > x . ItemType == ingredientContribution . ItemType ) ;
if ( componentMiscItem ) {
const ingredientMeta = meta . ingredients . find ( x = > x . ItemType == ingredientContribution . ItemType ) ! ;
if (
componentMiscItem . ItemCount + ingredientContribution . ItemCount >
scaleRequiredCount ( ingredientMeta . ItemCount )
) {
ingredientContribution . ItemCount =
scaleRequiredCount ( ingredientMeta . ItemCount ) - componentMiscItem . ItemCount ;
}
componentMiscItem . ItemCount += ingredientContribution . ItemCount ;
} else {
component . MiscItems . push ( ingredientContribution ) ;
}
const vaultMiscItem = guild . VaultMiscItems ! . find ( x = > x . ItemType == ingredientContribution . ItemType ) ! ;
vaultMiscItem . ItemCount -= ingredientContribution . ItemCount ;
}
}
if ( request . IngredientContributions . length ) {
const miscItemChanges : IMiscItem [ ] = [ ] ;
for ( const ingredientContribution of request . IngredientContributions ) {
const componentMiscItem = component . MiscItems . find ( x = > x . ItemType == ingredientContribution . ItemType ) ;
if ( componentMiscItem ) {
const ingredientMeta = meta . ingredients . find ( x = > x . ItemType == ingredientContribution . ItemType ) ! ;
if (
componentMiscItem . ItemCount + ingredientContribution . ItemCount >
scaleRequiredCount ( ingredientMeta . ItemCount )
) {
ingredientContribution . ItemCount =
scaleRequiredCount ( ingredientMeta . ItemCount ) - componentMiscItem . ItemCount ;
}
componentMiscItem . ItemCount += ingredientContribution . ItemCount ;
} else {
component . MiscItems . push ( ingredientContribution ) ;
2025-03-03 12:48:39 -08:00
}
2025-03-06 21:24:25 -08:00
miscItemChanges . push ( {
ItemType : ingredientContribution.ItemType ,
ItemCount : ingredientContribution.ItemCount * - 1
} ) ;
2025-03-27 03:33:08 -07:00
guildMember . MiscItemsContributed ? ? = [ ] ;
guildMember . MiscItemsContributed . push ( ingredientContribution ) ;
2025-03-03 12:48:39 -08:00
}
2025-03-06 21:24:25 -08:00
addMiscItems ( inventory , miscItemChanges ) ;
inventoryChanges . MiscItems = miscItemChanges ;
2025-03-03 12:48:39 -08:00
}
2025-03-05 23:54:47 -08:00
if ( component . RegularCredits >= scaleRequiredCount ( meta . price ) ) {
2025-03-03 12:48:39 -08:00
let fullyFunded = true ;
2025-03-05 23:54:47 -08:00
for ( const ingredient of meta . ingredients ) {
2025-03-03 12:48:39 -08:00
const componentMiscItem = component . MiscItems . find ( x = > x . ItemType == ingredient . ItemType ) ;
if ( ! componentMiscItem || componentMiscItem . ItemCount < scaleRequiredCount ( ingredient . ItemCount ) ) {
fullyFunded = false ;
break ;
}
}
if ( fullyFunded ) {
2025-03-05 23:54:47 -08:00
component . CompletionTime = new Date ( Date . now ( ) + meta . time * 1000 ) ;
2025-03-08 01:44:30 -08:00
processDojoBuildMaterialsGathered ( guild , meta ) ;
2025-03-03 12:48:39 -08:00
}
}
} ;