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:
parent
1350fdb78b
commit
ac459335c0
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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};
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
},
|
||||
)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user