Cultist circle expansion:

Added reward blacklist
Added itemrewardblacklist in cultist reward calculation
Added reward pool expansion
This commit is contained in:
Dev 2024-09-03 09:58:13 +01:00
parent 7de0a112dc
commit c3bd6e05b6
3 changed files with 48 additions and 7 deletions

View File

@ -22,6 +22,8 @@
"655c669103999d3c810c025b": ["635267ab3c89e2112001f826"], "655c669103999d3c810c025b": ["635267ab3c89e2112001f826"],
"66572cbdad599021091c611a": ["60a7ad2a2198820d95707a2e"], "66572cbdad599021091c611a": ["60a7ad2a2198820d95707a2e"],
"5c0530ee86f774697952d952": ["6389c8c5dbfd5e4b95197e6b"] "5c0530ee86f774697952d952": ["6389c8c5dbfd5e4b95197e6b"]
} },
"rewardItemBlacklist": [],
"rewardItemAdditionalRewards": []
} }
} }

View File

@ -20,5 +20,10 @@ export interface ICultistCircleSettings {
maxRewardItemCount: number; maxRewardItemCount: number;
maxAttemptsToPickRewardsWithinBudget: number; maxAttemptsToPickRewardsWithinBudget: number;
rewardPriceMultiplerMinMax: MinMax; rewardPriceMultiplerMinMax: MinMax;
/** Specific reward pool when player sacrificed one specific item */
directRewards: Record<string, string[]>; directRewards: Record<string, string[]>;
/** Item tpls to exclude from the reward pool */
rewardItemBlacklist: string[];
/** Item tpls to include in the reward pool */
additionalRewardItemPool: string[];
} }

View File

@ -18,11 +18,12 @@ import { IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig";
import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ILogger } from "@spt/models/spt/utils/ILogger";
import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder";
import { ConfigServer } from "@spt/servers/ConfigServer"; import { ConfigServer } from "@spt/servers/ConfigServer";
import { DatabaseService } from "@spt/services/DatabaseService";
import { ItemFilterService } from "@spt/services/ItemFilterService";
import { HashUtil } from "@spt/utils/HashUtil"; import { HashUtil } from "@spt/utils/HashUtil";
import { RandomUtil } from "@spt/utils/RandomUtil"; import { RandomUtil } from "@spt/utils/RandomUtil";
import { ICloner } from "@spt/utils/cloners/ICloner"; import { ICloner } from "@spt/utils/cloners/ICloner";
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { DatabaseService } from "./DatabaseService";
@injectable() @injectable()
export class CircleOfCultistService { export class CircleOfCultistService {
@ -41,6 +42,7 @@ export class CircleOfCultistService {
@inject("InventoryHelper") protected inventoryHelper: InventoryHelper, @inject("InventoryHelper") protected inventoryHelper: InventoryHelper,
@inject("HideoutHelper") protected hideoutHelper: HideoutHelper, @inject("HideoutHelper") protected hideoutHelper: HideoutHelper,
@inject("DatabaseService") protected databaseService: DatabaseService, @inject("DatabaseService") protected databaseService: DatabaseService,
@inject("ItemFilterService") protected itemFilterService: ItemFilterService,
@inject("ConfigServer") protected configServer: ConfigServer, @inject("ConfigServer") protected configServer: ConfigServer,
) { ) {
this.hideoutConfig = this.configServer.getConfig(ConfigTypes.HIDEOUT); this.hideoutConfig = this.configServer.getConfig(ConfigTypes.HIDEOUT);
@ -321,14 +323,22 @@ export class CircleOfCultistService {
/** /**
* Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas
* @param sessionId Session id * @param sessionId Session id
* @param pmcData Player profile * @param pmcData Profile of player who will be getting the rewards
* @returns Array of tpls * @returns Array of tpls
*/ */
protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[] { protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[] {
const rewardPool = new Set<string>(); const rewardPool = new Set<string>();
const cultistCircleConfig = this.hideoutConfig.cultistCircle;
const hideoutDbData = this.databaseService.getHideout();
// Merge reward item blacklist with cultist circle blacklist from config
const itemRewardBlacklist = [
...this.itemFilterService.getItemRewardBlacklist(),
...cultistCircleConfig.rewardItemBlacklist,
];
// What does player need to upgrade hideout areas // What does player need to upgrade hideout areas
const dbAreas = this.databaseService.getHideout().areas; const dbAreas = hideoutDbData.areas;
for (const area of pmcData.Hideout.Areas) { for (const area of pmcData.Hideout.Areas) {
const currentStageLevel = area.level; const currentStageLevel = area.level;
const areaType = area.type; const areaType = area.type;
@ -340,14 +350,18 @@ export class CircleOfCultistService {
// Next stage exists, gather up requirements and add to pool // Next stage exists, gather up requirements and add to pool
const itemRequirements = this.getItemRequirements(nextStageDbData.requirements); const itemRequirements = this.getItemRequirements(nextStageDbData.requirements);
for (const rewardToAdd of itemRequirements) { for (const rewardToAdd of itemRequirements) {
if (!itemRewardBlacklist.includes(rewardToAdd.templateId)) {
continue;
}
rewardPool.add(rewardToAdd.templateId); rewardPool.add(rewardToAdd.templateId);
} }
} }
} }
// What does player need to craft items with // What does player need to start crafts with
const playerUnlockedRecipes = pmcData.UnlockedInfo.unlockedProductionRecipe; const playerUnlockedRecipes = pmcData.UnlockedInfo.unlockedProductionRecipe;
const allRecipes = this.databaseService.getHideout().production; const allRecipes = hideoutDbData.production;
// Get default unlocked recipes + locked recipes they've unlocked // Get default unlocked recipes + locked recipes they've unlocked
const playerAccessibleRecipes = allRecipes.recipes.filter( const playerAccessibleRecipes = allRecipes.recipes.filter(
@ -356,6 +370,10 @@ export class CircleOfCultistService {
for (const recipe of playerAccessibleRecipes) { for (const recipe of playerAccessibleRecipes) {
const itemRequirements = this.getItemRequirements(recipe.requirements); const itemRequirements = this.getItemRequirements(recipe.requirements);
for (const requirement of itemRequirements) { for (const requirement of itemRequirements) {
if (!itemRewardBlacklist.includes(requirement.templateId)) {
continue;
}
rewardPool.add(requirement.templateId); rewardPool.add(requirement.templateId);
} }
} }
@ -364,17 +382,33 @@ export class CircleOfCultistService {
const hasScavCaseAreaUnlocked = pmcData.Hideout.Areas[HideoutAreas.SCAV_CASE]?.level > 0; const hasScavCaseAreaUnlocked = pmcData.Hideout.Areas[HideoutAreas.SCAV_CASE]?.level > 0;
if (hasScavCaseAreaUnlocked) { if (hasScavCaseAreaUnlocked) {
// Gather up items used to start scav case crafts // Gather up items used to start scav case crafts
const scavCaseCrafts = this.databaseService.getHideout().scavcase; const scavCaseCrafts = hideoutDbData.scavcase;
for (const craft of scavCaseCrafts) { for (const craft of scavCaseCrafts) {
// Find the item requirements from each craft // Find the item requirements from each craft
const itemRequirements = this.getItemRequirements(craft.Requirements); const itemRequirements = this.getItemRequirements(craft.Requirements);
for (const requirement of itemRequirements) { for (const requirement of itemRequirements) {
if (!itemRewardBlacklist.includes(requirement.templateId)) {
continue;
}
// Add tpl to reward pool // Add tpl to reward pool
rewardPool.add(requirement.templateId); rewardPool.add(requirement.templateId);
} }
} }
} }
// Add custom rewards from config
if (cultistCircleConfig.additionalRewardItemPool.length > 0) {
for (const additionalReward of cultistCircleConfig.additionalRewardItemPool) {
if (!itemRewardBlacklist.includes(additionalReward)) {
continue;
}
// Add tpl to reward pool
rewardPool.add(additionalReward);
}
}
return Array.from(rewardPool); return Array.from(rewardPool);
} }