Add new endpoint to calcualte a reduced raid time for scavs and send the maps base.EscapeTimeLimit value to client for PMC raids

This commit is contained in:
Dev 2023-11-26 21:11:03 +00:00
parent 1350fdb78b
commit ac459335c0
9 changed files with 203 additions and 5 deletions

View File

@ -793,5 +793,106 @@
"minFillStaticMagazinePercent": 50,
"makeWishingTreeAlwaysGiveGift": true,
"allowDuplicateItemsInStaticContainers": true,
"looseLootBlacklist": {}
"looseLootBlacklist": {},
"scavRaidTimeSettings": {
"bigmap": {
"reducedChancePercent": 40,
"reductionPercentWeights": {
"20": 12,
"40": 5,
"60": 2,
"80": 1
}
},
"factory4_day": {
"reducedChancePercent": 60,
"reductionPercentWeights": {
"20": 12,
"40": 5,
"60": 2,
"80": 1
}
},
"factory4_night": {
"reducedChancePercent": 40,
"reductionPercentWeights": {
"20": 12,
"40": 5,
"60": 2,
"80": 1
}
},
"interchange": {
"reducedChancePercent": 50,
"reductionPercentWeights": {
"20": 12,
"40": 5,
"60": 2,
"80": 1
}
},
"rezervbase": {
"reducedChancePercent": 40,
"reductionPercentWeights": {
"20": 12,
"40": 5,
"60": 2,
"80": 1
}
},
"laboratory": {
"reducedChancePercent": 30,
"reductionPercentWeights": {
"20": 12,
"40": 5,
"60": 2,
"80": 1
}
},
"lighthouse": {
"reducedChancePercent": 40,
"reductionPercentWeights": {
"20": 12,
"40": 5,
"60": 2,
"80": 1
}
},
"shoreline": {
"reducedChancePercent": 40,
"reductionPercentWeights": {
"20": 25,
"40": 10,
"60": 1,
"80": 1
}
},
"tarkovstreets": {
"reducedChancePercent": 40,
"reductionPercentWeights": {
"20": 25,
"40": 10,
"60": 1,
"80": 1
}
},
"woods": {
"reducedChancePercent": 40,
"reductionPercentWeights": {
"20": 25,
"40": 10,
"60": 1,
"80": 1
}
},
"default": {
"reducedChancePercent": 25,
"reductionPercentWeights": {
"20": 12,
"40": 5,
"60": 2,
"80": 1
}
}
}
}

View File

@ -10,6 +10,7 @@ import { IGameEmptyCrcRequestData } from "@spt-aki/models/eft/game/IGameEmptyCrc
import { IGameKeepAliveResponse } from "@spt-aki/models/eft/game/IGameKeepAliveResponse";
import { IGameLogoutResponseData } from "@spt-aki/models/eft/game/IGameLogoutResponseData";
import { IGameStartResponse } from "@spt-aki/models/eft/game/IGameStartResponse";
import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest";
import { IReportNicknameRequestData } from "@spt-aki/models/eft/game/IReportNicknameRequestData";
import { IServerDetails } from "@spt-aki/models/eft/game/IServerDetails";
import { IVersionValidateRequestData } from "@spt-aki/models/eft/game/IVersionValidateRequestData";
@ -157,6 +158,16 @@ class GameCallbacks implements OnLoad
{
return this.httpResponse.nullResponse();
}
/**
* Handle singleplayer/settings/getRaidTime
* @returns string
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any
{
return this.httpResponse.noBody(this.gameController.getRaidTime(sessionID, request));
}
}
export {GameCallbacks};

View File

@ -17,7 +17,7 @@ export class ApplicationContext
*
* const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue<string>();
*
* const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue<IStartOfflineRaidRequestData>();
* const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue<IGetRaidConfigurationRequestData>();
* @param type
* @returns
*/

View File

@ -1,5 +1,4 @@
export enum ContextVariableType
{
export enum ContextVariableType {
/** Logged in users session id */
SESSION_ID = 0,
/** Currently acive raid information */
@ -7,5 +6,5 @@ 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
}

View File

@ -5,6 +5,7 @@ import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
import { HideoutHelper } from "@spt-aki/helpers/HideoutHelper";
import { HttpServerHelper } from "@spt-aki/helpers/HttpServerHelper";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper";
import { PreAkiModLoader } from "@spt-aki/loaders/PreAkiModLoader";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
import { ILooseLoot } from "@spt-aki/models/eft/common/ILooseLoot";
@ -14,7 +15,10 @@ import { ICheckVersionResponse } from "@spt-aki/models/eft/game/ICheckVersionRes
import { ICurrentGroupResponse } from "@spt-aki/models/eft/game/ICurrentGroupResponse";
import { IGameConfigResponse } from "@spt-aki/models/eft/game/IGameConfigResponse";
import { IGameKeepAliveResponse } from "@spt-aki/models/eft/game/IGameKeepAliveResponse";
import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest";
import { IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse";
import { IServerDetails } from "@spt-aki/models/eft/game/IServerDetails";
import { IGetRaidConfigurationRequestData } from "@spt-aki/models/eft/match/IGetRaidConfigurationRequestData";
import { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile";
import { AccountTypes } from "@spt-aki/models/enums/AccountTypes";
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
@ -68,6 +72,7 @@ export class GameController
@inject("SeasonalEventService") protected seasonalEventService: SeasonalEventService,
@inject("ItemBaseClassService") protected itemBaseClassService: ItemBaseClassService,
@inject("GiftService") protected giftService: GiftService,
@inject("WeightedRandomHelper") protected weightedRandomHelper: WeightedRandomHelper,
@inject("ApplicationContext") protected applicationContext: ApplicationContext,
@inject("ConfigServer") protected configServer: ConfigServer,
)
@ -475,6 +480,53 @@ export class GameController
};
}
/**
* singleplayer/settings/getRaidTime
*/
public getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse
{
const baseEscapeTimeMinutes = this.databaseServer.getTables().locations[request.Location.toLowerCase()].base.EscapeTimeLimit;
const result: IGetRaidTimeResponse = {
RaidTimeMinutes: baseEscapeTimeMinutes
}
// Pmc raid, send default
if (request.Side.toLowerCase() === "pmc")
{
return result;
}
// We're scav
let mapSettings = this.locationConfig.scavRaidTimeSettings[request.Location.toLowerCase()];
if (!mapSettings)
{
this.logger.warning(`Unable to find scav raid time settings for map: ${request.Location}, using defaults`);
mapSettings = this.locationConfig.scavRaidTimeSettings.default;
}
// Chance of reducing raid time for scav, not guaranteed
if (!this.randomUtil.getChance100(mapSettings.reducedChancePercent))
{
// Send default
return result;
}
// Get the weighted percent to reduce the raid time by
const chosenRaidReductionPercent = this.weightedRandomHelper.getWeightedValue<string>(
mapSettings.reductionPercentWeights,
);
// How many minutes raid will be
const newRaidTime = Math.floor(this.randomUtil.reduceValueByPercent(baseEscapeTimeMinutes, Number.parseInt(chosenRaidReductionPercent)));
// Update result object with new time
result.RaidTimeMinutes = newRaidTime;
this.logger.debug(`Reduced: ${request.Location} raid time by: ${chosenRaidReductionPercent}% to ${newRaidTime} minutes`)
return result;
}
/**
* BSG have two values for shotgun dispersion, we make sure both have the same value
*/

View File

@ -38,6 +38,14 @@ export interface ILocationConfig extends IBaseConfig
allowDuplicateItemsInStaticContainers: boolean;
/** Key: map, value: loose loot ids to ignore */
looseLootBlacklist: Record<string, string[]>;
/** Key: map, value: settings to control how long scav raids are*/
scavRaidTimeSettings: Record<string, IScavRaidTimeLocationSettings>;
}
export interface IScavRaidTimeLocationSettings
{
reducedChancePercent: number
reductionPercentWeights: Record<string, number>
}
export interface IContainerRandomistionSettings

View File

@ -89,6 +89,14 @@ export class GameStaticRouter extends StaticRouter
return this.gameCallbacks.reportNickname(url, info, sessionID);
},
),
new RouteAction(
"/singleplayer/settings/getRaidTime",
// eslint-disable-next-line @typescript-eslint/no-unused-vars
(url: string, info: any, sessionID: string, output: string): any =>
{
return this.gameCallbacks.getRaidTime(url, info, sessionID);
},
)
]);
}
}

View File

@ -34,6 +34,13 @@ export class HttpResponseUtil
return this.clearString(this.jsonUtil.serialize(data));
}
/**
* Game client needs server responses in a particular format
* @param data
* @param err
* @param errmsg
* @returns
*/
public getBody<T>(data: T, err = 0, errmsg = null): IGetBodyResponseData<T>
{
return this.clearString(this.getUnclearedBody(data, err, errmsg));

View File

@ -231,6 +231,18 @@ export class RandomUtil
return Number.parseFloat(((percent * number) / 100).toFixed(toFixed));
}
/**
* Reduce a value by a percentage
* @param number Value to reduce
* @param percentage Percentage to reduce value by
* @returns Reduced value
*/
public reduceValueByPercent(number: number, percentage: number): number
{
const reductionAmount = number * (percentage / 100);
return number - reductionAmount;
}
/**
* Check if number passes a check out of 100
* @param chancePercent value check needs to be above