diff --git a/README.md b/README.md index 38601ba..b5a2145 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Mod examples for v3.7.3 +# Mod examples for v3.7.4 A collection of example mods that perform typical actions in SPT diff --git a/TypeScript/10ScopesAndTypes/types/callbacks/GameCallbacks.d.ts b/TypeScript/10ScopesAndTypes/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/10ScopesAndTypes/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/10ScopesAndTypes/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/10ScopesAndTypes/types/context/ApplicationContext.d.ts b/TypeScript/10ScopesAndTypes/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/10ScopesAndTypes/types/context/ApplicationContext.d.ts +++ b/TypeScript/10ScopesAndTypes/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/10ScopesAndTypes/types/context/ContextVariableType.d.ts b/TypeScript/10ScopesAndTypes/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/10ScopesAndTypes/types/context/ContextVariableType.d.ts +++ b/TypeScript/10ScopesAndTypes/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/10ScopesAndTypes/types/controllers/GameController.d.ts b/TypeScript/10ScopesAndTypes/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/10ScopesAndTypes/types/controllers/GameController.d.ts +++ b/TypeScript/10ScopesAndTypes/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/10ScopesAndTypes/types/controllers/HideoutController.d.ts b/TypeScript/10ScopesAndTypes/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/10ScopesAndTypes/types/controllers/HideoutController.d.ts +++ b/TypeScript/10ScopesAndTypes/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/10ScopesAndTypes/types/controllers/InraidController.d.ts b/TypeScript/10ScopesAndTypes/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/10ScopesAndTypes/types/controllers/InraidController.d.ts +++ b/TypeScript/10ScopesAndTypes/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/10ScopesAndTypes/types/controllers/LocationController.d.ts b/TypeScript/10ScopesAndTypes/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/10ScopesAndTypes/types/controllers/LocationController.d.ts +++ b/TypeScript/10ScopesAndTypes/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/10ScopesAndTypes/types/controllers/QuestController.d.ts b/TypeScript/10ScopesAndTypes/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/10ScopesAndTypes/types/controllers/QuestController.d.ts +++ b/TypeScript/10ScopesAndTypes/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/10ScopesAndTypes/types/controllers/TradeController.d.ts b/TypeScript/10ScopesAndTypes/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/10ScopesAndTypes/types/controllers/TradeController.d.ts +++ b/TypeScript/10ScopesAndTypes/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/10ScopesAndTypes/types/generators/BotWeaponGenerator.d.ts b/TypeScript/10ScopesAndTypes/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/10ScopesAndTypes/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/10ScopesAndTypes/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/10ScopesAndTypes/types/generators/LocationGenerator.d.ts b/TypeScript/10ScopesAndTypes/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/10ScopesAndTypes/types/generators/LocationGenerator.d.ts +++ b/TypeScript/10ScopesAndTypes/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/10ScopesAndTypes/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/10ScopesAndTypes/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/10ScopesAndTypes/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/10ScopesAndTypes/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/10ScopesAndTypes/types/helpers/HandbookHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/10ScopesAndTypes/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/10ScopesAndTypes/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/10ScopesAndTypes/types/helpers/InRaidHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/10ScopesAndTypes/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/10ScopesAndTypes/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/10ScopesAndTypes/types/helpers/ItemHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/10ScopesAndTypes/types/helpers/ItemHelper.d.ts +++ b/TypeScript/10ScopesAndTypes/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/10ScopesAndTypes/types/helpers/QuestHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/10ScopesAndTypes/types/helpers/QuestHelper.d.ts +++ b/TypeScript/10ScopesAndTypes/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/10ScopesAndTypes/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/10ScopesAndTypes/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/10ScopesAndTypes/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/10ScopesAndTypes/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/10ScopesAndTypes/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/10ScopesAndTypes/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/10ScopesAndTypes/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/10ScopesAndTypes/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/10ScopesAndTypes/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/10ScopesAndTypes/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/10ScopesAndTypes/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/10ScopesAndTypes/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/10ScopesAndTypes/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/10ScopesAndTypes/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/10ScopesAndTypes/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/10ScopesAndTypes/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/10ScopesAndTypes/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/10ScopesAndTypes/types/models/enums/BaseClasses.d.ts b/TypeScript/10ScopesAndTypes/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/10ScopesAndTypes/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/10ScopesAndTypes/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/10ScopesAndTypes/types/models/enums/ItemAddedResult.d.ts b/TypeScript/10ScopesAndTypes/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/10ScopesAndTypes/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/10ScopesAndTypes/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/10ScopesAndTypes/types/models/spt/config/IBotConfig.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/10ScopesAndTypes/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/10ScopesAndTypes/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/10ScopesAndTypes/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/10ScopesAndTypes/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/10ScopesAndTypes/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/10ScopesAndTypes/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/10ScopesAndTypes/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/10ScopesAndTypes/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/10ScopesAndTypes/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/10ScopesAndTypes/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/10ScopesAndTypes/types/routers/EventOutputHolder.d.ts b/TypeScript/10ScopesAndTypes/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/10ScopesAndTypes/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/10ScopesAndTypes/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/10ScopesAndTypes/types/services/ProfileFixerService.d.ts b/TypeScript/10ScopesAndTypes/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/10ScopesAndTypes/types/services/ProfileFixerService.d.ts +++ b/TypeScript/10ScopesAndTypes/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/10ScopesAndTypes/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/10ScopesAndTypes/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/10ScopesAndTypes/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/10ScopesAndTypes/types/utils/HttpResponseUtil.d.ts b/TypeScript/10ScopesAndTypes/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/10ScopesAndTypes/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/10ScopesAndTypes/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/10ScopesAndTypes/types/utils/RandomUtil.d.ts b/TypeScript/10ScopesAndTypes/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/10ScopesAndTypes/types/utils/RandomUtil.d.ts +++ b/TypeScript/10ScopesAndTypes/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/11BundleLoadingSample/types/callbacks/GameCallbacks.d.ts b/TypeScript/11BundleLoadingSample/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/11BundleLoadingSample/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/11BundleLoadingSample/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/11BundleLoadingSample/types/context/ApplicationContext.d.ts b/TypeScript/11BundleLoadingSample/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/11BundleLoadingSample/types/context/ApplicationContext.d.ts +++ b/TypeScript/11BundleLoadingSample/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/11BundleLoadingSample/types/context/ContextVariableType.d.ts b/TypeScript/11BundleLoadingSample/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/11BundleLoadingSample/types/context/ContextVariableType.d.ts +++ b/TypeScript/11BundleLoadingSample/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/11BundleLoadingSample/types/controllers/GameController.d.ts b/TypeScript/11BundleLoadingSample/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/11BundleLoadingSample/types/controllers/GameController.d.ts +++ b/TypeScript/11BundleLoadingSample/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/11BundleLoadingSample/types/controllers/HideoutController.d.ts b/TypeScript/11BundleLoadingSample/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/11BundleLoadingSample/types/controllers/HideoutController.d.ts +++ b/TypeScript/11BundleLoadingSample/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/11BundleLoadingSample/types/controllers/InraidController.d.ts b/TypeScript/11BundleLoadingSample/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/11BundleLoadingSample/types/controllers/InraidController.d.ts +++ b/TypeScript/11BundleLoadingSample/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/11BundleLoadingSample/types/controllers/LocationController.d.ts b/TypeScript/11BundleLoadingSample/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/11BundleLoadingSample/types/controllers/LocationController.d.ts +++ b/TypeScript/11BundleLoadingSample/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/11BundleLoadingSample/types/controllers/QuestController.d.ts b/TypeScript/11BundleLoadingSample/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/11BundleLoadingSample/types/controllers/QuestController.d.ts +++ b/TypeScript/11BundleLoadingSample/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/11BundleLoadingSample/types/controllers/TradeController.d.ts b/TypeScript/11BundleLoadingSample/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/11BundleLoadingSample/types/controllers/TradeController.d.ts +++ b/TypeScript/11BundleLoadingSample/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/11BundleLoadingSample/types/generators/BotWeaponGenerator.d.ts b/TypeScript/11BundleLoadingSample/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/11BundleLoadingSample/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/11BundleLoadingSample/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/11BundleLoadingSample/types/generators/LocationGenerator.d.ts b/TypeScript/11BundleLoadingSample/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/11BundleLoadingSample/types/generators/LocationGenerator.d.ts +++ b/TypeScript/11BundleLoadingSample/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/11BundleLoadingSample/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/11BundleLoadingSample/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/11BundleLoadingSample/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/11BundleLoadingSample/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/11BundleLoadingSample/types/helpers/HandbookHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/11BundleLoadingSample/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/11BundleLoadingSample/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/11BundleLoadingSample/types/helpers/InRaidHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/11BundleLoadingSample/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/11BundleLoadingSample/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/11BundleLoadingSample/types/helpers/ItemHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/11BundleLoadingSample/types/helpers/ItemHelper.d.ts +++ b/TypeScript/11BundleLoadingSample/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/11BundleLoadingSample/types/helpers/QuestHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/11BundleLoadingSample/types/helpers/QuestHelper.d.ts +++ b/TypeScript/11BundleLoadingSample/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/11BundleLoadingSample/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/11BundleLoadingSample/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/11BundleLoadingSample/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/11BundleLoadingSample/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/11BundleLoadingSample/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/11BundleLoadingSample/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/11BundleLoadingSample/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/11BundleLoadingSample/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/11BundleLoadingSample/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/11BundleLoadingSample/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/11BundleLoadingSample/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/11BundleLoadingSample/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/11BundleLoadingSample/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/11BundleLoadingSample/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/11BundleLoadingSample/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/11BundleLoadingSample/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/11BundleLoadingSample/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/11BundleLoadingSample/types/models/enums/BaseClasses.d.ts b/TypeScript/11BundleLoadingSample/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/11BundleLoadingSample/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/11BundleLoadingSample/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/11BundleLoadingSample/types/models/enums/ItemAddedResult.d.ts b/TypeScript/11BundleLoadingSample/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/11BundleLoadingSample/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/11BundleLoadingSample/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/11BundleLoadingSample/types/models/spt/config/IBotConfig.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/11BundleLoadingSample/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/11BundleLoadingSample/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/11BundleLoadingSample/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/11BundleLoadingSample/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/11BundleLoadingSample/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/11BundleLoadingSample/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/11BundleLoadingSample/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/11BundleLoadingSample/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/11BundleLoadingSample/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/11BundleLoadingSample/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/11BundleLoadingSample/types/routers/EventOutputHolder.d.ts b/TypeScript/11BundleLoadingSample/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/11BundleLoadingSample/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/11BundleLoadingSample/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/11BundleLoadingSample/types/services/ProfileFixerService.d.ts b/TypeScript/11BundleLoadingSample/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/11BundleLoadingSample/types/services/ProfileFixerService.d.ts +++ b/TypeScript/11BundleLoadingSample/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/11BundleLoadingSample/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/11BundleLoadingSample/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/11BundleLoadingSample/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/11BundleLoadingSample/types/utils/HttpResponseUtil.d.ts b/TypeScript/11BundleLoadingSample/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/11BundleLoadingSample/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/11BundleLoadingSample/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/11BundleLoadingSample/types/utils/RandomUtil.d.ts b/TypeScript/11BundleLoadingSample/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/11BundleLoadingSample/types/utils/RandomUtil.d.ts +++ b/TypeScript/11BundleLoadingSample/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/12ClassExtensionOverride/types/callbacks/GameCallbacks.d.ts b/TypeScript/12ClassExtensionOverride/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/12ClassExtensionOverride/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/12ClassExtensionOverride/types/context/ApplicationContext.d.ts b/TypeScript/12ClassExtensionOverride/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/12ClassExtensionOverride/types/context/ApplicationContext.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/12ClassExtensionOverride/types/context/ContextVariableType.d.ts b/TypeScript/12ClassExtensionOverride/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/12ClassExtensionOverride/types/context/ContextVariableType.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/12ClassExtensionOverride/types/controllers/GameController.d.ts b/TypeScript/12ClassExtensionOverride/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/12ClassExtensionOverride/types/controllers/GameController.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/12ClassExtensionOverride/types/controllers/HideoutController.d.ts b/TypeScript/12ClassExtensionOverride/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/12ClassExtensionOverride/types/controllers/HideoutController.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/12ClassExtensionOverride/types/controllers/InraidController.d.ts b/TypeScript/12ClassExtensionOverride/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/12ClassExtensionOverride/types/controllers/InraidController.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/12ClassExtensionOverride/types/controllers/LocationController.d.ts b/TypeScript/12ClassExtensionOverride/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/12ClassExtensionOverride/types/controllers/LocationController.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/12ClassExtensionOverride/types/controllers/QuestController.d.ts b/TypeScript/12ClassExtensionOverride/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/12ClassExtensionOverride/types/controllers/QuestController.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/12ClassExtensionOverride/types/controllers/TradeController.d.ts b/TypeScript/12ClassExtensionOverride/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/12ClassExtensionOverride/types/controllers/TradeController.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/12ClassExtensionOverride/types/generators/BotWeaponGenerator.d.ts b/TypeScript/12ClassExtensionOverride/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/12ClassExtensionOverride/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/12ClassExtensionOverride/types/generators/LocationGenerator.d.ts b/TypeScript/12ClassExtensionOverride/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/12ClassExtensionOverride/types/generators/LocationGenerator.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/12ClassExtensionOverride/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/12ClassExtensionOverride/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/12ClassExtensionOverride/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/HandbookHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/12ClassExtensionOverride/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/InRaidHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/12ClassExtensionOverride/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/ItemHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/12ClassExtensionOverride/types/helpers/ItemHelper.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/QuestHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/12ClassExtensionOverride/types/helpers/QuestHelper.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/12ClassExtensionOverride/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/12ClassExtensionOverride/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/12ClassExtensionOverride/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/12ClassExtensionOverride/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/12ClassExtensionOverride/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/12ClassExtensionOverride/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/12ClassExtensionOverride/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/12ClassExtensionOverride/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/12ClassExtensionOverride/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/12ClassExtensionOverride/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/12ClassExtensionOverride/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/12ClassExtensionOverride/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/12ClassExtensionOverride/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/12ClassExtensionOverride/types/models/enums/BaseClasses.d.ts b/TypeScript/12ClassExtensionOverride/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/12ClassExtensionOverride/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/12ClassExtensionOverride/types/models/enums/ItemAddedResult.d.ts b/TypeScript/12ClassExtensionOverride/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/12ClassExtensionOverride/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/12ClassExtensionOverride/types/models/spt/config/IBotConfig.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/12ClassExtensionOverride/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/12ClassExtensionOverride/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/12ClassExtensionOverride/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/12ClassExtensionOverride/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/12ClassExtensionOverride/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/12ClassExtensionOverride/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/12ClassExtensionOverride/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/12ClassExtensionOverride/types/routers/EventOutputHolder.d.ts b/TypeScript/12ClassExtensionOverride/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/12ClassExtensionOverride/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/12ClassExtensionOverride/types/services/ProfileFixerService.d.ts b/TypeScript/12ClassExtensionOverride/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/12ClassExtensionOverride/types/services/ProfileFixerService.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/12ClassExtensionOverride/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/12ClassExtensionOverride/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/12ClassExtensionOverride/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/12ClassExtensionOverride/types/utils/HttpResponseUtil.d.ts b/TypeScript/12ClassExtensionOverride/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/12ClassExtensionOverride/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/12ClassExtensionOverride/types/utils/RandomUtil.d.ts b/TypeScript/12ClassExtensionOverride/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/12ClassExtensionOverride/types/utils/RandomUtil.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/13AddTrader/types/callbacks/GameCallbacks.d.ts b/TypeScript/13AddTrader/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/13AddTrader/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/13AddTrader/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/13AddTrader/types/context/ApplicationContext.d.ts b/TypeScript/13AddTrader/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/13AddTrader/types/context/ApplicationContext.d.ts +++ b/TypeScript/13AddTrader/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/13AddTrader/types/context/ContextVariableType.d.ts b/TypeScript/13AddTrader/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/13AddTrader/types/context/ContextVariableType.d.ts +++ b/TypeScript/13AddTrader/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/13AddTrader/types/controllers/GameController.d.ts b/TypeScript/13AddTrader/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/13AddTrader/types/controllers/GameController.d.ts +++ b/TypeScript/13AddTrader/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/13AddTrader/types/controllers/HideoutController.d.ts b/TypeScript/13AddTrader/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/13AddTrader/types/controllers/HideoutController.d.ts +++ b/TypeScript/13AddTrader/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/13AddTrader/types/controllers/InraidController.d.ts b/TypeScript/13AddTrader/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/13AddTrader/types/controllers/InraidController.d.ts +++ b/TypeScript/13AddTrader/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/13AddTrader/types/controllers/LocationController.d.ts b/TypeScript/13AddTrader/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/13AddTrader/types/controllers/LocationController.d.ts +++ b/TypeScript/13AddTrader/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/13AddTrader/types/controllers/QuestController.d.ts b/TypeScript/13AddTrader/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/13AddTrader/types/controllers/QuestController.d.ts +++ b/TypeScript/13AddTrader/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/13AddTrader/types/controllers/TradeController.d.ts b/TypeScript/13AddTrader/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/13AddTrader/types/controllers/TradeController.d.ts +++ b/TypeScript/13AddTrader/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/13AddTrader/types/generators/BotWeaponGenerator.d.ts b/TypeScript/13AddTrader/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/13AddTrader/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/13AddTrader/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/13AddTrader/types/generators/LocationGenerator.d.ts b/TypeScript/13AddTrader/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/13AddTrader/types/generators/LocationGenerator.d.ts +++ b/TypeScript/13AddTrader/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/13AddTrader/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/13AddTrader/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/13AddTrader/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/13AddTrader/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/13AddTrader/types/helpers/HandbookHelper.d.ts b/TypeScript/13AddTrader/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/13AddTrader/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/13AddTrader/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/13AddTrader/types/helpers/InRaidHelper.d.ts b/TypeScript/13AddTrader/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/13AddTrader/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/13AddTrader/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/13AddTrader/types/helpers/ItemHelper.d.ts b/TypeScript/13AddTrader/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/13AddTrader/types/helpers/ItemHelper.d.ts +++ b/TypeScript/13AddTrader/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/13AddTrader/types/helpers/QuestHelper.d.ts b/TypeScript/13AddTrader/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/13AddTrader/types/helpers/QuestHelper.d.ts +++ b/TypeScript/13AddTrader/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/13AddTrader/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/13AddTrader/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/13AddTrader/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/13AddTrader/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/13AddTrader/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/13AddTrader/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/13AddTrader/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/13AddTrader/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/13AddTrader/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/13AddTrader/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/13AddTrader/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/13AddTrader/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/13AddTrader/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/13AddTrader/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/13AddTrader/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/13AddTrader/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/13AddTrader/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/13AddTrader/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/13AddTrader/types/models/enums/BaseClasses.d.ts b/TypeScript/13AddTrader/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/13AddTrader/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/13AddTrader/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/13AddTrader/types/models/enums/ItemAddedResult.d.ts b/TypeScript/13AddTrader/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/13AddTrader/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/13AddTrader/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/13AddTrader/types/models/spt/config/IBotConfig.d.ts b/TypeScript/13AddTrader/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/13AddTrader/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/13AddTrader/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/13AddTrader/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/13AddTrader/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/13AddTrader/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/13AddTrader/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/13AddTrader/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/13AddTrader/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/13AddTrader/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/13AddTrader/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/13AddTrader/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/13AddTrader/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/13AddTrader/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/13AddTrader/types/routers/EventOutputHolder.d.ts b/TypeScript/13AddTrader/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/13AddTrader/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/13AddTrader/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/13AddTrader/types/services/ProfileFixerService.d.ts b/TypeScript/13AddTrader/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/13AddTrader/types/services/ProfileFixerService.d.ts +++ b/TypeScript/13AddTrader/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/13AddTrader/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/13AddTrader/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/13AddTrader/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/13AddTrader/types/utils/HttpResponseUtil.d.ts b/TypeScript/13AddTrader/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/13AddTrader/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/13AddTrader/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/13AddTrader/types/utils/RandomUtil.d.ts b/TypeScript/13AddTrader/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/13AddTrader/types/utils/RandomUtil.d.ts +++ b/TypeScript/13AddTrader/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/14AfterDBLoadHook/types/callbacks/GameCallbacks.d.ts b/TypeScript/14AfterDBLoadHook/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/14AfterDBLoadHook/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/14AfterDBLoadHook/types/context/ApplicationContext.d.ts b/TypeScript/14AfterDBLoadHook/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/14AfterDBLoadHook/types/context/ApplicationContext.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/14AfterDBLoadHook/types/context/ContextVariableType.d.ts b/TypeScript/14AfterDBLoadHook/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/14AfterDBLoadHook/types/context/ContextVariableType.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/14AfterDBLoadHook/types/controllers/GameController.d.ts b/TypeScript/14AfterDBLoadHook/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/14AfterDBLoadHook/types/controllers/GameController.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/14AfterDBLoadHook/types/controllers/HideoutController.d.ts b/TypeScript/14AfterDBLoadHook/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/14AfterDBLoadHook/types/controllers/HideoutController.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/14AfterDBLoadHook/types/controllers/InraidController.d.ts b/TypeScript/14AfterDBLoadHook/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/14AfterDBLoadHook/types/controllers/InraidController.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/14AfterDBLoadHook/types/controllers/LocationController.d.ts b/TypeScript/14AfterDBLoadHook/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/14AfterDBLoadHook/types/controllers/LocationController.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/14AfterDBLoadHook/types/controllers/QuestController.d.ts b/TypeScript/14AfterDBLoadHook/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/14AfterDBLoadHook/types/controllers/QuestController.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/14AfterDBLoadHook/types/controllers/TradeController.d.ts b/TypeScript/14AfterDBLoadHook/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/14AfterDBLoadHook/types/controllers/TradeController.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/14AfterDBLoadHook/types/generators/BotWeaponGenerator.d.ts b/TypeScript/14AfterDBLoadHook/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/14AfterDBLoadHook/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/14AfterDBLoadHook/types/generators/LocationGenerator.d.ts b/TypeScript/14AfterDBLoadHook/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/14AfterDBLoadHook/types/generators/LocationGenerator.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/14AfterDBLoadHook/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/14AfterDBLoadHook/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/14AfterDBLoadHook/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/HandbookHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/14AfterDBLoadHook/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/InRaidHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/14AfterDBLoadHook/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/ItemHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/14AfterDBLoadHook/types/helpers/ItemHelper.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/QuestHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/14AfterDBLoadHook/types/helpers/QuestHelper.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/14AfterDBLoadHook/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/14AfterDBLoadHook/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/14AfterDBLoadHook/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/14AfterDBLoadHook/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/14AfterDBLoadHook/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/14AfterDBLoadHook/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/14AfterDBLoadHook/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/14AfterDBLoadHook/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/14AfterDBLoadHook/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/14AfterDBLoadHook/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/14AfterDBLoadHook/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/14AfterDBLoadHook/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/14AfterDBLoadHook/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/14AfterDBLoadHook/types/models/enums/BaseClasses.d.ts b/TypeScript/14AfterDBLoadHook/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/14AfterDBLoadHook/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/14AfterDBLoadHook/types/models/enums/ItemAddedResult.d.ts b/TypeScript/14AfterDBLoadHook/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/14AfterDBLoadHook/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/config/IBotConfig.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/14AfterDBLoadHook/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/14AfterDBLoadHook/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/14AfterDBLoadHook/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/14AfterDBLoadHook/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/14AfterDBLoadHook/types/routers/EventOutputHolder.d.ts b/TypeScript/14AfterDBLoadHook/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/14AfterDBLoadHook/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/14AfterDBLoadHook/types/services/ProfileFixerService.d.ts b/TypeScript/14AfterDBLoadHook/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/14AfterDBLoadHook/types/services/ProfileFixerService.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/14AfterDBLoadHook/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/14AfterDBLoadHook/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/14AfterDBLoadHook/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/14AfterDBLoadHook/types/utils/HttpResponseUtil.d.ts b/TypeScript/14AfterDBLoadHook/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/14AfterDBLoadHook/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/14AfterDBLoadHook/types/utils/RandomUtil.d.ts b/TypeScript/14AfterDBLoadHook/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/14AfterDBLoadHook/types/utils/RandomUtil.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/15HttpListenerExample/types/callbacks/GameCallbacks.d.ts b/TypeScript/15HttpListenerExample/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/15HttpListenerExample/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/15HttpListenerExample/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/15HttpListenerExample/types/context/ApplicationContext.d.ts b/TypeScript/15HttpListenerExample/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/15HttpListenerExample/types/context/ApplicationContext.d.ts +++ b/TypeScript/15HttpListenerExample/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/15HttpListenerExample/types/context/ContextVariableType.d.ts b/TypeScript/15HttpListenerExample/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/15HttpListenerExample/types/context/ContextVariableType.d.ts +++ b/TypeScript/15HttpListenerExample/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/15HttpListenerExample/types/controllers/GameController.d.ts b/TypeScript/15HttpListenerExample/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/15HttpListenerExample/types/controllers/GameController.d.ts +++ b/TypeScript/15HttpListenerExample/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/15HttpListenerExample/types/controllers/HideoutController.d.ts b/TypeScript/15HttpListenerExample/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/15HttpListenerExample/types/controllers/HideoutController.d.ts +++ b/TypeScript/15HttpListenerExample/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/15HttpListenerExample/types/controllers/InraidController.d.ts b/TypeScript/15HttpListenerExample/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/15HttpListenerExample/types/controllers/InraidController.d.ts +++ b/TypeScript/15HttpListenerExample/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/15HttpListenerExample/types/controllers/LocationController.d.ts b/TypeScript/15HttpListenerExample/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/15HttpListenerExample/types/controllers/LocationController.d.ts +++ b/TypeScript/15HttpListenerExample/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/15HttpListenerExample/types/controllers/QuestController.d.ts b/TypeScript/15HttpListenerExample/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/15HttpListenerExample/types/controllers/QuestController.d.ts +++ b/TypeScript/15HttpListenerExample/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/15HttpListenerExample/types/controllers/TradeController.d.ts b/TypeScript/15HttpListenerExample/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/15HttpListenerExample/types/controllers/TradeController.d.ts +++ b/TypeScript/15HttpListenerExample/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/15HttpListenerExample/types/generators/BotWeaponGenerator.d.ts b/TypeScript/15HttpListenerExample/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/15HttpListenerExample/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/15HttpListenerExample/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/15HttpListenerExample/types/generators/LocationGenerator.d.ts b/TypeScript/15HttpListenerExample/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/15HttpListenerExample/types/generators/LocationGenerator.d.ts +++ b/TypeScript/15HttpListenerExample/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/15HttpListenerExample/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/15HttpListenerExample/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/15HttpListenerExample/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/15HttpListenerExample/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/15HttpListenerExample/types/helpers/HandbookHelper.d.ts b/TypeScript/15HttpListenerExample/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/15HttpListenerExample/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/15HttpListenerExample/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/15HttpListenerExample/types/helpers/InRaidHelper.d.ts b/TypeScript/15HttpListenerExample/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/15HttpListenerExample/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/15HttpListenerExample/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/15HttpListenerExample/types/helpers/ItemHelper.d.ts b/TypeScript/15HttpListenerExample/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/15HttpListenerExample/types/helpers/ItemHelper.d.ts +++ b/TypeScript/15HttpListenerExample/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/15HttpListenerExample/types/helpers/QuestHelper.d.ts b/TypeScript/15HttpListenerExample/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/15HttpListenerExample/types/helpers/QuestHelper.d.ts +++ b/TypeScript/15HttpListenerExample/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/15HttpListenerExample/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/15HttpListenerExample/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/15HttpListenerExample/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/15HttpListenerExample/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/15HttpListenerExample/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/15HttpListenerExample/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/15HttpListenerExample/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/15HttpListenerExample/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/15HttpListenerExample/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/15HttpListenerExample/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/15HttpListenerExample/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/15HttpListenerExample/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/15HttpListenerExample/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/15HttpListenerExample/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/15HttpListenerExample/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/15HttpListenerExample/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/15HttpListenerExample/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/15HttpListenerExample/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/15HttpListenerExample/types/models/enums/BaseClasses.d.ts b/TypeScript/15HttpListenerExample/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/15HttpListenerExample/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/15HttpListenerExample/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/15HttpListenerExample/types/models/enums/ItemAddedResult.d.ts b/TypeScript/15HttpListenerExample/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/15HttpListenerExample/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/15HttpListenerExample/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/15HttpListenerExample/types/models/spt/config/IBotConfig.d.ts b/TypeScript/15HttpListenerExample/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/15HttpListenerExample/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/15HttpListenerExample/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/15HttpListenerExample/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/15HttpListenerExample/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/15HttpListenerExample/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/15HttpListenerExample/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/15HttpListenerExample/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/15HttpListenerExample/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/15HttpListenerExample/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/15HttpListenerExample/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/15HttpListenerExample/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/15HttpListenerExample/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/15HttpListenerExample/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/15HttpListenerExample/types/routers/EventOutputHolder.d.ts b/TypeScript/15HttpListenerExample/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/15HttpListenerExample/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/15HttpListenerExample/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/15HttpListenerExample/types/services/ProfileFixerService.d.ts b/TypeScript/15HttpListenerExample/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/15HttpListenerExample/types/services/ProfileFixerService.d.ts +++ b/TypeScript/15HttpListenerExample/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/15HttpListenerExample/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/15HttpListenerExample/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/15HttpListenerExample/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/15HttpListenerExample/types/utils/HttpResponseUtil.d.ts b/TypeScript/15HttpListenerExample/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/15HttpListenerExample/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/15HttpListenerExample/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/15HttpListenerExample/types/utils/RandomUtil.d.ts b/TypeScript/15HttpListenerExample/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/15HttpListenerExample/types/utils/RandomUtil.d.ts +++ b/TypeScript/15HttpListenerExample/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/16ImporterUtil/types/callbacks/GameCallbacks.d.ts b/TypeScript/16ImporterUtil/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/16ImporterUtil/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/16ImporterUtil/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/16ImporterUtil/types/context/ApplicationContext.d.ts b/TypeScript/16ImporterUtil/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/16ImporterUtil/types/context/ApplicationContext.d.ts +++ b/TypeScript/16ImporterUtil/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/16ImporterUtil/types/context/ContextVariableType.d.ts b/TypeScript/16ImporterUtil/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/16ImporterUtil/types/context/ContextVariableType.d.ts +++ b/TypeScript/16ImporterUtil/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/16ImporterUtil/types/controllers/GameController.d.ts b/TypeScript/16ImporterUtil/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/16ImporterUtil/types/controllers/GameController.d.ts +++ b/TypeScript/16ImporterUtil/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/16ImporterUtil/types/controllers/HideoutController.d.ts b/TypeScript/16ImporterUtil/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/16ImporterUtil/types/controllers/HideoutController.d.ts +++ b/TypeScript/16ImporterUtil/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/16ImporterUtil/types/controllers/InraidController.d.ts b/TypeScript/16ImporterUtil/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/16ImporterUtil/types/controllers/InraidController.d.ts +++ b/TypeScript/16ImporterUtil/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/16ImporterUtil/types/controllers/LocationController.d.ts b/TypeScript/16ImporterUtil/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/16ImporterUtil/types/controllers/LocationController.d.ts +++ b/TypeScript/16ImporterUtil/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/16ImporterUtil/types/controllers/QuestController.d.ts b/TypeScript/16ImporterUtil/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/16ImporterUtil/types/controllers/QuestController.d.ts +++ b/TypeScript/16ImporterUtil/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/16ImporterUtil/types/controllers/TradeController.d.ts b/TypeScript/16ImporterUtil/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/16ImporterUtil/types/controllers/TradeController.d.ts +++ b/TypeScript/16ImporterUtil/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/16ImporterUtil/types/generators/BotWeaponGenerator.d.ts b/TypeScript/16ImporterUtil/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/16ImporterUtil/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/16ImporterUtil/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/16ImporterUtil/types/generators/LocationGenerator.d.ts b/TypeScript/16ImporterUtil/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/16ImporterUtil/types/generators/LocationGenerator.d.ts +++ b/TypeScript/16ImporterUtil/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/16ImporterUtil/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/16ImporterUtil/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/16ImporterUtil/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/16ImporterUtil/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/16ImporterUtil/types/helpers/HandbookHelper.d.ts b/TypeScript/16ImporterUtil/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/16ImporterUtil/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/16ImporterUtil/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/16ImporterUtil/types/helpers/InRaidHelper.d.ts b/TypeScript/16ImporterUtil/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/16ImporterUtil/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/16ImporterUtil/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/16ImporterUtil/types/helpers/ItemHelper.d.ts b/TypeScript/16ImporterUtil/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/16ImporterUtil/types/helpers/ItemHelper.d.ts +++ b/TypeScript/16ImporterUtil/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/16ImporterUtil/types/helpers/QuestHelper.d.ts b/TypeScript/16ImporterUtil/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/16ImporterUtil/types/helpers/QuestHelper.d.ts +++ b/TypeScript/16ImporterUtil/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/16ImporterUtil/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/16ImporterUtil/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/16ImporterUtil/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/16ImporterUtil/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/16ImporterUtil/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/16ImporterUtil/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/16ImporterUtil/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/16ImporterUtil/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/16ImporterUtil/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/16ImporterUtil/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/16ImporterUtil/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/16ImporterUtil/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/16ImporterUtil/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/16ImporterUtil/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/16ImporterUtil/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/16ImporterUtil/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/16ImporterUtil/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/16ImporterUtil/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/16ImporterUtil/types/models/enums/BaseClasses.d.ts b/TypeScript/16ImporterUtil/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/16ImporterUtil/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/16ImporterUtil/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/16ImporterUtil/types/models/enums/ItemAddedResult.d.ts b/TypeScript/16ImporterUtil/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/16ImporterUtil/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/16ImporterUtil/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/16ImporterUtil/types/models/spt/config/IBotConfig.d.ts b/TypeScript/16ImporterUtil/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/16ImporterUtil/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/16ImporterUtil/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/16ImporterUtil/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/16ImporterUtil/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/16ImporterUtil/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/16ImporterUtil/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/16ImporterUtil/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/16ImporterUtil/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/16ImporterUtil/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/16ImporterUtil/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/16ImporterUtil/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/16ImporterUtil/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/16ImporterUtil/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/16ImporterUtil/types/routers/EventOutputHolder.d.ts b/TypeScript/16ImporterUtil/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/16ImporterUtil/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/16ImporterUtil/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/16ImporterUtil/types/services/ProfileFixerService.d.ts b/TypeScript/16ImporterUtil/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/16ImporterUtil/types/services/ProfileFixerService.d.ts +++ b/TypeScript/16ImporterUtil/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/16ImporterUtil/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/16ImporterUtil/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/16ImporterUtil/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/16ImporterUtil/types/utils/HttpResponseUtil.d.ts b/TypeScript/16ImporterUtil/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/16ImporterUtil/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/16ImporterUtil/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/16ImporterUtil/types/utils/RandomUtil.d.ts b/TypeScript/16ImporterUtil/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/16ImporterUtil/types/utils/RandomUtil.d.ts +++ b/TypeScript/16ImporterUtil/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/17AsyncImporterWithDependency1/types/callbacks/GameCallbacks.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/17AsyncImporterWithDependency1/types/context/ApplicationContext.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/context/ApplicationContext.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/17AsyncImporterWithDependency1/types/context/ContextVariableType.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/context/ContextVariableType.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/17AsyncImporterWithDependency1/types/controllers/GameController.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/controllers/GameController.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/17AsyncImporterWithDependency1/types/controllers/HideoutController.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/controllers/HideoutController.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/17AsyncImporterWithDependency1/types/controllers/InraidController.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/controllers/InraidController.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/17AsyncImporterWithDependency1/types/controllers/LocationController.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/controllers/LocationController.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/17AsyncImporterWithDependency1/types/controllers/QuestController.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/controllers/QuestController.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/17AsyncImporterWithDependency1/types/controllers/TradeController.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/controllers/TradeController.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/17AsyncImporterWithDependency1/types/generators/BotWeaponGenerator.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/17AsyncImporterWithDependency1/types/generators/LocationGenerator.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/generators/LocationGenerator.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/17AsyncImporterWithDependency1/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/17AsyncImporterWithDependency1/types/helpers/HandbookHelper.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/17AsyncImporterWithDependency1/types/helpers/InRaidHelper.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/17AsyncImporterWithDependency1/types/helpers/ItemHelper.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/helpers/ItemHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/17AsyncImporterWithDependency1/types/helpers/QuestHelper.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/helpers/QuestHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/17AsyncImporterWithDependency1/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/17AsyncImporterWithDependency1/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/17AsyncImporterWithDependency1/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/17AsyncImporterWithDependency1/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/17AsyncImporterWithDependency1/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/17AsyncImporterWithDependency1/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/17AsyncImporterWithDependency1/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/17AsyncImporterWithDependency1/types/models/enums/BaseClasses.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/17AsyncImporterWithDependency1/types/models/enums/ItemAddedResult.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/IBotConfig.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/17AsyncImporterWithDependency1/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/17AsyncImporterWithDependency1/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/17AsyncImporterWithDependency1/types/routers/EventOutputHolder.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/17AsyncImporterWithDependency1/types/services/ProfileFixerService.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/services/ProfileFixerService.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/17AsyncImporterWithDependency1/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/17AsyncImporterWithDependency1/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/17AsyncImporterWithDependency1/types/utils/HttpResponseUtil.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/17AsyncImporterWithDependency1/types/utils/RandomUtil.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/utils/RandomUtil.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/17AsyncImporterWithDependency2/types/callbacks/GameCallbacks.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/17AsyncImporterWithDependency2/types/context/ApplicationContext.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/context/ApplicationContext.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/17AsyncImporterWithDependency2/types/context/ContextVariableType.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/context/ContextVariableType.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/17AsyncImporterWithDependency2/types/controllers/GameController.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/controllers/GameController.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/17AsyncImporterWithDependency2/types/controllers/HideoutController.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/controllers/HideoutController.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/17AsyncImporterWithDependency2/types/controllers/InraidController.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/controllers/InraidController.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/17AsyncImporterWithDependency2/types/controllers/LocationController.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/controllers/LocationController.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/17AsyncImporterWithDependency2/types/controllers/QuestController.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/controllers/QuestController.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/17AsyncImporterWithDependency2/types/controllers/TradeController.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/controllers/TradeController.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/17AsyncImporterWithDependency2/types/generators/BotWeaponGenerator.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/17AsyncImporterWithDependency2/types/generators/LocationGenerator.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/generators/LocationGenerator.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/17AsyncImporterWithDependency2/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/17AsyncImporterWithDependency2/types/helpers/HandbookHelper.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/17AsyncImporterWithDependency2/types/helpers/InRaidHelper.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/17AsyncImporterWithDependency2/types/helpers/ItemHelper.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/helpers/ItemHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/17AsyncImporterWithDependency2/types/helpers/QuestHelper.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/helpers/QuestHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/17AsyncImporterWithDependency2/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/17AsyncImporterWithDependency2/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/17AsyncImporterWithDependency2/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/17AsyncImporterWithDependency2/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/17AsyncImporterWithDependency2/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/17AsyncImporterWithDependency2/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/17AsyncImporterWithDependency2/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/17AsyncImporterWithDependency2/types/models/enums/BaseClasses.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/17AsyncImporterWithDependency2/types/models/enums/ItemAddedResult.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/IBotConfig.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/17AsyncImporterWithDependency2/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/17AsyncImporterWithDependency2/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/17AsyncImporterWithDependency2/types/routers/EventOutputHolder.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/17AsyncImporterWithDependency2/types/services/ProfileFixerService.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/services/ProfileFixerService.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/17AsyncImporterWithDependency2/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/17AsyncImporterWithDependency2/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/17AsyncImporterWithDependency2/types/utils/HttpResponseUtil.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/17AsyncImporterWithDependency2/types/utils/RandomUtil.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/utils/RandomUtil.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/18CustomItemService/types/callbacks/GameCallbacks.d.ts b/TypeScript/18CustomItemService/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/18CustomItemService/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/18CustomItemService/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/18CustomItemService/types/context/ApplicationContext.d.ts b/TypeScript/18CustomItemService/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/18CustomItemService/types/context/ApplicationContext.d.ts +++ b/TypeScript/18CustomItemService/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/18CustomItemService/types/context/ContextVariableType.d.ts b/TypeScript/18CustomItemService/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/18CustomItemService/types/context/ContextVariableType.d.ts +++ b/TypeScript/18CustomItemService/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/18CustomItemService/types/controllers/GameController.d.ts b/TypeScript/18CustomItemService/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/18CustomItemService/types/controllers/GameController.d.ts +++ b/TypeScript/18CustomItemService/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/18CustomItemService/types/controllers/HideoutController.d.ts b/TypeScript/18CustomItemService/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/18CustomItemService/types/controllers/HideoutController.d.ts +++ b/TypeScript/18CustomItemService/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/18CustomItemService/types/controllers/InraidController.d.ts b/TypeScript/18CustomItemService/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/18CustomItemService/types/controllers/InraidController.d.ts +++ b/TypeScript/18CustomItemService/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/18CustomItemService/types/controllers/LocationController.d.ts b/TypeScript/18CustomItemService/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/18CustomItemService/types/controllers/LocationController.d.ts +++ b/TypeScript/18CustomItemService/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/18CustomItemService/types/controllers/QuestController.d.ts b/TypeScript/18CustomItemService/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/18CustomItemService/types/controllers/QuestController.d.ts +++ b/TypeScript/18CustomItemService/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/18CustomItemService/types/controllers/TradeController.d.ts b/TypeScript/18CustomItemService/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/18CustomItemService/types/controllers/TradeController.d.ts +++ b/TypeScript/18CustomItemService/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/18CustomItemService/types/generators/BotWeaponGenerator.d.ts b/TypeScript/18CustomItemService/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/18CustomItemService/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/18CustomItemService/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/18CustomItemService/types/generators/LocationGenerator.d.ts b/TypeScript/18CustomItemService/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/18CustomItemService/types/generators/LocationGenerator.d.ts +++ b/TypeScript/18CustomItemService/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/18CustomItemService/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/18CustomItemService/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/18CustomItemService/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/18CustomItemService/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/18CustomItemService/types/helpers/HandbookHelper.d.ts b/TypeScript/18CustomItemService/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/18CustomItemService/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/18CustomItemService/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/18CustomItemService/types/helpers/InRaidHelper.d.ts b/TypeScript/18CustomItemService/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/18CustomItemService/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/18CustomItemService/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/18CustomItemService/types/helpers/ItemHelper.d.ts b/TypeScript/18CustomItemService/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/18CustomItemService/types/helpers/ItemHelper.d.ts +++ b/TypeScript/18CustomItemService/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/18CustomItemService/types/helpers/QuestHelper.d.ts b/TypeScript/18CustomItemService/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/18CustomItemService/types/helpers/QuestHelper.d.ts +++ b/TypeScript/18CustomItemService/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/18CustomItemService/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/18CustomItemService/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/18CustomItemService/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/18CustomItemService/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/18CustomItemService/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/18CustomItemService/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/18CustomItemService/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/18CustomItemService/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/18CustomItemService/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/18CustomItemService/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/18CustomItemService/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/18CustomItemService/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/18CustomItemService/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/18CustomItemService/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/18CustomItemService/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/18CustomItemService/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/18CustomItemService/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/18CustomItemService/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/18CustomItemService/types/models/enums/BaseClasses.d.ts b/TypeScript/18CustomItemService/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/18CustomItemService/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/18CustomItemService/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/18CustomItemService/types/models/enums/ItemAddedResult.d.ts b/TypeScript/18CustomItemService/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/18CustomItemService/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/18CustomItemService/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/18CustomItemService/types/models/spt/config/IBotConfig.d.ts b/TypeScript/18CustomItemService/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/18CustomItemService/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/18CustomItemService/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/18CustomItemService/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/18CustomItemService/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/18CustomItemService/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/18CustomItemService/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/18CustomItemService/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/18CustomItemService/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/18CustomItemService/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/18CustomItemService/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/18CustomItemService/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/18CustomItemService/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/18CustomItemService/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/18CustomItemService/types/routers/EventOutputHolder.d.ts b/TypeScript/18CustomItemService/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/18CustomItemService/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/18CustomItemService/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/18CustomItemService/types/services/ProfileFixerService.d.ts b/TypeScript/18CustomItemService/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/18CustomItemService/types/services/ProfileFixerService.d.ts +++ b/TypeScript/18CustomItemService/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/18CustomItemService/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/18CustomItemService/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/18CustomItemService/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/18CustomItemService/types/utils/HttpResponseUtil.d.ts b/TypeScript/18CustomItemService/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/18CustomItemService/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/18CustomItemService/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/18CustomItemService/types/utils/RandomUtil.d.ts b/TypeScript/18CustomItemService/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/18CustomItemService/types/utils/RandomUtil.d.ts +++ b/TypeScript/18CustomItemService/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/19UseExternalLibraries/types/callbacks/GameCallbacks.d.ts b/TypeScript/19UseExternalLibraries/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/19UseExternalLibraries/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/19UseExternalLibraries/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/19UseExternalLibraries/types/context/ApplicationContext.d.ts b/TypeScript/19UseExternalLibraries/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/19UseExternalLibraries/types/context/ApplicationContext.d.ts +++ b/TypeScript/19UseExternalLibraries/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/19UseExternalLibraries/types/context/ContextVariableType.d.ts b/TypeScript/19UseExternalLibraries/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/19UseExternalLibraries/types/context/ContextVariableType.d.ts +++ b/TypeScript/19UseExternalLibraries/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/19UseExternalLibraries/types/controllers/GameController.d.ts b/TypeScript/19UseExternalLibraries/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/19UseExternalLibraries/types/controllers/GameController.d.ts +++ b/TypeScript/19UseExternalLibraries/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/19UseExternalLibraries/types/controllers/HideoutController.d.ts b/TypeScript/19UseExternalLibraries/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/19UseExternalLibraries/types/controllers/HideoutController.d.ts +++ b/TypeScript/19UseExternalLibraries/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/19UseExternalLibraries/types/controllers/InraidController.d.ts b/TypeScript/19UseExternalLibraries/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/19UseExternalLibraries/types/controllers/InraidController.d.ts +++ b/TypeScript/19UseExternalLibraries/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/19UseExternalLibraries/types/controllers/LocationController.d.ts b/TypeScript/19UseExternalLibraries/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/19UseExternalLibraries/types/controllers/LocationController.d.ts +++ b/TypeScript/19UseExternalLibraries/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/19UseExternalLibraries/types/controllers/QuestController.d.ts b/TypeScript/19UseExternalLibraries/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/19UseExternalLibraries/types/controllers/QuestController.d.ts +++ b/TypeScript/19UseExternalLibraries/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/19UseExternalLibraries/types/controllers/TradeController.d.ts b/TypeScript/19UseExternalLibraries/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/19UseExternalLibraries/types/controllers/TradeController.d.ts +++ b/TypeScript/19UseExternalLibraries/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/19UseExternalLibraries/types/generators/BotWeaponGenerator.d.ts b/TypeScript/19UseExternalLibraries/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/19UseExternalLibraries/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/19UseExternalLibraries/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/19UseExternalLibraries/types/generators/LocationGenerator.d.ts b/TypeScript/19UseExternalLibraries/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/19UseExternalLibraries/types/generators/LocationGenerator.d.ts +++ b/TypeScript/19UseExternalLibraries/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/19UseExternalLibraries/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/19UseExternalLibraries/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/19UseExternalLibraries/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/19UseExternalLibraries/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/19UseExternalLibraries/types/helpers/HandbookHelper.d.ts b/TypeScript/19UseExternalLibraries/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/19UseExternalLibraries/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/19UseExternalLibraries/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/19UseExternalLibraries/types/helpers/InRaidHelper.d.ts b/TypeScript/19UseExternalLibraries/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/19UseExternalLibraries/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/19UseExternalLibraries/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/19UseExternalLibraries/types/helpers/ItemHelper.d.ts b/TypeScript/19UseExternalLibraries/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/19UseExternalLibraries/types/helpers/ItemHelper.d.ts +++ b/TypeScript/19UseExternalLibraries/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/19UseExternalLibraries/types/helpers/QuestHelper.d.ts b/TypeScript/19UseExternalLibraries/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/19UseExternalLibraries/types/helpers/QuestHelper.d.ts +++ b/TypeScript/19UseExternalLibraries/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/19UseExternalLibraries/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/19UseExternalLibraries/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/19UseExternalLibraries/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/19UseExternalLibraries/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/19UseExternalLibraries/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/19UseExternalLibraries/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/19UseExternalLibraries/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/19UseExternalLibraries/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/19UseExternalLibraries/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/19UseExternalLibraries/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/19UseExternalLibraries/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/19UseExternalLibraries/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/19UseExternalLibraries/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/19UseExternalLibraries/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/19UseExternalLibraries/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/19UseExternalLibraries/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/19UseExternalLibraries/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/19UseExternalLibraries/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/19UseExternalLibraries/types/models/enums/BaseClasses.d.ts b/TypeScript/19UseExternalLibraries/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/19UseExternalLibraries/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/19UseExternalLibraries/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/19UseExternalLibraries/types/models/enums/ItemAddedResult.d.ts b/TypeScript/19UseExternalLibraries/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/19UseExternalLibraries/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/19UseExternalLibraries/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/19UseExternalLibraries/types/models/spt/config/IBotConfig.d.ts b/TypeScript/19UseExternalLibraries/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/19UseExternalLibraries/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/19UseExternalLibraries/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/19UseExternalLibraries/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/19UseExternalLibraries/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/19UseExternalLibraries/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/19UseExternalLibraries/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/19UseExternalLibraries/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/19UseExternalLibraries/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/19UseExternalLibraries/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/19UseExternalLibraries/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/19UseExternalLibraries/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/19UseExternalLibraries/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/19UseExternalLibraries/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/19UseExternalLibraries/types/routers/EventOutputHolder.d.ts b/TypeScript/19UseExternalLibraries/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/19UseExternalLibraries/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/19UseExternalLibraries/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/19UseExternalLibraries/types/services/ProfileFixerService.d.ts b/TypeScript/19UseExternalLibraries/types/services/ProfileFixerService.d.ts index b01f4a3..205d92c 100644 --- a/TypeScript/19UseExternalLibraries/types/services/ProfileFixerService.d.ts +++ b/TypeScript/19UseExternalLibraries/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements diff --git a/TypeScript/19UseExternalLibraries/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/19UseExternalLibraries/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/19UseExternalLibraries/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/19UseExternalLibraries/types/utils/HttpResponseUtil.d.ts b/TypeScript/19UseExternalLibraries/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/19UseExternalLibraries/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/19UseExternalLibraries/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/19UseExternalLibraries/types/utils/RandomUtil.d.ts b/TypeScript/19UseExternalLibraries/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/19UseExternalLibraries/types/utils/RandomUtil.d.ts +++ b/TypeScript/19UseExternalLibraries/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/1LogToConsole/types/callbacks/GameCallbacks.d.ts b/TypeScript/1LogToConsole/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/1LogToConsole/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/1LogToConsole/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/1LogToConsole/types/context/ApplicationContext.d.ts b/TypeScript/1LogToConsole/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/1LogToConsole/types/context/ApplicationContext.d.ts +++ b/TypeScript/1LogToConsole/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/1LogToConsole/types/context/ContextVariableType.d.ts b/TypeScript/1LogToConsole/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/1LogToConsole/types/context/ContextVariableType.d.ts +++ b/TypeScript/1LogToConsole/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/1LogToConsole/types/controllers/GameController.d.ts b/TypeScript/1LogToConsole/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/1LogToConsole/types/controllers/GameController.d.ts +++ b/TypeScript/1LogToConsole/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/1LogToConsole/types/controllers/HideoutController.d.ts b/TypeScript/1LogToConsole/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/1LogToConsole/types/controllers/HideoutController.d.ts +++ b/TypeScript/1LogToConsole/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/1LogToConsole/types/controllers/InraidController.d.ts b/TypeScript/1LogToConsole/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/1LogToConsole/types/controllers/InraidController.d.ts +++ b/TypeScript/1LogToConsole/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/1LogToConsole/types/controllers/LocationController.d.ts b/TypeScript/1LogToConsole/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/1LogToConsole/types/controllers/LocationController.d.ts +++ b/TypeScript/1LogToConsole/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/1LogToConsole/types/controllers/QuestController.d.ts b/TypeScript/1LogToConsole/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/1LogToConsole/types/controllers/QuestController.d.ts +++ b/TypeScript/1LogToConsole/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/1LogToConsole/types/controllers/TradeController.d.ts b/TypeScript/1LogToConsole/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/1LogToConsole/types/controllers/TradeController.d.ts +++ b/TypeScript/1LogToConsole/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/1LogToConsole/types/generators/BotWeaponGenerator.d.ts b/TypeScript/1LogToConsole/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/1LogToConsole/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/1LogToConsole/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/1LogToConsole/types/generators/LocationGenerator.d.ts b/TypeScript/1LogToConsole/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/1LogToConsole/types/generators/LocationGenerator.d.ts +++ b/TypeScript/1LogToConsole/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/1LogToConsole/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/1LogToConsole/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/1LogToConsole/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/1LogToConsole/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/1LogToConsole/types/helpers/HandbookHelper.d.ts b/TypeScript/1LogToConsole/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/1LogToConsole/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/1LogToConsole/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/1LogToConsole/types/helpers/InRaidHelper.d.ts b/TypeScript/1LogToConsole/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/1LogToConsole/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/1LogToConsole/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/1LogToConsole/types/helpers/ItemHelper.d.ts b/TypeScript/1LogToConsole/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/1LogToConsole/types/helpers/ItemHelper.d.ts +++ b/TypeScript/1LogToConsole/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/1LogToConsole/types/helpers/QuestHelper.d.ts b/TypeScript/1LogToConsole/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/1LogToConsole/types/helpers/QuestHelper.d.ts +++ b/TypeScript/1LogToConsole/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/1LogToConsole/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/1LogToConsole/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/1LogToConsole/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/1LogToConsole/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/1LogToConsole/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/1LogToConsole/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/1LogToConsole/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/1LogToConsole/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/1LogToConsole/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/1LogToConsole/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/1LogToConsole/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/1LogToConsole/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/1LogToConsole/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/1LogToConsole/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/1LogToConsole/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/1LogToConsole/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/1LogToConsole/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/1LogToConsole/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/1LogToConsole/types/models/enums/BaseClasses.d.ts b/TypeScript/1LogToConsole/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/1LogToConsole/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/1LogToConsole/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/1LogToConsole/types/models/enums/ItemAddedResult.d.ts b/TypeScript/1LogToConsole/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/1LogToConsole/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/1LogToConsole/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/1LogToConsole/types/models/spt/config/IBotConfig.d.ts b/TypeScript/1LogToConsole/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/1LogToConsole/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/1LogToConsole/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/1LogToConsole/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/1LogToConsole/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/1LogToConsole/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/1LogToConsole/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/1LogToConsole/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/1LogToConsole/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/1LogToConsole/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/1LogToConsole/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/1LogToConsole/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/1LogToConsole/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/1LogToConsole/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/1LogToConsole/types/routers/EventOutputHolder.d.ts b/TypeScript/1LogToConsole/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/1LogToConsole/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/1LogToConsole/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/1LogToConsole/types/services/ProfileFixerService.d.ts b/TypeScript/1LogToConsole/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/1LogToConsole/types/services/ProfileFixerService.d.ts +++ b/TypeScript/1LogToConsole/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/1LogToConsole/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/1LogToConsole/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/1LogToConsole/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/1LogToConsole/types/utils/HttpResponseUtil.d.ts b/TypeScript/1LogToConsole/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/1LogToConsole/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/1LogToConsole/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/1LogToConsole/types/utils/RandomUtil.d.ts b/TypeScript/1LogToConsole/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/1LogToConsole/types/utils/RandomUtil.d.ts +++ b/TypeScript/1LogToConsole/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/2EditDatabase/types/callbacks/GameCallbacks.d.ts b/TypeScript/2EditDatabase/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/2EditDatabase/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/2EditDatabase/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/2EditDatabase/types/context/ApplicationContext.d.ts b/TypeScript/2EditDatabase/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/2EditDatabase/types/context/ApplicationContext.d.ts +++ b/TypeScript/2EditDatabase/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/2EditDatabase/types/context/ContextVariableType.d.ts b/TypeScript/2EditDatabase/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/2EditDatabase/types/context/ContextVariableType.d.ts +++ b/TypeScript/2EditDatabase/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/2EditDatabase/types/controllers/GameController.d.ts b/TypeScript/2EditDatabase/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/2EditDatabase/types/controllers/GameController.d.ts +++ b/TypeScript/2EditDatabase/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/2EditDatabase/types/controllers/HideoutController.d.ts b/TypeScript/2EditDatabase/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/2EditDatabase/types/controllers/HideoutController.d.ts +++ b/TypeScript/2EditDatabase/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/2EditDatabase/types/controllers/InraidController.d.ts b/TypeScript/2EditDatabase/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/2EditDatabase/types/controllers/InraidController.d.ts +++ b/TypeScript/2EditDatabase/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/2EditDatabase/types/controllers/LocationController.d.ts b/TypeScript/2EditDatabase/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/2EditDatabase/types/controllers/LocationController.d.ts +++ b/TypeScript/2EditDatabase/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/2EditDatabase/types/controllers/QuestController.d.ts b/TypeScript/2EditDatabase/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/2EditDatabase/types/controllers/QuestController.d.ts +++ b/TypeScript/2EditDatabase/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/2EditDatabase/types/controllers/TradeController.d.ts b/TypeScript/2EditDatabase/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/2EditDatabase/types/controllers/TradeController.d.ts +++ b/TypeScript/2EditDatabase/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/2EditDatabase/types/generators/BotWeaponGenerator.d.ts b/TypeScript/2EditDatabase/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/2EditDatabase/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/2EditDatabase/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/2EditDatabase/types/generators/LocationGenerator.d.ts b/TypeScript/2EditDatabase/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/2EditDatabase/types/generators/LocationGenerator.d.ts +++ b/TypeScript/2EditDatabase/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/2EditDatabase/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/2EditDatabase/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/2EditDatabase/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/2EditDatabase/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/2EditDatabase/types/helpers/HandbookHelper.d.ts b/TypeScript/2EditDatabase/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/2EditDatabase/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/2EditDatabase/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/2EditDatabase/types/helpers/InRaidHelper.d.ts b/TypeScript/2EditDatabase/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/2EditDatabase/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/2EditDatabase/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/2EditDatabase/types/helpers/ItemHelper.d.ts b/TypeScript/2EditDatabase/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/2EditDatabase/types/helpers/ItemHelper.d.ts +++ b/TypeScript/2EditDatabase/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/2EditDatabase/types/helpers/QuestHelper.d.ts b/TypeScript/2EditDatabase/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/2EditDatabase/types/helpers/QuestHelper.d.ts +++ b/TypeScript/2EditDatabase/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/2EditDatabase/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/2EditDatabase/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/2EditDatabase/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/2EditDatabase/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/2EditDatabase/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/2EditDatabase/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/2EditDatabase/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/2EditDatabase/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/2EditDatabase/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/2EditDatabase/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/2EditDatabase/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/2EditDatabase/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/2EditDatabase/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/2EditDatabase/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/2EditDatabase/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/2EditDatabase/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/2EditDatabase/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/2EditDatabase/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/2EditDatabase/types/models/enums/BaseClasses.d.ts b/TypeScript/2EditDatabase/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/2EditDatabase/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/2EditDatabase/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/2EditDatabase/types/models/enums/ItemAddedResult.d.ts b/TypeScript/2EditDatabase/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/2EditDatabase/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/2EditDatabase/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/2EditDatabase/types/models/spt/config/IBotConfig.d.ts b/TypeScript/2EditDatabase/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/2EditDatabase/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/2EditDatabase/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/2EditDatabase/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/2EditDatabase/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/2EditDatabase/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/2EditDatabase/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/2EditDatabase/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/2EditDatabase/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/2EditDatabase/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/2EditDatabase/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/2EditDatabase/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/2EditDatabase/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/2EditDatabase/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/2EditDatabase/types/routers/EventOutputHolder.d.ts b/TypeScript/2EditDatabase/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/2EditDatabase/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/2EditDatabase/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/2EditDatabase/types/services/ProfileFixerService.d.ts b/TypeScript/2EditDatabase/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/2EditDatabase/types/services/ProfileFixerService.d.ts +++ b/TypeScript/2EditDatabase/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/2EditDatabase/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/2EditDatabase/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/2EditDatabase/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/2EditDatabase/types/utils/HttpResponseUtil.d.ts b/TypeScript/2EditDatabase/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/2EditDatabase/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/2EditDatabase/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/2EditDatabase/types/utils/RandomUtil.d.ts b/TypeScript/2EditDatabase/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/2EditDatabase/types/utils/RandomUtil.d.ts +++ b/TypeScript/2EditDatabase/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/3GetSptConfigFile/types/callbacks/GameCallbacks.d.ts b/TypeScript/3GetSptConfigFile/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/3GetSptConfigFile/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/3GetSptConfigFile/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/3GetSptConfigFile/types/context/ApplicationContext.d.ts b/TypeScript/3GetSptConfigFile/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/3GetSptConfigFile/types/context/ApplicationContext.d.ts +++ b/TypeScript/3GetSptConfigFile/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/3GetSptConfigFile/types/context/ContextVariableType.d.ts b/TypeScript/3GetSptConfigFile/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/3GetSptConfigFile/types/context/ContextVariableType.d.ts +++ b/TypeScript/3GetSptConfigFile/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/3GetSptConfigFile/types/controllers/GameController.d.ts b/TypeScript/3GetSptConfigFile/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/3GetSptConfigFile/types/controllers/GameController.d.ts +++ b/TypeScript/3GetSptConfigFile/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/3GetSptConfigFile/types/controllers/HideoutController.d.ts b/TypeScript/3GetSptConfigFile/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/3GetSptConfigFile/types/controllers/HideoutController.d.ts +++ b/TypeScript/3GetSptConfigFile/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/3GetSptConfigFile/types/controllers/InraidController.d.ts b/TypeScript/3GetSptConfigFile/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/3GetSptConfigFile/types/controllers/InraidController.d.ts +++ b/TypeScript/3GetSptConfigFile/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/3GetSptConfigFile/types/controllers/LocationController.d.ts b/TypeScript/3GetSptConfigFile/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/3GetSptConfigFile/types/controllers/LocationController.d.ts +++ b/TypeScript/3GetSptConfigFile/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/3GetSptConfigFile/types/controllers/QuestController.d.ts b/TypeScript/3GetSptConfigFile/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/3GetSptConfigFile/types/controllers/QuestController.d.ts +++ b/TypeScript/3GetSptConfigFile/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/3GetSptConfigFile/types/controllers/TradeController.d.ts b/TypeScript/3GetSptConfigFile/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/3GetSptConfigFile/types/controllers/TradeController.d.ts +++ b/TypeScript/3GetSptConfigFile/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/3GetSptConfigFile/types/generators/BotWeaponGenerator.d.ts b/TypeScript/3GetSptConfigFile/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/3GetSptConfigFile/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/3GetSptConfigFile/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/3GetSptConfigFile/types/generators/LocationGenerator.d.ts b/TypeScript/3GetSptConfigFile/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/3GetSptConfigFile/types/generators/LocationGenerator.d.ts +++ b/TypeScript/3GetSptConfigFile/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/3GetSptConfigFile/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/3GetSptConfigFile/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/3GetSptConfigFile/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/3GetSptConfigFile/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/3GetSptConfigFile/types/helpers/HandbookHelper.d.ts b/TypeScript/3GetSptConfigFile/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/3GetSptConfigFile/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/3GetSptConfigFile/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/3GetSptConfigFile/types/helpers/InRaidHelper.d.ts b/TypeScript/3GetSptConfigFile/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/3GetSptConfigFile/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/3GetSptConfigFile/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/3GetSptConfigFile/types/helpers/ItemHelper.d.ts b/TypeScript/3GetSptConfigFile/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/3GetSptConfigFile/types/helpers/ItemHelper.d.ts +++ b/TypeScript/3GetSptConfigFile/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/3GetSptConfigFile/types/helpers/QuestHelper.d.ts b/TypeScript/3GetSptConfigFile/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/3GetSptConfigFile/types/helpers/QuestHelper.d.ts +++ b/TypeScript/3GetSptConfigFile/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/3GetSptConfigFile/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/3GetSptConfigFile/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/3GetSptConfigFile/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/3GetSptConfigFile/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/3GetSptConfigFile/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/3GetSptConfigFile/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/3GetSptConfigFile/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/3GetSptConfigFile/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/3GetSptConfigFile/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/3GetSptConfigFile/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/3GetSptConfigFile/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/3GetSptConfigFile/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/3GetSptConfigFile/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/3GetSptConfigFile/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/3GetSptConfigFile/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/3GetSptConfigFile/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/3GetSptConfigFile/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/3GetSptConfigFile/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/3GetSptConfigFile/types/models/enums/BaseClasses.d.ts b/TypeScript/3GetSptConfigFile/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/3GetSptConfigFile/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/3GetSptConfigFile/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/3GetSptConfigFile/types/models/enums/ItemAddedResult.d.ts b/TypeScript/3GetSptConfigFile/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/3GetSptConfigFile/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/3GetSptConfigFile/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/3GetSptConfigFile/types/models/spt/config/IBotConfig.d.ts b/TypeScript/3GetSptConfigFile/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/3GetSptConfigFile/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/3GetSptConfigFile/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/3GetSptConfigFile/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/3GetSptConfigFile/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/3GetSptConfigFile/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/3GetSptConfigFile/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/3GetSptConfigFile/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/3GetSptConfigFile/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/3GetSptConfigFile/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/3GetSptConfigFile/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/3GetSptConfigFile/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/3GetSptConfigFile/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/3GetSptConfigFile/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/3GetSptConfigFile/types/routers/EventOutputHolder.d.ts b/TypeScript/3GetSptConfigFile/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/3GetSptConfigFile/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/3GetSptConfigFile/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/3GetSptConfigFile/types/services/ProfileFixerService.d.ts b/TypeScript/3GetSptConfigFile/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/3GetSptConfigFile/types/services/ProfileFixerService.d.ts +++ b/TypeScript/3GetSptConfigFile/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/3GetSptConfigFile/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/3GetSptConfigFile/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/3GetSptConfigFile/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/3GetSptConfigFile/types/utils/HttpResponseUtil.d.ts b/TypeScript/3GetSptConfigFile/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/3GetSptConfigFile/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/3GetSptConfigFile/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/3GetSptConfigFile/types/utils/RandomUtil.d.ts b/TypeScript/3GetSptConfigFile/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/3GetSptConfigFile/types/utils/RandomUtil.d.ts +++ b/TypeScript/3GetSptConfigFile/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/callbacks/GameCallbacks.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/context/ApplicationContext.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/context/ApplicationContext.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/context/ContextVariableType.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/context/ContextVariableType.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/GameController.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/GameController.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/HideoutController.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/HideoutController.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/InraidController.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/InraidController.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/LocationController.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/LocationController.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/QuestController.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/QuestController.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/TradeController.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/TradeController.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/BotWeaponGenerator.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/LocationGenerator.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/LocationGenerator.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/HandbookHelper.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/InRaidHelper.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/ItemHelper.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/ItemHelper.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/QuestHelper.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/QuestHelper.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/enums/BaseClasses.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/enums/ItemAddedResult.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/IBotConfig.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/routers/EventOutputHolder.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/ProfileFixerService.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/ProfileFixerService.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/utils/HttpResponseUtil.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/utils/RandomUtil.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/utils/RandomUtil.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/4UseACustomConfigFile/types/callbacks/GameCallbacks.d.ts b/TypeScript/4UseACustomConfigFile/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/4UseACustomConfigFile/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/4UseACustomConfigFile/types/context/ApplicationContext.d.ts b/TypeScript/4UseACustomConfigFile/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/4UseACustomConfigFile/types/context/ApplicationContext.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/4UseACustomConfigFile/types/context/ContextVariableType.d.ts b/TypeScript/4UseACustomConfigFile/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/4UseACustomConfigFile/types/context/ContextVariableType.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/4UseACustomConfigFile/types/controllers/GameController.d.ts b/TypeScript/4UseACustomConfigFile/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/4UseACustomConfigFile/types/controllers/GameController.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/4UseACustomConfigFile/types/controllers/HideoutController.d.ts b/TypeScript/4UseACustomConfigFile/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/4UseACustomConfigFile/types/controllers/HideoutController.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/4UseACustomConfigFile/types/controllers/InraidController.d.ts b/TypeScript/4UseACustomConfigFile/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/4UseACustomConfigFile/types/controllers/InraidController.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/4UseACustomConfigFile/types/controllers/LocationController.d.ts b/TypeScript/4UseACustomConfigFile/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/4UseACustomConfigFile/types/controllers/LocationController.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/4UseACustomConfigFile/types/controllers/QuestController.d.ts b/TypeScript/4UseACustomConfigFile/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/4UseACustomConfigFile/types/controllers/QuestController.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/4UseACustomConfigFile/types/controllers/TradeController.d.ts b/TypeScript/4UseACustomConfigFile/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/4UseACustomConfigFile/types/controllers/TradeController.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/4UseACustomConfigFile/types/generators/BotWeaponGenerator.d.ts b/TypeScript/4UseACustomConfigFile/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/4UseACustomConfigFile/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/4UseACustomConfigFile/types/generators/LocationGenerator.d.ts b/TypeScript/4UseACustomConfigFile/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/4UseACustomConfigFile/types/generators/LocationGenerator.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/4UseACustomConfigFile/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/4UseACustomConfigFile/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/4UseACustomConfigFile/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/HandbookHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/4UseACustomConfigFile/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/InRaidHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/4UseACustomConfigFile/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/ItemHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/4UseACustomConfigFile/types/helpers/ItemHelper.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/QuestHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/4UseACustomConfigFile/types/helpers/QuestHelper.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/4UseACustomConfigFile/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/4UseACustomConfigFile/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/4UseACustomConfigFile/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/4UseACustomConfigFile/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/4UseACustomConfigFile/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/4UseACustomConfigFile/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/4UseACustomConfigFile/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/4UseACustomConfigFile/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/4UseACustomConfigFile/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/4UseACustomConfigFile/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/4UseACustomConfigFile/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/4UseACustomConfigFile/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/4UseACustomConfigFile/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/4UseACustomConfigFile/types/models/enums/BaseClasses.d.ts b/TypeScript/4UseACustomConfigFile/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/4UseACustomConfigFile/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/4UseACustomConfigFile/types/models/enums/ItemAddedResult.d.ts b/TypeScript/4UseACustomConfigFile/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/4UseACustomConfigFile/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/config/IBotConfig.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/4UseACustomConfigFile/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/4UseACustomConfigFile/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/4UseACustomConfigFile/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/4UseACustomConfigFile/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/4UseACustomConfigFile/types/routers/EventOutputHolder.d.ts b/TypeScript/4UseACustomConfigFile/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/4UseACustomConfigFile/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/4UseACustomConfigFile/types/services/ProfileFixerService.d.ts b/TypeScript/4UseACustomConfigFile/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/4UseACustomConfigFile/types/services/ProfileFixerService.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/4UseACustomConfigFile/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/4UseACustomConfigFile/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/4UseACustomConfigFile/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/4UseACustomConfigFile/types/utils/HttpResponseUtil.d.ts b/TypeScript/4UseACustomConfigFile/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/4UseACustomConfigFile/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/4UseACustomConfigFile/types/utils/RandomUtil.d.ts b/TypeScript/4UseACustomConfigFile/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/4UseACustomConfigFile/types/utils/RandomUtil.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/5ReplaceMethod/types/callbacks/GameCallbacks.d.ts b/TypeScript/5ReplaceMethod/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/5ReplaceMethod/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/5ReplaceMethod/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/5ReplaceMethod/types/context/ApplicationContext.d.ts b/TypeScript/5ReplaceMethod/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/5ReplaceMethod/types/context/ApplicationContext.d.ts +++ b/TypeScript/5ReplaceMethod/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/5ReplaceMethod/types/context/ContextVariableType.d.ts b/TypeScript/5ReplaceMethod/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/5ReplaceMethod/types/context/ContextVariableType.d.ts +++ b/TypeScript/5ReplaceMethod/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/5ReplaceMethod/types/controllers/GameController.d.ts b/TypeScript/5ReplaceMethod/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/5ReplaceMethod/types/controllers/GameController.d.ts +++ b/TypeScript/5ReplaceMethod/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/5ReplaceMethod/types/controllers/HideoutController.d.ts b/TypeScript/5ReplaceMethod/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/5ReplaceMethod/types/controllers/HideoutController.d.ts +++ b/TypeScript/5ReplaceMethod/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/5ReplaceMethod/types/controllers/InraidController.d.ts b/TypeScript/5ReplaceMethod/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/5ReplaceMethod/types/controllers/InraidController.d.ts +++ b/TypeScript/5ReplaceMethod/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/5ReplaceMethod/types/controllers/LocationController.d.ts b/TypeScript/5ReplaceMethod/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/5ReplaceMethod/types/controllers/LocationController.d.ts +++ b/TypeScript/5ReplaceMethod/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/5ReplaceMethod/types/controllers/QuestController.d.ts b/TypeScript/5ReplaceMethod/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/5ReplaceMethod/types/controllers/QuestController.d.ts +++ b/TypeScript/5ReplaceMethod/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/5ReplaceMethod/types/controllers/TradeController.d.ts b/TypeScript/5ReplaceMethod/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/5ReplaceMethod/types/controllers/TradeController.d.ts +++ b/TypeScript/5ReplaceMethod/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/5ReplaceMethod/types/generators/BotWeaponGenerator.d.ts b/TypeScript/5ReplaceMethod/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/5ReplaceMethod/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/5ReplaceMethod/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/5ReplaceMethod/types/generators/LocationGenerator.d.ts b/TypeScript/5ReplaceMethod/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/5ReplaceMethod/types/generators/LocationGenerator.d.ts +++ b/TypeScript/5ReplaceMethod/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/5ReplaceMethod/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/5ReplaceMethod/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/5ReplaceMethod/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/5ReplaceMethod/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/5ReplaceMethod/types/helpers/HandbookHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/5ReplaceMethod/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/5ReplaceMethod/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/5ReplaceMethod/types/helpers/InRaidHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/5ReplaceMethod/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/5ReplaceMethod/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/5ReplaceMethod/types/helpers/ItemHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/5ReplaceMethod/types/helpers/ItemHelper.d.ts +++ b/TypeScript/5ReplaceMethod/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/5ReplaceMethod/types/helpers/QuestHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/5ReplaceMethod/types/helpers/QuestHelper.d.ts +++ b/TypeScript/5ReplaceMethod/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/5ReplaceMethod/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/5ReplaceMethod/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/5ReplaceMethod/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/5ReplaceMethod/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/5ReplaceMethod/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/5ReplaceMethod/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/5ReplaceMethod/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/5ReplaceMethod/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/5ReplaceMethod/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/5ReplaceMethod/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/5ReplaceMethod/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/5ReplaceMethod/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/5ReplaceMethod/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/5ReplaceMethod/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/5ReplaceMethod/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/5ReplaceMethod/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/5ReplaceMethod/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/5ReplaceMethod/types/models/enums/BaseClasses.d.ts b/TypeScript/5ReplaceMethod/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/5ReplaceMethod/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/5ReplaceMethod/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/5ReplaceMethod/types/models/enums/ItemAddedResult.d.ts b/TypeScript/5ReplaceMethod/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/5ReplaceMethod/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/5ReplaceMethod/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/5ReplaceMethod/types/models/spt/config/IBotConfig.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/5ReplaceMethod/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/5ReplaceMethod/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/5ReplaceMethod/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/5ReplaceMethod/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/5ReplaceMethod/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/5ReplaceMethod/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/5ReplaceMethod/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/5ReplaceMethod/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/5ReplaceMethod/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/5ReplaceMethod/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/5ReplaceMethod/types/routers/EventOutputHolder.d.ts b/TypeScript/5ReplaceMethod/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/5ReplaceMethod/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/5ReplaceMethod/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/5ReplaceMethod/types/services/ProfileFixerService.d.ts b/TypeScript/5ReplaceMethod/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/5ReplaceMethod/types/services/ProfileFixerService.d.ts +++ b/TypeScript/5ReplaceMethod/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/5ReplaceMethod/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/5ReplaceMethod/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/5ReplaceMethod/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/5ReplaceMethod/types/utils/HttpResponseUtil.d.ts b/TypeScript/5ReplaceMethod/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/5ReplaceMethod/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/5ReplaceMethod/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/5ReplaceMethod/types/utils/RandomUtil.d.ts b/TypeScript/5ReplaceMethod/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/5ReplaceMethod/types/utils/RandomUtil.d.ts +++ b/TypeScript/5ReplaceMethod/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/6ReferenceAnotherClass/types/callbacks/GameCallbacks.d.ts b/TypeScript/6ReferenceAnotherClass/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/6ReferenceAnotherClass/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/6ReferenceAnotherClass/types/context/ApplicationContext.d.ts b/TypeScript/6ReferenceAnotherClass/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/6ReferenceAnotherClass/types/context/ApplicationContext.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/6ReferenceAnotherClass/types/context/ContextVariableType.d.ts b/TypeScript/6ReferenceAnotherClass/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/6ReferenceAnotherClass/types/context/ContextVariableType.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/6ReferenceAnotherClass/types/controllers/GameController.d.ts b/TypeScript/6ReferenceAnotherClass/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/6ReferenceAnotherClass/types/controllers/GameController.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/6ReferenceAnotherClass/types/controllers/HideoutController.d.ts b/TypeScript/6ReferenceAnotherClass/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/6ReferenceAnotherClass/types/controllers/HideoutController.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/6ReferenceAnotherClass/types/controllers/InraidController.d.ts b/TypeScript/6ReferenceAnotherClass/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/6ReferenceAnotherClass/types/controllers/InraidController.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/6ReferenceAnotherClass/types/controllers/LocationController.d.ts b/TypeScript/6ReferenceAnotherClass/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/6ReferenceAnotherClass/types/controllers/LocationController.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/6ReferenceAnotherClass/types/controllers/QuestController.d.ts b/TypeScript/6ReferenceAnotherClass/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/6ReferenceAnotherClass/types/controllers/QuestController.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/6ReferenceAnotherClass/types/controllers/TradeController.d.ts b/TypeScript/6ReferenceAnotherClass/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/6ReferenceAnotherClass/types/controllers/TradeController.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/6ReferenceAnotherClass/types/generators/BotWeaponGenerator.d.ts b/TypeScript/6ReferenceAnotherClass/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/6ReferenceAnotherClass/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/6ReferenceAnotherClass/types/generators/LocationGenerator.d.ts b/TypeScript/6ReferenceAnotherClass/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/6ReferenceAnotherClass/types/generators/LocationGenerator.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/6ReferenceAnotherClass/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/6ReferenceAnotherClass/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/6ReferenceAnotherClass/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/HandbookHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/6ReferenceAnotherClass/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/InRaidHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/6ReferenceAnotherClass/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/ItemHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/6ReferenceAnotherClass/types/helpers/ItemHelper.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/QuestHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/6ReferenceAnotherClass/types/helpers/QuestHelper.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/6ReferenceAnotherClass/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/6ReferenceAnotherClass/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/6ReferenceAnotherClass/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/6ReferenceAnotherClass/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/6ReferenceAnotherClass/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/6ReferenceAnotherClass/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/6ReferenceAnotherClass/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/6ReferenceAnotherClass/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/6ReferenceAnotherClass/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/6ReferenceAnotherClass/types/models/enums/BaseClasses.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/6ReferenceAnotherClass/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/6ReferenceAnotherClass/types/models/enums/ItemAddedResult.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/6ReferenceAnotherClass/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IBotConfig.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/6ReferenceAnotherClass/types/routers/EventOutputHolder.d.ts b/TypeScript/6ReferenceAnotherClass/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/6ReferenceAnotherClass/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/6ReferenceAnotherClass/types/services/ProfileFixerService.d.ts b/TypeScript/6ReferenceAnotherClass/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/6ReferenceAnotherClass/types/services/ProfileFixerService.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/6ReferenceAnotherClass/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/6ReferenceAnotherClass/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/6ReferenceAnotherClass/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/6ReferenceAnotherClass/types/utils/HttpResponseUtil.d.ts b/TypeScript/6ReferenceAnotherClass/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/6ReferenceAnotherClass/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/6ReferenceAnotherClass/types/utils/RandomUtil.d.ts b/TypeScript/6ReferenceAnotherClass/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/6ReferenceAnotherClass/types/utils/RandomUtil.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/7OnLoadHook/types/callbacks/GameCallbacks.d.ts b/TypeScript/7OnLoadHook/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/7OnLoadHook/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/7OnLoadHook/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/7OnLoadHook/types/context/ApplicationContext.d.ts b/TypeScript/7OnLoadHook/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/7OnLoadHook/types/context/ApplicationContext.d.ts +++ b/TypeScript/7OnLoadHook/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/7OnLoadHook/types/context/ContextVariableType.d.ts b/TypeScript/7OnLoadHook/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/7OnLoadHook/types/context/ContextVariableType.d.ts +++ b/TypeScript/7OnLoadHook/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/7OnLoadHook/types/controllers/GameController.d.ts b/TypeScript/7OnLoadHook/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/7OnLoadHook/types/controllers/GameController.d.ts +++ b/TypeScript/7OnLoadHook/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/7OnLoadHook/types/controllers/HideoutController.d.ts b/TypeScript/7OnLoadHook/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/7OnLoadHook/types/controllers/HideoutController.d.ts +++ b/TypeScript/7OnLoadHook/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/7OnLoadHook/types/controllers/InraidController.d.ts b/TypeScript/7OnLoadHook/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/7OnLoadHook/types/controllers/InraidController.d.ts +++ b/TypeScript/7OnLoadHook/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/7OnLoadHook/types/controllers/LocationController.d.ts b/TypeScript/7OnLoadHook/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/7OnLoadHook/types/controllers/LocationController.d.ts +++ b/TypeScript/7OnLoadHook/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/7OnLoadHook/types/controllers/QuestController.d.ts b/TypeScript/7OnLoadHook/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/7OnLoadHook/types/controllers/QuestController.d.ts +++ b/TypeScript/7OnLoadHook/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/7OnLoadHook/types/controllers/TradeController.d.ts b/TypeScript/7OnLoadHook/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/7OnLoadHook/types/controllers/TradeController.d.ts +++ b/TypeScript/7OnLoadHook/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/7OnLoadHook/types/generators/BotWeaponGenerator.d.ts b/TypeScript/7OnLoadHook/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/7OnLoadHook/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/7OnLoadHook/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/7OnLoadHook/types/generators/LocationGenerator.d.ts b/TypeScript/7OnLoadHook/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/7OnLoadHook/types/generators/LocationGenerator.d.ts +++ b/TypeScript/7OnLoadHook/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/7OnLoadHook/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/7OnLoadHook/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/7OnLoadHook/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/7OnLoadHook/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/7OnLoadHook/types/helpers/HandbookHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/7OnLoadHook/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/7OnLoadHook/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/7OnLoadHook/types/helpers/InRaidHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/7OnLoadHook/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/7OnLoadHook/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/7OnLoadHook/types/helpers/ItemHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/7OnLoadHook/types/helpers/ItemHelper.d.ts +++ b/TypeScript/7OnLoadHook/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/7OnLoadHook/types/helpers/QuestHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/7OnLoadHook/types/helpers/QuestHelper.d.ts +++ b/TypeScript/7OnLoadHook/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/7OnLoadHook/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/7OnLoadHook/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/7OnLoadHook/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/7OnLoadHook/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/7OnLoadHook/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/7OnLoadHook/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/7OnLoadHook/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/7OnLoadHook/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/7OnLoadHook/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/7OnLoadHook/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/7OnLoadHook/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/7OnLoadHook/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/7OnLoadHook/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/7OnLoadHook/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/7OnLoadHook/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/7OnLoadHook/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/7OnLoadHook/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/7OnLoadHook/types/models/enums/BaseClasses.d.ts b/TypeScript/7OnLoadHook/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/7OnLoadHook/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/7OnLoadHook/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/7OnLoadHook/types/models/enums/ItemAddedResult.d.ts b/TypeScript/7OnLoadHook/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/7OnLoadHook/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/7OnLoadHook/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/7OnLoadHook/types/models/spt/config/IBotConfig.d.ts b/TypeScript/7OnLoadHook/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/7OnLoadHook/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/7OnLoadHook/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/7OnLoadHook/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/7OnLoadHook/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/7OnLoadHook/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/7OnLoadHook/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/7OnLoadHook/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/7OnLoadHook/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/7OnLoadHook/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/7OnLoadHook/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/7OnLoadHook/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/7OnLoadHook/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/7OnLoadHook/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/7OnLoadHook/types/routers/EventOutputHolder.d.ts b/TypeScript/7OnLoadHook/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/7OnLoadHook/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/7OnLoadHook/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/7OnLoadHook/types/services/ProfileFixerService.d.ts b/TypeScript/7OnLoadHook/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/7OnLoadHook/types/services/ProfileFixerService.d.ts +++ b/TypeScript/7OnLoadHook/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/7OnLoadHook/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/7OnLoadHook/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/7OnLoadHook/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/7OnLoadHook/types/utils/HttpResponseUtil.d.ts b/TypeScript/7OnLoadHook/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/7OnLoadHook/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/7OnLoadHook/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/7OnLoadHook/types/utils/RandomUtil.d.ts b/TypeScript/7OnLoadHook/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/7OnLoadHook/types/utils/RandomUtil.d.ts +++ b/TypeScript/7OnLoadHook/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/8OnUpdateHook/types/callbacks/GameCallbacks.d.ts b/TypeScript/8OnUpdateHook/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/8OnUpdateHook/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/8OnUpdateHook/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/8OnUpdateHook/types/context/ApplicationContext.d.ts b/TypeScript/8OnUpdateHook/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/8OnUpdateHook/types/context/ApplicationContext.d.ts +++ b/TypeScript/8OnUpdateHook/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/8OnUpdateHook/types/context/ContextVariableType.d.ts b/TypeScript/8OnUpdateHook/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/8OnUpdateHook/types/context/ContextVariableType.d.ts +++ b/TypeScript/8OnUpdateHook/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/8OnUpdateHook/types/controllers/GameController.d.ts b/TypeScript/8OnUpdateHook/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/8OnUpdateHook/types/controllers/GameController.d.ts +++ b/TypeScript/8OnUpdateHook/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/8OnUpdateHook/types/controllers/HideoutController.d.ts b/TypeScript/8OnUpdateHook/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/8OnUpdateHook/types/controllers/HideoutController.d.ts +++ b/TypeScript/8OnUpdateHook/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/8OnUpdateHook/types/controllers/InraidController.d.ts b/TypeScript/8OnUpdateHook/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/8OnUpdateHook/types/controllers/InraidController.d.ts +++ b/TypeScript/8OnUpdateHook/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/8OnUpdateHook/types/controllers/LocationController.d.ts b/TypeScript/8OnUpdateHook/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/8OnUpdateHook/types/controllers/LocationController.d.ts +++ b/TypeScript/8OnUpdateHook/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/8OnUpdateHook/types/controllers/QuestController.d.ts b/TypeScript/8OnUpdateHook/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/8OnUpdateHook/types/controllers/QuestController.d.ts +++ b/TypeScript/8OnUpdateHook/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/8OnUpdateHook/types/controllers/TradeController.d.ts b/TypeScript/8OnUpdateHook/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/8OnUpdateHook/types/controllers/TradeController.d.ts +++ b/TypeScript/8OnUpdateHook/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/8OnUpdateHook/types/generators/BotWeaponGenerator.d.ts b/TypeScript/8OnUpdateHook/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/8OnUpdateHook/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/8OnUpdateHook/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/8OnUpdateHook/types/generators/LocationGenerator.d.ts b/TypeScript/8OnUpdateHook/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/8OnUpdateHook/types/generators/LocationGenerator.d.ts +++ b/TypeScript/8OnUpdateHook/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/8OnUpdateHook/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/8OnUpdateHook/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/8OnUpdateHook/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/8OnUpdateHook/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/8OnUpdateHook/types/helpers/HandbookHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/8OnUpdateHook/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/8OnUpdateHook/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/8OnUpdateHook/types/helpers/InRaidHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/8OnUpdateHook/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/8OnUpdateHook/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/8OnUpdateHook/types/helpers/ItemHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/8OnUpdateHook/types/helpers/ItemHelper.d.ts +++ b/TypeScript/8OnUpdateHook/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/8OnUpdateHook/types/helpers/QuestHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/8OnUpdateHook/types/helpers/QuestHelper.d.ts +++ b/TypeScript/8OnUpdateHook/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/8OnUpdateHook/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/8OnUpdateHook/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/8OnUpdateHook/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/8OnUpdateHook/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/8OnUpdateHook/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/8OnUpdateHook/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/8OnUpdateHook/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/8OnUpdateHook/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/8OnUpdateHook/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/8OnUpdateHook/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/8OnUpdateHook/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/8OnUpdateHook/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/8OnUpdateHook/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/8OnUpdateHook/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/8OnUpdateHook/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/8OnUpdateHook/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/8OnUpdateHook/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/8OnUpdateHook/types/models/enums/BaseClasses.d.ts b/TypeScript/8OnUpdateHook/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/8OnUpdateHook/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/8OnUpdateHook/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/8OnUpdateHook/types/models/enums/ItemAddedResult.d.ts b/TypeScript/8OnUpdateHook/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/8OnUpdateHook/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/8OnUpdateHook/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/8OnUpdateHook/types/models/spt/config/IBotConfig.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/8OnUpdateHook/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/8OnUpdateHook/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/8OnUpdateHook/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/8OnUpdateHook/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/8OnUpdateHook/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/8OnUpdateHook/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/8OnUpdateHook/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/8OnUpdateHook/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/8OnUpdateHook/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/8OnUpdateHook/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/8OnUpdateHook/types/routers/EventOutputHolder.d.ts b/TypeScript/8OnUpdateHook/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/8OnUpdateHook/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/8OnUpdateHook/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/8OnUpdateHook/types/services/ProfileFixerService.d.ts b/TypeScript/8OnUpdateHook/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/8OnUpdateHook/types/services/ProfileFixerService.d.ts +++ b/TypeScript/8OnUpdateHook/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/8OnUpdateHook/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/8OnUpdateHook/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/8OnUpdateHook/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/8OnUpdateHook/types/utils/HttpResponseUtil.d.ts b/TypeScript/8OnUpdateHook/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/8OnUpdateHook/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/8OnUpdateHook/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/8OnUpdateHook/types/utils/RandomUtil.d.ts b/TypeScript/8OnUpdateHook/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/8OnUpdateHook/types/utils/RandomUtil.d.ts +++ b/TypeScript/8OnUpdateHook/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above diff --git a/TypeScript/9RouterHooks/types/callbacks/GameCallbacks.d.ts b/TypeScript/9RouterHooks/types/callbacks/GameCallbacks.d.ts index 4c4061b..54bdfc7 100644 --- a/TypeScript/9RouterHooks/types/callbacks/GameCallbacks.d.ts +++ b/TypeScript/9RouterHooks/types/callbacks/GameCallbacks.d.ts @@ -8,6 +8,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"; @@ -68,5 +69,10 @@ declare class GameCallbacks implements OnLoad { */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/getRaidTime + * @returns string + */ + getRaidTime(url: string, request: IGetRaidTimeRequest, sessionID: string): any; } export { GameCallbacks }; diff --git a/TypeScript/9RouterHooks/types/context/ApplicationContext.d.ts b/TypeScript/9RouterHooks/types/context/ApplicationContext.d.ts index 295a95e..5eea16e 100644 --- a/TypeScript/9RouterHooks/types/context/ApplicationContext.d.ts +++ b/TypeScript/9RouterHooks/types/context/ApplicationContext.d.ts @@ -10,11 +10,12 @@ export declare class ApplicationContext { * * const activePlayerSessionId = this.applicationContext.getLatestValue(ContextVariableType.SESSION_ID).getValue(); * - * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.MATCH_INFO).getValue(); + * const matchInfo = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue(); * @param type * @returns */ getLatestValue(type: ContextVariableType): ContextVariable; getValues(type: ContextVariableType): ContextVariable[]; addValue(type: ContextVariableType, value: any): void; + clearValues(type: ContextVariableType): void; } diff --git a/TypeScript/9RouterHooks/types/context/ContextVariableType.d.ts b/TypeScript/9RouterHooks/types/context/ContextVariableType.d.ts index 49f3267..0722a98 100644 --- a/TypeScript/9RouterHooks/types/context/ContextVariableType.d.ts +++ b/TypeScript/9RouterHooks/types/context/ContextVariableType.d.ts @@ -6,5 +6,6 @@ export declare 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, + RAID_ADJUSTMENTS = 4 } diff --git a/TypeScript/9RouterHooks/types/controllers/GameController.d.ts b/TypeScript/9RouterHooks/types/controllers/GameController.d.ts index 168071d..d2a978b 100644 --- a/TypeScript/9RouterHooks/types/controllers/GameController.d.ts +++ b/TypeScript/9RouterHooks/types/controllers/GameController.d.ts @@ -9,6 +9,8 @@ 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 { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; @@ -26,7 +28,9 @@ import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; +import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -35,6 +39,7 @@ export declare class GameController { protected databaseServer: DatabaseServer; protected jsonUtil: JsonUtil; protected timeUtil: TimeUtil; + protected hashUtil: HashUtil; protected preAkiModLoader: PreAkiModLoader; protected httpServerHelper: HttpServerHelper; protected randomUtil: RandomUtil; @@ -47,6 +52,7 @@ export declare class GameController { protected seasonalEventService: SeasonalEventService; protected itemBaseClassService: ItemBaseClassService; protected giftService: GiftService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; @@ -55,7 +61,7 @@ export declare class GameController { protected ragfairConfig: IRagfairConfig; protected pmcConfig: IPmcConfig; protected lootConfig: ILootConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, applicationContext: ApplicationContext, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, hashUtil: HashUtil, preAkiModLoader: PreAkiModLoader, httpServerHelper: HttpServerHelper, randomUtil: RandomUtil, hideoutHelper: HideoutHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, customLocationWaveService: CustomLocationWaveService, openZoneService: OpenZoneService, seasonalEventService: SeasonalEventService, itemBaseClassService: ItemBaseClassService, giftService: GiftService, raidTimeAdjustmentService: RaidTimeAdjustmentService, applicationContext: ApplicationContext, configServer: ConfigServer); load(): void; /** * Handle client/game/start @@ -90,6 +96,10 @@ export declare class GameController { * Handle client/game/keepalive */ getKeepAlive(sessionId: string): IGameKeepAliveResponse; + /** + * Handle singleplayer/settings/getRaidTime + */ + getRaidTime(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; /** * BSG have two values for shotgun dispersion, we make sure both have the same value */ diff --git a/TypeScript/9RouterHooks/types/controllers/HideoutController.d.ts b/TypeScript/9RouterHooks/types/controllers/HideoutController.d.ts index bb940dd..5595648 100644 --- a/TypeScript/9RouterHooks/types/controllers/HideoutController.d.ts +++ b/TypeScript/9RouterHooks/types/controllers/HideoutController.d.ts @@ -101,7 +101,7 @@ export declare class HideoutController { */ protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void; /** - * @param output Objet to send to client + * @param output Object to send to client * @param sessionID Session/player id * @param areaType Hideout area that had stash added * @param hideoutDbData Hideout area that caused addition of stash diff --git a/TypeScript/9RouterHooks/types/controllers/InraidController.d.ts b/TypeScript/9RouterHooks/types/controllers/InraidController.d.ts index d651d67..8ec13ba 100644 --- a/TypeScript/9RouterHooks/types/controllers/InraidController.d.ts +++ b/TypeScript/9RouterHooks/types/controllers/InraidController.d.ts @@ -95,9 +95,14 @@ export declare class InraidController { /** * Does provided profile contain any condition counters * @param profile Profile to check for condition counters - * @returns + * @returns Profile has condition counters */ protected profileHasConditionCounters(profile: IPmcData): boolean; + /** + * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually + * @param scavProfile Scav profile with quest progress post-raid + * @param pmcProfile Server pmc profile to copy scav quest progress into + */ protected migrateScavQuestProgressToPmcProfile(scavProfile: IPmcData, pmcProfile: IPmcData): void; /** * Is the player dead after a raid - dead is anything other than "survived" / "runner" diff --git a/TypeScript/9RouterHooks/types/controllers/LocationController.d.ts b/TypeScript/9RouterHooks/types/controllers/LocationController.d.ts index 7d37be3..eb4144a 100644 --- a/TypeScript/9RouterHooks/types/controllers/LocationController.d.ts +++ b/TypeScript/9RouterHooks/types/controllers/LocationController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; @@ -13,6 +14,7 @@ import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RaidTimeAdjustmentService } from "@spt-aki/services/RaidTimeAdjustmentService"; import { HashUtil } from "@spt-aki/utils/HashUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil"; @@ -25,13 +27,15 @@ export declare class LocationController { protected logger: ILogger; protected locationGenerator: LocationGenerator; protected localisationService: LocalisationService; + protected raidTimeAdjustmentService: RaidTimeAdjustmentService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; + protected applicationContext: ApplicationContext; protected airdropConfig: IAirdropConfig; protected locationConfig: ILocationConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, raidTimeAdjustmentService: RaidTimeAdjustmentService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer, applicationContext: ApplicationContext); /** * Handle client/location/getLocalloot * Get a location (map) with generated loot data diff --git a/TypeScript/9RouterHooks/types/controllers/QuestController.d.ts b/TypeScript/9RouterHooks/types/controllers/QuestController.d.ts index 26e992f..140573b 100644 --- a/TypeScript/9RouterHooks/types/controllers/QuestController.d.ts +++ b/TypeScript/9RouterHooks/types/controllers/QuestController.d.ts @@ -82,7 +82,7 @@ export declare class QuestController { * @param pmcData Profile to update * @param acceptedQuest Quest accepted * @param sessionID Session id - * @returns client response + * @returns Client response */ acceptQuest(pmcData: IPmcData, acceptedQuest: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/TypeScript/9RouterHooks/types/controllers/TradeController.d.ts b/TypeScript/9RouterHooks/types/controllers/TradeController.d.ts index 064eeb2..8812b1f 100644 --- a/TypeScript/9RouterHooks/types/controllers/TradeController.d.ts +++ b/TypeScript/9RouterHooks/types/controllers/TradeController.d.ts @@ -41,7 +41,7 @@ declare class TradeController { /** Handle RagFairBuyOffer event */ confirmRagfairTrading(pmcData: IPmcData, body: IProcessRagfairTradeRequestData, sessionID: string): IItemEventRouterResponse; /** Handle SellAllFromSavage event */ - sellScavItemsToFence(pmcData: IPmcData, body: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; + sellScavItemsToFence(pmcData: IPmcData, request: ISellScavItemsToFenceRequestData, sessionId: string): IItemEventRouterResponse; /** * Sell all sellable items to a trader from inventory * WILL DELETE ITEMS FROM INVENTORY + CHILDREN OF ITEMS SOLD diff --git a/TypeScript/9RouterHooks/types/generators/BotWeaponGenerator.d.ts b/TypeScript/9RouterHooks/types/generators/BotWeaponGenerator.d.ts index 04ae4a6..125b43f 100644 --- a/TypeScript/9RouterHooks/types/generators/BotWeaponGenerator.d.ts +++ b/TypeScript/9RouterHooks/types/generators/BotWeaponGenerator.d.ts @@ -73,12 +73,13 @@ export declare class BotWeaponGenerator { */ generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** - * Insert a cartridge into a weapon + * Insert a cartridge(s) into a weapon + * Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc * @param weaponWithModsArray Weapon and mods * @param ammoTpl Cartridge to add to weapon - * @param desiredSlotId name of slot, e.g. patron_in_weapon + * @param chamberSlotIds name of slots to create or add ammo to */ - protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, desiredSlotId: string): void; + protected addCartridgeToChamber(weaponWithModsArray: Item[], ammoTpl: string, chamberSlotIds: string[]): void; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/TypeScript/9RouterHooks/types/generators/LocationGenerator.d.ts b/TypeScript/9RouterHooks/types/generators/LocationGenerator.d.ts index 923a197..1305af1 100644 --- a/TypeScript/9RouterHooks/types/generators/LocationGenerator.d.ts +++ b/TypeScript/9RouterHooks/types/generators/LocationGenerator.d.ts @@ -121,11 +121,11 @@ export declare class LocationGenerator { generateDynamicLoot(dynamicLootDist: ILooseLoot, staticAmmoDist: Record, locationName: string): SpawnpointTemplate[]; /** * Add forced spawn point loot into loot parameter array - * @param loot array to add forced loot to - * @param forcedSpawnPoints forced loot to add - * @param name of map currently generating forced loot for + * @param lootLocationTemplates array to add forced loot spawn locations to + * @param forcedSpawnPoints forced Forced loot locations that must be added + * @param locationName Name of map currently having force loot created for */ - protected addForcedLoot(loot: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; + protected addForcedLoot(lootLocationTemplates: SpawnpointTemplate[], forcedSpawnPoints: SpawnpointsForced[], locationName: string): void; /** * Create array of item (with child items) and return * @param chosenComposedKey Key we want to look up items for diff --git a/TypeScript/9RouterHooks/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/TypeScript/9RouterHooks/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index a13b227..edc4734 100644 --- a/TypeScript/9RouterHooks/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/TypeScript/9RouterHooks/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -2,15 +2,24 @@ import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; +import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + protected randomUtil: RandomUtil; + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, randomUtil: RandomUtil); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; + /** + * Get a random compatible external magazine for a weapon, excluses internal magazines from possible pool + * @param weaponTpl Weapon to get mag for + * @returns tpl of magazine + */ + protected getRandomExternalMagazineForInternalMagazineGun(weaponTpl: string, magazineBlacklist: string[]): ITemplateItem; } diff --git a/TypeScript/9RouterHooks/types/helpers/HandbookHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/HandbookHelper.d.ts index 1cc78bd..43b0ec5 100644 --- a/TypeScript/9RouterHooks/types/helpers/HandbookHelper.d.ts +++ b/TypeScript/9RouterHooks/types/helpers/HandbookHelper.d.ts @@ -1,4 +1,5 @@ import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { JsonUtil } from "@spt-aki/utils/JsonUtil"; declare class LookupItem { readonly byId: Map; readonly byParent: Map; @@ -11,9 +12,10 @@ export declare class LookupCollection { } export declare class HandbookHelper { protected databaseServer: DatabaseServer; + protected jsonUtil: JsonUtil; protected lookupCacheGenerated: boolean; protected handbookPriceCache: LookupCollection; - constructor(databaseServer: DatabaseServer); + constructor(databaseServer: DatabaseServer, jsonUtil: JsonUtil); /** * Create an in-memory cache of all items with associated handbook price in handbookPriceCache class */ diff --git a/TypeScript/9RouterHooks/types/helpers/InRaidHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/InRaidHelper.d.ts index f8df2ba..bcc77e8 100644 --- a/TypeScript/9RouterHooks/types/helpers/InRaidHelper.d.ts +++ b/TypeScript/9RouterHooks/types/helpers/InRaidHelper.d.ts @@ -15,6 +15,7 @@ import { SaveServer } from "@spt-aki/servers/SaveServer"; import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { ProfileHelper } from "./ProfileHelper"; export declare class InRaidHelper { protected logger: ILogger; protected saveServer: SaveServer; @@ -22,6 +23,7 @@ export declare class InRaidHelper { protected itemHelper: ItemHelper; protected databaseServer: DatabaseServer; protected inventoryHelper: InventoryHelper; + protected profileHelper: ProfileHelper; protected questHelper: QuestHelper; protected paymentHelper: PaymentHelper; protected localisationService: LocalisationService; @@ -29,7 +31,7 @@ export declare class InRaidHelper { protected configServer: ConfigServer; protected lostOnDeathConfig: ILostOnDeathConfig; protected inRaidConfig: IInRaidConfig; - constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); + constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, itemHelper: ItemHelper, databaseServer: DatabaseServer, inventoryHelper: InventoryHelper, profileHelper: ProfileHelper, questHelper: QuestHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, profileFixerService: ProfileFixerService, configServer: ConfigServer); /** * Lookup quest item loss from lostOnDeath config * @returns True if items should be removed from inventory @@ -64,16 +66,36 @@ export declare class InRaidHelper { * @param sessionID Session id * @returns Reset profile object */ - updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): IPmcData; + updateProfileBaseStats(profileData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionID: string): void; /** - * Look for quests not are now status = fail that were not failed pre-raid and run the failQuest() function + * Reset the skill points earned in a raid to 0, ready for next raid + * @param profile Profile to update + */ + protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + /** Check counters are correct in profile */ + protected validateBackendCounters(saveProgressRequest: ISaveProgressRequestData, profileData: IPmcData): void; + /** + * Update various serverPMC profile values; quests/limb hp/trader standing with values post-raic + * @param pmcData Server PMC profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updatePmcProfileDataPostRaid(pmcData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Update scav quest values on server profile with updated values post-raid + * @param scavData Server scav profile + * @param saveProgressRequest Post-raid request data + * @param sessionId Session id + */ + updateScavProfileDataPostRaid(scavData: IPmcData, saveProgressRequest: ISaveProgressRequestData, sessionId: string): void; + /** + * Look for quests with status = fail that were not failed pre-raid and run the failQuest() function * @param sessionId Player id * @param pmcData Player profile * @param preRaidQuests Quests prior to starting raid - * @param postRaidQuests Quest after raid + * @param postRaidProfile Profile sent by client */ - protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidQuests: IQuestStatus[]): void; - protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void; + protected processFailedQuests(sessionId: string, pmcData: IPmcData, preRaidQuests: IQuestStatus[], postRaidProfile: IPostRaidPmcData): void; /** * Take body part effects from client profile and apply to server profile * @param saveProgressRequest post-raid request diff --git a/TypeScript/9RouterHooks/types/helpers/ItemHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/ItemHelper.d.ts index e1c7720..be5d92d 100644 --- a/TypeScript/9RouterHooks/types/helpers/ItemHelper.d.ts +++ b/TypeScript/9RouterHooks/types/helpers/ItemHelper.d.ts @@ -323,7 +323,7 @@ declare class ItemHelper { * Chose a randomly weighted cartridge that fits * @param caliber Desired caliber * @param staticAmmoDist Cartridges and thier weights - * @returns Tpl of cartrdige + * @returns Tpl of cartridge */ protected drawAmmoTpl(caliber: string, staticAmmoDist: Record): string; /** diff --git a/TypeScript/9RouterHooks/types/helpers/QuestHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/QuestHelper.d.ts index 5ea1a52..2b9a531 100644 --- a/TypeScript/9RouterHooks/types/helpers/QuestHelper.d.ts +++ b/TypeScript/9RouterHooks/types/helpers/QuestHelper.d.ts @@ -206,16 +206,23 @@ export declare class QuestHelper { * @param questId Id of the quest to alter the status of */ updateQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; + /** + * Resets a quests values back to its chosen state + * @param pmcData Profile to update + * @param newQuestState New state the quest should be in + * @param questId Id of the quest to alter the status of + */ + resetQuestState(pmcData: IPmcData, newQuestState: QuestStatus, questId: string): void; /** * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param pmcData Player profile + * @param profileData Player profile (scav or pmc) * @param questId questId of quest to get rewards for * @param state State of the quest to get rewards for * @param sessionId Session id * @param questResponse Response to send back to client * @returns Array of reward objects */ - applyQuestReward(pmcData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; + applyQuestReward(profileData: IPmcData, questId: string, state: QuestStatus, sessionId: string, questResponse: IItemEventRouterResponse): Reward[]; /** * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile * also update client response recipeUnlocked array with craft id diff --git a/TypeScript/9RouterHooks/types/helpers/WeightedRandomHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/WeightedRandomHelper.d.ts index 5fd9edc..8d81024 100644 --- a/TypeScript/9RouterHooks/types/helpers/WeightedRandomHelper.d.ts +++ b/TypeScript/9RouterHooks/types/helpers/WeightedRandomHelper.d.ts @@ -25,7 +25,7 @@ export declare class WeightedRandomHelper { * @param {number[]} weights * @returns {{item: any, index: number}} */ - weightedRandom(items: string | any[], weights: string | any[]): { + weightedRandom(items: any[], weights: any[]): { item: any; index: number; }; diff --git a/TypeScript/9RouterHooks/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/9RouterHooks/types/models/eft/common/tables/IBotBase.d.ts index 380203e..8ff3ba9 100644 --- a/TypeScript/9RouterHooks/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/9RouterHooks/types/models/eft/common/tables/IBotBase.d.ts @@ -309,6 +309,8 @@ export interface Productive { sptIsScavCase?: boolean; /** Some crafts are always inProgress, but need to be reset, e.g. water collector */ sptIsComplete?: boolean; + /** Is the craft a Continuous, e.g bitcoins/water collector */ + sptIsContinuous?: boolean; } export interface Production extends Productive { RecipeId: string; @@ -361,7 +363,7 @@ export interface IQuestStatus { startTime: number; status: QuestStatus; statusTimers?: Record; - /** SPT specific property */ + /** Property does not exist in live profile data, but is used by ProfileChanges.questsStatus when sent to client*/ completedConditions?: string[]; availableAfter?: number; } @@ -373,14 +375,6 @@ export interface TraderInfo { unlocked: boolean; disabled: boolean; } -/** This object is sent to the client as part of traderRelations */ -export interface TraderData { - salesSum: number; - standing: number; - loyalty: number; - unlocked: boolean; - disabled: boolean; -} export interface RagfairInfo { rating: number; isRatingGrowing: boolean; diff --git a/TypeScript/9RouterHooks/types/models/eft/game/IGetRaidTimeRequest.d.ts b/TypeScript/9RouterHooks/types/models/eft/game/IGetRaidTimeRequest.d.ts new file mode 100644 index 0000000..b93fb0c --- /dev/null +++ b/TypeScript/9RouterHooks/types/models/eft/game/IGetRaidTimeRequest.d.ts @@ -0,0 +1,4 @@ +export interface IGetRaidTimeRequest { + Side: string; + Location: string; +} diff --git a/TypeScript/9RouterHooks/types/models/eft/game/IGetRaidTimeResponse.d.ts b/TypeScript/9RouterHooks/types/models/eft/game/IGetRaidTimeResponse.d.ts new file mode 100644 index 0000000..4dcf0a0 --- /dev/null +++ b/TypeScript/9RouterHooks/types/models/eft/game/IGetRaidTimeResponse.d.ts @@ -0,0 +1,12 @@ +export interface IGetRaidTimeResponse { + RaidTimeMinutes: number; + NewSurviveTimeSeconds: number; + OriginalSurvivalTimeSeconds: number; + ExitChanges: ExtractChange[]; +} +export interface ExtractChange { + Name: string; + MinTime?: number; + MaxTime?: number; + Chance?: number; +} diff --git a/TypeScript/9RouterHooks/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/TypeScript/9RouterHooks/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index f302650..a1babfd 100644 --- a/TypeScript/9RouterHooks/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/TypeScript/9RouterHooks/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -1,4 +1,4 @@ -import { Health, IQuestStatus, Productive, Skills, TraderData } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { Health, IQuestStatus, Productive, Skills } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Item, Upd } from "@spt-aki/models/eft/common/tables/IItem"; import { IQuest } from "@spt-aki/models/eft/common/tables/IQuest"; import { IPmcDataRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests"; @@ -62,6 +62,14 @@ export interface Improvement { completed: boolean; improveCompleteTimestamp: number; } +/** Related to TraderInfo */ +export interface TraderData { + salesSum: number; + standing: number; + loyalty: number; + unlocked: boolean; + disabled: boolean; +} export interface Product { _id: string; _tpl?: string; diff --git a/TypeScript/9RouterHooks/types/models/enums/BaseClasses.d.ts b/TypeScript/9RouterHooks/types/models/enums/BaseClasses.d.ts index 76938ad..a9acb69 100644 --- a/TypeScript/9RouterHooks/types/models/enums/BaseClasses.d.ts +++ b/TypeScript/9RouterHooks/types/models/enums/BaseClasses.d.ts @@ -54,6 +54,7 @@ export declare enum BaseClasses { GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568", SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569", SPEC_ITEM = "5447e0e74bdc2d3c308b4567", + SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944", KNIFE = "5447e1d04bdc2dff2f8b4567", AMMO = "5485a8684bdc2da71d8b4567", AMMO_BOX = "543be5cb4bdc2deb348b4568", diff --git a/TypeScript/9RouterHooks/types/models/enums/ItemAddedResult.d.ts b/TypeScript/9RouterHooks/types/models/enums/ItemAddedResult.d.ts index e64b660..6c8a1cf 100644 --- a/TypeScript/9RouterHooks/types/models/enums/ItemAddedResult.d.ts +++ b/TypeScript/9RouterHooks/types/models/enums/ItemAddedResult.d.ts @@ -1,4 +1,6 @@ export declare enum ItemAddedResult { + UNKNOWN = -1, SUCCESS = 1, - NO_SPACE = 2 + NO_SPACE = 2, + NO_CONTAINERS = 3 } diff --git a/TypeScript/9RouterHooks/types/models/spt/config/IBotConfig.d.ts b/TypeScript/9RouterHooks/types/models/spt/config/IBotConfig.d.ts index 24c8c19..517ec27 100644 --- a/TypeScript/9RouterHooks/types/models/spt/config/IBotConfig.d.ts +++ b/TypeScript/9RouterHooks/types/models/spt/config/IBotConfig.d.ts @@ -25,6 +25,8 @@ export interface IBotConfig extends IBaseConfig { showTypeInNickname: boolean; /** What ai brain should a normal scav use per map */ assaultBrainType: Record>; + /** What ai brain should a player scav use per map */ + playerScavBrainType: Record>; /** Max number of bots that can be spawned in a raid at any one time */ maxBotCap: Record; /** Chance scav has fake pscav name e.g. Scav name (player name) */ diff --git a/TypeScript/9RouterHooks/types/models/spt/config/ICoreConfig.d.ts b/TypeScript/9RouterHooks/types/models/spt/config/ICoreConfig.d.ts index 69e3a1c..7d6e513 100644 --- a/TypeScript/9RouterHooks/types/models/spt/config/ICoreConfig.d.ts +++ b/TypeScript/9RouterHooks/types/models/spt/config/ICoreConfig.d.ts @@ -19,6 +19,8 @@ export interface IGameFixes { fixShotgunDispersion: boolean; /** Remove items added by mods when the mod no longer exists - can fix dead profiles stuck at game load*/ removeModItemsFromProfile: boolean; + /** Fix issues that cause the game to not start due to inventory item issues */ + fixProfileBreakingInventoryItemIssues: boolean; } export interface IServerFeatures { autoInstallModDependencies: boolean; diff --git a/TypeScript/9RouterHooks/types/models/spt/config/ILocationConfig.d.ts b/TypeScript/9RouterHooks/types/models/spt/config/ILocationConfig.d.ts index 79f225e..1489f4f 100644 --- a/TypeScript/9RouterHooks/types/models/spt/config/ILocationConfig.d.ts +++ b/TypeScript/9RouterHooks/types/models/spt/config/ILocationConfig.d.ts @@ -36,15 +36,8 @@ export interface ILocationConfig extends IBaseConfig { allowDuplicateItemsInStaticContainers: boolean; /** Key: map, value: loose loot ids to ignore */ looseLootBlacklist: Record; -} -export interface IContainerRandomistionSettings { - enabled: boolean; - /** What maps can use the container randomisation feature */ - maps: Record; - /** Some container types don't work when randomised */ - containerTypesToNotRandomise: string[]; - containerGroupMinSizeMultiplier: number; - containerGroupMaxSizeMultiplier: number; + /** Key: map, value: settings to control how long scav raids are*/ + scavRaidTimeSettings: IScavRaidTimeSettings; } export interface IFixEmptyBotWavesSettings { enabled: boolean; @@ -86,3 +79,30 @@ export interface LootMultiplier { terminal: number; town: number; } +export interface IContainerRandomistionSettings { + enabled: boolean; + /** What maps can use the container randomisation feature */ + maps: Record; + /** Some container types don't work when randomised */ + containerTypesToNotRandomise: string[]; + containerGroupMinSizeMultiplier: number; + containerGroupMaxSizeMultiplier: number; +} +export interface IScavRaidTimeSettings { + settings: IScavRaidTimeConfigSettings; + maps: Record; +} +export interface IScavRaidTimeConfigSettings { + trainArrivalDelayObservedSeconds: number; +} +export interface IScavRaidTimeLocationSettings { + /** 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; + /** Should bot waves be removed / spawn times be adjusted */ + adjustWaves: boolean; +} diff --git a/TypeScript/9RouterHooks/types/models/spt/location/IRaidChanges.d.ts b/TypeScript/9RouterHooks/types/models/spt/location/IRaidChanges.d.ts new file mode 100644 index 0000000..b7a989b --- /dev/null +++ b/TypeScript/9RouterHooks/types/models/spt/location/IRaidChanges.d.ts @@ -0,0 +1,8 @@ +export interface IRaidChanges { + /** What percentage of dynamic loot should the map contain */ + dynamicLootPercent: number; + /** What percentage of static loot should the map contain */ + staticLootPercent: number; + /** How many seconds into the raid is the player simulated to spawn in at */ + simulatedRaidStartSeconds: number; +} diff --git a/TypeScript/9RouterHooks/types/routers/EventOutputHolder.d.ts b/TypeScript/9RouterHooks/types/routers/EventOutputHolder.d.ts index d687a3a..8ee10ef 100644 --- a/TypeScript/9RouterHooks/types/routers/EventOutputHolder.d.ts +++ b/TypeScript/9RouterHooks/types/routers/EventOutputHolder.d.ts @@ -1,6 +1,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; -import { IHideoutImprovement, Productive, TraderData, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { IHideoutImprovement, Productive, TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase"; +import { TraderData } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @@ -48,5 +49,5 @@ export declare class EventOutputHolder { * Required as continuous productions don't reset and stay at 100% completion but client thinks it hasn't started * @param productions Productions in a profile */ - protected resetSptIsCompleteFlaggedCrafts(productions: Record): void; + protected cleanUpCompleteCraftsInProfile(productions: Record): void; } diff --git a/TypeScript/9RouterHooks/types/services/ProfileFixerService.d.ts b/TypeScript/9RouterHooks/types/services/ProfileFixerService.d.ts index b01f4a3..e2e140b 100644 --- a/TypeScript/9RouterHooks/types/services/ProfileFixerService.d.ts +++ b/TypeScript/9RouterHooks/types/services/ProfileFixerService.d.ts @@ -41,6 +41,11 @@ export declare class ProfileFixerService { * @param pmcProfile profile to check and fix */ checkForAndFixPmcProfileIssues(pmcProfile: IPmcData): void; + /** + * Find issues in the scav profile data that may cause issues + * @param scavProfile profile to check and fix + */ + checkForAndFixScavProfileIssues(scavProfile: IPmcData): void; protected addMissingGunStandContainerImprovements(pmcProfile: IPmcData): void; protected ensureGunStandLevelsMatch(pmcProfile: IPmcData): void; protected addHideoutAreaStashes(pmcProfile: IPmcData): void; @@ -67,9 +72,9 @@ export declare class ProfileFixerService { * Adjust profile quest status and statusTimers object values * quest.status is numeric e.g. 2 * quest.statusTimers keys are numeric as strings e.g. "2" - * @param pmcProfile profile to update + * @param profile profile to update */ - protected updateProfileQuestDataValues(pmcProfile: IPmcData): void; + protected updateProfileQuestDataValues(profile: IPmcData): void; protected addMissingRepeatableQuestsProperty(pmcProfile: IPmcData): void; /** * Some profiles have hideout maxed and therefore no improvements @@ -115,6 +120,11 @@ export declare class ProfileFixerService { * @param pmcProfile Profile to check inventory of */ checkForOrphanedModdedItems(sessionId: string, fullProfile: IAkiProfile): void; + /** + * Attempt to fix common item issues that corrupt profiles + * @param pmcProfile Profile to check items of + */ + fixProfileBreakingInventoryItemIssues(pmcProfile: IPmcData): void; /** * Add `Improvements` object to hideout if missing - added in eft 13.0.21469 * @param pmcProfile profile to update diff --git a/TypeScript/9RouterHooks/types/services/RaidTimeAdjustmentService.d.ts b/TypeScript/9RouterHooks/types/services/RaidTimeAdjustmentService.d.ts new file mode 100644 index 0000000..a2a223a --- /dev/null +++ b/TypeScript/9RouterHooks/types/services/RaidTimeAdjustmentService.d.ts @@ -0,0 +1,60 @@ +import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; +import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; +import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; +import { IGetRaidTimeRequest } from "@spt-aki/models/eft/game/IGetRaidTimeRequest"; +import { ExtractChange, IGetRaidTimeResponse } from "@spt-aki/models/eft/game/IGetRaidTimeResponse"; +import { ILocationConfig, IScavRaidTimeLocationSettings, LootMultiplier } from "@spt-aki/models/spt/config/ILocationConfig"; +import { IRaidChanges } from "@spt-aki/models/spt/location/IRaidChanges"; +import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; +import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; +import { RandomUtil } from "@spt-aki/utils/RandomUtil"; +export declare class RaidTimeAdjustmentService { + protected logger: ILogger; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected weightedRandomHelper: WeightedRandomHelper; + protected applicationContext: ApplicationContext; + protected configServer: ConfigServer; + protected locationConfig: ILocationConfig; + constructor(logger: ILogger, databaseServer: DatabaseServer, randomUtil: RandomUtil, weightedRandomHelper: WeightedRandomHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + /** + * Make alterations to the base map data passed in + * Loot multipliers/waves/wave start times + * @param raidAdjustments Changes to process on map + * @param mapBase Map to adjust + */ + makeAdjustmentsToMap(raidAdjustments: IRaidChanges, mapBase: ILocationBase): void; + /** + * 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; + /** + * Adjust bot waves to act as if player spawned later + * @param mapBase map to adjust + * @param raidAdjustments Map adjustments + */ + protected adjustWaves(mapBase: ILocationBase, raidAdjustments: IRaidChanges): void; + /** + * Create a randomised adjustment to the raid based on map data in location.json + * @param sessionId Session id + * @param request Raid adjustment request + * @returns Response to send to client + */ + getRaidAdjustments(sessionId: string, request: IGetRaidTimeRequest): IGetRaidTimeResponse; + /** + * Get raid start time settings for specific map + * @param location Map Location e.g. bigmap + * @returns IScavRaidTimeLocationSettings + */ + protected getMapSettings(location: string): IScavRaidTimeLocationSettings; + /** + * Adjust exit times to handle scavs entering raids part-way through + * @param mapBase Map base file player is on + * @param newRaidTimeMinutes How long raid is in minutes + * @returns List of exit changes to send to client + */ + protected getExitAdjustments(mapBase: ILocationBase, newRaidTimeMinutes: number): ExtractChange[]; +} diff --git a/TypeScript/9RouterHooks/types/utils/HttpResponseUtil.d.ts b/TypeScript/9RouterHooks/types/utils/HttpResponseUtil.d.ts index 6e16229..eb0b3b8 100644 --- a/TypeScript/9RouterHooks/types/utils/HttpResponseUtil.d.ts +++ b/TypeScript/9RouterHooks/types/utils/HttpResponseUtil.d.ts @@ -15,6 +15,13 @@ export declare class HttpResponseUtil { * @returns */ noBody(data: any): any; + /** + * Game client needs server responses in a particular format + * @param data + * @param err + * @param errmsg + * @returns + */ getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; getUnclearedBody(data: any, err?: number, errmsg?: any): string; emptyResponse(): IGetBodyResponseData; diff --git a/TypeScript/9RouterHooks/types/utils/RandomUtil.d.ts b/TypeScript/9RouterHooks/types/utils/RandomUtil.d.ts index 71435bd..3552fb4 100644 --- a/TypeScript/9RouterHooks/types/utils/RandomUtil.d.ts +++ b/TypeScript/9RouterHooks/types/utils/RandomUtil.d.ts @@ -111,6 +111,13 @@ export declare class RandomUtil { getFloat(min: number, max: number): number; getBool(): boolean; getPercentOfValue(percent: number, number: number, toFixed?: number): number; + /** + * Reduce a value by a percentage + * @param number Value to reduce + * @param percentage Percentage to reduce value by + * @returns Reduced value + */ + reduceValueByPercent(number: number, percentage: number): number; /** * Check if number passes a check out of 100 * @param chancePercent value check needs to be above