Add system that adjusts the loot multipliers for a scav raid based on the percentage of the raid time remaining
Controlled per location Most maps are capped at 40/50% min Added multiple config proeprties to configure how system works Added ability to remove all AppContext values by key During `getRaidTime()` loot % modifier values are stored in app context, Then, during `generate()` those values are retreived and applied if found After loot generation values are reset to their original value
This commit is contained in:
parent
f9cf3242c8
commit
9c2725e2fe
@ -796,6 +796,9 @@
|
||||
"looseLootBlacklist": {},
|
||||
"scavRaidTimeSettings": {
|
||||
"bigmap": {
|
||||
"reduceLootByPercent": true,
|
||||
"minDynamicLootPercent": 50,
|
||||
"minStaticLootPercent": 40,
|
||||
"reducedChancePercent": 40,
|
||||
"reductionPercentWeights": {
|
||||
"20": 12,
|
||||
@ -806,7 +809,10 @@
|
||||
}
|
||||
},
|
||||
"factory4_day": {
|
||||
"reducedChancePercent": 60,
|
||||
"reduceLootByPercent": true,
|
||||
"minDynamicLootPercent": 50,
|
||||
"minStaticLootPercent": 40,
|
||||
"reducedChancePercent": 50,
|
||||
"reductionPercentWeights": {
|
||||
"20": 12,
|
||||
"30": 7,
|
||||
@ -816,6 +822,9 @@
|
||||
}
|
||||
},
|
||||
"factory4_night": {
|
||||
"reduceLootByPercent": true,
|
||||
"minDynamicLootPercent": 50,
|
||||
"minStaticLootPercent": 40,
|
||||
"reducedChancePercent": 40,
|
||||
"reductionPercentWeights": {
|
||||
"20": 12,
|
||||
@ -826,6 +835,9 @@
|
||||
}
|
||||
},
|
||||
"interchange": {
|
||||
"reduceLootByPercent": true,
|
||||
"minDynamicLootPercent": 50,
|
||||
"minStaticLootPercent": 40,
|
||||
"reducedChancePercent": 50,
|
||||
"reductionPercentWeights": {
|
||||
"20": 12,
|
||||
@ -836,7 +848,11 @@
|
||||
}
|
||||
},
|
||||
"rezervbase": {
|
||||
"reduceLootByPercent": true,
|
||||
"minDynamicLootPercent": 50,
|
||||
"minStaticLootPercent": 40,
|
||||
"reducedChancePercent": 40,
|
||||
|
||||
"reductionPercentWeights": {
|
||||
"20": 12,
|
||||
"30": 7,
|
||||
@ -846,6 +862,9 @@
|
||||
}
|
||||
},
|
||||
"laboratory": {
|
||||
"reduceLootByPercent": true,
|
||||
"minDynamicLootPercent": 50,
|
||||
"minStaticLootPercent": 40,
|
||||
"reducedChancePercent": 30,
|
||||
"reductionPercentWeights": {
|
||||
"20": 12,
|
||||
@ -856,6 +875,9 @@
|
||||
}
|
||||
},
|
||||
"lighthouse": {
|
||||
"reduceLootByPercent": true,
|
||||
"minDynamicLootPercent": 50,
|
||||
"minStaticLootPercent": 40,
|
||||
"reducedChancePercent": 40,
|
||||
"reductionPercentWeights": {
|
||||
"20": 12,
|
||||
@ -866,6 +888,9 @@
|
||||
}
|
||||
},
|
||||
"shoreline": {
|
||||
"reduceLootByPercent": true,
|
||||
"minDynamicLootPercent": 50,
|
||||
"minStaticLootPercent": 40,
|
||||
"reducedChancePercent": 40,
|
||||
"reductionPercentWeights": {
|
||||
"20": 25,
|
||||
@ -876,6 +901,9 @@
|
||||
}
|
||||
},
|
||||
"tarkovstreets": {
|
||||
"reduceLootByPercent": true,
|
||||
"minDynamicLootPercent": 50,
|
||||
"minStaticLootPercent": 40,
|
||||
"reducedChancePercent": 40,
|
||||
"reductionPercentWeights": {
|
||||
"20": 25,
|
||||
@ -886,6 +914,9 @@
|
||||
}
|
||||
},
|
||||
"woods": {
|
||||
"reduceLootByPercent": true,
|
||||
"minDynamicLootPercent": 50,
|
||||
"minStaticLootPercent": 40,
|
||||
"reducedChancePercent": 40,
|
||||
"reductionPercentWeights": {
|
||||
"20": 25,
|
||||
@ -896,6 +927,9 @@
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"reduceLootByPercent": true,
|
||||
"minDynamicLootPercent": 50,
|
||||
"minStaticLootPercent": 50,
|
||||
"reducedChancePercent": 25,
|
||||
"reductionPercentWeights": {
|
||||
"20": 12,
|
||||
|
@ -61,4 +61,12 @@ export class ApplicationContext
|
||||
list.add(new ContextVariable(value, type));
|
||||
this.variables.set(type, list);
|
||||
}
|
||||
|
||||
public clearValues(type: ContextVariableType): void
|
||||
{
|
||||
this.variables.has(type)
|
||||
{
|
||||
this.variables.delete(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,5 +6,6 @@ export enum ContextVariableType {
|
||||
/** Timestamp when client first connected */
|
||||
CLIENT_START_TIMESTAMP = 2,
|
||||
/** When player is loading into map and loot is requested */
|
||||
REGISTER_PLAYER_REQUEST = 3
|
||||
REGISTER_PLAYER_REQUEST = 3,
|
||||
LOOT_MULTIPLER_CHANGE = 4,
|
||||
}
|
||||
|
@ -598,12 +598,22 @@ export class GameController
|
||||
}
|
||||
|
||||
// Get the weighted percent to reduce the raid time by
|
||||
const chosenRaidReductionPercent = this.weightedRandomHelper.getWeightedValue<string>(
|
||||
const chosenRaidReductionPercent = Number.parseInt(this.weightedRandomHelper.getWeightedValue<string>(
|
||||
mapSettings.reductionPercentWeights,
|
||||
);
|
||||
));
|
||||
|
||||
if (mapSettings.reduceLootByPercent)
|
||||
{
|
||||
// Store time reduction percent in app context so loot gen can pick it up later
|
||||
this.applicationContext.addValue(ContextVariableType.LOOT_MULTIPLER_CHANGE,
|
||||
{
|
||||
dynamicLootPercent: Math.max(chosenRaidReductionPercent, mapSettings.minDynamicLootPercent),
|
||||
staticLootPercent: Math.max(chosenRaidReductionPercent, mapSettings.minStaticLootPercent)
|
||||
});
|
||||
}
|
||||
|
||||
// How many minutes raid will be
|
||||
const newRaidTimeMinutes = Math.floor(this.randomUtil.reduceValueByPercent(baseEscapeTimeMinutes, Number.parseInt(chosenRaidReductionPercent)));
|
||||
const newRaidTimeMinutes = Math.floor(this.randomUtil.reduceValueByPercent(baseEscapeTimeMinutes, chosenRaidReductionPercent));
|
||||
|
||||
// Update result object with new time
|
||||
result.RaidTimeMinutes = newRaidTimeMinutes;
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ApplicationContext } from "@spt-aki/context/ApplicationContext";
|
||||
import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
|
||||
import { LocationGenerator } from "@spt-aki/generators/LocationGenerator";
|
||||
import { LootGenerator } from "@spt-aki/generators/LootGenerator";
|
||||
import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper";
|
||||
@ -12,7 +14,8 @@ import { IGetLocationRequestData } from "@spt-aki/models/eft/location/IGetLocati
|
||||
import { AirdropTypeEnum } from "@spt-aki/models/enums/AirdropType";
|
||||
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
||||
import { IAirdropConfig } from "@spt-aki/models/spt/config/IAirdropConfig";
|
||||
import { ILocationConfig } from "@spt-aki/models/spt/config/ILocationConfig";
|
||||
import { ILocationConfig, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig";
|
||||
import { ILootMultiplerChange } from "@spt-aki/models/spt/location/ILootMultiplerChange";
|
||||
import { ILocations } from "@spt-aki/models/spt/server/ILocations";
|
||||
import { LootRequest } from "@spt-aki/models/spt/services/LootRequest";
|
||||
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
|
||||
@ -42,6 +45,7 @@ export class LocationController
|
||||
@inject("DatabaseServer") protected databaseServer: DatabaseServer,
|
||||
@inject("TimeUtil") protected timeUtil: TimeUtil,
|
||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
||||
@inject("ApplicationContext") protected applicationContext: ApplicationContext,
|
||||
)
|
||||
{
|
||||
this.airdropConfig = this.configServer.getConfig(ConfigTypes.AIRDROP);
|
||||
@ -83,10 +87,23 @@ export class LocationController
|
||||
return output;
|
||||
}
|
||||
|
||||
// Check for a loot multipler adjustment in app context and apply if one is found
|
||||
let locationConfigCopy: ILocationConfig;
|
||||
const lootMultiplierAdjustment = this.applicationContext.getLatestValue(ContextVariableType.LOOT_MULTIPLER_CHANGE)?.getValue<ILootMultiplerChange>();
|
||||
if (lootMultiplierAdjustment)
|
||||
{
|
||||
this.logger.debug(`Adjusting dynamic loot multipliers to ${lootMultiplierAdjustment.dynamicLootPercent}% and static loot multipliers to ${lootMultiplierAdjustment.staticLootPercent}% of original`)
|
||||
locationConfigCopy = this.jsonUtil.clone(this.locationConfig); // Clone values so they can be used to reset originals later
|
||||
|
||||
// Change loot multipler values before they're used below
|
||||
this.adjustLootMultipliers(this.locationConfig.looseLootMultiplier, lootMultiplierAdjustment.dynamicLootPercent);
|
||||
this.adjustLootMultipliers(this.locationConfig.staticLootMultiplier, lootMultiplierAdjustment.staticLootPercent);
|
||||
}
|
||||
|
||||
const staticAmmoDist = this.jsonUtil.clone(db.loot.staticAmmo);
|
||||
|
||||
// Create containers and add loot to them
|
||||
const staticLoot = this.locationGenerator.generateStaticContainers(location.base, staticAmmoDist);
|
||||
const staticLoot = this.locationGenerator.generateStaticContainers(output, staticAmmoDist);
|
||||
output.Loot.push(...staticLoot);
|
||||
|
||||
// Add dyanmic loot to output loot
|
||||
@ -107,9 +124,32 @@ export class LocationController
|
||||
);
|
||||
this.logger.success(this.localisationService.getText("location-generated_success", name));
|
||||
|
||||
// Reset loot multipliers back to original values
|
||||
if (lootMultiplierAdjustment)
|
||||
{
|
||||
this.logger.debug("Resetting loot multipliers back to their original values");
|
||||
this.locationConfig.staticLootMultiplier = locationConfigCopy.staticLootMultiplier;
|
||||
this.locationConfig.looseLootMultiplier = locationConfigCopy.looseLootMultiplier;
|
||||
|
||||
this.applicationContext.clearValues(ContextVariableType.LOOT_MULTIPLER_CHANGE);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust the loot multiplier values passed in to be a % of their original value
|
||||
* @param mapLootMultiplers Multiplers to adjust
|
||||
* @param loosePercent Percent to change values to
|
||||
*/
|
||||
protected adjustLootMultipliers(mapLootMultiplers: LootMultiplier, loosePercent: number): void
|
||||
{
|
||||
for (const key in mapLootMultiplers)
|
||||
{
|
||||
mapLootMultiplers[key] = this.randomUtil.getPercentOfValue(mapLootMultiplers[key], loosePercent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle client/locations
|
||||
* Get all maps base location properties without loot data
|
||||
|
@ -44,8 +44,13 @@ export interface ILocationConfig extends IBaseConfig
|
||||
|
||||
export interface IScavRaidTimeLocationSettings
|
||||
{
|
||||
reducedChancePercent: number
|
||||
reductionPercentWeights: Record<string, number>
|
||||
/** Should loot be reduced by same percent length of raid is reduced by */
|
||||
reduceLootByPercent: boolean;
|
||||
minStaticLootPercent: number;
|
||||
minDynamicLootPercent: number;
|
||||
/** Chance raid time is reduced */
|
||||
reducedChancePercent: number;
|
||||
reductionPercentWeights: Record<string, number>;
|
||||
}
|
||||
|
||||
export interface IContainerRandomistionSettings
|
||||
|
5
project/src/models/spt/location/ILootMultiplerChange.ts
Normal file
5
project/src/models/spt/location/ILootMultiplerChange.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export interface ILootMultiplerChange
|
||||
{
|
||||
dynamicLootPercent: number
|
||||
staticLootPercent: number
|
||||
}
|
Loading…
Reference in New Issue
Block a user